Задача: 374. Guess Number Higher or Lower
Сложность: easy
Мы играем в игру "Угадай число". Правила игры следующие:
Я загадываю число от 1 до n. Вам нужно угадать, какое число я загадал.
Каждый раз, когда вы угадываете неправильно, я говорю вам, загаданное число больше или меньше вашего предположения.
Вы вызываете предопределенный API int guess(int num), который возвращает один из трех возможных результатов:
-1: Ваше предположение больше загаданного числа (т.е. num > pick).
1: Ваше предположение меньше загаданного числа (т.е. num < pick).
0: Ваше предположение равно загаданному числу (т.е. num == pick).
Верните загаданное число.
Пример:
👨💻 Алгоритм:
1⃣Применяем бинарный поиск для нахождения загаданного числа. Начинаем с числа, расположенного в середине диапазона. Передаем это число функции guess.
2⃣Если функция guess возвращает -1, это означает, что загаданное число меньше предположенного. Продолжаем бинарный поиск в диапазоне чисел, меньших данного.
3⃣Если функция guess возвращает 1, это означает, что загаданное число больше предположенного. Продолжаем бинарный поиск в диапазоне чисел, больших данного.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Мы играем в игру "Угадай число". Правила игры следующие:
Я загадываю число от 1 до n. Вам нужно угадать, какое число я загадал.
Каждый раз, когда вы угадываете неправильно, я говорю вам, загаданное число больше или меньше вашего предположения.
Вы вызываете предопределенный API int guess(int num), который возвращает один из трех возможных результатов:
-1: Ваше предположение больше загаданного числа (т.е. num > pick).
1: Ваше предположение меньше загаданного числа (т.е. num < pick).
0: Ваше предположение равно загаданному числу (т.е. num == pick).
Верните загаданное число.
Пример:
Input: n = 10, pick = 6
Output: 6
👨💻 Алгоритм:
1⃣Применяем бинарный поиск для нахождения загаданного числа. Начинаем с числа, расположенного в середине диапазона. Передаем это число функции guess.
2⃣Если функция guess возвращает -1, это означает, что загаданное число меньше предположенного. Продолжаем бинарный поиск в диапазоне чисел, меньших данного.
3⃣Если функция guess возвращает 1, это означает, что загаданное число больше предположенного. Продолжаем бинарный поиск в диапазоне чисел, больших данного.
😎 Решение:
public class Solution : GuessGame {
public int GuessNumber(int n) {
int low = 1;
int high = n;
while (low <= high) {
int mid = low + (high - low) / 2;
int res = guess(mid);
if (res == 0)
return mid;
else if (res < 0)
high = mid - 1;
else
low = mid + 1;
}
return -1;
}
}Ставь 👍 и забирай 📚 Базу знаний
Задача: 954. Array of Doubled Pairs
Сложность: medium
Если задан целочисленный массив четной длины arr, верните true, если можно переупорядочить arr так, чтобы arr[2 * i + 1] = 2 * arr[2 * i] для каждого 0 <= i < len(arr) / 2, или false в противном случае.
Пример:
👨💻 Алгоритм:
1⃣Подсчитать частоту каждого элемента в массиве.
Отсортировать массив по абсолютным значениям элементов.
2⃣Для каждого элемента в отсортированном массиве:
Проверить, можно ли сопоставить его с элементом, равным его удвоенному значению.
Уменьшить счетчик обоих элементов в словаре частот.
3⃣Если для каждого элемента можно найти пару, вернуть true, иначе вернуть false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задан целочисленный массив четной длины arr, верните true, если можно переупорядочить arr так, чтобы arr[2 * i + 1] = 2 * arr[2 * i] для каждого 0 <= i < len(arr) / 2, или false в противном случае.
Пример:
Input: arr = [3,1,3,6]
Output: false
👨💻 Алгоритм:
1⃣Подсчитать частоту каждого элемента в массиве.
Отсортировать массив по абсолютным значениям элементов.
2⃣Для каждого элемента в отсортированном массиве:
Проверить, можно ли сопоставить его с элементом, равным его удвоенному значению.
Уменьшить счетчик обоих элементов в словаре частот.
3⃣Если для каждого элемента можно найти пару, вернуть true, иначе вернуть false.
😎 Решение:
using System;
using System.Collections.Generic;
public class Solution {
public bool CanReorderDoubled(int[] arr) {
Dictionary<int, int> count = new Dictionary<int, int>();
foreach (int num in arr) {
if (count.ContainsKey(num)) {
count[num]++;
} else {
count[num] = 1;
}
}
Array.Sort(arr, (a, b) => Math.Abs(a).CompareTo(Math.Abs(b)));
foreach (int num in arr) {
if (count[num] == 0) continue;
if (!count.ContainsKey(2 * num) || count[2 * num] == 0) return false;
count[num]--;
count[2 * num]--;
}
return true;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Задача: 1143. Longest Common Subsequence
Сложность: medium
Даны две строки text1 и text2. Верните длину их наибольшей общей подпоследовательности. Если общей подпоследовательности нет, верните 0.
Подпоследовательность строки — это новая строка, созданная из оригинальной строки путем удаления некоторых символов (может быть ни одного) без изменения относительного порядка оставшихся символов.
Например, "ace" является подпоследовательностью "abcde".
Общая подпоследовательность двух строк — это подпоследовательность, которая является общей для обеих строк.
Пример:
👨💻 Алгоритм:
1⃣Создайте двумерный массив memo для хранения промежуточных результатов, чтобы избежать повторных вычислений. Инициализируйте массив значением -1, чтобы указать, что эти ячейки еще не были рассчитаны.
2⃣Реализуйте рекурсивную функцию memoSolve, которая принимает два указателя на текущие позиции в text1 и text2 и возвращает длину наибольшей общей подпоследовательности для этих подстрок. Если текущие символы совпадают, добавьте 1 к результату рекурсивного вызова для следующих символов. Если не совпадают, найдите максимум между рекурсивными вызовами с измененными указателями.
3⃣Возвращайте значение memoSolve(0, 0), чтобы получить результат для всей строки.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны две строки text1 и text2. Верните длину их наибольшей общей подпоследовательности. Если общей подпоследовательности нет, верните 0.
Подпоследовательность строки — это новая строка, созданная из оригинальной строки путем удаления некоторых символов (может быть ни одного) без изменения относительного порядка оставшихся символов.
Например, "ace" является подпоследовательностью "abcde".
Общая подпоследовательность двух строк — это подпоследовательность, которая является общей для обеих строк.
Пример:
Input: text1 = "abcde", text2 = "ace"
Output: 3
Explanation: The longest common subsequence is "ace" and its length is 3.
👨💻 Алгоритм:
1⃣Создайте двумерный массив memo для хранения промежуточных результатов, чтобы избежать повторных вычислений. Инициализируйте массив значением -1, чтобы указать, что эти ячейки еще не были рассчитаны.
2⃣Реализуйте рекурсивную функцию memoSolve, которая принимает два указателя на текущие позиции в text1 и text2 и возвращает длину наибольшей общей подпоследовательности для этих подстрок. Если текущие символы совпадают, добавьте 1 к результату рекурсивного вызова для следующих символов. Если не совпадают, найдите максимум между рекурсивными вызовами с измененными указателями.
3⃣Возвращайте значение memoSolve(0, 0), чтобы получить результат для всей строки.
😎 Решение:
public class Solution {
private int[][] memo;
private string text1;
private string text2;
public int LongestCommonSubsequence(string text1, string text2) {
this.text1 = text1;
this.text2 = text2;
memo = new int[text1.Length + 1][];
for (int i = 0; i < text1.Length + 1; i++) {
memo[i] = new int[text2.Length + 1];
Array.Fill(memo[i], -1);
}
return MemoSolve(0, 0);
}
private int MemoSolve(int p1, int p2) {
if (p1 == text1.Length || p2 == text2.Length) return 0;
if (memo[p1][p2] != -1) return memo[p1][p2];
int answer;
if (text1[p1] == text2[p2]) {
answer = 1 + MemoSolve(p1 + 1, p2 + 1);
} else {
answer = Math.Max(MemoSolve(p1, p2 + 1), MemoSolve(p1 + 1, p2));
}
memo[p1][p2] = answer;
return answer;
}
}Ставь 👍 и забирай 📚 Базу знаний
Задача: CodeTestcaseTest ResultTest Result1187. Make Array Strictly Increasing
Сложность: hard
Даны два целочисленных массива arr1 и arr2. Верните минимальное количество операций (возможно, ноль), необходимых для того, чтобы сделать arr1 строго возрастающим.
В одной операции вы можете выбрать два индекса 0 <= i < arr1.length и 0 <= j < arr2.length и выполнить присваивание arr1[i] = arr2[j].
Если нет способа сделать arr1 строго возрастающим, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Сначала отсортируйте массив arr2 и инициализируйте хэш-таблицу dp для хранения промежуточных результатов. Определите функцию dfs(i, prev), которая вычисляет минимальное количество операций для сортировки массива arr1, начиная с индекса i, при условии, что предыдущий элемент равен prev. Если результат для (i, prev) уже существует в dp, то просто верните сохраненное значение.
2⃣Внутри функции dfs инициализируйте переменную cost значением float('inf'). Если arr1[i] больше, чем prev, обновите значение cost результатом вызова dfs(i + 1, arr1[i]). Используйте бинарный поиск, чтобы найти индекс idx наименьшего значения в arr2, которое больше prev. Если такой индекс существует, обновите значение cost результатом минимального значения между текущим значением cost и 1 + dfs(i + 1, arr2[idx]).
3⃣После всех вычислений обновите dp[(i, prev)] значением cost и верните cost. В конце вызовите dfs(0, -1) и верните его значение, если оно не равно float('inf'); в противном случае верните -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Даны два целочисленных массива arr1 и arr2. Верните минимальное количество операций (возможно, ноль), необходимых для того, чтобы сделать arr1 строго возрастающим.
В одной операции вы можете выбрать два индекса 0 <= i < arr1.length и 0 <= j < arr2.length и выполнить присваивание arr1[i] = arr2[j].
Если нет способа сделать arr1 строго возрастающим, верните -1.
Пример:
Input: arr1 = [1,5,3,6,7], arr2 = [1,3,2,4]
Output: 1
Explanation: Replace 5 with 2, then arr1 = [1, 2, 3, 6, 7].
👨💻 Алгоритм:
1⃣ Сначала отсортируйте массив arr2 и инициализируйте хэш-таблицу dp для хранения промежуточных результатов. Определите функцию dfs(i, prev), которая вычисляет минимальное количество операций для сортировки массива arr1, начиная с индекса i, при условии, что предыдущий элемент равен prev. Если результат для (i, prev) уже существует в dp, то просто верните сохраненное значение.
2⃣Внутри функции dfs инициализируйте переменную cost значением float('inf'). Если arr1[i] больше, чем prev, обновите значение cost результатом вызова dfs(i + 1, arr1[i]). Используйте бинарный поиск, чтобы найти индекс idx наименьшего значения в arr2, которое больше prev. Если такой индекс существует, обновите значение cost результатом минимального значения между текущим значением cost и 1 + dfs(i + 1, arr2[idx]).
3⃣После всех вычислений обновите dp[(i, prev)] значением cost и верните cost. В конце вызовите dfs(0, -1) и верните его значение, если оно не равно float('inf'); в противном случае верните -1.
😎 Решение:
public class Solution {
public int MakeArrayIncreasing(int[] arr1, int[] arr2) {
Array.Sort(arr2);
int answer = Dfs(0, -1, arr1, arr2);
return answer < 2001 ? answer : -1;
}
Dictionary<(int, int), int> dp = new Dictionary<(int, int), int>();
private int Dfs(int i, int prev, int[] arr1, int[] arr2) {
if (i == arr1.Length) {
return 0;
}
var key = (i, prev);
if (dp.ContainsKey(key)) {
return dp[key];
}
int cost = 2001;
if (arr1[i] > prev) {
cost = Dfs(i + 1, arr1[i], arr1, arr2);
}
int idx = Array.BinarySearch(arr2, prev + 1);
if (idx < 0) {
idx = ~idx;
}
if (idx < arr2.Length) {
cost = Math.Min(cost, 1 + Dfs(i + 1, arr2[idx], arr1, arr2));
}
dp[key] = cost;
return cost;
}
}Ставь 👍 и забирай 📚 Базу знаний
Задача: 927. Three Equal Parts
Сложность: hard
Вам дан массив arr, состоящий только из нулей и единиц. Разделите массив на три непустые части так, чтобы все эти части представляли одно и то же двоичное значение. Если это возможно, верните любой [i, j] с i + 1 < j, такой что: arr[0], arr[1], ..., arr[i] - это первая часть, arr[i + 1], arr[i + 2], ...., arr[j - 1] - вторая часть, и arr[j], arr[j + 1], ..., arr[arr.length - 1] - третья часть. Все три части имеют одинаковые двоичные значения. Если это невозможно, верните [-1, -1]. Обратите внимание, что вся часть используется при рассмотрении того, какое двоичное значение она представляет. Например, [1,1,0] представляет 6 в десятичной системе, а не 3. Кроме того, допускаются ведущие нули, поэтому [0,1,1] и [1,1] представляют одно и то же значение.
Пример:
👨💻 Алгоритм:
1⃣Подсчитать количество единиц в массиве.
2⃣Если количество единиц не делится на три, вернуть [-1, -1].
Найти индексы начала каждой части, игнорируя ведущие нули.
Использовать эти индексы для проверки, могут ли три части быть одинаковыми.
3⃣Если три части одинаковы, вернуть соответствующие индексы, иначе вернуть [-1, -1].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дан массив arr, состоящий только из нулей и единиц. Разделите массив на три непустые части так, чтобы все эти части представляли одно и то же двоичное значение. Если это возможно, верните любой [i, j] с i + 1 < j, такой что: arr[0], arr[1], ..., arr[i] - это первая часть, arr[i + 1], arr[i + 2], ...., arr[j - 1] - вторая часть, и arr[j], arr[j + 1], ..., arr[arr.length - 1] - третья часть. Все три части имеют одинаковые двоичные значения. Если это невозможно, верните [-1, -1]. Обратите внимание, что вся часть используется при рассмотрении того, какое двоичное значение она представляет. Например, [1,1,0] представляет 6 в десятичной системе, а не 3. Кроме того, допускаются ведущие нули, поэтому [0,1,1] и [1,1] представляют одно и то же значение.
Пример:
Input: arr = [1,0,1,0,1]
Output: [0,3]
👨💻 Алгоритм:
1⃣Подсчитать количество единиц в массиве.
2⃣Если количество единиц не делится на три, вернуть [-1, -1].
Найти индексы начала каждой части, игнорируя ведущие нули.
Использовать эти индексы для проверки, могут ли три части быть одинаковыми.
3⃣Если три части одинаковы, вернуть соответствующие индексы, иначе вернуть [-1, -1].
😎 Решение:
public class Solution {
public int[] ThreeEqualParts(int[] arr) {
int ones = 0;
foreach (int num in arr) {
ones += num;
}
if (ones % 3 != 0) return new int[]{-1, -1};
if (ones == 0) return new int[]{0, arr.Length - 1};
int partOnes = ones / 3;
int first = 0, second = 0, third = 0, cnt = 0;
for (int i = 0; i < arr.Length; i++) {
if (arr[i] == 1) {
if (cnt == 0) first = i;
else if (cnt == partOnes) second = i;
else if (cnt == 2 * partOnes) third = i;
cnt++;
}
}
while (third < arr.Length && arr[first] == arr[second] && arr[first] == arr[third]) {
first++;
second++;
third++;
}
if (third == arr.Length) return new int[]{first - 1, second};
return new int[]{-1, -1};
}
}Ставь 👍 и забирай 📚 Базу знаний
Задача: 645. Set Mismatch
Сложность: easy
У вас есть набор целых чисел s, который изначально содержит все числа от 1 до n. К сожалению, из-за какой-то ошибки одно из чисел в s продублировалось в другое число в наборе, что привело к повторению одного числа и потере другого. Вам дан целочисленный массив nums, представляющий состояние данных в этом наборе после ошибки. Найдите число, которое встречается дважды, и число, которое отсутствует, и верните их в виде массива.
Пример:
👨💻 Алгоритм:
1⃣Пройдите по массиву, используя набор для отслеживания чисел, чтобы определить дублированное число.
2⃣Определите отсутствующее число, используя сумму чисел от 1 до n и текущую сумму массива.
3⃣Верните дублированное и отсутствующее числа в виде массива.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
У вас есть набор целых чисел s, который изначально содержит все числа от 1 до n. К сожалению, из-за какой-то ошибки одно из чисел в s продублировалось в другое число в наборе, что привело к повторению одного числа и потере другого. Вам дан целочисленный массив nums, представляющий состояние данных в этом наборе после ошибки. Найдите число, которое встречается дважды, и число, которое отсутствует, и верните их в виде массива.
Пример:
Input: nums = [1,2,2,4]
Output: [2,3]
👨💻 Алгоритм:
1⃣Пройдите по массиву, используя набор для отслеживания чисел, чтобы определить дублированное число.
2⃣Определите отсутствующее число, используя сумму чисел от 1 до n и текущую сумму массива.
3⃣Верните дублированное и отсутствующее числа в виде массива.
😎 Решение:
public class Solution {
public int[] FindErrorNums(int[] nums) {
int n = nums.Length;
HashSet<int> numSet = new HashSet<int>();
int duplicate = -1;
foreach (int num in nums) {
if (!numSet.Add(num)) {
duplicate = num;
}
}
int missing = (n * (n + 1)) / 2 - numSet.Sum();
return new int[] { duplicate, missing };
}
}Ставь 👍 и забирай 📚 Базу знаний
🔥 Скрытые вакансии с удаленной работой для C# разработчика, которые нигде больше не публикуются. Напрямую от компаний, с контактами рекрутеров.
🔹 C# .NET Jobs | Вакансии
🔹 Unity Jobs | Вакансии
🔸 Все каналы с вакансиями
🔹 C# .NET Jobs | Вакансии
🔹 Unity Jobs | Вакансии
🔸 Все каналы с вакансиями
Задача: 1509. Minimum Difference Between Largest and Smallest Value in Three Moves
Сложность: medium
Вам дан массив целых чисел nums.
За один ход вы можете выбрать один элемент массива nums и изменить его на любое значение.
Верните минимальную разницу между наибольшим и наименьшим значением в массиве nums после выполнения не более трех ходов.
Пример:
👨💻 Алгоритм:
1⃣Инициализация: определите размер массива nums, если размер меньше или равен 4, верните 0. Отсортируйте массив nums и инициализируйте переменную minDiff очень большим числом.
2⃣Итерация по первым четырем элементам отсортированного массива: для каждого индекса left от 0 до 3 вычислите соответствующий правый индекс, разницу между элементами на этих индексах и обновите minDiff с минимальным значением.
3⃣Верните minDiff, которое хранит минимальную разницу между наибольшими и наименьшими значениями после удаления до трех элементов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан массив целых чисел nums.
За один ход вы можете выбрать один элемент массива nums и изменить его на любое значение.
Верните минимальную разницу между наибольшим и наименьшим значением в массиве nums после выполнения не более трех ходов.
Пример:
Input: nums = [5,3,2,4]
Output: 0
Explanation: We can make at most 3 moves.
In the first move, change 2 to 3. nums becomes [5,3,3,4].
In the second move, change 4 to 3. nums becomes [5,3,3,3].
In the third move, change 5 to 3. nums becomes [3,3,3,3].
After performing 3 moves, the difference between the minimum and maximum is 3 - 3 = 0.
👨💻 Алгоритм:
1⃣Инициализация: определите размер массива nums, если размер меньше или равен 4, верните 0. Отсортируйте массив nums и инициализируйте переменную minDiff очень большим числом.
2⃣Итерация по первым четырем элементам отсортированного массива: для каждого индекса left от 0 до 3 вычислите соответствующий правый индекс, разницу между элементами на этих индексах и обновите minDiff с минимальным значением.
3⃣Верните minDiff, которое хранит минимальную разницу между наибольшими и наименьшими значениями после удаления до трех элементов.
😎 Решение:
public class Solution {
public int MinDifference(int[] nums) {
int numsSize = nums.Length;
if (numsSize <= 4) return 0;
Array.Sort(nums);
int minDiff = int.MaxValue;
for (int left = 0, right = numsSize - 4; left < 4; left++, right++) {
minDiff = Math.Min(minDiff, nums[right] - nums[left]);
}
return minDiff;
}
}Ставь 👍 и забирай 📚 Базу знаний
Задача: 525. Contiguous Array
Сложность: medium
Дан бинарный массив nums. Верните максимальную длину непрерывного подмассива с равным количеством 0 и 1.
Пример:
👨💻 Алгоритм:
1⃣Инициализируйте переменную count для отслеживания разности между количеством 1 и 0, и переменную max_length для хранения максимальной длины подмассива. Создайте хеш-таблицу map для хранения первых встреч каждого значения count. Добавьте начальное значение (0, -1) в хеш-таблицу.
2⃣Итеративно пройдите по массиву nums. На каждой итерации обновляйте значение count (увеличивайте на 1 для 1 и уменьшайте на 1 для 0). Если текущее значение count уже существует в хеш-таблице, вычислите длину подмассива между текущим индексом и индексом из хеш-таблицы. Обновите max_length, если текущий подмассив длиннее.
3⃣Если текущее значение count не существует в хеш-таблице, добавьте его с текущим индексом. После завершения итерации верните max_length.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан бинарный массив nums. Верните максимальную длину непрерывного подмассива с равным количеством 0 и 1.
Пример:
Input: nums = [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1.
👨💻 Алгоритм:
1⃣Инициализируйте переменную count для отслеживания разности между количеством 1 и 0, и переменную max_length для хранения максимальной длины подмассива. Создайте хеш-таблицу map для хранения первых встреч каждого значения count. Добавьте начальное значение (0, -1) в хеш-таблицу.
2⃣Итеративно пройдите по массиву nums. На каждой итерации обновляйте значение count (увеличивайте на 1 для 1 и уменьшайте на 1 для 0). Если текущее значение count уже существует в хеш-таблице, вычислите длину подмассива между текущим индексом и индексом из хеш-таблицы. Обновите max_length, если текущий подмассив длиннее.
3⃣Если текущее значение count не существует в хеш-таблице, добавьте его с текущим индексом. После завершения итерации верните max_length.
😎 Решение:
using System.Collections.Generic;
public class Solution {
public int FindMaxLength(int[] nums) {
Dictionary<int, int> countMap = new Dictionary<int, int> { {0, -1} };
int maxLength = 0;
int count = 0;
for (int i = 0; i < nums.Length; i++) {
count += (nums[i] == 1 ? 1 : -1);
if (countMap.ContainsKey(count)) {
maxLength = Math.Max(maxLength, i - countMap[count]);
} else {
countMap[count] = i;
}
}
return maxLength;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Задача: 1061. Lexicographically Smallest Equivalent String
Сложность: medium
Даны две строки одинаковой длины s1 и s2, а также строка baseStr.
Мы говорим, что символы s1[i] и s2[i] эквивалентны.
Например, если s1 = "abc" и s2 = "cde", то 'a' == 'c', 'b' == 'd' и 'c' == 'e'. Эквивалентные символы следуют правилам рефлексивности, симметрии и транзитивности.
Верните лексикографически наименьшую эквивалентную строку baseStr, используя информацию об эквивалентности из s1 и s2.
Пример:
👨💻 Алгоритм:
1⃣Создайте матрицу смежности adjMatrix размером 26x26 для хранения рёбер и массив visited для отслеживания посещённых символов.
2⃣Итеративно обрабатывайте каждый символ от 0 до 25:
Если символ ещё не посещён, выполните DFS, начиная с этого символа, и сохраните все пройденные символы в векторе component, а минимальный из этих символов в переменной minChar.
Обновите все символы из component до minChar в векторе mappingChar, который хранит окончательное сопоставление символов baseStr.
3⃣Пройдите по baseStr и создайте итоговую строку ans, используя символы из mappingChar.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны две строки одинаковой длины s1 и s2, а также строка baseStr.
Мы говорим, что символы s1[i] и s2[i] эквивалентны.
Например, если s1 = "abc" и s2 = "cde", то 'a' == 'c', 'b' == 'd' и 'c' == 'e'. Эквивалентные символы следуют правилам рефлексивности, симметрии и транзитивности.
Верните лексикографически наименьшую эквивалентную строку baseStr, используя информацию об эквивалентности из s1 и s2.
Пример:
Input: s1 = "parker", s2 = "morris", baseStr = "parser"
Output: "makkek"
Explanation: Based on the equivalency information in s1 and s2, we can group their characters as [m,p], [a,o], [k,r,s], [e,i].
The characters in each group are equivalent and sorted in lexicographical order.
So the answer is "makkek".
👨💻 Алгоритм:
1⃣Создайте матрицу смежности adjMatrix размером 26x26 для хранения рёбер и массив visited для отслеживания посещённых символов.
2⃣Итеративно обрабатывайте каждый символ от 0 до 25:
Если символ ещё не посещён, выполните DFS, начиная с этого символа, и сохраните все пройденные символы в векторе component, а минимальный из этих символов в переменной minChar.
Обновите все символы из component до minChar в векторе mappingChar, который хранит окончательное сопоставление символов baseStr.
3⃣Пройдите по baseStr и создайте итоговую строку ans, используя символы из mappingChar.
😎 Решение:
class Solution {
void DFS(int src, int[,] adjMatrix, int[] visited, List<int> component, ref int minChar) {
visited[src] = 1;
component.Add(src);
minChar = Math.Min(minChar, src);
for (int i = 0; i < 26; i++) {
if (adjMatrix[src, i] != 0 && visited[i] == 0) {
DFS(i, adjMatrix, visited, component, ref minChar);
}
}
}
public string SmallestEquivalentString(string s1, string s2, string baseStr) {
int[,] adjMatrix = new int[26, 26];
for (int i = 0; i < s1.Length; i++) {
adjMatrix[s1[i] - 'a', s2[i] - 'a'] = 1;
adjMatrix[s2[i] - 'a', s1[i] - 'a'] = 1;
}
int[] mappingChar = new int[26];
for (int i = 0; i < 26; i++) {
mappingChar[i] = i;
}
int[] visited = new int[26];
for (int c = 0; c < 26; c++) {
if (visited[c] == 0) {
List<int> component = new List<int>();
int minChar = 27;
DFS(c, adjMatrix, visited, component, ref minChar);
foreach (int vertex in component) {
mappingChar[vertex] = minChar;
}
}
}
StringBuilder ans = new StringBuilder();
foreach (char c in baseStr) {
ans.Append((char)(mappingChar[c - 'a'] + 'a'));
}
return ans.ToString();
}
}Ставь 👍 и забирай 📚 Базу знаний
Задача: 1171. Remove Zero Sum Consecutive Nodes from Linked List
Сложность: medium
Дан указатель на голову связанного списка. Мы многократно удаляем последовательные последовательности узлов, сумма которых равна 0, до тех пор, пока такие последовательности не исчезнут.
После этого верните голову конечного связанного списка. Вы можете вернуть любой такой ответ.
Пример:
👨💻 Алгоритм:
1⃣Инициализируйте новый узел ListNode с именем front со значением 0, у которого поле next указывает на head, и узел start, указывающий на front.
2⃣Обрабатывайте все узлы в связанном списке, пока start != null. Инициализируйте переменную prefixSum значением 0 и узел ListNode с именем end, указывающий на start.next. Обрабатывайте остальные узлы в связанном списке, пока end != null: добавьте значение узла end к prefixSum. Если prefixSum равен 0, установите соединение от узла start к последнему узлу после последовательности с суммой ноль, установив start.next равным end.next. Установите end равным end.next.
3⃣Установите start равным start.next. Верните front.next. Узел front указывает на голову конечного связанного списка.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан указатель на голову связанного списка. Мы многократно удаляем последовательные последовательности узлов, сумма которых равна 0, до тех пор, пока такие последовательности не исчезнут.
После этого верните голову конечного связанного списка. Вы можете вернуть любой такой ответ.
Пример:
Input: head = [1,2,-3,3,1]
Output: [3,1]
Note: The answer [1,2,1] would also be accepted.
👨💻 Алгоритм:
1⃣Инициализируйте новый узел ListNode с именем front со значением 0, у которого поле next указывает на head, и узел start, указывающий на front.
2⃣Обрабатывайте все узлы в связанном списке, пока start != null. Инициализируйте переменную prefixSum значением 0 и узел ListNode с именем end, указывающий на start.next. Обрабатывайте остальные узлы в связанном списке, пока end != null: добавьте значение узла end к prefixSum. Если prefixSum равен 0, установите соединение от узла start к последнему узлу после последовательности с суммой ноль, установив start.next равным end.next. Установите end равным end.next.
3⃣Установите start равным start.next. Верните front.next. Узел front указывает на голову конечного связанного списка.
😎 Решение:
public class ListNode {
public int val;
public ListNode next;
public ListNode(int val=0, ListNode next=null) {
this.val = val;
this.next = next;
}
}
public class Solution {
public ListNode RemoveZeroSumSublists(ListNode head) {
ListNode front = new ListNode(0, head);
ListNode start = front;
while (start != null) {
int prefixSum = 0;
ListNode end = start.next;
while (end != null) {
prefixSum += end.val;
if (prefixSum == 0) {
start.next = end.next;
}
end = end.next;
}
start = start.next;
}
return front.next;
}
}Ставь 👍 и забирай 📚 Базу знаний