Задача: 903. Valid Permutations for DI Sequence
Сложность: hard
Вам дана строка s длины n, где s[i] либо: 'D' означает убывание, либо 'I' означает возрастание. Перестановка perm из n + 1 целых чисел всех целых чисел в диапазоне [0, n] называется допустимой, если для всех допустимых i: если s[i] == 'D', то perm[i] > perm[i + 1], а если s[i] == 'I', то perm[i] < perm[i + 1]. Верните количество допустимых перестановок perm. Поскольку ответ может быть большим, верните его по модулю 109 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Создать двумерный массив dp, где dp[i][j] представляет количество допустимых перестановок длины i, оканчивающихся на j.
2⃣ Заполнить массив dp, учитывая условия возрастания и убывания из строки s.
3⃣ Вернуть сумму dp[n][j] для всех j, что даст количество допустимых перестановок длины n + 1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дана строка s длины n, где s[i] либо: 'D' означает убывание, либо 'I' означает возрастание. Перестановка perm из n + 1 целых чисел всех целых чисел в диапазоне [0, n] называется допустимой, если для всех допустимых i: если s[i] == 'D', то perm[i] > perm[i + 1], а если s[i] == 'I', то perm[i] < perm[i + 1]. Верните количество допустимых перестановок perm. Поскольку ответ может быть большим, верните его по модулю 109 + 7.
Пример:
Input: s = "DID"
Output: 5
public class Solution {
public int NumPermsDISequence(string s) {
int MOD = 1_000_000_007;
int n = s.Length;
int[][] dp = new int[n + 1][];
for (int i = 0; i <= n; i++) {
dp[i] = new int[n + 1];
}
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= i; j++) {
if (s[i - 1] == 'D') {
for (int k = j; k < i; k++) {
dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
}
} else {
for (int k = 0; k < j; k++) {
dp[i][j] = (dp[i][j] + dp[i - 1][k]) % MOD;
}
}
}
}
int result = 0;
for (int j = 0; j <= n; j++) {
result = (result + dp[n][j]) % MOD;
}
return result;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 925. Long Pressed Name
Сложность: easy
Ваш друг набирает на клавиатуре свое имя. Иногда, при наборе символа c, клавиша может быть долго нажата, и символ будет набран 1 или более раз. Вы исследуете набранные символы клавиатуры. Верните True, если возможно, что это было имя вашего друга, при этом некоторые символы (возможно, ни один) не были долго нажаты.
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать два указателя i и j для строки имени и набранной строки соответственно.
2⃣ Пройти по набранной строке:
Если символы имени и набранной строки совпадают, сдвинуть оба указателя.
Если символы не совпадают, проверить, является ли текущий символ набранной строки повторением предыдущего символа. Если да, сдвинуть указатель набранной строки.
Если символ не совпадает и не является повторением предыдущего символа, вернуть False.
После завершения цикла проверить, что все символы имени были обработаны.
3⃣ Вернуть True, если все символы имени были обработаны, иначе False.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Ваш друг набирает на клавиатуре свое имя. Иногда, при наборе символа c, клавиша может быть долго нажата, и символ будет набран 1 или более раз. Вы исследуете набранные символы клавиатуры. Верните True, если возможно, что это было имя вашего друга, при этом некоторые символы (возможно, ни один) не были долго нажаты.
Пример:
Input: name = "alex", typed = "aaleex"
Output: true
Если символы имени и набранной строки совпадают, сдвинуть оба указателя.
Если символы не совпадают, проверить, является ли текущий символ набранной строки повторением предыдущего символа. Если да, сдвинуть указатель набранной строки.
Если символ не совпадает и не является повторением предыдущего символа, вернуть False.
После завершения цикла проверить, что все символы имени были обработаны.
public class Solution {
public bool IsLongPressedName(string name, string typed) {
int i = 0, j = 0;
while (j < typed.Length) {
if (i < name.Length && name[i] == typed[j]) {
i++;
} else if (j == 0 || typed[j] != typed[j - 1]) {
return false;
}
j++;
}
return i == name.Length;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 227. Basic Calculator II
Сложность: medium
Дана строка s, представляющая выражение. Вычислите это выражение и верните его значение.
Целочисленное деление должно округляться к нулю.
Вы можете предположить, что данное выражение всегда является допустимым. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1].
Примечание: Запрещено использовать какие-либо встроенные функции, которые вычисляют строки как математические выражения, такие как eval().
Пример:
👨💻 Алгоритм:
1⃣ Вместо использования стека, используем переменную lastNumber для отслеживания значения последнего вычисленного выражения.
2⃣ Если операция сложения (+) или вычитания (-), добавляем lastNumber к результату вместо того, чтобы помещать его в стек. Текущее значение currentNumber будет обновлено на lastNumber для следующей итерации.
3⃣ Если операция умножения (*) или деления (/), вычисляем выражение lastNumber * currentNumber и обновляем lastNumber с результатом выражения. Это значение будет добавлено к результату после сканирования всей строки.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана строка s, представляющая выражение. Вычислите это выражение и верните его значение.
Целочисленное деление должно округляться к нулю.
Вы можете предположить, что данное выражение всегда является допустимым. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1].
Примечание: Запрещено использовать какие-либо встроенные функции, которые вычисляют строки как математические выражения, такие как eval().
Пример:
Input: s = "3+2*2"
Output: 7
public class Solution {
public int Calculate(string s) {
int length = s.Length;
if (length == 0) return 0;
int currentNumber = 0, lastNumber = 0, result = 0;
char sign = '+';
for (int i = 0; i < length; i++) {
char currentChar = s[i];
if (char.IsDigit(currentChar)) {
currentNumber = (currentNumber * 10) + (currentChar - '0');
}
if (!char.IsDigit(currentChar) && !char.IsWhiteSpace(currentChar) || i == length - 1) {
if (sign == '+' || sign == '-') {
result += lastNumber;
lastNumber = (sign == '+') ? currentNumber : -currentNumber;
} else if (sign == '*') {
lastNumber *= currentNumber;
} else if (sign == '/') {
lastNumber /= currentNumber;
}
sign = currentChar;
currentNumber = 0;
}
}
result += lastNumber;
return result;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1056. Confusing Number
Сложность: easy
Запутанное число - это число, которое при повороте на 180 градусов становится другим числом, каждая цифра которого действительна. Мы можем повернуть цифры числа на 180 градусов, чтобы получить новые цифры. Когда 0, 1, 6, 8 и 9 поворачиваются на 180 градусов, они становятся 0, 1, 9, 8 и 6 соответственно.
При повороте на 180 градусов 2, 3, 4, 5 и 7 становятся недействительными. Обратите внимание, что после поворота числа мы можем игнорировать ведущие нули. Например, после поворота 8000 мы получим 0008, которое считается просто 8. Если задано целое число n, верните true, если это запутанное число, или false в противном случае.
Пример:
👨💻 Алгоритм:
1⃣ Преобразуй число в строку для удобства работы с его цифрами.
Используй словарь для хранения соответствий цифр при повороте на 180 градусов.
2⃣ Пройди по цифрам числа, проверяя, что все цифры действительны и заменяя их на соответствующие при повороте.
3⃣ Проверь, что перевернутая строка отличается от исходной.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Запутанное число - это число, которое при повороте на 180 градусов становится другим числом, каждая цифра которого действительна. Мы можем повернуть цифры числа на 180 градусов, чтобы получить новые цифры. Когда 0, 1, 6, 8 и 9 поворачиваются на 180 градусов, они становятся 0, 1, 9, 8 и 6 соответственно.
При повороте на 180 градусов 2, 3, 4, 5 и 7 становятся недействительными. Обратите внимание, что после поворота числа мы можем игнорировать ведущие нули. Например, после поворота 8000 мы получим 0008, которое считается просто 8. Если задано целое число n, верните true, если это запутанное число, или false в противном случае.
Пример:
Input: n = 6
Output: true
Используй словарь для хранения соответствий цифр при повороте на 180 градусов.
public class Solution {
public bool IsConfusingNumber(int n) {
string nStr = n.ToString();
Dictionary<char, char> rotationMap = new Dictionary<char, char> {
{'0', '0'}, {'1', '1'}, {'6', '9'}, {'8', '8'}, {'9', '6'}
};
StringBuilder rotatedStr = new StringBuilder();
foreach (char ch in nStr) {
if (!rotationMap.ContainsKey(ch)) {
return false;
}
rotatedStr.Insert(0, rotationMap[ch]);
}
return rotatedStr.ToString() != nStr;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 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.
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;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 105. Construct Binary Tree from Preorder and Inorder Traversal
Сложность: medium
Даны два массива целых чисел: preorder и inorder, где preorder — это результат преордер обхода бинарного дерева, а inorder — результат инордер обхода того же дерева. Постройте и верните бинарное дерево.
Пример:
👨💻 Алгоритм:
1⃣ Создайте хеш-таблицу для записи соотношения значений и их индексов в массиве inorder, чтобы можно было быстро найти позицию корня.
2⃣ Инициализируйте переменную целочисленного типа preorderIndex для отслеживания элемента, который будет использоваться для создания корня. Реализуйте рекурсивную функцию arrayToTree, которая принимает диапазон массива inorder и возвращает построенное бинарное дерево:
Если диапазон пуст, возвращается null;
Инициализируйте корень элементом preorder[preorderIndex], затем увеличьте preorderIndex;
Рекурсивно используйте левую и правую части массива inorder для построения левого и правого поддеревьев.
3⃣ Просто вызовите функцию рекурсии с полным диапазоном массива inorder.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны два массива целых чисел: preorder и inorder, где preorder — это результат преордер обхода бинарного дерева, а inorder — результат инордер обхода того же дерева. Постройте и верните бинарное дерево.
Пример:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
Если диапазон пуст, возвращается null;
Инициализируйте корень элементом preorder[preorderIndex], затем увеличьте preorderIndex;
Рекурсивно используйте левую и правую части массива inorder для построения левого и правого поддеревьев.
public class Solution {
private int preorderIndex;
private Dictionary<int, int> inorderIndexMap;
public TreeNode BuildTree(int[] preorder, int[] inorder) {
preorderIndex = 0;
inorderIndexMap = new Dictionary<int, int>();
for (int i = 0; i < inorder.Length; i++) {
inorderIndexMap[inorder[i]] = i;
}
return ArrayToTree(preorder, 0, preorder.Length - 1);
}
private TreeNode ArrayToTree(int[] preorder, int left, int right) {
if (left > right)
return null;
int rootValue = preorder[preorderIndex++];
TreeNode root = new TreeNode(rootValue);
root.left = ArrayToTree(preorder, left, inorderIndexMap[rootValue] - 1);
root.right =
ArrayToTree(preorder, inorderIndexMap[rootValue] + 1, right);
return root;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 739. Daily Temperatures
Сложность: medium
Задав массив целых чисел temperature, представляющих дневные температуры, верните массив answer, такой, что answer[i] - это количество дней, которые нужно подождать после i-го дня, чтобы температура стала теплее. Если в будущем не существует дня, для которого это возможно, сохраните answer[i] == 0.
Пример:
👨💻 Алгоритм:
1⃣ Создайте стек для хранения индексов дней с температурами, для которых еще не найден более теплый день.
2⃣ Пройдите по массиву температур и для каждого дня: Пока текущая температура больше температуры дня на вершине стека, обновляйте массив ответов и удаляйте вершину стека. Добавьте текущий день в стек.
3⃣ Возвращайте массив ответов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Задав массив целых чисел temperature, представляющих дневные температуры, верните массив answer, такой, что answer[i] - это количество дней, которые нужно подождать после i-го дня, чтобы температура стала теплее. Если в будущем не существует дня, для которого это возможно, сохраните answer[i] == 0.
Пример:
Input: temperatures = [73,74,75,71,69,72,76,73]
Output: [1,1,4,2,1,1,0,0]
public class Solution {
public int[] DailyTemperatures(int[] T) {
int n = T.Length;
int[] answer = new int[n];
Stack<int> stack = new Stack<int>();
for (int i = 0; i < n; i++) {
while (stack.Count > 0 && T[i] > T[stack.Peek()]) {
int j = stack.Pop();
answer[j] = i - j;
}
stack.Push(i);
}
return answer;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 725. Split Linked List in Parts
Сложность: medium
Учитывая голову односвязного списка и целое число k, разбейте связный список на k последовательных частей связного списка. Длина каждой части должна быть как можно более одинаковой: никакие две части не должны иметь размер, отличающийся более чем на единицу. Это может привести к тому, что некоторые части будут нулевыми. Части должны располагаться в порядке появления во входном списке, и части, появившиеся раньше, всегда должны иметь размер, больший или равный частям, появившимся позже. Возвращается массив из k частей.
Пример:
👨💻 Алгоритм:
1⃣ Определите общую длину связного списка.
2⃣ Вычислите базовый размер каждой части и количество частей, которые должны быть на одну единицу длиннее.
3⃣ Разделите список на части, присваивая каждую часть в массив результатов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Учитывая голову односвязного списка и целое число k, разбейте связный список на k последовательных частей связного списка. Длина каждой части должна быть как можно более одинаковой: никакие две части не должны иметь размер, отличающийся более чем на единицу. Это может привести к тому, что некоторые части будут нулевыми. Части должны располагаться в порядке появления во входном списке, и части, появившиеся раньше, всегда должны иметь размер, больший или равный частям, появившимся позже. Возвращается массив из k частей.
Пример:
Input: head = [1,2,3], k = 5
Output: [[1],[2],[3],[],[]]
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[] SplitListToParts(ListNode root, int k) {
int length = 0;
ListNode node = root;
while (node != null) {
length++;
node = node.next;
}
int partLength = length / k;
int extraParts = length % k;
ListNode[] parts = new ListNode[k];
node = root;
for (int i = 0; i < k; i++) {
ListNode partHead = node;
int partSize = partLength + (i < extraParts ? 1 : 0);
for (int j = 0; j < partSize - 1; j++) {
if (node != null) node = node.next;
}
if (node != null) {
ListNode nextPart = node.next;
node.next = null;
node = nextPart;
}
parts[i] = partHead;
}
return parts;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 115. Distinct Subsequences
Сложность: hard
"Даны две строки s и t. Верните количество различных подпоследовательностей строки s, которые равны строке t.
Тестовые примеры сгенерированы таким образом, что ответ укладывается в 32-битное целое число со знаком."
Пример:
👨💻 Алгоритм:
1⃣ Определите функцию с названием recurse, которая принимает два целочисленных значения i и j. Первое значение представляет текущий обрабатываемый символ в строке S, а второе - текущий символ в строке T. Инициализируйте словарь под названием memo, который будет кэшировать результаты различных вызовов рекурсии.**
2⃣ Проверьте базовый случай. Если одна из строк закончилась, возвращается 0 или 1 в зависимости от того, удалось ли обработать всю строку T или нет. Есть ещё один базовый случай, который следует рассмотреть. Если оставшаяся длина строки S меньше, чем у строки T, то совпадение невозможно. Если это обнаруживается, то рекурсия также обрезается и возвращается 0.**
3⃣ Затем проверяем, существует ли текущая пара индексов в нашем словаре. Если да, то просто возвращаем сохранённое/кэшированное значение. Если нет, то продолжаем обычную обработку. Сравниваем символы s[i] и t[j]. Сохраняем результат вызова recurse(i + 1, j) в переменную. Как упоминалось ранее, результат этой рекурсии необходим, независимо от совпадения символов. Если символы совпадают, добавляем к переменной результат вызова recurse(i + 1, j + 1). Наконец, сохраняем значение этой переменной в словаре с ключом (i, j) и возвращаем это значение в качестве ответа.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
"Даны две строки s и t. Верните количество различных подпоследовательностей строки s, которые равны строке t.
Тестовые примеры сгенерированы таким образом, что ответ укладывается в 32-битное целое число со знаком."
Пример:
Input: s = "rabbbit", t = "rabbit"
Output: 3
Explanation:
As shown below, there are 3 ways you can generate "rabbit" from s.
rabbbit
rabbbit
rabbbit
public class Solution {
private Dictionary<string, int> memo;
public int NumDistinct(string s, string t) {
if (s.Length < t.Length)
return 0;
if (s == t || t == "")
return 1;
memo = new Dictionary<string, int>();
return DistinctHelper(s.Substring(0, s.Length - 1), t) +
((s[s.Length - 1] == t[t.Length - 1])
? DistinctHelper(s.Substring(0, s.Length - 1),
t.Substring(0, t.Length - 1))
: 0);
}
private int DistinctHelper(string s, string t) {
if (memo.ContainsKey(s + "," + t))
return memo[s + "," + t];
if (s.Length < t.Length)
return 0;
if (s == t || t == "")
return 1;
memo[s + "," + t] = DistinctHelper(s.Substring(0, s.Length - 1), t) +
((s[s.Length - 1] == t[t.Length - 1])
? DistinctHelper(s.Substring(0, s.Length - 1),
t.Substring(0, t.Length - 1))
: 0);
return memo[s + "," + t];
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 764. Largest Plus Sign
Сложность: medium
Вам дано целое число n. У вас есть бинарная сетка размером n x n, в которой все значения изначально равны 1, за исключением некоторых индексов, указанных в массиве mines. Элемент массива mines с индексом i определяется как mines[i] = [xi, yi], где grid[xi][yi] == 0.
Верните порядок самого большого крестообразного знака из 1, выровненного по осям, который содержится в сетке. Если такого знака нет, верните 0.
Крестообразный знак из 1 порядка k имеет некоторый центр grid[r][c] == 1, а также четыре луча длиной k - 1, идущих вверх, вниз, влево и вправо, состоящие из 1. Обратите внимание, что за пределами лучей креста могут быть 0 или 1, проверяется только соответствующая область крестообразного знака на наличие 1.
Пример:
👨💻 Алгоритм:
1⃣ Создайте сетку размером n x n, заполненную единицами. Затем используйте массив mines, чтобы установить значения нулей в соответствующих ячейках сетки.
2⃣ Для каждой ячейки в сетке создайте четыре дополнительных сетки: left, right, up и down, которые будут хранить длину непрерывных единиц, простирающихся в соответствующем направлении от каждой ячейки.
3⃣ Пройдите по всей сетке и для каждой ячейки определите минимальную длину луча среди четырех направлений. Эта минимальная длина будет определять порядок крестообразного знака с центром в данной ячейке. Обновите максимальный порядок крестообразного знака и верните его после завершения обхода всей сетки. Если такого знака нет, верните 0.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дано целое число n. У вас есть бинарная сетка размером n x n, в которой все значения изначально равны 1, за исключением некоторых индексов, указанных в массиве mines. Элемент массива mines с индексом i определяется как mines[i] = [xi, yi], где grid[xi][yi] == 0.
Верните порядок самого большого крестообразного знака из 1, выровненного по осям, который содержится в сетке. Если такого знака нет, верните 0.
Крестообразный знак из 1 порядка k имеет некоторый центр grid[r][c] == 1, а также четыре луча длиной k - 1, идущих вверх, вниз, влево и вправо, состоящие из 1. Обратите внимание, что за пределами лучей креста могут быть 0 или 1, проверяется только соответствующая область крестообразного знака на наличие 1.
Пример:
Input: n = 5, mines = [[4,2]]
Output: 2
Explanation: In the above grid, the largest plus sign can only be of order 2. One of them is shown.
public class Solution {
public int OrderOfLargestPlusSign(int N, int[][] mines) {
var banned = new HashSet<int>();
foreach (var mine in mines) {
banned.Add(mine[0] * N + mine[1]);
}
int ans = 0;
for (int r = 0; r < N; ++r) {
for (int c = 0; c < N; ++c) {
int k = 0;
while (k <= r && r < N - k && k <= c && c < N - k &&
!banned.Contains((r - k) * N + c) &&
!banned.Contains((r + k) * N + c) &&
!banned.Contains(r * N + c - k) &&
!banned.Contains(r * N + c + k)) {
k++;
}
ans = Math.Max(ans, k);
}
}
return ans;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 943. Find the Shortest Superstring
Сложность: hard
Учитывая массив строк words, верните наименьшую строку, которая содержит каждую строку в words в качестве подстроки. Если существует несколько допустимых строк наименьшей длины, верните любую из них. Вы можете предположить, что ни одна строка в words не является подстрокой другой строки в words.
Пример:
👨💻 Алгоритм:
1⃣ Реализовать функцию overlap для вычисления максимального перекрытия двух строк, где одна строка заканчивается, а другая начинается.
2⃣ Реализовать функцию merge для объединения двух строк с максимальным перекрытием.
Использовать жадный алгоритм для нахождения двух строк с максимальным перекрытием и объединить их, повторяя до тех пор, пока не останется одна строка.
3⃣ Вернуть результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Учитывая массив строк words, верните наименьшую строку, которая содержит каждую строку в words в качестве подстроки. Если существует несколько допустимых строк наименьшей длины, верните любую из них. Вы можете предположить, что ни одна строка в words не является подстрокой другой строки в words.
Пример:
Input: words = ["alex","loves","leetcode"]
Output: "alexlovesleetcode"
Использовать жадный алгоритм для нахождения двух строк с максимальным перекрытием и объединить их, повторяя до тех пор, пока не останется одна строка.
public class Solution {
public string ShortestSuperstring(string[] words) {
while (words.Length > 1) {
int maxOverlap = -1;
int l = 0, r = 0;
string merged = "";
for (int i = 0; i < words.Length; i++) {
for (int j = 0; j < words.Length; j++) {
if (i != j) {
int ovlp = Overlap(words[i], words[j]);
if (ovlp > maxOverlap) {
maxOverlap = ovlp;
l = i;
r = j;
merged = Merge(words[i], words[j], ovlp);
}
}
}
}
words[l] = merged;
words = words.Where((val, idx) => idx != r).ToArray();
}
return words[0];
}
private int Overlap(string a, string b) {
int maxOverlap = 0;
for (int i = 1; i <= Math.Min(a.Length, b.Length); i++) {
if (a.Substring(a.Length - i) == b.Substring(0, i)) {
maxOverlap = i;
}
}
return maxOverlap;
}
private string Merge(string a, string b, int overlapLen) {
return a + b.Substring(overlapLen);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 198. House Robber
Сложность: medium
Вы — профессиональный грабитель, планирующий ограбление домов вдоль улицы. В каждом доме спрятана определённая сумма денег, единственное ограничение, мешающее ограбить каждый из них, заключается в том, что соседние дома оснащены охранными системами, которые автоматически свяжутся с полицией, если в одну и ту же ночь будут взломаны два соседних дома.
Учитывая целочисленный массив nums, представляющий сумму денег в каждом доме, верните максимальную сумму денег, которую вы можете ограбить этой ночью, не подняв тревогу.
Пример:
👨💻 Алгоритм:
1⃣ Определите функцию robFrom(), которая принимает индекс дома, который грабитель должен осмотреть, и массив nums, необходимый для вычислений. На каждом шаге рекурсивного вызова у грабителя есть два варианта: ограбить текущий дом или нет.
2⃣ Если грабитель выбирает ограбить текущий дом, он должен пропустить следующий, т.е. вызвать robFrom(i + 2, nums). Ответ будет равен значению robFrom(i + 2, nums) плюс сумма, которую грабитель получит, ограбив текущий дом, т.е. nums[i]. В противном случае он может перейти к следующему дому и вернуть прибыль, которую он получит в подзадаче, т.е. robFrom(i + 1, nums).
3⃣ Нужно найти, сохранить в кэше и вернуть максимум из этих двух вариантов на каждом шаге. robFrom(0, nums) даст ответ на всю задачу.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вы — профессиональный грабитель, планирующий ограбление домов вдоль улицы. В каждом доме спрятана определённая сумма денег, единственное ограничение, мешающее ограбить каждый из них, заключается в том, что соседние дома оснащены охранными системами, которые автоматически свяжутся с полицией, если в одну и ту же ночь будут взломаны два соседних дома.
Учитывая целочисленный массив nums, представляющий сумму денег в каждом доме, верните максимальную сумму денег, которую вы можете ограбить этой ночью, не подняв тревогу.
Пример:
Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
class Solution {
private int[] memo;
public int Rob(int[] nums) {
memo = new int[100];
for (int i = 0; i < memo.Length; i++) {
memo[i] = -1;
}
return RobFrom(0, nums);
}
private int RobFrom(int i, int[] nums) {
if (i >= nums.Length) {
return 0;
}
if (memo[i] > -1) {
return memo[i];
}
int ans = Math.Max(RobFrom(i + 1, nums), RobFrom(i + 2, nums) + nums[i]);
memo[i] = ans;
return ans;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 94. Binary Tree Inorder Traversal
Сложность: easy
Дан корень бинарного дерева. Верните обход значений его узлов в симметричном порядке.
Пример:
👨💻 Алгоритм:
1⃣ Используйте рекурсивную вспомогательную функцию Helper, чтобы обойти дерево.
2⃣ В каждом вызове сначала рекурсивно вызывайте левое поддерево.
3⃣ Затем укажите значение текущего узла в результате и рекурсивно вызовите правое поддерево.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан корень бинарного дерева. Верните обход значений его узлов в симметричном порядке.
Пример:
Input: root = [1,null,2,3]
Output: [1,3,2]
public class Solution {
List<int> res = new List<int>();
public IList<int> InorderTraversal(TreeNode root) {
Helper(root);
return res;
}
public void Helper(TreeNode root) {
if (root != null) {
Helper(root.left);
res.Add(root.val);
Helper(root.right);
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1493. Longest Subarray of 1's After Deleting One Element
Сложность: medium
Дан бинарный массив nums, из которого следует удалить один элемент.
Верните размер самой длинной непустой подмассивы, содержащей только 1, в результирующем массиве. Верните 0, если такого подмассива не существует.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация переменных:
zeroCount для подсчёта нулей в текущем окне, longestWindow для хранения максимальной длины окна, содержащего не более одного нуля, и start для левой границы окна.
2⃣ Итерация по массиву:
При каждом элементе увеличиваем zeroCount, если это ноль.
Если zeroCount превышает 1, сокращаем окно, перемещая левую границу вправо и уменьшая zeroCount, пока количество нулей не станет меньше или равно 1.
Обновляем longestWindow текущей длиной окна i - start.
3⃣ Возврат результата:
Вернуть longestWindow.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан бинарный массив nums, из которого следует удалить один элемент.
Верните размер самой длинной непустой подмассивы, содержащей только 1, в результирующем массиве. Верните 0, если такого подмассива не существует.
Пример:
Input: nums = [0,1,1,1,0,1,1,0,1]
Output: 5
Explanation: After deleting the number in position 4, [0,1,1,1,1,1,0,1] longest subarray with value of 1's is [1,1,1,1,1].
zeroCount для подсчёта нулей в текущем окне, longestWindow для хранения максимальной длины окна, содержащего не более одного нуля, и start для левой границы окна.
При каждом элементе увеличиваем zeroCount, если это ноль.
Если zeroCount превышает 1, сокращаем окно, перемещая левую границу вправо и уменьшая zeroCount, пока количество нулей не станет меньше или равно 1.
Обновляем longestWindow текущей длиной окна i - start.
Вернуть longestWindow.
public class Solution {
public int LongestSubarray(int[] nums) {
int zeroCount = 0;
int longestWindow = 0;
int start = 0;
for (int i = 0; i < nums.Length; i++) {
if (nums[i] == 0) {
zeroCount++;
}
while (zeroCount > 1) {
if (nums[start] == 0) {
zeroCount--;
}
start++;
}
longestWindow = Math.Max(longestWindow, i - start);
}
return longestWindow;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1006. Clumsy Factorial
Сложность: medium
Факториал целого положительного числа n - это произведение всех целых положительных чисел, меньших или равных n. Например, факториал(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1.
Мы составляем неуклюжий факториал, используя целые числа в порядке убывания, заменяя операции умножения на фиксированную последовательность операций с умножением "*", делением "/", сложением "+" и вычитанием "-" в этом порядке. Например, clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1. Однако эти операции по-прежнему применяются с использованием обычного порядка операций арифметики. Мы выполняем все шаги умножения и деления перед шагами сложения и вычитания, а шаги умножения и деления выполняются слева направо. Кроме того, деление, которое мы используем, является делением с полом, так что 10 * 9 / 8 = 90 / 8 = 11. Учитывая целое число n, верните неуклюжий факториал n.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация переменных и обработка первых трех чисел:
Создайте переменные для хранения результата и текущего значения.
Если n меньше или равен 3, обработайте случай отдельно, выполняя операции в порядке убывания, и верните результат.
2⃣ Выполнение операций в цикле:
Создайте цикл, который будет обрабатывать числа от n до 1 в порядке убывания.
В цикле выполняйте операции *, /, +, и - последовательно.
Обновляйте текущий результат на каждом шаге в зависимости от остатка от деления текущего индекса на 4.
3⃣ Учет оставшихся операций и возврат результата:
После завершения цикла добавьте или вычтите оставшиеся числа (если есть) к результату.
Верните окончательный результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Факториал целого положительного числа n - это произведение всех целых положительных чисел, меньших или равных n. Например, факториал(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1.
Мы составляем неуклюжий факториал, используя целые числа в порядке убывания, заменяя операции умножения на фиксированную последовательность операций с умножением "*", делением "/", сложением "+" и вычитанием "-" в этом порядке. Например, clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1. Однако эти операции по-прежнему применяются с использованием обычного порядка операций арифметики. Мы выполняем все шаги умножения и деления перед шагами сложения и вычитания, а шаги умножения и деления выполняются слева направо. Кроме того, деление, которое мы используем, является делением с полом, так что 10 * 9 / 8 = 90 / 8 = 11. Учитывая целое число n, верните неуклюжий факториал n.
Пример:
Input: nums = [4,2,3], k = 1
Output: 5
Создайте переменные для хранения результата и текущего значения.
Если n меньше или равен 3, обработайте случай отдельно, выполняя операции в порядке убывания, и верните результат.
Создайте цикл, который будет обрабатывать числа от n до 1 в порядке убывания.
В цикле выполняйте операции *, /, +, и - последовательно.
Обновляйте текущий результат на каждом шаге в зависимости от остатка от деления текущего индекса на 4.
После завершения цикла добавьте или вычтите оставшиеся числа (если есть) к результату.
Верните окончательный результат.
public class Solution {
public int Clumsy(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2 * 1;
if (n == 3) return 3 * 2 / 1;
int res = n * (n - 1) / (n - 2);
n -= 3;
if (n > 0) res += n--;
while (n > 0) {
res -= n * (n - 1) / (n - 2);
n -= 3;
if (n > 0) res += n--;
}
return res;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 238. Product of Array Except Self
Сложность: medium
Дан массив целых чисел nums, верните массив answer такой, что answer[i] равен произведению всех элементов массива nums, кроме nums[i].
Произведение любого префикса или суффикса массива nums гарантированно помещается в 32-битное целое число.
Вы должны написать алгоритм, который работает за время O(n) и не использует операцию деления.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация массивов L и R: Инициализируйте два пустых массива L и R. Массив L будет содержать произведение всех чисел слева от i, а массив R будет содержать произведение всех чисел справа от i. Заполните массив L, установив L[0] равным 1, а для остальных элементов используйте формулу L[i] = L[i-1] * nums[i-1]. Заполните массив R, установив R[length-1] равным 1, а для остальных элементов используйте формулу R[i] = R[i+1] * nums[i+1].
2⃣ Заполнение массивов L и R: Пройдите два цикла для заполнения массивов L и R. В первом цикле заполните массив L, начиная с L[0] и двигаясь вправо. Во втором цикле заполните массив R, начиная с R[length-1] и двигаясь влево.
3⃣ Формирование результата: Пройдите по исходному массиву и для каждого элемента i вычислите произведение всех элементов, кроме nums[i], используя L[i] * R[i]. Сохраните результат в массиве answer и верните его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел nums, верните массив answer такой, что answer[i] равен произведению всех элементов массива nums, кроме nums[i].
Произведение любого префикса или суффикса массива nums гарантированно помещается в 32-битное целое число.
Вы должны написать алгоритм, который работает за время O(n) и не использует операцию деления.
Пример:
Input: nums = [1,2,3,4]
Output: [24,12,8,6]
public class Solution {
public int[] ProductExceptSelf(int[] nums) {
int length = nums.Length;
int[] L = new int[length];
int[] R = new int[length];
int[] answer = new int[length];
L[0] = 1;
for (int i = 1; i < length; i++) {
L[i] = nums[i - 1] * L[i - 1];
}
R[length - 1] = 1;
for (int i = length - 2; i >= 0; i--) {
R[i] = nums[i + 1] * R[i + 1];
}
for (int i = 0; i < length; i++) {
answer[i] = L[i] * R[i];
}
return answer;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 128. Longest Consecutive Sequence
Сложность: medium
Дан несортированный массив целых чисел nums. Верните длину самой длинной последовательности последовательных элементов.
Необходимо написать алгоритм, который работает за время O(n).
Пример:
👨💻 Алгоритм:
1⃣ Проверка базового случая:
Перед началом работы проверяем базовый случай с пустым массивом.
Самая длинная последовательность в пустом массиве, очевидно, равна 0, поэтому мы можем просто вернуть это значение.
2⃣ Обработка чисел в массиве:
Для всех других случаев мы сортируем массив nums и рассматриваем каждое число, начиная со второго (поскольку нам нужно сравнивать каждое число с предыдущим).
Если текущее число и предыдущее равны, то текущая последовательность не удлиняется и не прерывается, поэтому мы просто переходим к следующему числу.
Если числа не равны, то нужно проверить, удлиняет ли текущее число последовательность (т.е. nums[i] == nums[i-1] + 1). Если удлиняет, то мы увеличиваем наш текущий счёт и продолжаем.
3⃣ Завершение обработки и возврат результата:
В противном случае последовательность прерывается, и мы записываем нашу текущую последовательность и сбрасываем её до 1 (чтобы включить число, которое прервало последовательность).
Возможно, что последний элемент массива nums является частью самой длинной последовательности, поэтому мы возвращаем максимум из текущей последовательности и самой длинной.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан несортированный массив целых чисел nums. Верните длину самой длинной последовательности последовательных элементов.
Необходимо написать алгоритм, который работает за время O(n).
Пример:
Input: nums = [100,4,200,1,3,2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.
Перед началом работы проверяем базовый случай с пустым массивом.
Самая длинная последовательность в пустом массиве, очевидно, равна 0, поэтому мы можем просто вернуть это значение.
Для всех других случаев мы сортируем массив nums и рассматриваем каждое число, начиная со второго (поскольку нам нужно сравнивать каждое число с предыдущим).
Если текущее число и предыдущее равны, то текущая последовательность не удлиняется и не прерывается, поэтому мы просто переходим к следующему числу.
Если числа не равны, то нужно проверить, удлиняет ли текущее число последовательность (т.е. nums[i] == nums[i-1] + 1). Если удлиняет, то мы увеличиваем наш текущий счёт и продолжаем.
В противном случае последовательность прерывается, и мы записываем нашу текущую последовательность и сбрасываем её до 1 (чтобы включить число, которое прервало последовательность).
Возможно, что последний элемент массива nums является частью самой длинной последовательности, поэтому мы возвращаем максимум из текущей последовательности и самой длинной.
public class Solution {
private bool ArrayContains(int[] arr, int num) {
for (int i = 0; i < arr.Length; i++) {
if (arr[i] == num) {
return true;
}
}
return false;
}
public int LongestConsecutive(int[] nums) {
int longestStreak = 0;
for (int i = 0; i < nums.Length; i++) {
int currentNum = nums[i];
int currentStreak = 1;
while (ArrayContains(nums, currentNum + 1)) {
currentNum += 1;
currentStreak += 1;
}
longestStreak = Math.Max(longestStreak, currentStreak);
}
return longestStreak;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 229. Majority Element II
Сложность: medium
Дан массив целых чисел размера n, найдите все элементы, которые встречаются более ⌊ n/3 ⌋ раз.
Пример:
👨💻 Алгоритм:
1⃣ Поиск кандидатов: Пройдите через массив, используя алгоритм Бойера-Мура для поиска двух потенциальных кандидатов, которые могут встречаться более ⌊ n/3 ⌋ раз. Поддерживайте два счётчика и двух кандидатов. Если текущий элемент равен одному из кандидатов, увеличьте соответствующий счётчик. Если счётчик равен нулю, установите текущий элемент как кандидата и установите счётчик в 1. Если текущий элемент не совпадает ни с одним из кандидатов, уменьшите оба счётчика.
2⃣ Подсчёт голосов: После определения двух кандидатов, пройдите через массив снова, чтобы посчитать фактическое количество появлений каждого кандидата.
3⃣ Проверка порога: Проверьте, превышает ли количество появлений каждого кандидата порог ⌊ n/3 ⌋. Если да, добавьте кандидата в результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел размера n, найдите все элементы, которые встречаются более ⌊ n/3 ⌋ раз.
Пример:
Input: nums = [3,2,3]
Output: [3]
public class Solution {
public IList<int> MajorityElement(int[] nums) {
int count1 = 0, count2 = 0;
int? candidate1 = null, candidate2 = null;
foreach (int n in nums) {
if (candidate1.HasValue && candidate1 == n) {
count1++;
} else if (candidate2.HasValue && candidate2 == n) {
count2++;
} else if (count1 == 0) {
candidate1 = n;
count1 = 1;
} else if (count2 == 0) {
candidate2 = n;
count2 = 1;
} else {
count1--;
count2--;
}
}
count1 = 0;
count2 = 0;
foreach (int n in nums) {
if (candidate1.HasValue && candidate1 == n) count1++;
if (candidate2.HasValue && candidate2 == n) count2++;
}
IList<int> result = new List<int>();
int nLength = nums.Length;
if (count1 > nLength / 3) result.Add(candidate1.Value);
if (count2 > nLength / 3) result.Add(candidate2.Value);
return result;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 108. Convert Sorted Array to Binary Search Tree
Сложность: easy
Дан массив целых чисел nums, элементы которого отсортированы в порядке возрастания. Преобразуйте его в сбалансированное по высоте двоичное дерево поиска.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация функции помощника: Реализуйте функцию помощника helper(left, right), которая строит двоичное дерево поиска (BST) из элементов массива nums между индексами left и right.
Если left > right, это означает, что элементов для построения поддерева нет, возвращаем None.
2⃣ Выбор корня и разделение массива:
Выберите элемент в середине для корня: p = (left + right) // 2.
Инициализируйте корень: root = TreeNode(nums[p]).
3⃣ Рекурсивное построение поддеревьев:
Рекурсивно стройте левое поддерево: root.left = helper(left, p - 1).
Рекурсивно стройте правое поддерево: root.right = helper(p + 1, right).
В качестве результата возвращайте helper(0, len(nums) - 1), начиная с корня дерева.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан массив целых чисел nums, элементы которого отсортированы в порядке возрастания. Преобразуйте его в сбалансированное по высоте двоичное дерево поиска.
Пример:
Input: nums = [-10,-3,0,5,9]
Output: [0,-3,9,-10,null,5]
Explanation: [0,-10,5,null,-3,null,9] is also accepted:
Если left > right, это означает, что элементов для построения поддерева нет, возвращаем None.
Выберите элемент в середине для корня: p = (left + right) // 2.
Инициализируйте корень: root = TreeNode(nums[p]).
Рекурсивно стройте левое поддерево: root.left = helper(left, p - 1).
Рекурсивно стройте правое поддерево: root.right = helper(p + 1, right).
В качестве результата возвращайте helper(0, len(nums) - 1), начиная с корня дерева.
public class Solution {
public TreeNode SortedArrayToBST(int[] nums) {
return helper(nums, 0, nums.Length - 1);
}
public TreeNode helper(int[] nums, int left, int right) {
if (left > right) {
return null;
}
int p = (left + right) / 2;
TreeNode root = new TreeNode(nums[p]);
root.left = helper(nums, left, p - 1);
root.right = helper(nums, p + 1, right);
return root;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1027. Longest Arithmetic Subsequence
Сложность: medium
Если задан массив nums целых чисел, верните длину самой длинной арифметической подпоследовательности в nums. Примечание: Подпоследовательность - это массив, который может быть получен из другого массива путем удаления некоторых или ни одного элемента без изменения порядка оставшихся элементов. Последовательность seq является арифметической, если seq[i + 1] - seq[i] имеют одинаковое значение (для 0 <= i < seq.length - 1).
Пример:
👨💻 Алгоритм:
1⃣ Инициализация переменных:
Создайте массив словарей dp, где dp[i][d] будет хранить длину самой длинной арифметической подпоследовательности, заканчивающейся на элементе i с разностью d.
2⃣ Заполнение массива dp:
Пройдитесь по каждому элементу массива nums.
Для каждого элемента nums[j] (где j идет от 0 до i-1), вычислите разность d = nums[i] - nums[j].
Обновите dp[i][d] на основе значения dp[j][d].
3⃣ Поиск максимальной длины:
Пройдите по массиву dp и найдите максимальное значение среди всех значений dp[i][d].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задан массив nums целых чисел, верните длину самой длинной арифметической подпоследовательности в nums. Примечание: Подпоследовательность - это массив, который может быть получен из другого массива путем удаления некоторых или ни одного элемента без изменения порядка оставшихся элементов. Последовательность seq является арифметической, если seq[i + 1] - seq[i] имеют одинаковое значение (для 0 <= i < seq.length - 1).
Пример:
Input: nums = [3,6,9,12]
Output: 4
Создайте массив словарей dp, где dp[i][d] будет хранить длину самой длинной арифметической подпоследовательности, заканчивающейся на элементе i с разностью d.
Пройдитесь по каждому элементу массива nums.
Для каждого элемента nums[j] (где j идет от 0 до i-1), вычислите разность d = nums[i] - nums[j].
Обновите dp[i][d] на основе значения dp[j][d].
Пройдите по массиву dp и найдите максимальное значение среди всех значений dp[i][d].
public class Solution {
public int LongestArithSeqLength(int[] nums) {
if (nums.Length == 0) return 0;
var dp = new Dictionary<int, int>[nums.Length];
for (int i = 0; i < nums.Length; i++) {
dp[i] = new Dictionary<int, int>();
}
int maxLength = 0;
for (int i = 0; i < nums.Length; i++) {
for (int j = 0; j < i; j++) {
int diff = nums[i] - nums[j];
if (dp[j].TryGetValue(diff, out int length)) {
dp[i][diff] = length + 1;
} else {
dp[i][diff] = 2;
}
maxLength = Math.Max(maxLength, dp[i][diff]);
}
}
return maxLength;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 625. Minimum Factorization
Сложность: medium
Если задано целое положительное число num, верните наименьшее целое положительное число x, умножение каждого разряда которого равно num. Если ответа нет или ответ не помещается в 32-битное знаковое целое число, возвращается 0.
Пример:
👨💻 Алгоритм:
1⃣ Если num равно 1, верните 1. Инициализируйте массив для хранения множителей.
2⃣ Разделите num на множители от 9 до 2, пока num больше 1. Если в процессе остаются множители больше 9, верните 0.
3⃣ Постройте результат, собирая найденные множители в обратном порядке. Если результат больше 32-битного целого числа, верните 0.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задано целое положительное число num, верните наименьшее целое положительное число x, умножение каждого разряда которого равно num. Если ответа нет или ответ не помещается в 32-битное знаковое целое число, возвращается 0.
Пример:
Input: num = 48
Output: 68
public class Solution {
public int SmallestFactorization(int num) {
if (num == 1) return 1;
List<int> factors = new List<int>();
for (int i = 9; i >= 2; i--) {
while (num % i == 0) {
factors.Add(i);
num /= i;
}
}
if (num > 1) return 0;
long result = 0;
for (int i = factors.Count - 1; i >= 0; i--) {
result = result * 10 + factors[i];
if (result > int.MaxValue) return 0;
}
return (int) result;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM