Задача: 856. Score of Parentheses
Сложность: medium
Дана строка s, состоящая из сбалансированных скобок, верните счёт строки.
Счёт сбалансированной строки скобок основывается на следующих правилах:
"()" имеет счёт 1.
AB имеет счёт A + B, где A и B — сбалансированные строки скобок.
(A) имеет счёт 2 * A, где A — сбалансированная строка скобок.
Пример:
👨💻 Алгоритм:
1⃣ Назовём сбалансированную строку примитивной, если её нельзя разделить на две непустые сбалансированные строки.
2⃣ Отслеживая баланс (количество открывающих скобок минус количество закрывающих скобок), мы можем разделить строку S на примитивные подстроки S = P_1 + P_2 + ... + P_n. Тогда, по определению, score(S) = score(P_1) + score(P_2) + ... + score(P_n).
3⃣ Для каждой примитивной подстроки (S[i], S[i+1], ..., S[k]), если длина строки равна 2, то её счёт равен 1. В противном случае, счёт равен удвоенному счёту подстроки (S[i+1], S[i+2], ..., S[k-1]).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана строка s, состоящая из сбалансированных скобок, верните счёт строки.
Счёт сбалансированной строки скобок основывается на следующих правилах:
"()" имеет счёт 1.
AB имеет счёт A + B, где A и B — сбалансированные строки скобок.
(A) имеет счёт 2 * A, где A — сбалансированная строка скобок.
Пример:
Input: s = "()"
Output: 1
public class Solution {
public int ScoreOfParentheses(string S) {
return F(S, 0, S.Length);
}
private int F(string S, int i, int j) {
int ans = 0, bal = 0;
for (int k = i; k < j; ++k) {
bal += S[k] == '(' ? 1 : -1;
if (bal == 0) {
if (k - i == 1) ans++;
else ans += 2 * F(S, i + 1, k);
i = k + 1;
}
}
return ans;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 167. Two Sum II - Input Array Is Sorted
Сложность: medium
Дан массив целых чисел numbers, индексированный с 1, который уже отсортирован в неубывающем порядке. Найдите два числа так, чтобы их сумма составляла заданное целевое число. Пусть эти два числа будут numbers[index1] и numbers[index2], где 1 <= index1 < index2 <= numbers.length.
Верните индексы этих двух чисел, index1 и index2, увеличенные на один, в виде массива из двух элементов [index1, index2].
Тесты генерируются таким образом, что существует ровно одно решение. Нельзя использовать один и тот же элемент дважды.
Ваше решение должно использовать только константное дополнительное пространство.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация указателей:
Используйте два указателя: один (left) начинается с начала массива, а другой (right) - с конца.
2⃣ Поиск решения:
Сравните сумму элементов, на которые указывают left и right, с целевым значением target.
Если сумма равна target, верните индексы этих элементов как решение.
Если сумма меньше target, увеличьте left (так как массив отсортирован и увеличение left увеличивает сумму).
Если сумма больше target, уменьшите right (чтобы уменьшить сумму).
3⃣ Продолжение до нахождения решения:
Перемещайте указатели left и right, повторяя сравнение, пока не будет найдено решение.
Учитывая, что задача гарантирует существование ровно одного решения, этот метод всегда найдет ответ.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел numbers, индексированный с 1, который уже отсортирован в неубывающем порядке. Найдите два числа так, чтобы их сумма составляла заданное целевое число. Пусть эти два числа будут numbers[index1] и numbers[index2], где 1 <= index1 < index2 <= numbers.length.
Верните индексы этих двух чисел, index1 и index2, увеличенные на один, в виде массива из двух элементов [index1, index2].
Тесты генерируются таким образом, что существует ровно одно решение. Нельзя использовать один и тот же элемент дважды.
Ваше решение должно использовать только константное дополнительное пространство.
Пример:
Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore, index1 = 1, index2 = 2. We return [1, 2].
Используйте два указателя: один (left) начинается с начала массива, а другой (right) - с конца.
Сравните сумму элементов, на которые указывают left и right, с целевым значением target.
Если сумма равна target, верните индексы этих элементов как решение.
Если сумма меньше target, увеличьте left (так как массив отсортирован и увеличение left увеличивает сумму).
Если сумма больше target, уменьшите right (чтобы уменьшить сумму).
Перемещайте указатели left и right, повторяя сравнение, пока не будет найдено решение.
Учитывая, что задача гарантирует существование ровно одного решения, этот метод всегда найдет ответ.
public class Solution {
public int[] TwoSum(int[] numbers, int target) {
int low = 0;
int high = numbers.Length - 1;
while (low < high) {
int sum = numbers[low] + numbers[high];
if (sum == target) {
return new int[] { low + 1, high + 1 };
} else if (sum < target) {
++low;
} else {
--high;
}
}
return new int[] { -1, -1 };
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1416. Restore The Array
Сложность: hard
Программа должна была напечатать массив целых чисел. Программа забыла напечатать пробелы, и массив напечатан как строка цифр s, и всё, что мы знаем, это что все числа в массиве были в диапазоне [1, k] и в массиве нет ведущих нулей.
Учитывая строку s и целое число k, верните количество возможных массивов, которые могут быть напечатаны как s с использованием упомянутой программы. Так как ответ может быть очень большим, верните его по модулю 10^9 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Создать массив dp размера m + 1, чтобы хранить значения dfs(x).
2⃣ Для получения значения dfs(start), если dp[start] не равно нулю, вернуть его значение. Иначе:
Если s[start] == 0, вернуть 0.
Если start = m, вернуть 1.
Инициализировать count = 0, чтобы считать количество возможных массивов.
Перебрать все возможные конечные индексы end, и если s[start ~ end] представляет допустимое число, продолжить рекурсивный вызов dfs(end + 1) и обновить count как count += dfs(end + 1).
Обновить dp[start] значением dfs(start).
3⃣ Вернуть dfs(0).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Программа должна была напечатать массив целых чисел. Программа забыла напечатать пробелы, и массив напечатан как строка цифр s, и всё, что мы знаем, это что все числа в массиве были в диапазоне [1, k] и в массиве нет ведущих нулей.
Учитывая строку s и целое число k, верните количество возможных массивов, которые могут быть напечатаны как s с использованием упомянутой программы. Так как ответ может быть очень большим, верните его по модулю 10^9 + 7.
Пример:
Input: s = "1000", k = 10000
Output: 1
Explanation: The only possible array is [1000]
Если s[start] == 0, вернуть 0.
Если start = m, вернуть 1.
Инициализировать count = 0, чтобы считать количество возможных массивов.
Перебрать все возможные конечные индексы end, и если s[start ~ end] представляет допустимое число, продолжить рекурсивный вызов dfs(end + 1) и обновить count как count += dfs(end + 1).
Обновить dp[start] значением dfs(start).
public class Solution {
private int mod = 1_000_000_007;
private int Dfs(int[] dp, int start, string s, int k) {
if (dp[start] != 0) return dp[start];
if (start == s.Length) return 1;
if (s[start] == '0') return 0;
long count = 0;
for (int end = start; end < s.Length; ++end) {
string currNumber = s.Substring(start, end - start + 1);
if (long.Parse(currNumber) > k) break;
count = (count + Dfs(dp, end + 1, s, k)) % mod;
}
dp[start] = (int)count;
return (int)count;
}
public int NumberOfArrays(string s, int k) {
int[] dp = new int[s.Length + 1];
return Dfs(dp, 0, s, k);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1074. Number of Submatrices That Sum to Target
Сложность: hard
Дана матрица и целевое значение. Верните количество непустых подматриц, сумма элементов которых равна целевому значению.
Подматрица x1, y1, x2, y2 — это набор всех ячеек matrix[x][y] с x1 <= x <= x2 и y1 <= y <= y2.
Две подматрицы (x1, y1, x2, y2) и (x1', y1', x2', y2') различны, если у них есть какая-то различающаяся координата: например, если x1 != x1'.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте результат: count = 0. Вычислите количество строк: r = len(matrix) и количество столбцов: c = len(matrix[0]). Вычислите двумерную префиксную сумму ps, выделив еще одну строку и еще один столбец для нулевых значений.
2⃣ Итерируйте по строкам: r1 от 1 до r и r2 от r1 до r. Внутри этого двойного цикла фиксируйте левые и правые границы строк и инициализируйте хэш-таблицу для хранения префиксных сумм. Итерируйте по столбцам от 1 до c + 1, вычислите текущую префиксную сумму 1D curr_sum и увеличьте count на количество матриц, сумма которых равна target.
3⃣ Добавьте текущую префиксную сумму 1D в хэш-таблицу. Когда все итерации завершены, верните count.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дана матрица и целевое значение. Верните количество непустых подматриц, сумма элементов которых равна целевому значению.
Подматрица x1, y1, x2, y2 — это набор всех ячеек matrix[x][y] с x1 <= x <= x2 и y1 <= y <= y2.
Две подматрицы (x1, y1, x2, y2) и (x1', y1', x2', y2') различны, если у них есть какая-то различающаяся координата: например, если x1 != x1'.
Пример:
Input: matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
Output: 4
Explanation: The four 1x1 submatrices that only contain 0.
public class Solution {
public int NumSubmatrixSumTarget(int[][] matrix, int target) {
int r = matrix.Length, c = matrix[0].Length;
int[,] ps = new int[r + 1, c + 1];
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
ps[i, j] = ps[i - 1, j] + ps[i, j - 1] - ps[i - 1, j - 1] + matrix[i - 1][j - 1];
}
}
int count = 0;
for (int r1 = 1; r1 <= r; ++r1) {
for (int r2 = r1; r2 <= r; ++r2) {
Dictionary<int, int> h = new Dictionary<int, int>();
h[0] = 1;
for (int col = 1; col <= c; ++col) {
int currSum = ps[r2, col] - ps[r1 - 1, col];
if (h.ContainsKey(currSum - target)) {
count += h[currSum - target];
}
if (h.ContainsKey(currSum)) {
h[currSum]++;
} else {
h[currSum] = 1;
}
}
}
}
return count;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 141. Linked List Cycle
Сложность: easy
Дана переменная head, которая является началом связного списка. Определите, содержит ли связный список цикл.
Цикл в связном списке существует, если существует узел в списке, до которого можно добраться снова, последовательно следуя по указателю next. Внутренне переменная pos используется для обозначения индекса узла, к которому подключен указатель next последнего узла. Обратите внимание, что pos не передается в качестве параметра.
Верните true, если в связном списке есть цикл. В противном случае верните false.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация структуры данных:
Создайте хеш-таблицу (или множество) для хранения ссылок на узлы, чтобы отслеживать уже посещённые узлы.
2⃣ Обход списка:
Перемещайтесь по связному списку, начиная с головы (head), и проверяйте каждый узел по очереди.
3⃣ Проверка на цикл:
Если текущий узел равен null, это означает, что вы достигли конца списка, и список не имеет циклов. В этом случае верните false.
Если текущий узел уже содержится в хеш-таблице, это означает, что вы вернулись к ранее посещённому узлу, и, следовательно, в списке присутствует цикл. Верните true.
Если ни одно из этих условий не выполнено, добавьте текущий узел в хеш-таблицу и продолжите обход списка.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дана переменная head, которая является началом связного списка. Определите, содержит ли связный список цикл.
Цикл в связном списке существует, если существует узел в списке, до которого можно добраться снова, последовательно следуя по указателю next. Внутренне переменная pos используется для обозначения индекса узла, к которому подключен указатель next последнего узла. Обратите внимание, что pos не передается в качестве параметра.
Верните true, если в связном списке есть цикл. В противном случае верните false.
Пример:
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).
Создайте хеш-таблицу (или множество) для хранения ссылок на узлы, чтобы отслеживать уже посещённые узлы.
Перемещайтесь по связному списку, начиная с головы (head), и проверяйте каждый узел по очереди.
Если текущий узел равен null, это означает, что вы достигли конца списка, и список не имеет циклов. В этом случае верните false.
Если текущий узел уже содержится в хеш-таблице, это означает, что вы вернулись к ранее посещённому узлу, и, следовательно, в списке присутствует цикл. Верните true.
Если ни одно из этих условий не выполнено, добавьте текущий узел в хеш-таблицу и продолжите обход списка.
public class Solution {
public bool HasCycle(ListNode head) {
HashSet<ListNode> nodesSeen = new HashSet<ListNode>();
ListNode current = head;
while (current != null) {
if (nodesSeen.Contains(current)) {
return true;
}
nodesSeen.Add(current);
current = current.next;
}
return false;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 974. Subarray Sums Divisible by K
Сложность: medium
Дан целочисленный массив nums и целое число k. Верните количество непустых подмассивов, сумма которых делится на k.
Подмассив — это непрерывная часть массива.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и подготовка. Инициализируйте prefixMod = 0 для хранения остатка от суммы элементов до текущего индекса при делении на k. Инициализируйте result = 0 для хранения количества подмассивов, сумма которых делится на k. Инициализируйте массив modGroups длиной k, где modGroups[R] хранит количество подмассивов с остатком R. Установите modGroups[0] = 1.
2⃣ Итерирование по массиву. Для каждого элемента массива nums вычислите новый prefixMod как (prefixMod + nums[i] % k + k) % k, чтобы избежать отрицательных значений. Увеличьте result на значение modGroups[prefixMod], чтобы добавить количество подмассивов с текущим остатком. Увеличьте значение modGroups[prefixMod] на 1 для будущих совпадений.
3⃣ Возврат результата. Верните значение result, которое содержит количество подмассивов, сумма которых делится на k.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан целочисленный массив nums и целое число k. Верните количество непустых подмассивов, сумма которых делится на k.
Подмассив — это непрерывная часть массива.
Пример:
Input: nums = [4,5,0,-2,-3,1], k = 5
Output: 7
Explanation: There are 7 subarrays with a sum divisible by k = 5:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
public class Solution {
public int SubarraysDivByK(int[] nums, int k) {
int prefixMod = 0, result = 0;
int[] modGroups = new int[k];
modGroups[0] = 1;
foreach (int num in nums) {
prefixMod = (prefixMod + num % k + k) % k;
result += modGroups[prefixMod];
modGroups[prefixMod]++;
}
return result;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 616. Add Bold Tag in String
Сложность: medium
Вам дана строка s и массив строк words. Вы должны добавить закрытую пару полужирных тегов <b> и </b>, чтобы обернуть подстроки в s, которые существуют в words. Если две такие подстроки пересекаются, вы должны обернуть их вместе только одной парой закрытых полужирных тегов. Если две подстроки, обернутые полужирными тегами, идут подряд, вы должны объединить их. Верните s после добавления полужирных тегов.
Пример:
👨💻 Алгоритм:
1⃣ Найдите все позиции вхождений подстрок из words в строку s и пометьте эти позиции для выделения тегами <b> и </b>.
2⃣ Пройдитесь по помеченным позициям, чтобы определить области, которые нужно обернуть в полужирные теги, слияя пересекающиеся и смежные области.
3⃣ Постройте новую строку s, добавляя теги <b> и </b> в определенные позиции.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана строка s и массив строк words. Вы должны добавить закрытую пару полужирных тегов <b> и </b>, чтобы обернуть подстроки в s, которые существуют в words. Если две такие подстроки пересекаются, вы должны обернуть их вместе только одной парой закрытых полужирных тегов. Если две подстроки, обернутые полужирными тегами, идут подряд, вы должны объединить их. Верните s после добавления полужирных тегов.
Пример:
Input: s = "abcxyz123", words = ["abc","123"]
Output: "<b>abc</b>xyz<b>123</b>"
public class Solution {
public string AddBoldTag(string s, string[] words) {
int n = s.Length;
bool[] bold = new bool[n];
foreach (var word in words) {
int start = s.IndexOf(word);
while (start != -1) {
for (int i = start; i < start + word.Length; i++) {
bold[i] = true;
}
start = s.IndexOf(word, start + 1);
}
}
var result = new StringBuilder();
int j = 0;
while (j < n) {
if (bold[j]) {
result.Append("<b>");
while (j < n && bold[j]) {
result.Append(s[j]);
j++;
}
result.Append("</b>");
} else {
result.Append(s[j]);
j++;
}
}
return result.ToString();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 311. Sparse Matrix Multiplication
Сложность: medium
Даны две разреженные матрицы mat1 размером m x k и mat2 размером k x n. Верните результат перемножения матриц mat1 x mat2. Вы можете предположить, что умножение всегда возможно.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация результирующей матрицы
Создайте результирующую матрицу result размером m x n, заполненную нулями.
2⃣ Хранение ненулевых элементов
Пройдите по каждой строке матрицы mat1 и сохраните индексы и значения ненулевых элементов в хеш-карте mat1_map. Пройдите по каждой колонке матрицы mat2 и сохраните индексы и значения ненулевых элементов в хеш-карте mat2_map.
3⃣ Вычисление произведения
Для каждой строки i в mat1 и для каждой колонки j в mat2: Если в mat1_map есть ненулевой элемент в строке i и в mat2_map есть ненулевой элемент в колонке j с одинаковым индексом k, добавьте произведение этих элементов к result[i][j].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 311. Sparse Matrix Multiplication
Сложность: medium
Даны две разреженные матрицы mat1 размером m x k и mat2 размером k x n. Верните результат перемножения матриц mat1 x mat2. Вы можете предположить, что умножение всегда возможно.
Пример:
Input: mat1 = [[1,0,0],[-1,0,3]], mat2 = [[7,0,0],[0,0,0],[0,0,1]]
Output: [[7,0,0],[-7,0,3]]
Создайте результирующую матрицу result размером m x n, заполненную нулями.
Пройдите по каждой строке матрицы mat1 и сохраните индексы и значения ненулевых элементов в хеш-карте mat1_map. Пройдите по каждой колонке матрицы mat2 и сохраните индексы и значения ненулевых элементов в хеш-карте mat2_map.
Для каждой строки i в mat1 и для каждой колонки j в mat2: Если в mat1_map есть ненулевой элемент в строке i и в mat2_map есть ненулевой элемент в колонке j с одинаковым индексом k, добавьте произведение этих элементов к result[i][j].
public class Solution {
public int[][] Multiply(int[][] mat1, int[][] mat2) {
int n = mat1.Length;
int k = mat1[0].Length;
int m = mat2[0].Length;
int[][] ans = new int[n][];
for (int i = 0; i < n; i++) {
ans[i] = new int[m];
}
for (int rowIndex = 0; rowIndex < n; rowIndex++) {
for (int elementIndex = 0; elementIndex < k; elementIndex++) {
if (mat1[rowIndex][elementIndex] != 0) {
for (int colIndex = 0; colIndex < m; colIndex++) {
ans[rowIndex][colIndex] += mat1[rowIndex][elementIndex] * mat2[elementIndex][colIndex];
}
}
}
}
return ans;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1016. Binary String With Substrings Representing 1 To N
Сложность: medium
Если задана двоичная строка s и положительное целое число n, верните true, если двоичное представление всех целых чисел в диапазоне [1, n] является подстрокой s, или false в противном случае. Подстрока - это непрерывная последовательность символов в строке.
Пример:
👨💻 Алгоритм:
1⃣ Генерация двоичных строк:
Для каждого числа в диапазоне [1, n] сгенерируйте его двоичное представление.
2⃣ Проверка подстрок:
Проверьте, является ли каждое из двоичных представлений подстрокой строки s.
3⃣ Возврат результата:
Если все двоичные представления являются подстроками строки s, верните true. В противном случае, верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задана двоичная строка s и положительное целое число n, верните true, если двоичное представление всех целых чисел в диапазоне [1, n] является подстрокой s, или false в противном случае. Подстрока - это непрерывная последовательность символов в строке.
Пример:
Input: s = "0110", n = 3
Output: true
Для каждого числа в диапазоне [1, n] сгенерируйте его двоичное представление.
Проверьте, является ли каждое из двоичных представлений подстрокой строки s.
Если все двоичные представления являются подстроками строки s, верните true. В противном случае, верните false.
public class Solution {
public bool QueryString(string s, int n) {
for (int i = 1; i <= n; i++) {
string binary = Convert.ToString(i, 2);
if (!s.Contains(binary)) {
return false;
}
}
return true;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1426. Counting Elements
Сложность: easy
Дан целочисленный массив arr, посчитайте, сколько элементов x в нем есть таких, что x + 1 также находится в arr. Если в arr есть дубликаты, считайте их отдельно.
Пример:
👨💻 Алгоритм:
1⃣ Создайте вспомогательную функцию для проверки, содержится ли элемент в массиве.
2⃣ Итерируйте по каждому элементу массива и используйте вспомогательную функцию для проверки, содержится ли элемент x + 1 в массиве.
3⃣ Увеличьте счетчик, если x + 1 найден, и верните значение счетчика.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан целочисленный массив arr, посчитайте, сколько элементов x в нем есть таких, что x + 1 также находится в arr. Если в arr есть дубликаты, считайте их отдельно.
Пример:
Input: arr = [1,2,3]
Output: 2
Explanation: 1 and 2 are counted cause 2 and 3 are in arr.
public class Solution {
public int CountElements(int[] arr) {
int count = 0;
foreach (int x in arr) {
if (IntegerInArray(arr, x + 1)) {
count++;
}
}
return count;
}
public bool IntegerInArray(int[] arr, int target) {
foreach (int x in arr) {
if (x == target) {
return true;
}
}
return false;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 162. Find Peak Element
Сложность: medium
Пиковым элементом называется элемент, который строго больше своих соседей.
Для массива целых чисел nums с индексацией с нуля найдите пиковый элемент и верните его индекс. Если в массиве несколько пиков, верните индекс любого из пиков.
Вы можете представить, что nums[-1] = nums[n] = -∞. Другими словами, элемент всегда считается строго большим, чем сосед, находящийся за пределами массива.
Необходимо написать алгоритм, который работает за время O(log n).
Пример:
👨💻 Алгоритм:
1⃣ Начальная проверка:
Определяем средний элемент массива mid как mid = low + (high - low) / 2. Это помогает предотвратить возможное переполнение при больших значениях индексов.
2⃣ Определение направления поиска:
Сравниваем элемент nums[mid] с его правым соседом nums[mid + 1]. Если nums[mid] меньше nums[mid + 1], это указывает на наличие восходящей последовательности, и мы двигаемся вправо, устанавливая low = mid + 1. Это потому, что пик гарантированно находится в правой части.
Если nums[mid] больше nums[mid + 1], это указывает на наличие нисходящей последовательности, и пик находится либо в mid, либо слева от него, тогда устанавливаем high = mid.
3⃣ Завершение поиска:
Процесс продолжается до тех пор, пока low не станет равным high, что означает сужение поисковой области до одного элемента, который и является пиком, поскольку мы исключили все другие возможности.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Пиковым элементом называется элемент, который строго больше своих соседей.
Для массива целых чисел nums с индексацией с нуля найдите пиковый элемент и верните его индекс. Если в массиве несколько пиков, верните индекс любого из пиков.
Вы можете представить, что nums[-1] = nums[n] = -∞. Другими словами, элемент всегда считается строго большим, чем сосед, находящийся за пределами массива.
Необходимо написать алгоритм, который работает за время O(log n).
Пример:
Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.
Определяем средний элемент массива mid как mid = low + (high - low) / 2. Это помогает предотвратить возможное переполнение при больших значениях индексов.
Сравниваем элемент nums[mid] с его правым соседом nums[mid + 1]. Если nums[mid] меньше nums[mid + 1], это указывает на наличие восходящей последовательности, и мы двигаемся вправо, устанавливая low = mid + 1. Это потому, что пик гарантированно находится в правой части.
Если nums[mid] больше nums[mid + 1], это указывает на наличие нисходящей последовательности, и пик находится либо в mid, либо слева от него, тогда устанавливаем high = mid.
Процесс продолжается до тех пор, пока low не станет равным high, что означает сужение поисковой области до одного элемента, который и является пиком, поскольку мы исключили все другие возможности.
public class Solution {
public int FindPeakElement(int[] nums) {
return Search(nums, 0, nums.Length - 1);
}
public int Search(int[] nums, int l, int r) {
if (l == r)
return l;
int mid = (l + r) / 2;
if (nums[mid] > nums[mid + 1])
return Search(nums, l, mid);
return Search(nums, mid + 1, r);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1376. Time Needed to Inform All Employees
Сложность: medium
В компании работает n сотрудников, каждому из которых присвоен уникальный идентификатор от 0 до n - 1. Руководитель компании имеет идентификатор headID.
У каждого сотрудника есть один непосредственный начальник, указанный в массиве manager, где manager[i] — это непосредственный начальник i-го сотрудника, manager[headID] = -1. Также гарантируется, что отношения подчинения образуют древовидную структуру.
Руководитель компании хочет сообщить всем сотрудникам компании срочную новость. Он сообщит своим непосредственным подчиненным, а они сообщат своим подчиненным и так далее, пока все сотрудники не узнают о срочной новости.
i-й сотрудник нуждается в informTime[i] минутах, чтобы сообщить всем своим непосредственным подчиненным (т.е. через informTime[i] минут все его непосредственные подчиненные могут начать распространять новость).
Верните количество минут, необходимых для того, чтобы сообщить всем сотрудникам о срочной новости.
Пример:
👨💻 Алгоритм:
1⃣ Создайте список смежности adjList; индекс i будет хранить смежные узлы для сотрудника с идентификатором i.
2⃣ Итерируйте по сотрудникам от 0 до N - 1, и для каждого сотрудника i добавляйте ребро manager[i] -> i, если manager[i] не равен -1.
3⃣ Начните выполнение DFS с узла headID и временем 0 для каждого узла как curr. Обновите максимальное время maxTime, сравнив его с текущим временем. Итерируйте по смежным узлам curr и для каждого смежного узла выполните DFS с временем time + informTime[curr]. Когда DFS завершится, верните maxTime.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
В компании работает n сотрудников, каждому из которых присвоен уникальный идентификатор от 0 до n - 1. Руководитель компании имеет идентификатор headID.
У каждого сотрудника есть один непосредственный начальник, указанный в массиве manager, где manager[i] — это непосредственный начальник i-го сотрудника, manager[headID] = -1. Также гарантируется, что отношения подчинения образуют древовидную структуру.
Руководитель компании хочет сообщить всем сотрудникам компании срочную новость. Он сообщит своим непосредственным подчиненным, а они сообщат своим подчиненным и так далее, пока все сотрудники не узнают о срочной новости.
i-й сотрудник нуждается в informTime[i] минутах, чтобы сообщить всем своим непосредственным подчиненным (т.е. через informTime[i] минут все его непосредственные подчиненные могут начать распространять новость).
Верните количество минут, необходимых для того, чтобы сообщить всем сотрудникам о срочной новости.
Пример:
Input: n = 6, headID = 2, manager = [2,2,-1,2,2,2], informTime = [0,0,1,0,0,0]
Output: 1
Explanation: The head of the company with id = 2 is the direct manager of all the employees in the company and needs 1 minute to inform them all.
The tree structure of the employees in the company is shown.
public class Solution {
private int maxTime = int.MinValue;
private void DFS(List<int>[] adjList, int[] informTime, int curr, int time) {
maxTime = Math.Max(maxTime, time);
foreach (int adjacent in adjList[curr]) {
DFS(adjList, informTime, adjacent, time + informTime[curr]);
}
}
public int NumOfMinutes(int n, int headID, int[] manager, int[] informTime) {
List<int>[] adjList = new List<int>[n];
for (int i = 0; i < n; i++) {
adjList[i] = new List<int>();
}
for (int i = 0; i < n; i++) {
if (manager[i] != -1) {
adjList[manager[i]].Add(i);
}
}
DFS(adjList, informTime, headID, 0);
return maxTime;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1009. Complement of Base 10 Integer
Сложность: easy
Дополнение целого числа - это целое число, которое получается, если перевернуть все 0 в 1 и все 1 в 0 в его двоичном представлении. Например, целое число 5 - это "101" в двоичном представлении, а его дополнение - "010", то есть целое число 2. Если задано целое число n, верните его дополнение.
Пример:
👨💻 Алгоритм:
1⃣ Определение длины двоичного представления:
Найдите длину двоичного представления числа n.
2⃣ Создание маски:
Создайте маску, которая состоит из всех единиц и имеет ту же длину, что и двоичное представление числа n.
3⃣ Вычисление дополнения:
Примените побитовую операцию XOR между числом n и маской, чтобы получить дополнение числа.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дополнение целого числа - это целое число, которое получается, если перевернуть все 0 в 1 и все 1 в 0 в его двоичном представлении. Например, целое число 5 - это "101" в двоичном представлении, а его дополнение - "010", то есть целое число 2. Если задано целое число n, верните его дополнение.
Пример:
Input: n = 5
Output: 2
Найдите длину двоичного представления числа n.
Создайте маску, которая состоит из всех единиц и имеет ту же длину, что и двоичное представление числа n.
Примените побитовую операцию XOR между числом n и маской, чтобы получить дополнение числа.
public class Solution {
public int FindComplement(int num) {
int length = (int)Math.Log(num, 2) + 1;
int mask = (1 << length) - 1;
return num ^ mask;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM