Forwarded from easyoffer
Я поставил целью сбора скромные 300 тыс. рублей, но ребята, вы накидали больше млн. всего за 1 день. Это просто невероятно!
Благодаря вашей поддержке, я смогу привлечь еще больше людей для разработки сайта и обработки собеседований. Ваш вклад сделает проект качественнее и ускорит его выход! Огромное вам спасибо!
Краудфандинг будет продолжаться еще 31 день и все кто поддержать проект сейчас, до его выхода, смогут получить:
🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
➕ Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)
Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer
Огромное спасибо за вашу поддержку! 🤝
Благодаря вашей поддержке, я смогу привлечь еще больше людей для разработки сайта и обработки собеседований. Ваш вклад сделает проект качественнее и ускорит его выход! Огромное вам спасибо!
Краудфандинг будет продолжаться еще 31 день и все кто поддержать проект сейчас, до его выхода, смогут получить:
🚀 PRO-тариф на 1 год, по цене месячной подписки на релизе.
➕ Доступ к закрытому бета-тесту easyoffer 2.0 (середина–конец мая)
Поддержать проект можно здесь:
https://planeta.ru/campaigns/easyoffer
Огромное спасибо за вашу поддержку! 🤝
Задача: 1326. Minimum Number of Taps to Open to Water a Garden
Сложность: hard
Есть одномерный сад на оси x. Сад начинается в точке 0 и заканчивается в точке n. (т.е. длина сада равна n).
В саду есть n + 1 кранов, расположенных в точках [0, 1, ..., n].
Даны целое число n и целочисленный массив ranges длиной n + 1, где ranges[i] (индексация начинается с 0) означает, что i-й кран может поливать область [i - ranges[i], i + ranges[i]], если он открыт.
Верните минимальное количество кранов, которые должны быть открыты для полива всего сада. Если сад невозможно полить, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Объявите массив dp размера n+1. Инициализируйте его значениями бесконечности (в коде используем большое число 10^9 для представления бесконечности). Установите dp[0] в 0 (базовый случай DP).
2⃣ Итерируйтесь от i до n (через каждый кран слева направо). Рассчитайте самую левую позицию, достижимую текущим краном, как tap_start=max(0,i−ranges[i]). И самую правую позицию tap_end=min(n,i+ranges[i]).
3⃣ Итерируйтесь через позиции j от tap_start до tap_end (в пределах досягаемости крана). Обновите dp[tap_end] значением dp[j]+1, если оно меньше. Если dp[n] остается бесконечным, значит, полить весь сад невозможно, и мы возвращаем −1. Верните dp[n].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Есть одномерный сад на оси x. Сад начинается в точке 0 и заканчивается в точке n. (т.е. длина сада равна n).
В саду есть n + 1 кранов, расположенных в точках [0, 1, ..., n].
Даны целое число n и целочисленный массив ranges длиной n + 1, где ranges[i] (индексация начинается с 0) означает, что i-й кран может поливать область [i - ranges[i], i + ranges[i]], если он открыт.
Верните минимальное количество кранов, которые должны быть открыты для полива всего сада. Если сад невозможно полить, верните -1.
Пример:
Input: n = 5, ranges = [3,4,1,1,0,0]
Output: 1
Explanation: The tap at point 0 can cover the interval [-3,3]
The tap at point 1 can cover the interval [-3,5]
The tap at point 2 can cover the interval [1,3]
The tap at point 3 can cover the interval [2,4]
The tap at point 4 can cover the interval [4,4]
The tap at point 5 can cover the interval [5,5]
Opening Only the second tap will water the whole garden [0,5]
public class Solution {
public int MinTaps(int n, int[] ranges) {
const int INF = int.MaxValue;
int[] dp = new int[n + 1];
Array.Fill(dp, INF);
dp[0] = 0;
for (int i = 0; i <= n; i++) {
int tapStart = Math.Max(0, i - ranges[i]);
int tapEnd = Math.Min(n, i + ranges[i]);
for (int j = tapStart; j <= tapEnd; j++) {
dp[tapEnd] = Math.Min(dp[tapEnd], dp[j] + 1);
}
}
return dp[n] == INF ? -1 : dp[n];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1167. Minimum Cost to Connect Sticks
Сложность: medium
У вас есть несколько палочек с положительными целыми длинами. Эти длины даны в виде массива sticks, где sticks[i] — длина i-й палочки.
Вы можете соединить любые две палочки длиной x и y в одну палочку, заплатив стоимость x + y. Вы должны соединить все палочки, пока не останется только одна палочка.
Верните минимальную стоимость соединения всех данных палочек в одну палочку таким образом.
Пример:
👨💻 Алгоритм:
1⃣ Всегда выбирайте две самые маленькие палочки для соединения и продолжайте делать это, пока не останется только одна палочка. Рассмотрим 4 палочки следующих длин: sticks=[a1, a2, a3, a4]. Попробуем соединить их слева направо. После первого соединения у нас будет: sticks=[(a1 + a2), a3, a4], стоимость=(a1 + a2). После второго соединения у нас будет: sticks=[(a1 + a2 + a3), a4], стоимость=(a1 + a2)+(a1 + a2 + a3). И, наконец, последняя палочка будет выглядеть так: sticks=[(a1 + a2 + a3 + a4)], стоимость=(a1 + a2)+(a1 + a2 + a3)+(a1 + a2 + a3 + a4).
2⃣ Итоговая стоимость может быть переписана следующим образом: стоимость=(3a1 + 3a2 + 2a3 + a4). Как видим, палочки, которые соединяются первыми, включаются в итоговую стоимость больше, чем те, которые выбираются позже. Следовательно, оптимально сначала выбирать меньшие палочки, чтобы получить наименьшую стоимость.
3⃣ Для выполнения следующих задач будет оптимальна структура данных min heap (которая обычно реализуется как PriorityQueue в большинстве языков): получить две самые маленькие палочки (stick1 и stick2) из массива; добавить одну палочку (stick1 + stick2) обратно в массив. Эта структура данных дает сложность O(logN) для обеих операций.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
У вас есть несколько палочек с положительными целыми длинами. Эти длины даны в виде массива sticks, где sticks[i] — длина i-й палочки.
Вы можете соединить любые две палочки длиной x и y в одну палочку, заплатив стоимость x + y. Вы должны соединить все палочки, пока не останется только одна палочка.
Верните минимальную стоимость соединения всех данных палочек в одну палочку таким образом.
Пример:
Input: sticks = [5]
Output: 0
Explanation: There is only one stick, so you don't need to do anything. The total cost is 0.
using System;
using System.Collections.Generic;
public class Solution {
public int ConnectSticks(int[] sticks) {
int totalCost = 0;
PriorityQueue<int, int> pq = new PriorityQueue<int, int>();
foreach (int stick in sticks) {
pq.Enqueue(stick, stick);
}
while (pq.Count > 1) {
int stick1 = pq.Dequeue();
int stick2 = pq.Dequeue();
int cost = stick1 + stick2;
totalCost += cost;
pq.Enqueue(cost, cost);
}
return totalCost;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1248. Count Number of Nice Subarrays
Сложность: medium
Вам даны две строки s1 и s2 одинаковой длины, состоящие только из букв "x" и "y". Ваша задача - сделать эти две строки равными друг другу. Вы можете поменять местами любые два символа, принадлежащие разным строкам, что означает: поменять местами s1[i] и s2[j]. Верните минимальное количество обменов, необходимое для того, чтобы сделать s1 и s2 равными, или верните -1, если это невозможно сделать.
Пример:
👨💻 Алгоритм:
1⃣ Преобразуйте массив чисел nums, заменив все чётные числа на 0, а все нечётные числа на 1.
2⃣ Используя технику скользящего окна (или двух указателей), найдите все подмассивы, содержащие ровно k единиц.
3⃣ Подсчитайте количество таких подмассивов и верните этот результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам даны две строки s1 и s2 одинаковой длины, состоящие только из букв "x" и "y". Ваша задача - сделать эти две строки равными друг другу. Вы можете поменять местами любые два символа, принадлежащие разным строкам, что означает: поменять местами s1[i] и s2[j]. Верните минимальное количество обменов, необходимое для того, чтобы сделать s1 и s2 равными, или верните -1, если это невозможно сделать.
Пример:
Input: arr = [1,2]
Output: 2
public class Solution {
public int NumberOfSubarrays(int[] nums, int k) {
return AtMost(nums, k) - AtMost(nums, k - 1);
}
private int AtMost(int[] nums, int k) {
int res = 0, left = 0, count = 0;
for (int right = 0; right < nums.Length; right++) {
if (nums[right] % 2 == 1) count++;
while (count > k) {
if (nums[left++] % 2 == 1) count--;
}
res += right - left + 1;
}
return res;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1146. Snapshot Array
Сложность: medium
Реализуйте SnapshotArray, который поддерживает следующий интерфейс:
SnapshotArray(int length) инициализирует структуру данных, похожую на массив, с заданной длиной. Изначально каждый элемент равен 0.
void set(index, val) устанавливает элемент с заданным индексом равным val.
int snap() делает снимок массива и возвращает snap_id: общее количество вызовов snap() минус 1.
int get(index, snap_id) возвращает значение на заданном индексе в момент, когда мы сделали снимок с указанным snap_id.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация: Для каждого элемента nums[i] в массиве создайте пустой список для хранения его исторических значений в формате [snap_id, value]. Инициализируйте каждый список, добавив первую запись [0, 0].
2⃣ Метод set: Добавьте историческую запись [snap_id, value] в список записей historyRecords[index].
3⃣ Методы snap и get:
Метод snap возвращает snap_id и увеличивает его на 1.
Метод get использует бинарный поиск, чтобы найти индекс последней вставки snap_id в данный снимок (целевой индекс будет snap_index - 1). Возвращает historyRecords[index][snap_index - 1][1].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Реализуйте SnapshotArray, который поддерживает следующий интерфейс:
SnapshotArray(int length) инициализирует структуру данных, похожую на массив, с заданной длиной. Изначально каждый элемент равен 0.
void set(index, val) устанавливает элемент с заданным индексом равным val.
int snap() делает снимок массива и возвращает snap_id: общее количество вызовов snap() минус 1.
int get(index, snap_id) возвращает значение на заданном индексе в момент, когда мы сделали снимок с указанным snap_id.
Пример:
Input: ["SnapshotArray","set","snap","set","get"]
[[3],[0,5],[],[0,6],[0,0]]
Output: [null,null,0,null,5]
Explanation:
SnapshotArray snapshotArr = new SnapshotArray(3); // set the length to be 3
snapshotArr.set(0,5); // Set array[0] = 5
snapshotArr.snap(); // Take a snapshot, return snap_id = 0
snapshotArr.set(0,6);
snapshotArr.get(0,0); // Get the value of array[0] with snap_id = 0, return 5
Метод snap возвращает snap_id и увеличивает его на 1.
Метод get использует бинарный поиск, чтобы найти индекс последней вставки snap_id в данный снимок (целевой индекс будет snap_index - 1). Возвращает historyRecords[index][snap_index - 1][1].
public class SnapshotArray {
private int snapId = 0;
private List<SortedDictionary<int, int>> historyRecords;
public SnapshotArray(int length) {
historyRecords = new List<SortedDictionary<int, int>>(length);
for (int i = 0; i < length; i++) {
historyRecords.Add(new SortedDictionary<int, int> { { 0, 0 } });
}
}
public void Set(int index, int val) {
historyRecords[index][snapId] = val;
}
public int Snap() {
return snapId++;
}
public int Get(int index, int snapId) {
var record = historyRecords[index];
while (snapId >= 0) {
if (record.ContainsKey(snapId)) {
return record[snapId];
}
snapId--;
}
return 0;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 967. Numbers With Same Consecutive Differences
Сложность: medium
Даны два целых числа n и k, верните массив всех целых чисел длины n, где разница между каждыми двумя последовательными цифрами равна k. Вы можете вернуть ответ в любом порядке.
Учтите, что целые числа не должны начинаться с нулей. Целые числа, такие как 02 и 043, не допускаются.
Пример:
👨💻 Алгоритм:
1⃣ Если n равно 1, верните массив от 0 до 9, так как все однозначные числа являются допустимыми.
2⃣ Инициализируйте список очередей начальными цифрами от 1 до 9.
3⃣ Для каждого уровня (от 1 до n-1) создайте новый список очередей, добавляя к каждому числу в текущей очереди допустимые цифры, которые удовлетворяют условию разницы k.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны два целых числа n и k, верните массив всех целых чисел длины n, где разница между каждыми двумя последовательными цифрами равна k. Вы можете вернуть ответ в любом порядке.
Учтите, что целые числа не должны начинаться с нулей. Целые числа, такие как 02 и 043, не допускаются.
Пример:
Input: n = 3, k = 7
Output: [181,292,707,818,929]
Explanation: Note that 070 is not a valid number, because it has leading zeroes.
public class Solution {
public int[] NumsSameConsecDiff(int N, int K) {
if (N == 1) return Enumerable.Range(0, 10).ToArray();
var queue = new List<int>(Enumerable.Range(1, 9));
for (int level = 1; level < N; ++level) {
var nextQueue = new List<int>();
foreach (int num in queue) {
int tailDigit = num % 10;
var nextDigits = new int[] { tailDigit + K, tailDigit - K };
foreach (int nextDigit in nextDigits) {
if (nextDigit >= 0 && nextDigit < 10) {
nextQueue.Add(num * 10 + nextDigit);
}
}
}
queue = nextQueue;
}
return queue.ToArray();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1037. Valid Boomerang
Сложность: easy
Если задан массив points, где points[i] = [xi, yi] представляет точку на плоскости X-Y, верните true, если эти точки являются бумерангом. Бумеранг - это набор из трех точек, которые отличаются друг от друга и не являются прямой линией.
Пример:
👨💻 Алгоритм:
1⃣ Проверка уникальности точек:
Убедитесь, что все три точки уникальны. Если любые две точки совпадают, то это не бумеранг.
2⃣ Проверка на коллинеарность:
Используйте определитель (или площадь параллелограмма) для проверки, находятся ли три точки на одной прямой. Если площадь параллелограмма, образованного тремя точками, равна нулю, то точки коллинеарны.
3⃣ Результат:
Если точки уникальны и не коллинеарны, верните true. В противном случае, верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Если задан массив points, где points[i] = [xi, yi] представляет точку на плоскости X-Y, верните true, если эти точки являются бумерангом. Бумеранг - это набор из трех точек, которые отличаются друг от друга и не являются прямой линией.
Пример:
Input: blocked = [[0,1],[1,0]], source = [0,0], target = [0,2]
Output: false
Убедитесь, что все три точки уникальны. Если любые две точки совпадают, то это не бумеранг.
Используйте определитель (или площадь параллелограмма) для проверки, находятся ли три точки на одной прямой. Если площадь параллелограмма, образованного тремя точками, равна нулю, то точки коллинеарны.
Если точки уникальны и не коллинеарны, верните true. В противном случае, верните false.
public class Solution {
public bool IsBoomerang(int[][] points) {
int x1 = points[0][0], y1 = points[0][1];
int x2 = points[1][0], y2 = points[1][1];
int x3 = points[2][0], y3 = points[2][1];
return (x1 != x2 || y1 != y2) &&
(x1 != x3 || y1 != y3) &&
(x2 != x3 || y2 != y3) &&
(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) != 0;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Задача: 1510. Stone Game IV
Сложность: hard
Алиса и Боб поочередно играют в игру, причем Алиса начинает первой.
Изначально в куче n камней. В ходе каждого хода игрок удаляет любое ненулевое количество камней, являющееся квадратом целого числа.
Кроме того, если игрок не может сделать ход, он/она проигрывает игру.
Дано положительное целое число n, верните true, если и только если Алиса выиграет игру, иначе верните false, предполагая, что оба игрока играют оптимально.
Пример:
👨💻 Алгоритм:
1⃣ Функция dfs(remain) представляет собой проверку, должен ли текущий игрок выиграть при оставшихся remain камнях.
2⃣ Для определения результата dfs(n) необходимо итерировать k от 0, чтобы проверить, существует ли такое k, что dfs(remain - k*k) == False. Чтобы предотвратить избыточные вычисления, используйте карту для хранения результатов функции dfs.
3⃣ Не забудьте базовые случаи: dfs(0) == False и dfs(1) == True.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Алиса и Боб поочередно играют в игру, причем Алиса начинает первой.
Изначально в куче n камней. В ходе каждого хода игрок удаляет любое ненулевое количество камней, являющееся квадратом целого числа.
Кроме того, если игрок не может сделать ход, он/она проигрывает игру.
Дано положительное целое число n, верните true, если и только если Алиса выиграет игру, иначе верните false, предполагая, что оба игрока играют оптимально.
Пример:
Input: n = 1
Output: true
Explanation: Alice can remove 1 stone winning the game because Bob doesn't have any moves.
public class Solution {
public bool WinnerSquareGame(int n) {
Dictionary<int, bool> cache = new Dictionary<int, bool>();
cache[0] = false;
return Dfs(cache, n);
}
public bool Dfs(Dictionary<int, bool> cache, int remain) {
if (cache.ContainsKey(remain)) {
return cache[remain];
}
int sqrtRoot = (int) Math.Sqrt(remain);
for (int i = 1; i <= sqrtRoot; ++i) {
if (!Dfs(cache, remain - i * i)) {
cache[remain] = true;
return true;
}
}
cache[remain] = false;
return false;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 920. Number of Music Playlists
Сложность: hard
В вашем плеере есть n разных песен. Во время путешествия вы хотите прослушать goal песен (не обязательно разных). Чтобы избежать скуки, вы создадите плейлист таким образом, чтобы: каждая песня играла хотя бы один раз. Песня может быть проиграна снова только в том случае, если было проиграно k других песен. Учитывая n, цель и k, верните количество возможных плейлистов, которые вы можете создать. Поскольку ответ может быть очень большим, верните его по модулю 10^9 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Создать двумерный массив dp, где dp[i][j] представляет количество возможных плейлистов длины i, содержащих j различных песен.
2⃣ Инициализировать dp[0][0] = 1, что означает, что существует один способ создать плейлист длины 0 с 0 песнями.
Заполнить массив dp, используя два случая:
Добавление новой песни, которая не была проиграна раньше: dp[i][j] += dp[i-1][j-1] * (n - j + 1)
Повторное проигрывание песни, если было проиграно k других песен: dp[i][j] += dp[i-1][j] * max(j - k, 0)
3⃣ Ответ находится в dp[goal][n].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
В вашем плеере есть n разных песен. Во время путешествия вы хотите прослушать goal песен (не обязательно разных). Чтобы избежать скуки, вы создадите плейлист таким образом, чтобы: каждая песня играла хотя бы один раз. Песня может быть проиграна снова только в том случае, если было проиграно k других песен. Учитывая n, цель и k, верните количество возможных плейлистов, которые вы можете создать. Поскольку ответ может быть очень большим, верните его по модулю 10^9 + 7.
Пример:
Input: n = 3, goal = 3, k = 1
Output: 6
Заполнить массив dp, используя два случая:
Добавление новой песни, которая не была проиграна раньше: dp[i][j] += dp[i-1][j-1] * (n - j + 1)
Повторное проигрывание песни, если было проиграно k других песен: dp[i][j] += dp[i-1][j] * max(j - k, 0)
public class Solution {
public int NumMusicPlaylists(int n, int goal, int k) {
const int MOD = 1_000_000_007;
long[,] dp = new long[goal + 1, n + 1];
dp[0, 0] = 1;
for (int i = 1; i <= goal; i++) {
for (int j = 1; j <= n; j++) {
dp[i, j] = dp[i - 1, j - 1] * (n - j + 1) % MOD;
if (j > k) {
dp[i, j] = (dp[i, j] + dp[i - 1, j] * (j - k) % MOD) % MOD;
}
}
}
return (int)dp[goal, n];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1249. Minimum Remove to Make Valid Parentheses
Сложность: medium
Дана строка s из '(' , ')' и строчных английских символов. Ваша задача - удалить минимальное количество скобок ( '(' или ')' в любых позициях), чтобы полученная строка со скобками была допустимой, и вернуть любую допустимую строку. Формально строка со скобками допустима тогда и только тогда, когда: она пустая, содержит только строчные символы, или может быть записана как AB (A, конкатенированная с B), где A и B - допустимые строки, или может быть записана как (A), где A - допустимая строка.
Пример:
👨💻 Алгоритм:
1⃣ Пройдите по строке s и сохраните индексы всех открывающих скобок '(' в стек. При встрече закрывающей скобки ')', удалите соответствующую открытую скобку из стека. Если в стеке нет соответствующей открывающей скобки, пометьте эту закрывающую скобку для удаления.
2⃣ После первого прохода, все оставшиеся в стеке открывающие скобки пометьте для удаления.
3⃣ Создайте новую строку, удалив все помеченные скобки.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана строка s из '(' , ')' и строчных английских символов. Ваша задача - удалить минимальное количество скобок ( '(' или ')' в любых позициях), чтобы полученная строка со скобками была допустимой, и вернуть любую допустимую строку. Формально строка со скобками допустима тогда и только тогда, когда: она пустая, содержит только строчные символы, или может быть записана как AB (A, конкатенированная с B), где A и B - допустимые строки, или может быть записана как (A), где A - допустимая строка.
Пример:
Input: s = "lee(t(c)o)de)"
Output: "lee(t(c)o)de"
public class Solution {
public string MinRemoveToMakeValid(string s) {
var stack = new Stack<int>();
var sb = new StringBuilder(s);
for (int i = 0; i < sb.Length; i++) {
if (sb[i] == '(') {
stack.Push(i);
} else if (sb[i] == ')') {
if (stack.Count > 0) {
stack.Pop();
} else {
sb[i] = '*';
}
}
}
while (stack.Count > 0) {
sb[stack.Pop()] = '*';
}
return sb.ToString().Replace("*", "");
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 845. Longest Mountain in Array
Сложность: medium
Вы можете вспомнить, что массив arr является горным массивом тогда и только тогда, когда:
длина массива arr >= 3
Существует индекс i (счёт начинается с 0) такой, что:
arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
Дан целочисленный массив arr, верните длину самой длинной подпоследовательности, которая является горной. Верните 0, если такой подпоследовательности нет.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменные для отслеживания текущего основания и максимальной длины горного массива.
2⃣ Для каждого индекса, который может быть началом горного массива, определите пиковый элемент и найдите правую границу горного массива.
3⃣ Если найден горный массив, обновите максимальную длину и переместите основание на конец текущего горного массива.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вы можете вспомнить, что массив arr является горным массивом тогда и только тогда, когда:
длина массива arr >= 3
Существует индекс i (счёт начинается с 0) такой, что:
arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
Дан целочисленный массив arr, верните длину самой длинной подпоследовательности, которая является горной. Верните 0, если такой подпоследовательности нет.
Пример:
Input: arr = [2,1,4,7,3,2,5]
Output: 5
Explanation: The largest mountain is [1,4,7,3,2] which has length 5.
public class Solution {
public int LongestMountain(int[] arr) {
int n = arr.Length;
int ans = 0;
int baseIndex = 0;
while (baseIndex < n) {
int end = baseIndex;
if (end + 1 < n && arr[end] < arr[end + 1]) {
while (end + 1 < n && arr[end] < arr[end + 1]) {
end++;
}
if (end + 1 < n && arr[end] > arr[end + 1]) {
while (end + 1 < n && arr[end] > arr[end + 1]) {
end++;
}
ans = Math.Max(ans, end - baseIndex + 1);
}
}
baseIndex = Math.Max(end, baseIndex + 1);
}
return ans;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Задача: 1273. Delete Tree Nodes
Сложность: medium
Дерево, укорененное в узле 0, задано следующим образом: количество узлов - nodes; значение i-го узла - value[i]; родитель i-го узла - parent[i]. Удалите все поддеревья, сумма значений узлов которых равна нулю. Верните количество оставшихся узлов в дереве.
Пример:
👨💻 Алгоритм:
1⃣ Постройте дерево из заданных узлов, значений и родителей.
2⃣ Используйте постфиксный обход для вычисления суммы значений в каждом поддереве и помечайте узлы для удаления, если их сумма равна нулю.
3⃣ Удалите отмеченные узлы и их поддеревья и верните количество оставшихся узлов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дерево, укорененное в узле 0, задано следующим образом: количество узлов - nodes; значение i-го узла - value[i]; родитель i-го узла - parent[i]. Удалите все поддеревья, сумма значений узлов которых равна нулю. Верните количество оставшихся узлов в дереве.
Пример:
Input: nodes = 7, parent = [-1,0,0,1,2,2,2], value = [1,-2,4,0,-2,-1,-1]
Output: 2
using System;
using System.Collections.Generic;
public class Solution {
public int DeleteTreeNodes(int nodes, int[] parent, int[] value) {
var tree = new Dictionary<int, List<int>>();
for (int i = 0; i < nodes; i++) {
if (!tree.ContainsKey(parent[i])) tree[parent[i]] = new List<int>();
tree[parent[i]].Add(i);
}
(int, int) Dfs(int node) {
int totalSum = value[node];
int totalCount = 1;
if (tree.ContainsKey(node)) {
foreach (int child in tree[node]) {
var (childSum, childCount) = Dfs(child);
totalSum += childSum;
totalCount += childCount;
}
}
return totalSum == 0 ? (0, 0) : (totalSum, totalCount);
}
return Dfs(0).Item2;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Задача: 921. Minimum Add to Make Parentheses Valid
Сложность: medium
Строка со скобками допустима тогда и только тогда, когда: это пустая строка, ее можно записать как AB (A, совмещенное с B), где A и B - допустимые строки, или ее можно записать как (A), где A - допустимая строка. Вам дана строка s со скобками. За один ход вы можете вставить скобку в любую позицию строки. Например, если s = "()))", вы можете вставить открывающую скобку в виде "(()))" или закрывающую скобку в виде "())))". Верните минимальное количество ходов, необходимое для того, чтобы сделать s допустимой.
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать два счетчика open_needed и close_needed.
2⃣ Пройти по строке s символ за символом:
Если текущий символ - открывающая скобка (, увеличьте open_needed.
Если текущий символ - закрывающая скобка ), проверьте:
Если open_needed больше 0, уменьшите open_needed.
Иначе увеличьте close_needed.
3⃣ Суммируйте значения open_needed и close_needed, чтобы получить минимальное количество вставок.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Строка со скобками допустима тогда и только тогда, когда: это пустая строка, ее можно записать как AB (A, совмещенное с B), где A и B - допустимые строки, или ее можно записать как (A), где A - допустимая строка. Вам дана строка s со скобками. За один ход вы можете вставить скобку в любую позицию строки. Например, если s = "()))", вы можете вставить открывающую скобку в виде "(()))" или закрывающую скобку в виде "())))". Верните минимальное количество ходов, необходимое для того, чтобы сделать s допустимой.
Пример:
Input: n = 3, goal = 3, k = 1
Output: 6
Если текущий символ - открывающая скобка (, увеличьте open_needed.
Если текущий символ - закрывающая скобка ), проверьте:
Если open_needed больше 0, уменьшите open_needed.
Иначе увеличьте close_needed.
public class Solution {
public int MinAddToMakeValid(string s) {
int openNeeded = 0;
int closeNeeded = 0;
foreach (char c in s) {
if (c == '(') {
openNeeded++;
} else if (c == ')') {
if (openNeeded > 0) {
openNeeded--;
} else {
closeNeeded++;
}
}
}
return openNeeded + closeNeeded;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 657. Robot Return to Origin
Сложность: easy
На плоскости с координатами (0, 0) находится робот. Дана последовательность его движений, определите, возвращается ли робот в исходную точку (0, 0) после завершения всех своих движений.
Вам дана строка moves, представляющая последовательность движений робота, где moves[i] представляет его i-ое движение. Допустимые движения: 'R' (вправо), 'L' (влево), 'U' (вверх) и 'D' (вниз).
Верните true, если робот возвращается в исходную точку после завершения всех своих движений, или false в противном случае.
Примечание: направление, в котором "смотрит" робот, не имеет значения. 'R' всегда будет перемещать робота на один шаг вправо, 'L' всегда будет перемещать его на один шаг влево и т.д. Также предполагается, что величина перемещения робота одинакова для каждого хода.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация координат:
Начните с координат (0, 0).
2⃣ Обработка движений:
Пройдите по строке moves и обновляйте координаты в зависимости от движения:
'R' увеличивает координату x на 1.
'L' уменьшает координату x на 1.
'U' увеличивает координату y на 1.
'D' уменьшает координату y на 1.
3⃣ Проверка конечных координат:
Если после всех движений координаты снова равны (0, 0), верните true. В противном случае, верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
На плоскости с координатами (0, 0) находится робот. Дана последовательность его движений, определите, возвращается ли робот в исходную точку (0, 0) после завершения всех своих движений.
Вам дана строка moves, представляющая последовательность движений робота, где moves[i] представляет его i-ое движение. Допустимые движения: 'R' (вправо), 'L' (влево), 'U' (вверх) и 'D' (вниз).
Верните true, если робот возвращается в исходную точку после завершения всех своих движений, или false в противном случае.
Примечание: направление, в котором "смотрит" робот, не имеет значения. 'R' всегда будет перемещать робота на один шаг вправо, 'L' всегда будет перемещать его на один шаг влево и т.д. Также предполагается, что величина перемещения робота одинакова для каждого хода.
Пример:
Input: moves = "UD"
Output: true
Начните с координат (0, 0).
Пройдите по строке moves и обновляйте координаты в зависимости от движения:
'R' увеличивает координату x на 1.
'L' уменьшает координату x на 1.
'U' увеличивает координату y на 1.
'D' уменьшает координату y на 1.
Если после всех движений координаты снова равны (0, 0), верните true. В противном случае, верните false.
public class Solution {
public bool JudgeCircle(string moves) {
int x = 0, y = 0;
foreach (char move in moves) {
switch (move) {
case 'R': x++; break;
case 'L': x--; break;
case 'U': y++; break;
case 'D': y--; break;
}
}
return x == 0 && y == 0;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 909. Snakes and Ladders
Сложность: medium
Вам дана доска с целочисленной матрицей n x n, клетки которой помечены метками от 1 до n2 в стиле Бустрофедона, начиная с левого нижнего края доски (т.е. board[n - 1][0]) и чередуя направление в каждой строке. Вы начинаете на клетке 1 доски. В каждый ход, начиная с клетки curr, вы делаете следующее: выбираете клетку назначения next с меткой в диапазоне [curr + 1, min(curr + 6, n2)]. Этот выбор имитирует результат стандартного броска 6-гранного кубика: то есть всегда существует не более 6 мест назначения, независимо от размера доски. Если next имеет змейку или лестницу, вы должны двигаться к месту назначения этой змейки или лестницы. В противном случае вы переходите на следующий. Игра заканчивается, когда вы достигаете клетки n2. Клетка доски в строке r и столбце c имеет змейку или лестницу, если board[r][c] != -1. Местом назначения этой змейки или лестницы является доска[r][c]. В клетках 1 и n2 нет змейки или лестницы. Обратите внимание, что вы можете взять змейку или лестницу не более одного раза за ход. Если конечный пункт змейки или лестницы является началом другой змейки или лестницы, вы не ходите по последующей змейке или лестнице. Например, предположим, что доска имеет вид [[-1,4],[-1,3]], и на первом ходу ваш конечный квадрат - 2. Вы ходите по лестнице до квадрата 3, но не ходите по последующей лестнице до 4. Верните наименьшее количество ходов, необходимое для достижения квадрата n2. Если достичь квадрата невозможно, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Представить доску в виде одномерного массива, чтобы легко определить позицию следующего хода.
2⃣ Использовать BFS (поиск в ширину) для минимизации количества ходов до клетки n2.
В каждом ходе проверять клетки от curr + 1 до min(curr + 6, n2) и перемещаться по змейкам и лестницам, если они существуют.
3⃣ Если достижение клетки n2 невозможно, вернуть -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана доска с целочисленной матрицей n x n, клетки которой помечены метками от 1 до n2 в стиле Бустрофедона, начиная с левого нижнего края доски (т.е. board[n - 1][0]) и чередуя направление в каждой строке. Вы начинаете на клетке 1 доски. В каждый ход, начиная с клетки curr, вы делаете следующее: выбираете клетку назначения next с меткой в диапазоне [curr + 1, min(curr + 6, n2)]. Этот выбор имитирует результат стандартного броска 6-гранного кубика: то есть всегда существует не более 6 мест назначения, независимо от размера доски. Если next имеет змейку или лестницу, вы должны двигаться к месту назначения этой змейки или лестницы. В противном случае вы переходите на следующий. Игра заканчивается, когда вы достигаете клетки n2. Клетка доски в строке r и столбце c имеет змейку или лестницу, если board[r][c] != -1. Местом назначения этой змейки или лестницы является доска[r][c]. В клетках 1 и n2 нет змейки или лестницы. Обратите внимание, что вы можете взять змейку или лестницу не более одного раза за ход. Если конечный пункт змейки или лестницы является началом другой змейки или лестницы, вы не ходите по последующей змейке или лестнице. Например, предположим, что доска имеет вид [[-1,4],[-1,3]], и на первом ходу ваш конечный квадрат - 2. Вы ходите по лестнице до квадрата 3, но не ходите по последующей лестнице до 4. Верните наименьшее количество ходов, необходимое для достижения квадрата n2. Если достичь квадрата невозможно, верните -1.
Пример:
Input: board = [[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,35,-1,-1,13,-1],[-1,-1,-1,-1,-1,-1],[-1,15,-1,-1,-1,-1]]
Output: 4
В каждом ходе проверять клетки от curr + 1 до min(curr + 6, n2) и перемещаться по змейкам и лестницам, если они существуют.
using System;
using System.Collections.Generic;
public class Solution {
public int SnakesAndLadders(int[][] board) {
int n = board.Length;
int[] GetPos(int x) {
int quot = (x - 1) / n;
int rem = (x - 1) % n;
int row = n - 1 - quot;
int col = (row % 2 != n % 2) ? rem : n - 1 - rem;
return new int[] { row, col };
}
var visited = new HashSet<int>();
var queue = new Queue<int[]>();
queue.Enqueue(new int[] { 1, 0 });
while (queue.Count > 0) {
var curr = queue.Dequeue();
int pos = curr[0];
int steps = curr[1];
for (int i = 1; i <= 6; i++) {
int nextPos = pos + i;
if (nextPos > n * n) continue;
var rc = GetPos(nextPos);
int r = rc[0], c = rc[1];
if (board[r][c] != -1) {
nextPos = board[r][c];
}
if (nextPos == n * n) {
return steps + 1;
}
if (!visited.Contains(nextPos)) {
visited.Add(nextPos);
queue.Enqueue(new int[] { nextPos, steps + 1 });
}
}
}
return -1;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1043. Partition Array for Maximum Sum
Сложность: medium
Если задан целочисленный массив arr, разбейте его на (смежные) подмассивы длины не более k. После разбиения значения каждого подмассива меняются так, чтобы стать максимальным значением этого подмассива. Верните наибольшую сумму заданного массива после разбиения. Тестовые примеры генерируются таким образом, чтобы ответ умещался в 32-битное целое число.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация:
Создаем массив dp, где dp[i] будет хранить наибольшую сумму подмассива, заканчивающегося в позиции i.
2⃣ Заполнение массива dp:
Проходим по массиву arr и для каждой позиции i пытаемся разбить подмассив длины до k и обновить dp[i] с максимальной возможной суммой.
3⃣ Поддержание максимального значения в подмассиве:
Для каждого подмассива длины 1 до k, вычисляем максимальное значение в этом подмассиве и обновляем dp[i].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задан целочисленный массив arr, разбейте его на (смежные) подмассивы длины не более k. После разбиения значения каждого подмассива меняются так, чтобы стать максимальным значением этого подмассива. Верните наибольшую сумму заданного массива после разбиения. Тестовые примеры генерируются таким образом, чтобы ответ умещался в 32-битное целое число.
Пример:
Input: arr = [1,15,7,9,2,5,10], k = 3
Output: 84
Создаем массив dp, где dp[i] будет хранить наибольшую сумму подмассива, заканчивающегося в позиции i.
Проходим по массиву arr и для каждой позиции i пытаемся разбить подмассив длины до k и обновить dp[i] с максимальной возможной суммой.
Для каждого подмассива длины 1 до k, вычисляем максимальное значение в этом подмассиве и обновляем dp[i].
public class Solution {
public int MaxSumAfterPartitioning(int[] arr, int k) {
int n = arr.Length;
int[] dp = new int[n];
for (int i = 0; i < n; i++) {
int maxVal = 0;
for (int j = 1; j <= k; j++) {
if (i - j + 1 >= 0) {
maxVal = Math.Max(maxVal, arr[i - j + 1]);
if (i - j >= 0) {
dp[i] = Math.Max(dp[i], dp[i - j] + maxVal * j);
} else {
dp[i] = Math.Max(dp[i], maxVal * j);
}
}
}
}
return dp[n - 1];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1255. Maximum Score Words Formed by Letters
Сложность: hard
Даны список слов, список отдельных букв (могут повторяться) и оценка каждого символа. Верните максимальную оценку любого правильного набора слов, образованного с помощью заданных букв (words[i] не может быть использовано два или более раз). Не обязательно использовать все символы в буквах, каждая буква может быть использована только один раз. Оценка букв 'a', 'b', 'c', ... , 'z' задаются значениями score[0], score[1], ... , score[25] соответственно.
Пример:
👨💻 Алгоритм:
1⃣ Создайте функцию для вычисления оценки слова.
2⃣ Используйте метод перебора подмножеств (или битовое представление всех подмножеств) для нахождения всех возможных комбинаций слов.
Для каждой комбинации проверяйте, можно ли составить каждое слово из доступных букв.
3⃣ Вычислите суммарную оценку для каждой допустимой комбинации слов и сохраните максимальную оценку.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Даны список слов, список отдельных букв (могут повторяться) и оценка каждого символа. Верните максимальную оценку любого правильного набора слов, образованного с помощью заданных букв (words[i] не может быть использовано два или более раз). Не обязательно использовать все символы в буквах, каждая буква может быть использована только один раз. Оценка букв 'a', 'b', 'c', ... , 'z' задаются значениями score[0], score[1], ... , score[25] соответственно.
Пример:
Input: words = ["dog","cat","dad","good"], letters = ["a","a","c","d","d","d","g","o","o"], score = [1,0,9,5,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0]
Output: 23
Для каждой комбинации проверяйте, можно ли составить каждое слово из доступных букв.
public class Solution {
public int MaxScoreWords(string[] words, char[] letters, int[] score) {
Dictionary<char, int> letterCount = new Dictionary<char, int>();
foreach (char ch in letters) {
if (!letterCount.ContainsKey(ch)) {
letterCount[ch] = 0;
}
letterCount[ch]++;
}
int WordScore(string word) {
int total = 0;
foreach (char ch in word) {
total += score[ch - 'a'];
}
return total;
}
bool CanFormWord(string word, Dictionary<char, int> letterCount) {
Dictionary<char, int> count = new Dictionary<char, int>();
foreach (char ch in word) {
if (!count.ContainsKey(ch)) {
count[ch] = 0;
}
count[ch]++;
if (count[ch] > letterCount.GetValueOrDefault(ch, 0)) {
return false;
}
}
return true;
}
int maxScore = 0;
int n = words.Length;
for (int i = 1; i < (1 << n); i++) {
int currScore = 0;
Dictionary<char, int> usedLetters = new Dictionary<char, int>();
bool valid = true;
for (int j = 0; j < n; j++) {
if ((i & (1 << j)) != 0) {
string word = words[j];
if (CanFormWord(word, letterCount)) {
currScore += WordScore(word);
foreach (char ch in word) {
if (!usedLetters.ContainsKey(ch)) {
usedLetters[ch] = 0;
}
usedLetters[ch]++;
}
} else {
valid = false;
break;
}
}
}
if (valid) {
maxScore = Math.Max(maxScore, currScore);
}
}
return maxScore;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1238. Circular Permutation in Binary Representation
Сложность: medium
Даны 2 целых числа n и start. Ваша задача - вернуть любую перестановку p из (0,1,2.....,2^n -1) такую, что : p[0] = start p[i] и p[i+1] отличаются только одним битом в их двоичном представлении. p[0] и p[2^n -1] также должны отличаться только одним битом в их двоичном представлении.
Пример:
👨💻 Алгоритм:
1⃣ Генерация Грей-кода:
Генерация Грей-кода для чисел от 0 до 2𝑛−1
2⃣ Определение начальной позиции:
Находим индекс числа start в последовательности Грей-кода.
3⃣ Построение перестановки:
Формируем перестановку, начиная с числа start и следуя по циклическому Грей-коду.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны 2 целых числа n и start. Ваша задача - вернуть любую перестановку p из (0,1,2.....,2^n -1) такую, что : p[0] = start p[i] и p[i+1] отличаются только одним битом в их двоичном представлении. p[0] и p[2^n -1] также должны отличаться только одним битом в их двоичном представлении.
Пример:
Input: n = 2, start = 3
Output: [3,2,0,1]
Генерация Грей-кода для чисел от 0 до 2𝑛−1
Находим индекс числа start в последовательности Грей-кода.
Формируем перестановку, начиная с числа start и следуя по циклическому Грей-коду.
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public IList<int> CircularPermutation(int n, int start) {
var gray = GrayCode(n);
int startIndex = gray.IndexOf(start);
var result = new List<int>();
result.AddRange(gray.Skip(startIndex));
result.AddRange(gray.Take(startIndex));
return result;
}
private List<int> GrayCode(int n) {
var result = new List<int>();
int numElements = 1 << n;
for (int i = 0; i < numElements; i++) {
result.Add(i ^ (i >> 1));
}
return result;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1122. Relative Sort Array
Сложность: easy
Даны два массива arr1 и arr2, элементы arr2 уникальны, и все элементы arr2 также присутствуют в arr1.
Отсортируйте элементы arr1 таким образом, чтобы относительный порядок элементов в arr1 был таким же, как в arr2. Элементы, которые не встречаются в arr2, должны быть размещены в конце arr1 в порядке возрастания.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и подсчёт:
Инициализируйте пустой массив result и массив remaining для хранения оставшихся элементов.
Создайте хеш-таблицу countMap для хранения количества вхождений каждого элемента из arr2 в arr1.
2⃣ Заполнение countMap и remaining:
Пройдитесь по элементам arr1 и если элемент присутствует в countMap, увеличьте его счетчик. Если элемент не присутствует в arr2, добавьте его в remaining.
3⃣ Формирование результирующего массива:
Пройдитесь по arr2 и добавьте элементы в result в соответствии с их количеством в countMap.
Отсортируйте массив remaining и добавьте его элементы в result.
Верните result в виде массива.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны два массива arr1 и arr2, элементы arr2 уникальны, и все элементы arr2 также присутствуют в arr1.
Отсортируйте элементы arr1 таким образом, чтобы относительный порядок элементов в arr1 был таким же, как в arr2. Элементы, которые не встречаются в arr2, должны быть размещены в конце arr1 в порядке возрастания.
Пример:
Input: arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
Output: [2,2,2,1,4,3,3,9,6,7,19]
Инициализируйте пустой массив result и массив remaining для хранения оставшихся элементов.
Создайте хеш-таблицу countMap для хранения количества вхождений каждого элемента из arr2 в arr1.
Пройдитесь по элементам arr1 и если элемент присутствует в countMap, увеличьте его счетчик. Если элемент не присутствует в arr2, добавьте его в remaining.
Пройдитесь по arr2 и добавьте элементы в result в соответствии с их количеством в countMap.
Отсортируйте массив remaining и добавьте его элементы в result.
Верните result в виде массива.
public class Solution {
public int[] RelativeSortArray(int[] arr1, int[] arr2) {
var countMap = new Dictionary<int, int>();
var remaining = new List<int>();
var result = new List<int>();
foreach (var value in arr2) {
countMap[value] = 0;
}
foreach (var value in arr1) {
if (countMap.ContainsKey(value)) {
countMap[value]++;
} else {
remaining.Add(value);
}
}
remaining.Sort();
foreach (var value in arr2) {
for (int i = 0; i < countMap[value]; i++) {
result.Add(value);
}
}
result.AddRange(remaining);
return result.ToArray();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 33. Search in Rotated Sorted Array
Сложность: medium
Дан отсортированный массив
Пример:
👨💻 Алгоритм:
1⃣ Использовать бинарный поиск для нахождения индекса поворота.
2⃣ Определить, в какой из двух отсортированных частей массива находится
3⃣ Выполнить бинарный поиск в нужной части массива.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан отсортированный массив
nums, который мог быть повернут в неизвестном индексе. Необходимо найти индекс элемента target или вернуть -1, если его нет. Алгоритм должен работать за O(log n). Пример:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
target. public class Solution {
public int Search(int[] nums, int target) {
int left = 0, right = nums.Length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid])
right = mid - 1;
else
left = mid + 1;
} else {
if (nums[mid] < target && target <= nums[right])
left = mid + 1;
else
right = mid - 1;
}
}
return -1;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM