Задача: 566. Reshape the Matrix
Сложность: easy
В MATLAB есть удобная функция под названием reshape, которая может преобразовать матрицу размером m x n в новую матрицу с другим размером r x c, сохраняя исходные данные.
Вам дана матрица m x n mat и два целых числа r и c, представляющие количество строк и столбцов желаемой преобразованной матрицы.
Преобразованная матрица должна быть заполнена всеми элементами исходной матрицы в том же порядке обхода строк, в котором они были.
Если операция преобразования с заданными параметрами возможна и допустима, выведите новую преобразованную матрицу; в противном случае выведите исходную матрицу.
Пример:
👨💻 Алгоритм:
1⃣ Проверить, можно ли преобразовать матрицу с заданными параметрами r и c. Это возможно, если произведение m * n равно произведению r * c. Если преобразование невозможно, вернуть исходную матрицу.
2⃣ Создать новый массив для хранения преобразованной матрицы. Перебрать все элементы исходной матрицы и вставить их в новый массив в порядке обхода строк.
3⃣ Вернуть преобразованную матрицу, если преобразование возможно, иначе вернуть исходную матрицу.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
В MATLAB есть удобная функция под названием reshape, которая может преобразовать матрицу размером m x n в новую матрицу с другим размером r x c, сохраняя исходные данные.
Вам дана матрица m x n mat и два целых числа r и c, представляющие количество строк и столбцов желаемой преобразованной матрицы.
Преобразованная матрица должна быть заполнена всеми элементами исходной матрицы в том же порядке обхода строк, в котором они были.
Если операция преобразования с заданными параметрами возможна и допустима, выведите новую преобразованную матрицу; в противном случае выведите исходную матрицу.
Пример:
Input: mat = [[1,2],[3,4]], r = 1, c = 4
Output: [[1,2,3,4]]
public class Solution {
public int[][] MatrixReshape(int[][] mat, int r, int c) {
int m = mat.Length, n = mat[0].Length;
if (m * n != r * c) {
return mat;
}
int[][] reshapedMatrix = new int[r][];
for (int i = 0; i < r; i++) {
reshapedMatrix[i] = new int[c];
}
int row = 0, col = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
reshapedMatrix[row][col] = mat[i][j];
col++;
if (col == c) {
col = 0;
row++;
}
}
}
return reshapedMatrix;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 713. Subarray Product Less Than K
Сложность: medium
Если задан массив целых чисел nums и целое число k, верните количество смежных подмассивов, в которых произведение всех элементов в подмассиве строго меньше k.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменные для отслеживания текущего произведения и количества допустимых подмассивов. Используйте два указателя для границ подмассива.
2⃣ Перемещайте правый указатель по массиву и умножайте текущий элемент на текущее произведение. Если произведение становится больше или равно k, перемещайте левый указатель, уменьшая произведение до тех пор, пока оно снова не станет меньше k.
3⃣ Подсчитайте количество подмассивов с текущим правым указателем, добавив к общему количеству допустимых подмассивов разницу между правым и левым указателями.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задан массив целых чисел nums и целое число k, верните количество смежных подмассивов, в которых произведение всех элементов в подмассиве строго меньше k.
Пример:
Input: nums = [10,5,2,6], k = 100
Output: 8
public class Solution {
public int NumSubarrayProductLessThanK(int[] nums, int k) {
if (k <= 1) return 0;
int product = 1, count = 0, left = 0;
for (int right = 0; right < nums.Length; right++) {
product *= nums[right];
while (product >= k) {
product /= nums[left];
left++;
}
count += right - left + 1;
}
return count;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 423. Reconstruct Original Digits from English
Сложность: medium
Дана строка s, содержащая неупорядоченное английское представление цифр от 0 до 9, верните цифры в порядке возрастания.
Пример:
👨💻 Алгоритм:
1⃣ Подсчитайте количество каждого символа в строке s с помощью хэш-таблицы или массива, чтобы определить количество каждого символа.
2⃣ Используйте уникальные символы, присутствующие только в одном числе (например, 'z' для 0, 'w' для 2, 'u' для 4, 'x' для 6, 'g' для 8), чтобы определить количество этих цифр в строке. Затем определите количество остальных цифр, вычитая уже найденные цифры.
3⃣ Соберите найденные цифры в строку в порядке возрастания и верните результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана строка s, содержащая неупорядоченное английское представление цифр от 0 до 9, верните цифры в порядке возрастания.
Пример:
Input: s = "owoztneoer"
Output: "012"
public class Solution {
public string OriginalDigits(string s) {
int[] count = new int[26];
foreach (char letter in s) {
count[letter - 'a']++;
}
int[] out = new int[10];
out[0] = count['z' - 'a'];
out[2] = count['w' - 'a'];
out[4] = count['u' - 'a'];
out[6] = count['x' - 'a'];
out[8] = count['g' - 'a'];
out[3] = count['h' - 'a'] - out[8];
out[5] = count['f' - 'a'] - out[4];
out[7] = count['s' - 'a'] - out[6];
out[9] = count['i' - 'a'] - out[5] - out[6] - out[8];
out[1] = count['n' - 'a'] - out[7] - 2 * out[9];
StringBuilder output = new StringBuilder();
for(int i = 0; i < 10; i++)
for (int j = 0; j < out[i]; j++)
output.Append(i);
return output.ToString();
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 186. Reverse Words in a String II
Сложность: medium
Дан массив символов s, переверните порядок слов.
Слово определяется как последовательность символов, не являющихся пробелами. Слова в s будут разделены одним пробелом.
Ваш код должен решать задачу на месте, то есть без выделения дополнительного пространства.
Пример:
👨💻 Алгоритм:
1⃣ Перевернуть всю строку: применить функцию reverse, которая переворачивает весь массив символов от начала до конца.
2⃣ Перевернуть каждое слово: пройти по всей строке, идентифицировать границы каждого слова и использовать функцию reverse для переворачивания символов в пределах каждого слова.
3⃣ Окончательная корректировка: проверить, чтобы между словами оставался только один пробел, и удалить лишние пробелы в начале и конце строки, если это необходимо.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив символов s, переверните порядок слов.
Слово определяется как последовательность символов, не являющихся пробелами. Слова в s будут разделены одним пробелом.
Ваш код должен решать задачу на месте, то есть без выделения дополнительного пространства.
Пример:
Input: s = ["a"]
Output: ["a"]
public class Solution {
public void ReverseWords(char[] s) {
Array.Reverse(s);
int start = 0, end = 0, n = s.Length;
while (start < n) {
while (end < n && s[end] != ' ') end++;
Array.Reverse(s, start, end - start);
end++;
start = end;
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 339. Nested List Weight Sum
Сложность: medium
Вам дан вложенный список целых чисел nestedList. Каждый элемент либо целое число, либо список, элементы которого также могут быть целыми числами или другими списками.
Глубина целого числа — это количество списков, в которых оно находится. Например, вложенный список [1,[2,2],[[3],2],1] имеет значения каждого целого числа, установленные в его глубину.
Верните сумму каждого целого числа в nestedList, умноженного на его глубину.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и вызов рекурсивной функции:
Создайте основную функцию, которая принимает вложенный список и вызывает вспомогательную рекурсивную функцию с начальной глубиной 1.
2⃣ Рекурсивное исследование списка:
В вспомогательной функции пройдите по каждому элементу списка. Если элемент является целым числом, добавьте его значение, умноженное на текущую глубину, к общей сумме. Если элемент является списком, вызовите вспомогательную функцию рекурсивно с увеличенной глубиной.
3⃣ Возврат результата:
Возвращайте общую сумму на каждом уровне рекурсии. Основная функция возвращает итоговую сумму.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан вложенный список целых чисел nestedList. Каждый элемент либо целое число, либо список, элементы которого также могут быть целыми числами или другими списками.
Глубина целого числа — это количество списков, в которых оно находится. Например, вложенный список [1,[2,2],[[3],2],1] имеет значения каждого целого числа, установленные в его глубину.
Верните сумму каждого целого числа в nestedList, умноженного на его глубину.
Пример:
Input: nestedList = [1,[4,[6]]]
Output: 27
Explanation: One 1 at depth 1, one 4 at depth 2, and one 6 at depth 3. 1*1 + 4*2 + 6*3 = 27.
Создайте основную функцию, которая принимает вложенный список и вызывает вспомогательную рекурсивную функцию с начальной глубиной 1.
В вспомогательной функции пройдите по каждому элементу списка. Если элемент является целым числом, добавьте его значение, умноженное на текущую глубину, к общей сумме. Если элемент является списком, вызовите вспомогательную функцию рекурсивно с увеличенной глубиной.
Возвращайте общую сумму на каждом уровне рекурсии. Основная функция возвращает итоговую сумму.
public class Solution {
public int DepthSum(IList<NestedInteger> nestedList) {
return Dfs(nestedList, 1);
}
private int Dfs(IList<NestedInteger> list, int depth) {
int total = 0;
foreach (var nested in list) {
if (nested.IsInteger()) {
total += nested.GetInteger() * depth;
} else {
total += Dfs(nested.GetList(), depth + 1);
}
}
return total;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 379. Design Phone Directory
Сложность: medium
Создайте телефонный справочник, который изначально имеет maxNumbers пустых слотов для хранения номеров. Справочник должен хранить номера, проверять, пуст ли определенный слот, и освобождать данный слот.
Реализуйте класс PhoneDirectory:
PhoneDirectory(int maxNumbers) Инициализирует телефонный справочник с количеством доступных слотов maxNumbers.
int get() Предоставляет номер, который никому не назначен. Возвращает -1, если номера недоступны.
bool check(int number) Возвращает true, если слот доступен, и false в противном случае.
void release(int number) Перераспределяет или освобождает номер слота.
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать массив isSlotAvailable размером maxNumbers, установив значение true во всех индексах.
2⃣ Метод get(): Проходить по массиву isSlotAvailable. Если найдется true на каком-либо индексе, установить isSlotAvailable[i] = false и вернуть i. Если доступных слотов нет, вернуть -1.
Метод check(number): Вернуть значение isSlotAvailable[number].
3⃣ Метод release(number): Установить isSlotAvailable[number] = true.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Создайте телефонный справочник, который изначально имеет maxNumbers пустых слотов для хранения номеров. Справочник должен хранить номера, проверять, пуст ли определенный слот, и освобождать данный слот.
Реализуйте класс PhoneDirectory:
PhoneDirectory(int maxNumbers) Инициализирует телефонный справочник с количеством доступных слотов maxNumbers.
int get() Предоставляет номер, который никому не назначен. Возвращает -1, если номера недоступны.
bool check(int number) Возвращает true, если слот доступен, и false в противном случае.
void release(int number) Перераспределяет или освобождает номер слота.
Пример:
Input
["PhoneDirectory", "get", "get", "check", "get", "check", "release", "check"]
[[3], [], [], [2], [], [2], [2], [2]]
Output
[null, 0, 1, true, 2, false, null, true]
Метод check(number): Вернуть значение isSlotAvailable[number].
using System;
public class PhoneDirectory {
private bool[] isSlotAvailable;
public PhoneDirectory(int maxNumbers) {
isSlotAvailable = new bool[maxNumbers];
for (int i = 0; i < maxNumbers; i++) {
isSlotAvailable[i] = true;
}
}
public int Get() {
for (int i = 0; i < isSlotAvailable.Length; i++) {
if (isSlotAvailable[i]) {
isSlotAvailable[i] = false;
return i;
}
}
return -1;
}
public bool Check(int number) {
return isSlotAvailable[number];
}
public void Release(int number) {
isSlotAvailable[number] = true;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 630. Course Schedule III
Сложность: hard
Имеется n различных онлайн-курсов, пронумерованных от 1 до n. Вам дан массив courses, где courses[i] = [durationi, lastDayi] указывает, что i-й курс должен быть пройден непрерывно в течениеi дней и должен быть закончен до или в lastDayi. Вы начинаете в 1-й день и не можете проходить два или более курсов одновременно. Верните максимальное количество курсов, которые вы можете пройти.
Пример:
👨💻 Алгоритм:
1⃣ Сортировка курсов
Отсортируйте курсы по их конечным датам (lastDay). Это позволяет проходить курсы как можно ближе к их крайним срокам.
2⃣ Проход по курсам
Используйте приоритетную очередь (max-heap) для отслеживания продолжительности пройденных курсов.
3⃣ Добавление и удаление курсов
Для каждого курса: Добавьте его продолжительность в приоритетную очередь и обновите общее время прохождения курсов. Если общее время превышает крайний срок текущего курса, удалите самый длительный курс из очереди и скорректируйте общее время.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Имеется n различных онлайн-курсов, пронумерованных от 1 до n. Вам дан массив courses, где courses[i] = [durationi, lastDayi] указывает, что i-й курс должен быть пройден непрерывно в течениеi дней и должен быть закончен до или в lastDayi. Вы начинаете в 1-й день и не можете проходить два или более курсов одновременно. Верните максимальное количество курсов, которые вы можете пройти.
Пример:
Input: courses = [[100,200],[200,1300],[1000,1250],[2000,3200]]
Output: 3
Отсортируйте курсы по их конечным датам (lastDay). Это позволяет проходить курсы как можно ближе к их крайним срокам.
Используйте приоритетную очередь (max-heap) для отслеживания продолжительности пройденных курсов.
Для каждого курса: Добавьте его продолжительность в приоритетную очередь и обновите общее время прохождения курсов. Если общее время превышает крайний срок текущего курса, удалите самый длительный курс из очереди и скорректируйте общее время.
using System;
using System.Collections.Generic;
public class Solution {
public int ScheduleCourse(int[][] courses) {
Array.Sort(courses, (a, b) => a[1].CompareTo(b[1]));
var maxHeap = new PriorityQueue<int, int>(Comparer<int>.Create((a, b) => b.CompareTo(a)));
int time = 0;
foreach (var course in courses) {
time += course[0];
maxHeap.Enqueue(course[0], course[0]);
if (time > course[1]) {
time -= maxHeap.Dequeue();
}
}
return maxHeap.Count;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 906. Super Palindromes
Сложность: hard
Если задан целочисленный массив nums, переместите все четные числа в начало массива, а затем все нечетные. Верните любой массив, удовлетворяющий этому условию.
Пример:
👨💻 Алгоритм:
1⃣ Найти все палиндромы до корня из right.
2⃣ Проверить, являются ли квадраты этих палиндромов палиндромами и лежат ли в диапазоне [left, right].
3⃣ Подсчитать количество таких суперпалиндромов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Если задан целочисленный массив nums, переместите все четные числа в начало массива, а затем все нечетные. Верните любой массив, удовлетворяющий этому условию.
Пример:
Input: left = "4", right = "1000"
Output: 4
public class Solution {
private bool IsPalindrome(long x) {
string s = x.ToString();
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return s == new string(arr);
}
public int SuperpalindromesInRange(string left, string right) {
long leftNum = long.Parse(left);
long rightNum = long.Parse(right);
int count = 0;
for (int i = 1; i < 100000; i++) {
string s = i.ToString();
long palin1 = long.Parse(s + new string(s.Reverse().ToArray()));
long palin2 = long.Parse(s + new string(s.Reverse().Skip(1).ToArray()));
if (palin1 * palin1 > rightNum) {
break;
}
if (palin1 * palin1 >= leftNum && IsPalindrome(palin1 * palin1)) {
count++;
}
if (palin2 * palin2 >= leftNum && palin2 * palin2 <= rightNum && IsPalindrome(palin2 * palin2)) {
count++;
}
}
return count;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊2
Задача: 1228. Missing Number In Arithmetic Progression
Сложность: easy
В массиве arr значения находились в арифметической прогрессии: значения arr[i + 1] - arr[i] равны для всех 0 <= i < arr.length - 1.
Из массива arr было удалено значение, которое не было первым или последним значением в массиве.
Дан массив arr, вернуть удаленное значение.
Пример:
👨💻 Алгоритм:
1⃣ Рассчитать разность difference между элементами арифметической прогрессии.
2⃣ Начать с первого элемента массива и последовательно увеличивать ожидаемое значение на difference, проверяя каждый элемент массива.
3⃣ Вернуть первое ожидаемое значение, которое не совпадает с текущим значением в массиве.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
В массиве arr значения находились в арифметической прогрессии: значения arr[i + 1] - arr[i] равны для всех 0 <= i < arr.length - 1.
Из массива arr было удалено значение, которое не было первым или последним значением в массиве.
Дан массив arr, вернуть удаленное значение.
Пример:
Input: arr = [5,7,11,13]
Output: 9
Explanation: The previous array was [5,7,9,11,13].
public class Solution {
public int MissingNumber(int[] arr) {
int n = arr.Length;
int difference = (arr[n - 1] - arr[0]) / n;
int expected = arr[0];
foreach (int val in arr) {
if (val != expected) {
return expected;
}
expected += difference;
}
return expected;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1425. Constrained Subsequence Sum
Сложность: hard
Дан целочисленный массив nums и целое число k, верните максимальную сумму непустой подпоследовательности этого массива, такую, что для любых двух последовательных целых чисел в подпоследовательности nums[i] и nums[j], где i < j, выполняется условие j - i <= k.
Подпоследовательность массива получается путем удаления некоторого количества элементов (может быть ноль) из массива, оставляя оставшиеся элементы в их исходном порядке.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте очередь queue и массив dp той же длины, что и nums.
2⃣ Итерируйте i по индексам nums:
Если i минус первый элемент queue больше k, удалите элемент из начала queue.
Установите dp[i] как dp[queue.front()] + nums[i]. Если queue пуст, используйте 0 вместо dp[queue.front()].
Пока dp[queue.back()] меньше dp[i], удаляйте элементы с конца queue.
Если dp[i] > 0, добавьте i в конец queue.
3⃣ Верните максимальное значение в массиве dp.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан целочисленный массив nums и целое число k, верните максимальную сумму непустой подпоследовательности этого массива, такую, что для любых двух последовательных целых чисел в подпоследовательности nums[i] и nums[j], где i < j, выполняется условие j - i <= k.
Подпоследовательность массива получается путем удаления некоторого количества элементов (может быть ноль) из массива, оставляя оставшиеся элементы в их исходном порядке.
Пример:
Input: nums = [10,2,-10,5,20], k = 2
Output: 37
Explanation: The subsequence is [10, 2, 5, 20].
Если i минус первый элемент queue больше k, удалите элемент из начала queue.
Установите dp[i] как dp[queue.front()] + nums[i]. Если queue пуст, используйте 0 вместо dp[queue.front()].
Пока dp[queue.back()] меньше dp[i], удаляйте элементы с конца queue.
Если dp[i] > 0, добавьте i в конец queue.
public class Solution {
public int ConstrainedSubsetSum(int[] nums, int k) {
Deque<int> queue = new LinkedList<int>();
int[] dp = new int[nums.Length];
int maxSum = int.MinValue;
for (int i = 0; i < nums.Length; i++) {
if (queue.Count > 0 && i - queue.First.Value > k) {
queue.RemoveFirst();
}
dp[i] = (queue.Count > 0 ? dp[queue.First.Value] : 0) + nums[i];
while (queue.Count > 0 && dp[queue.Last.Value] < dp[i]) {
queue.RemoveLast();
}
if (dp[i] > 0) {
queue.AddLast(i);
}
maxSum = Math.Max(maxSum, dp[i]);
}
return maxSum;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 583. Delete Operation for Two Strings
Сложность: medium
Даны две строки word1 и word2, вернуть минимальное количество шагов, необходимых для того, чтобы сделать word1 и word2 одинаковыми.
На одном шаге можно удалить ровно один символ в любой строке.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация массива:
Создайте одномерный массив dp для хранения минимального количества удалений, необходимых для уравнивания строк word1 и word2.
2⃣ Заполнение массива:
Используйте временный массив temp для обновления значений dp, представляющих текущую строку. Обновите temp с использованием значений dp предыдущей строки.
3⃣ Обновление и результат:
Скопируйте временный массив temp обратно в dp после обработки каждой строки. В конце верните значение из dp, представляющее минимальное количество удалений.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны две строки word1 и word2, вернуть минимальное количество шагов, необходимых для того, чтобы сделать word1 и word2 одинаковыми.
На одном шаге можно удалить ровно один символ в любой строке.
Пример:
Input: word1 = "sea", word2 = "eat"
Output: 2
Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".
Создайте одномерный массив dp для хранения минимального количества удалений, необходимых для уравнивания строк word1 и word2.
Используйте временный массив temp для обновления значений dp, представляющих текущую строку. Обновите temp с использованием значений dp предыдущей строки.
Скопируйте временный массив temp обратно в dp после обработки каждой строки. В конце верните значение из dp, представляющее минимальное количество удалений.
public class Solution {
public int MinDistance(string word1, string word2) {
int m = word1.Length;
int n = word2.Length;
int[] dp = new int[n + 1];
for (int i = 0; i <= m; i++) {
int[] temp = new int[n + 1];
for (int j = 0; j <= n; j++) {
if (i == 0 || j == 0) {
temp[j] = i + j;
} else if (word1[i - 1] == word2[j - 1]) {
temp[j] = dp[j - 1];
} else {
temp[j] = 1 + Math.Min(dp[j], temp[j - 1]);
}
}
dp = temp;
}
return dp[n];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 446. Arithmetic Slices II - Subsequence
Сложность: hard
Дан целочисленный массив nums, вернуть количество всех арифметических подпоследовательностей nums.
Последовательность чисел называется арифметической, если она состоит как минимум из трех элементов и если разница между любыми двумя последовательными элементами одинаковая.
Например, [1, 3, 5, 7, 9], [7, 7, 7, 7] и [3, -1, -5, -9] являются арифметическими последовательностями.
Например, [1, 1, 2, 5, 7] не является арифметической последовательностью.
Подпоследовательность массива - это последовательность, которая может быть образована путем удаления некоторых элементов (возможно, ни одного) из массива.
Например, [2, 5, 10] является подпоследовательностью [1, 2, 1, 2, 4, 1, 5, 10].
Тестовые случаи сгенерированы таким образом, что ответ помещается в 32-битное целое число.
Пример:
👨💻 Алгоритм:
1⃣ Мы можем использовать поиск в глубину (DFS) для генерации всех подпоследовательностей.
2⃣ Мы можем проверить, является ли подпоследовательность арифметической, согласно ее определению.
3⃣ Возвращаем количество всех арифметических подпоследовательностей.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан целочисленный массив nums, вернуть количество всех арифметических подпоследовательностей nums.
Последовательность чисел называется арифметической, если она состоит как минимум из трех элементов и если разница между любыми двумя последовательными элементами одинаковая.
Например, [1, 3, 5, 7, 9], [7, 7, 7, 7] и [3, -1, -5, -9] являются арифметическими последовательностями.
Например, [1, 1, 2, 5, 7] не является арифметической последовательностью.
Подпоследовательность массива - это последовательность, которая может быть образована путем удаления некоторых элементов (возможно, ни одного) из массива.
Например, [2, 5, 10] является подпоследовательностью [1, 2, 1, 2, 4, 1, 5, 10].
Тестовые случаи сгенерированы таким образом, что ответ помещается в 32-битное целое число.
Пример:
Input: nums = [2,4,6,8,10]
Output: 7
Explanation: All arithmetic subsequence slices are:
[2,4,6]
[4,6,8]
[6,8,10]
[2,4,6,8]
[4,6,8,10]
[2,4,6,8,10]
[2,6,10]
public class Solution {
private int n;
private int ans;
private void Dfs(int dep, int[] A, List<long> cur) {
if (dep == n) {
if (cur.Count < 3) return;
for (int i = 1; i < cur.Count; i++) {
if (cur[i] - cur[i - 1] != cur[1] - cur[0]) return;
}
ans++;
return;
}
Dfs(dep + 1, A, cur);
cur.Add(A[dep]);
Dfs(dep + 1, A, cur);
cur.RemoveAt(cur.Count - 1);
}
public int NumberOfArithmeticSlices(int[] A) {
n = A.Length;
ans = 0;
Dfs(0, A, new List<long>());
return ans;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1178. Number of Valid Words for Each PuzzleHardTopicsHint
Сложность: hard
Относительно заданной строки-головоломки, слово является допустимым, если выполняются оба следующих условия:
Слово содержит первую букву головоломки.
Каждая буква в слове присутствует в головоломке.
Например, если головоломка "abcdefg", то допустимыми словами являются "faced", "cabbage" и "baggage", а недопустимыми словами являются "beefed" (не включает 'a') и "based" (включает 's', которой нет в головоломке).
Верните массив answer, где answer[i] - это количество слов в данном списке слов words, которые допустимы относительно головоломки puzzles[i].
Пример:
👨💻 Алгоритм:
1⃣ Постройте карту. Для каждого слова в списке words:
Преобразуйте его в битовую маску его символов. Если эта битовая маска не была ранее встречена, сохраните ее в качестве ключа в карте со значением 1. Если она была ранее встречена, увеличьте счетчик для этой битовой маски на 1.
2⃣ Подсчитайте количество допустимых слов для каждой головоломки. Для каждой головоломки в списке puzzles:
Преобразуйте ее в битовую маску ее символов. Итерируйте по каждой возможной подмаске, содержащей первую букву головоломки (puzzle[i][0]). Слово является допустимым для головоломки, если его битовая маска совпадает с одной из подмасок головоломки.
3⃣ Для каждой подмаски увеличивайте счетчик на количество слов, соответствующих подмаске. Мы можем найти количество слов, соответствующих подмаске, используя карту, построенную на предыдущем шаге.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Относительно заданной строки-головоломки, слово является допустимым, если выполняются оба следующих условия:
Слово содержит первую букву головоломки.
Каждая буква в слове присутствует в головоломке.
Например, если головоломка "abcdefg", то допустимыми словами являются "faced", "cabbage" и "baggage", а недопустимыми словами являются "beefed" (не включает 'a') и "based" (включает 's', которой нет в головоломке).
Верните массив answer, где answer[i] - это количество слов в данном списке слов words, которые допустимы относительно головоломки puzzles[i].
Пример:
Input: words = ["apple","pleas","please"], puzzles = ["aelwxyz","aelpxyz","aelpsxy","saelpxy","xaelpsy"]
Output: [0,1,3,2,0]
Преобразуйте его в битовую маску его символов. Если эта битовая маска не была ранее встречена, сохраните ее в качестве ключа в карте со значением 1. Если она была ранее встречена, увеличьте счетчик для этой битовой маски на 1.
Преобразуйте ее в битовую маску ее символов. Итерируйте по каждой возможной подмаске, содержащей первую букву головоломки (puzzle[i][0]). Слово является допустимым для головоломки, если его битовая маска совпадает с одной из подмасок головоломки.
public class Solution {
private int Bitmask(string word) {
int mask = 0;
foreach (char letter in word) {
mask |= 1 << (letter - 'a');
}
return mask;
}
public IList<int> FindNumOfValidWords(string[] words, string[] puzzles) {
var wordCount = new Dictionary<int, int>();
foreach (var word in words) {
int mask = Bitmask(word);
if (!wordCount.ContainsKey(mask)) {
wordCount[mask] = 0;
}
wordCount[mask]++;
}
var result = new List<int>();
foreach (var puzzle in puzzles) {
int first = 1 << (puzzle[0] - 'a');
int count = wordCount.ContainsKey(first) ? wordCount[first] : 0;
int mask = Bitmask(puzzle.Substring(1));
for (int submask = mask; submask > 0; submask = (submask - 1) & mask) {
count += wordCount.ContainsKey(submask | first) ? wordCount[submask | first] : 0;
}
result.Add(count);
}
return result;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 785. Is Graph Bipartite?
Сложность: medium
Есть неориентированный граф с n узлами, где каждый узел пронумерован от 0 до n - 1. Вам дан двумерный массив graph, где graph[u] — это массив узлов, смежных с узлом u. Более формально, для каждого v в graph[u] существует неориентированное ребро между узлом u и узлом v. Граф обладает следующими свойствами:
Нет петель (graph[u] не содержит u).
Нет параллельных ребер (graph[u] не содержит дублирующихся значений).
Если v есть в graph[u], то u есть в graph[v] (граф неориентированный).
Граф может быть несвязным, то есть могут существовать два узла u и v, между которыми нет пути.
Граф является двудольным, если узлы можно разделить на два независимых множества A и B так, что каждое ребро в графе соединяет узел из множества A с узлом из множества B.
Верните true, если и только если граф является двудольным.
Пример:
👨💻 Алгоритм:
1⃣ Мы будем хранить массив (или hashmap) для поиска цвета каждого узла: color[node]. Цвета могут быть 0, 1 или неокрашенные (-1 или null).
2⃣ Мы должны быть внимательны к рассмотрению несвязных компонентов графа, выполняя поиск для каждого узла. Для каждого неокрашенного узла мы начнем процесс окрашивания, выполняя поиск в глубину (DFS) для этого узла. Каждый соседний узел получает цвет, противоположный цвету текущего узла. Если мы обнаруживаем, что соседний узел окрашен в тот же цвет, что и текущий узел, значит, наше окрашивание невозможно.
3⃣ Для выполнения поиска в глубину мы используем стек. Для каждого неокрашенного соседа в graph[node] мы будем его окрашивать и добавлять в наш стек, который действует как своего рода "список дел" для узлов, которые нужно посетить дальше. Наш внешний цикл для start... гарантирует, что мы окрасим каждый узел.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Есть неориентированный граф с n узлами, где каждый узел пронумерован от 0 до n - 1. Вам дан двумерный массив graph, где graph[u] — это массив узлов, смежных с узлом u. Более формально, для каждого v в graph[u] существует неориентированное ребро между узлом u и узлом v. Граф обладает следующими свойствами:
Нет петель (graph[u] не содержит u).
Нет параллельных ребер (graph[u] не содержит дублирующихся значений).
Если v есть в graph[u], то u есть в graph[v] (граф неориентированный).
Граф может быть несвязным, то есть могут существовать два узла u и v, между которыми нет пути.
Граф является двудольным, если узлы можно разделить на два независимых множества A и B так, что каждое ребро в графе соединяет узел из множества A с узлом из множества B.
Верните true, если и только если граф является двудольным.
Пример:
Input: graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
Output: false
Explanation: There is no way to partition the nodes into two independent sets such that every edge connects a node in one and a node in the other.
public class Solution {
public bool IsBipartite(int[][] graph) {
Dictionary<int, int> color = new Dictionary<int, int>();
for (int node = 0; node < graph.Length; node++) {
if (!color.ContainsKey(node)) {
Stack<int> stack = new Stack<int>();
stack.Push(node);
color[node] = 0;
while (stack.Count > 0) {
int currentNode = stack.Pop();
foreach (int neighbor in graph[currentNode]) {
if (!color.ContainsKey(neighbor)) {
stack.Push(neighbor);
color[neighbor] = color[currentNode] ^ 1;
} else if (color[neighbor] == color[currentNode]) {
return false;
}
}
}
}
}
return true;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1250. Check If It Is a Good Array
Сложность: hard
Дан массив nums из целых положительных чисел. Ваша задача - выбрать некоторое подмножество nums, умножить каждый элемент на целое число и сложить все эти числа.Массив считается хорошим, если из него можно получить сумму, равную 1, при любом возможном подмножестве и множителе. Верните True, если массив хороший, иначе верните False.
Пример:
👨💻 Алгоритм:
1⃣ Если наибольший общий делитель (НОД) всех чисел в массиве равен 1, то массив считается хорошим.
2⃣ Если НОД всех чисел больше 1, то массив не считается хорошим
3⃣ Получить сумму, равную 1, умножая и складывая элементы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан массив nums из целых положительных чисел. Ваша задача - выбрать некоторое подмножество nums, умножить каждый элемент на целое число и сложить все эти числа.Массив считается хорошим, если из него можно получить сумму, равную 1, при любом возможном подмножестве и множителе. Верните True, если массив хороший, иначе верните False.
Пример:
Input: nums = [12,5,7,23]
Output: true
public class Solution {
public bool IsGoodArray(int[] nums) {
int gcd = nums[0];
foreach (int num in nums) {
gcd = Gcd(gcd, num);
if (gcd == 1) return true;
}
return gcd == 1;
}
private int Gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1220. Count Vowels Permutation
Сложность: hard
Дано целое число n, ваша задача состоит в том, чтобы посчитать, сколько строк длины n можно сформировать по следующим правилам:
Каждый символ является строчной гласной буквой ('a', 'e', 'i', 'o', 'u')
Каждая гласная 'a' может быть только перед 'e'.
Каждая гласная 'e' может быть только перед 'a' или 'i'.
Каждая гласная 'i' не может быть перед другой 'i'.
Каждая гласная 'o' может быть только перед 'i' или 'u'.
Каждая гласная 'u' может быть только перед 'a'.
Так как ответ может быть слишком большим, верните его по модулю 10^9 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация массивов и начальных условий:
Инициализируйте пять одномерных массивов размером n для хранения количества строк, оканчивающихся на каждую гласную.
Установите первый элемент в каждом массиве равным 1, так как для строк длиной 1 существует только одна возможная строка для каждой гласной.
2⃣ Заполнение массивов в соответствии с правилами:
Проходите по длине строки от 1 до n.
Обновляйте значения массивов, следуя правилам для каждой гласной, учитывая предыдущие значения.
3⃣ Суммирование и возврат результата:
Возьмите сумму последних элементов всех пяти массивов.
Верните результат по модулю 10^9 + 7.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дано целое число n, ваша задача состоит в том, чтобы посчитать, сколько строк длины n можно сформировать по следующим правилам:
Каждый символ является строчной гласной буквой ('a', 'e', 'i', 'o', 'u')
Каждая гласная 'a' может быть только перед 'e'.
Каждая гласная 'e' может быть только перед 'a' или 'i'.
Каждая гласная 'i' не может быть перед другой 'i'.
Каждая гласная 'o' может быть только перед 'i' или 'u'.
Каждая гласная 'u' может быть только перед 'a'.
Так как ответ может быть слишком большим, верните его по модулю 10^9 + 7.
Пример:
Input: n = 2
Output: 10
Explanation: All possible strings are: "ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou" and "ua".
Инициализируйте пять одномерных массивов размером n для хранения количества строк, оканчивающихся на каждую гласную.
Установите первый элемент в каждом массиве равным 1, так как для строк длиной 1 существует только одна возможная строка для каждой гласной.
Проходите по длине строки от 1 до n.
Обновляйте значения массивов, следуя правилам для каждой гласной, учитывая предыдущие значения.
Возьмите сумму последних элементов всех пяти массивов.
Верните результат по модулю 10^9 + 7.
public class Solution {
public int CountVowelPermutation(int n) {
const int MOD = 1000000007;
var a = new long[n];
var e = new long[n];
var i = new long[n];
var o = new long[n];
var u = new long[n];
a[0] = 1;
e[0] = 1;
i[0] = 1;
o[0] = 1;
u[0] = 1;
for (int k = 1; k < n; k++) {
a[k] = (e[k - 1] + i[k - 1] + u[k - 1]) % MOD;
e[k] = (a[k - 1] + i[k - 1]) % MOD;
i[k] = (e[k - 1] + o[k - 1]) % MOD;
o[k] = i[k - 1] % MOD;
u[k] = (i[k - 1] + o[k - 1]) % MOD;
}
return (int)((a[n - 1] + e[n - 1] + i[n - 1] + o[n - 1] + u[n - 1]) % MOD);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1202. Smallest String With Swaps
Сложность: medium
Вам дана строка s и массив пар индексов в строке pairs, где pairs[i] = [a, b] указывает на 2 индекса (начиная с 0) в строке.
Вы можете менять местами символы в любой паре индексов в заданных парах любое количество раз.
Верните лексикографически наименьшую строку, которую можно получить после выполнения перестановок.
Пример:
👨💻 Алгоритм:
1⃣ Создание списка смежности:
Итеративно пройдитесь по парам и создайте список смежности adj, где adj[source] содержит все смежные вершины вершины source.
2⃣ Обход графа и сбор индексов и символов:
Итеративно пройдитесь по индексам от 0 до s.size() - 1. Для каждого индекса vertex:
- выполните DFS, если вершина еще не посещена (visited[vertex] = false).
- во время выполнения DFS сохраняйте vertex в список indices и символ s[vertex] в список characters.
3⃣ Сортировка и построение результирующей строки:
Отсортируйте списки indices и characters.
Пройдитесь по индексам и символам, и разместите i-й символ в i-й индекс результирующей строки smallestString.
Верните smallestString.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана строка s и массив пар индексов в строке pairs, где pairs[i] = [a, b] указывает на 2 индекса (начиная с 0) в строке.
Вы можете менять местами символы в любой паре индексов в заданных парах любое количество раз.
Верните лексикографически наименьшую строку, которую можно получить после выполнения перестановок.
Пример:
Input: s = "dcab", pairs = [[0,3],[1,2]]
Output: "bacd"
Explaination:
Swap s[0] and s[3], s = "bcad"
Swap s[1] and s[2], s = "bacd"
Итеративно пройдитесь по парам и создайте список смежности adj, где adj[source] содержит все смежные вершины вершины source.
Итеративно пройдитесь по индексам от 0 до s.size() - 1. Для каждого индекса vertex:
- выполните DFS, если вершина еще не посещена (visited[vertex] = false).
- во время выполнения DFS сохраняйте vertex в список indices и символ s[vertex] в список characters.
Отсортируйте списки indices и characters.
Пройдитесь по индексам и символам, и разместите i-й символ в i-й индекс результирующей строки smallestString.
Верните smallestString.
public class Solution {
public string SmallestStringWithSwaps(string s, IList<IList<int>> pairs) {
int n = s.Length;
List<int>[] adj = new List<int>[n];
for (int i = 0; i < n; i++) {
adj[i] = new List<int>();
}
foreach (var pair in pairs) {
adj[pair[0]].Add(pair[1]);
adj[pair[1]].Add(pair[0]);
}
bool[] visited = new bool[n];
char[] sArray = s.ToCharArray();
void Dfs(int node, List<int> indices, List<char> chars) {
visited[node] = true;
indices.Add(node);
chars.Add(sArray[node]);
foreach (var neighbor in adj[node]) {
if (!visited[neighbor]) {
Dfs(neighbor, indices, chars);
}
}
}
for (int i = 0; i < n; i++) {
if (!visited[i]) {
List<int> indices = new List<int>();
List<char> chars = new List<char>();
Dfs(i, indices, chars);
indices.Sort();
chars.Sort();
for (int j = 0; j < indices.Count; j++) {
sArray[indices[j]] = chars[j];
}
}
}
return new string(sArray);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1026. Maximum Difference Between Node and Ancestor
Сложность: medium
Учитывая корень бинарного дерева, найдите максимальное значение v, для которого существуют различные вершины a и b, где v = |a.val - b.val| и a является предком b. Вершина a является предком b, если: любой ребенок a равен b или любой ребенок a является предком b.
Пример:
👨💻 Алгоритм:
1⃣ Рекурсивный обход дерева:
Используйте рекурсивную функцию для обхода дерева. Передавайте минимальное и максимальное значения, встреченные на пути от корня к текущему узлу.
2⃣ Обновление максимальной разницы:
При посещении каждого узла обновляйте минимальное и максимальное значения. Вычисляйте разницу между текущим значением узла и минимальным и максимальным значениями на пути. Обновляйте максимальную разницу, если текущая разница больше.
3⃣ Рекурсивный вызов для детей:
Рекурсивно вызывайте функцию для левого и правого поддерева, передавая обновленные минимальное и максимальное значения.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Учитывая корень бинарного дерева, найдите максимальное значение v, для которого существуют различные вершины a и b, где v = |a.val - b.val| и a является предком b. Вершина a является предком b, если: любой ребенок a равен b или любой ребенок a является предком b.
Пример:
Input: root = [8,3,10,1,6,null,14,null,null,4,7,13]
Output: 7
Используйте рекурсивную функцию для обхода дерева. Передавайте минимальное и максимальное значения, встреченные на пути от корня к текущему узлу.
При посещении каждого узла обновляйте минимальное и максимальное значения. Вычисляйте разницу между текущим значением узла и минимальным и максимальным значениями на пути. Обновляйте максимальную разницу, если текущая разница больше.
Рекурсивно вызывайте функцию для левого и правого поддерева, передавая обновленные минимальное и максимальное значения.
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) { val = x; }
}
public class Solution {
public int MaxAncestorDiff(TreeNode root) {
return Dfs(root, root.val, root.val);
}
private int Dfs(TreeNode node, int minVal, int maxVal) {
if (node == null) return maxVal - minVal;
minVal = Math.Min(minVal, node.val);
maxVal = Math.Max(maxVal, node.val);
int left = Dfs(node.left, minVal, maxVal);
int right = Dfs(node.right, minVal, maxVal);
return Math.Max(left, right);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 941. Valid Mountain Array
Сложность: easy
Задав массив целых чисел arr, верните true тогда и только тогда, когда он является допустимым горным массивом. Напомним, что arr является горным массивом тогда и только тогда, когда: arr.length >= 3 Существует некоторое i с 0 < i < arr.length - 1 такое, что: arr[0] < arr[1] < ... < arr[i - 1] < arr[i] arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
Пример:
👨💻 Алгоритм:
1⃣ Убедиться, что длина массива не меньше 3.
2⃣ Найти вершину горы, которая удовлетворяет условиям горного массива.
Проверить, что все элементы слева от вершины строго возрастают.
Проверить, что все элементы справа от вершины строго убывают.
3⃣ Вернуть true, если оба условия выполнены, иначе вернуть false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Задав массив целых чисел arr, верните true тогда и только тогда, когда он является допустимым горным массивом. Напомним, что arr является горным массивом тогда и только тогда, когда: arr.length >= 3 Существует некоторое i с 0 < i < arr.length - 1 такое, что: arr[0] < arr[1] < ... < arr[i - 1] < arr[i] arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
Пример:
Input: arr = [2,1]
Output: false
Проверить, что все элементы слева от вершины строго возрастают.
Проверить, что все элементы справа от вершины строго убывают.
public class Solution {
public bool ValidMountainArray(int[] arr) {
if (arr.Length < 3) return false;
int i = 1;
while (i < arr.Length && arr[i] > arr[i - 1]) i++;
if (i == 1 || i == arr.Length) return false;
while (i < arr.Length && arr[i] < arr[i - 1]) i++;
return i == arr.Length;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1036. Escape a Large Maze
Сложность: hard
Имеется сетка размером 1 миллион на 1 миллион на плоскости XY, координаты каждого квадрата сетки - (x, y). Мы начинаем с исходного квадрата = [sx, sy] и хотим достичь цели = [tx, ty]. Существует также массив заблокированных квадратов, где каждый заблокированный[i] = [xi, yi] представляет собой заблокированный квадрат с координатами (xi, yi). Каждый ход мы можем пройти один квадрат на север, восток, юг или запад, если квадрат не находится в массиве заблокированных квадратов. Нам также не разрешается выходить за пределы сетки. Возвращается true тогда и только тогда, когда можно достичь целевого квадрата из исходного квадрата с помощью последовательности правильных ходов.
Пример:
👨💻 Алгоритм:
1⃣ Обработка входных данных:
Загрузите координаты исходного квадрата sx, sy, целевого квадрата tx, ty и список заблокированных квадратов blocked.
2⃣ Проверка простого случая:
Если список blocked пуст, верните true, так как путь не будет заблокирован.
Проверка начальной или целевой клетки:
Если исходная или целевая клетка заблокированы, верните false.
3⃣ Поиск пути с использованием BFS или DFS:
Используйте алгоритм поиска в ширину (BFS) или поиска в глубину (DFS) для поиска пути от sx, sy до tx, ty, избегая заблокированных клеток.
Если обнаружен путь, верните true, в противном случае верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Имеется сетка размером 1 миллион на 1 миллион на плоскости XY, координаты каждого квадрата сетки - (x, y). Мы начинаем с исходного квадрата = [sx, sy] и хотим достичь цели = [tx, ty]. Существует также массив заблокированных квадратов, где каждый заблокированный[i] = [xi, yi] представляет собой заблокированный квадрат с координатами (xi, yi). Каждый ход мы можем пройти один квадрат на север, восток, юг или запад, если квадрат не находится в массиве заблокированных квадратов. Нам также не разрешается выходить за пределы сетки. Возвращается true тогда и только тогда, когда можно достичь целевого квадрата из исходного квадрата с помощью последовательности правильных ходов.
Пример:
Input: blocked = [[0,1],[1,0]], source = [0,0], target = [0,2]
Output: false
Загрузите координаты исходного квадрата sx, sy, целевого квадрата tx, ty и список заблокированных квадратов blocked.
Если список blocked пуст, верните true, так как путь не будет заблокирован.
Проверка начальной или целевой клетки:
Если исходная или целевая клетка заблокированы, верните false.
Используйте алгоритм поиска в ширину (BFS) или поиска в глубину (DFS) для поиска пути от sx, sy до tx, ty, избегая заблокированных клеток.
Если обнаружен путь, верните true, в противном случае верните false.
public class Solution {
public bool IsEscapePossible(int[][] blocked, int[] source, int[] target) {
var blockedSet = new HashSet<(int, int)>(blocked.Select(b => (b[0], b[1])));
var src = (source[0], source[1]);
var tgt = (target[0], target[1]);
if (blockedSet.Contains(src) || blockedSet.Contains(tgt)) return false;
var directions = new (int, int)[] { (0, 1), (1, 0), (0, -1), (-1, 0) };
int maxArea = blocked.Length * (blocked.Length - 1) / 2;
bool Bfs((int, int) start, (int, int) end) {
var queue = new Queue<(int, int)>();
queue.Enqueue(start);
var visited = new HashSet<(int, int)> { start };
while (queue.Count > 0) {
if (visited.Count > maxArea) return true;
var (x, y) = queue.Dequeue();
foreach (var (dx, dy) in directions) {
var nx = x + dx;
var ny = y + dy;
var next = (nx, ny);
if (nx >= 0 && nx < 1_000_000 && ny >= 0 && ny < 1_000_000 && !visited.Contains(next) && !blockedSet.Contains(next)) {
if (next == end) return true;
queue.Enqueue(next);
visited.Add(next);
}
}
}
return false;
}
return Bfs(src, tgt) && Bfs(tgt, src);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM