Задача: 930. Binary Subarrays With Sum
Сложность: medium
Если задан двоичный массив nums и целочисленная цель, верните количество непустых подмассивов с целью sum. Подмассив - это смежная часть массива.
Пример:
👨💻 Алгоритм:
1⃣ Использовать словарь для хранения количества встреченных сумм префиксов.
Инициализировать текущую сумму и счетчик подмассивов с нулевыми значениями.
2⃣ Пройти по массиву и обновить текущую сумму.
Если текущая сумма минус цель уже в словаре, добавить количество таких префиксов к счетчику подмассивов.
Обновить словарь префиксных сумм.
3⃣ Вернуть счетчик подмассивов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задан двоичный массив nums и целочисленная цель, верните количество непустых подмассивов с целью sum. Подмассив - это смежная часть массива.
Пример:
Input: nums = [1,0,1,0,1], goal = 2
Output: 4
Инициализировать текущую сумму и счетчик подмассивов с нулевыми значениями.
Если текущая сумма минус цель уже в словаре, добавить количество таких префиксов к счетчику подмассивов.
Обновить словарь префиксных сумм.
class Solution {
public:
int numSubarraysWithSum(vector<int>& nums, int goal) {
unordered_map<int, int> prefixSumCount;
prefixSumCount[0] = 1;
int currentSum = 0;
int count = 0;
for (int num : nums) {
currentSum += num;
count += prefixSumCount[currentSum - goal];
prefixSumCount[currentSum]++;
}
return count;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 1503. Last Moment Before All Ants Fall Out of a Plank
Сложность: medium
У нас есть деревянная доска длиной n единиц. Некоторые муравьи ходят по доске, каждый муравей движется со скоростью 1 единица в секунду. Некоторые муравьи движутся влево, другие движутся вправо.
Когда два муравья, движущиеся в разных направлениях, встречаются в какой-то точке, они меняют свои направления и продолжают двигаться дальше. Предполагается, что изменение направлений не занимает дополнительного времени.
Когда муравей достигает одного из концов доски в момент времени t, он сразу же падает с доски.
Дано целое число n и два целых массива left и right, обозначающие позиции муравьев, движущихся влево и вправо соответственно. Верните момент, когда последний(е) муравей(и) падает(ют) с доски.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменную ans значением 0.
2⃣ Итерация по массиву left и обновление ans значением num, если оно больше текущего значения ans.
3⃣ Итерация по массиву right и обновление ans значением n - num, если оно больше текущего значения ans. Верните значение ans.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
У нас есть деревянная доска длиной n единиц. Некоторые муравьи ходят по доске, каждый муравей движется со скоростью 1 единица в секунду. Некоторые муравьи движутся влево, другие движутся вправо.
Когда два муравья, движущиеся в разных направлениях, встречаются в какой-то точке, они меняют свои направления и продолжают двигаться дальше. Предполагается, что изменение направлений не занимает дополнительного времени.
Когда муравей достигает одного из концов доски в момент времени t, он сразу же падает с доски.
Дано целое число n и два целых массива left и right, обозначающие позиции муравьев, движущихся влево и вправо соответственно. Верните момент, когда последний(е) муравей(и) падает(ют) с доски.
Пример:
Input: n = 4, left = [4,3], right = [0,1]
Output: 4
Explanation: In the image above:
-The ant at index 0 is named A and going to the right.
-The ant at index 1 is named B and going to the right.
-The ant at index 3 is named C and going to the left.
-The ant at index 4 is named D and going to the left.
The last moment when an ant was on the plank is t = 4 seconds. After that, it falls immediately out of the plank. (i.e., We can say that at t = 4.0000000001, there are no ants on the plank).
class Solution {
public:
int getLastMoment(int n, vector<int>& left, vector<int>& right) {
int ans = 0;
for (int num : left) {
ans = max(ans, num);
}
for (int num : right) {
ans = max(ans, n - num);
}
return ans;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 660. Remove 9
Сложность: hard
Начните с целого числа 1, уберите любое число, которое содержит 9, такое как 9, 19, 29...
Теперь у вас будет новая последовательность целых чисел [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, ...].
Дано целое число n, верните n-е (начиная с 1) целое число в новой последовательности.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация:
Начните с числа 1 и создайте переменную для отслеживания количества найденных чисел, не содержащих цифру 9.
2⃣ Итерация и проверка:
Последовательно увеличивайте число и проверяйте, содержит ли оно цифру 9.
Если не содержит, увеличьте счетчик.
3⃣ Поиск n-го числа:
Продолжайте процесс до тех пор, пока не найдете n-е число, не содержащее цифру 9.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Начните с целого числа 1, уберите любое число, которое содержит 9, такое как 9, 19, 29...
Теперь у вас будет новая последовательность целых чисел [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, ...].
Дано целое число n, верните n-е (начиная с 1) целое число в новой последовательности.
Пример:
Input: n = 9
Output: 10
Начните с числа 1 и создайте переменную для отслеживания количества найденных чисел, не содержащих цифру 9.
Последовательно увеличивайте число и проверяйте, содержит ли оно цифру 9.
Если не содержит, увеличьте счетчик.
Продолжайте процесс до тех пор, пока не найдете n-е число, не содержащее цифру 9.
class Solution {
public:
int newInteger(int n) {
int count = 0;
int num = 0;
while (count < n) {
num++;
if (to_string(num).find('9') == string::npos) {
count++;
}
}
return num;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 861. Score After Flipping Matrix
Сложность: hard
Дан целочисленный массив nums и целое число k. Верните длину самой короткой непустой подмассива nums, сумма которого составляет как минимум k. Если такого подмассива нет, верните -1.
Подмассив — это непрерывная часть массива.
Пример:
👨💻 Алгоритм:
1⃣ Создайте "моноочередь" индексов P: дек индексов x_0, x_1, ..., так чтобы P[x_0], P[x_1], ... увеличивались.
2⃣ При добавлении нового индекса y, удалите x_i из конца дека, чтобы P[x_0], P[x_1], ..., P[y] увеличивались.
3⃣ Если P[y] >= P[x_0] + K, то (как описано ранее) мы больше не рассматриваем этот x_0 и удаляем его из начала дека.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан целочисленный массив nums и целое число k. Верните длину самой короткой непустой подмассива nums, сумма которого составляет как минимум k. Если такого подмассива нет, верните -1.
Подмассив — это непрерывная часть массива.
Пример:
Input: nums = [1], k = 1
Output: 1
class Solution {
public:
int shortestSubarray(vector<int>& A, int K) {
int N = A.size();
vector<long> P(N + 1);
for (int i = 0; i < N; ++i)
P[i + 1] = P[i] + A[i];
int ans = N + 1;
deque<int> monoq;
for (int y = 0; y < P.size(); ++y) {
while (!monoq.empty() && P[y] <= P[monoq.back()])
monoq.pop_back();
while (!monoq.empty() && P[y] >= P[monoq.front()] + K)
ans = min(ans, y - monoq.pop_front());
monoq.push_back(y);
}
return ans < N + 1 ? ans : -1;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 230. Kth Smallest Element in a BST
Сложность: medium
Дан корень бинарного дерева поиска и целое число k. Верните k-ое по величине значение (нумерация с 1) среди всех значений узлов в дереве.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация стека и обход в глубину: Инициализируйте стек для хранения узлов дерева. Начните обход дерева в глубину, начиная с корня, и перемещайтесь влево, добавляя каждый узел в стек, пока не достигнете самого левого узла.
2⃣ Извлечение узлов и проверка: Когда достигнете самого левого узла, извлеките узел из стека и уменьшите значение k на 1. Если k становится равным нулю, верните значение текущего узла, так как это и есть k-ое по величине значение.
3⃣ Переход к правому поддереву: Если k не равен нулю, переместитесь к правому поддереву текущего узла и продолжайте обход, повторяя шаги 1 и 2, пока не найдете k-ое по величине значение.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан корень бинарного дерева поиска и целое число k. Верните k-ое по величине значение (нумерация с 1) среди всех значений узлов в дереве.
Пример:
Input: root = [3,1,4,null,2], k = 1
Output: 1
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
stack<TreeNode*> stack;
while (true) {
while (root != nullptr) {
stack.push(root);
root = root->left;
}
root = stack.top();
stack.pop();
if (--k == 0) return root->val;
root = root->right;
}
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 543. Diameter of Binary Tree
Сложность: easy
Учитывая корень бинарного дерева, вернуть длину диаметра дерева.
Диаметр бинарного дерева — это длина самого длинного пути между любыми двумя узлами в дереве. Этот путь может проходить или не проходить через корень.
Длина пути между двумя узлами представлена числом ребер между ними.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте целочисленную переменную diameter для отслеживания самого длинного пути, найденного с помощью DFS.
2⃣ Реализуйте рекурсивную функцию longestPath, которая принимает TreeNode в качестве входных данных и рекурсивно исследует дерево: Если узел равен None, вернуть 0. Рекурсивно исследовать левые и правые дочерние узлы, возвращая длины путей leftPath и rightPath. Если сумма leftPath и rightPath больше текущего diameter, обновить diameter. Вернуть большее из leftPath и rightPath плюс 1.
3⃣ Вызвать longestPath с root.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Учитывая корень бинарного дерева, вернуть длину диаметра дерева.
Диаметр бинарного дерева — это длина самого длинного пути между любыми двумя узлами в дереве. Этот путь может проходить или не проходить через корень.
Длина пути между двумя узлами представлена числом ребер между ними.
Пример:
Input: root = [1,2]
Output: 1
class Solution {
int diameter;
public:
int diameterOfBinaryTree(TreeNode* root) {
diameter = 0;
longestPath(root);
return diameter;
}
private:
int longestPath(TreeNode* node) {
if (node == nullptr) return 0;
int leftPath = longestPath(node->left);
int rightPath = longestPath(node->right);
diameter = std::max(diameter, leftPath + rightPath);
return std::max(leftPath, rightPath) + 1;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 899. Orderly Queue
Сложность: hard
Вам дана строка s и целое число k. Вы можете выбрать одну из первых k букв s и добавить ее в конец строки. Верните лексикографически наименьшую строку, которая может получиться после применения указанного шага за любое количество ходов.
Пример:
👨💻 Алгоритм:
1⃣ Если k равно 1, найти лексикографически наименьшую строку путем вращения строки и поиска минимального варианта.
2⃣ Если k больше 1, отсортировать строку, так как любое количество перемещений позволит упорядочить все символы в строке.
3⃣ Вернуть результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дана строка s и целое число k. Вы можете выбрать одну из первых k букв s и добавить ее в конец строки. Верните лексикографически наименьшую строку, которая может получиться после применения указанного шага за любое количество ходов.
Пример:
Input: s = "cba", k = 1
Output: "acb"
class Solution {
public:
string orderlyQueue(string s, int k) {
if (k == 1) {
string minString = s;
for (int i = 1; i < s.length(); i++) {
string rotated = s.substr(i) + s.substr(0, i);
if (rotated < minString) {
minString = rotated;
}
}
return minString;
} else {
sort(s.begin(), s.end());
return s;
}
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 509. Fibonacci Number
Сложность: easy
Числа Фибоначчи, обычно обозначаемые как F(n), образуют последовательность, называемую последовательностью Фибоначчи, так что каждое число является суммой двух предыдущих, начиная с 0 и 1. То есть,
F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), для n > 1.
Дано n, вычислите F(n).
Пример:
👨💻 Алгоритм:
1⃣ Проверка начального условия
Если N <= 1, вернуть N.
2⃣ Инициализация переменных
Инициализируйте current значением 0. Инициализируйте prev1 значением 1, что будет представлять fib(N-1) при вычислении текущего значения. Инициализируйте prev2 значением 0, что будет представлять fib(N-2) при вычислении текущего значения.
3⃣ Итерация и вычисление
Итерация от 2 до N включительно. На каждой итерации: установите current как сумму prev1 и prev2. Обновите prev2 значением prev1. Обновите prev1 значением current. Вернуть значение current после завершения итерации.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Числа Фибоначчи, обычно обозначаемые как F(n), образуют последовательность, называемую последовательностью Фибоначчи, так что каждое число является суммой двух предыдущих, начиная с 0 и 1. То есть,
F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), для n > 1.
Дано n, вычислите F(n).
Пример:
Input: n = 3
Output: 2
Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.
Если N <= 1, вернуть N.
Инициализируйте current значением 0. Инициализируйте prev1 значением 1, что будет представлять fib(N-1) при вычислении текущего значения. Инициализируйте prev2 значением 0, что будет представлять fib(N-2) при вычислении текущего значения.
Итерация от 2 до N включительно. На каждой итерации: установите current как сумму prev1 и prev2. Обновите prev2 значением prev1. Обновите prev1 значением current. Вернуть значение current после завершения итерации.
class Solution {
public:
int fib(int N) {
if (N <= 1) return N;
int current = 0, prev1 = 1, prev2 = 0;
for (int i = 2; i <= N; ++i) {
current = prev1 + prev2;
prev2 = prev1;
prev1 = current;
}
return current;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 75. Sort Colors
Сложность: medium
Дан массив nums, содержащий n объектов, окрашенных в красный, белый или синий цвет.
Отсортируйте их на месте так, чтобы объекты одного цвета находились рядом, а цвета шли в порядке:
красный (0), белый (1), синий (2).
Запрещено использовать встроенные функции сортировки.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация указателя p0 = 0, отвечающего за край для нулей.
2⃣ Инициализация указателя p2 = n - 1, отвечающего за край для двоек.
3⃣ Индекс текущего элемента: curr = 0.
Пока curr <= p2:
если nums[curr] == 0 → меняем с nums[p0], сдвигаем p0 и curr вправо
если nums[curr] == 2 → меняем с nums[p2], сдвигаем p2 влево
если nums[curr] == 1 → просто двигаем curr
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив nums, содержащий n объектов, окрашенных в красный, белый или синий цвет.
Отсортируйте их на месте так, чтобы объекты одного цвета находились рядом, а цвета шли в порядке:
красный (0), белый (1), синий (2).
Запрещено использовать встроенные функции сортировки.
Пример:
Input: nums = [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
Пока curr <= p2:
если nums[curr] == 0 → меняем с nums[p0], сдвигаем p0 и curr вправо
если nums[curr] == 2 → меняем с nums[p2], сдвигаем p2 влево
если nums[curr] == 1 → просто двигаем curr
class Solution {
public:
void sortColors(vector<int>& nums) {
int p0 = 0, curr = 0;
int p2 = nums.size() - 1;
while (curr <= p2) {
if (nums[curr] == 0) {
swap(nums[curr++], nums[p0++]);
}
else if (nums[curr] == 2) {
swap(nums[curr], nums[p2--]);
}
else curr++;
}
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 679. 24 Game
Сложность: hard
Дан массив целых чисел cards длиной 4. У вас есть четыре карты, каждая из которых содержит число в диапазоне от 1 до 9. Вам нужно расположить числа на этих картах в математическом выражении, используя операторы ['+', '-', '*', '/'] и скобки '(' и ')' так, чтобы получить значение 24.
Вы ограничены следующими правилами:
Оператор деления '/' представляет собой реальное деление, а не целочисленное деление.
Например, 4 / (1 - 2 / 3) = 4 / (1 / 3) = 12.
Каждая операция выполняется между двумя числами. В частности, мы не можем использовать '-' как унарный оператор.
Например, если cards = [1, 1, 1, 1], выражение "-1 - 1 - 1 - 1" не допускается.
Вы не можете объединять числа вместе.
Например, если cards = [1, 2, 1, 2], выражение "12 + 12" недопустимо.
Вернуть true, если вы можете получить такое выражение, которое оценивается в 24, и false в противном случае.
Пример:
👨💻 Алгоритм:
1⃣ Создайте функцию generatePossibleResults(a, b), которая возвращает массив результатов всех возможных математических операций над двумя числами.
2⃣ Создайте функцию checkIfResultReached(list), чтобы проверить, можем ли мы достичь результата 24, используя текущий массив list. Сначала проверьте базовые условия: если размер массива равен 1, верните true, если результат равен 24, иначе верните false.
3⃣ Если размер массива больше 1, выберите любые два числа из списка, выполните все математические операции над ними, создайте новый список с обновленными элементами и снова вызовите рекурсивную функцию с этим новым списком. Если ни одна комбинация не приводит к результату 24, верните false. Вызовите checkIfResultReached с исходным списком карт.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дан массив целых чисел cards длиной 4. У вас есть четыре карты, каждая из которых содержит число в диапазоне от 1 до 9. Вам нужно расположить числа на этих картах в математическом выражении, используя операторы ['+', '-', '*', '/'] и скобки '(' и ')' так, чтобы получить значение 24.
Вы ограничены следующими правилами:
Оператор деления '/' представляет собой реальное деление, а не целочисленное деление.
Например, 4 / (1 - 2 / 3) = 4 / (1 / 3) = 12.
Каждая операция выполняется между двумя числами. В частности, мы не можем использовать '-' как унарный оператор.
Например, если cards = [1, 1, 1, 1], выражение "-1 - 1 - 1 - 1" не допускается.
Вы не можете объединять числа вместе.
Например, если cards = [1, 2, 1, 2], выражение "12 + 12" недопустимо.
Вернуть true, если вы можете получить такое выражение, которое оценивается в 24, и false в противном случае.
Пример:
Input: cards = [4,1,8,7]
Output: true
Explanation: (8-4) * (7-1) = 24
class Solution {
public:
vector<double> generatePossibleResults(double a, double b) {
vector<double> res = { a + b, a - b, b - a, a * b };
if (a != 0) res.push_back(b / a);
if (b != 0) res.push_back(a / b);
return res;
}
bool checkIfResultReached(vector<double> list) {
if (list.size() == 1) return abs(list[0] - 24) <= 0.1;
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
vector<double> newList;
for (int k = 0; k < list.size(); k++) {
if (k != i && k != j) newList.push_back(list[k]);
}
for (double res : generatePossibleResults(list[i], list[j])) {
newList.push_back(res);
if (checkIfResultReached(newList)) return true;
newList.pop_back();
}
}
}
return false;
}
bool judgePoint24(vector<int>& cards) {
vector<double> list(cards.begin(), cards.end());
return checkIfResultReached(list);
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 536. Construct Binary Tree from String
Сложность: medium
Вам нужно построить бинарное дерево из строки, состоящей из круглых скобок и целых чисел.
Весь ввод представляет собой бинарное дерево. Он содержит целое число, за которым следуют ноль, одна или две пары круглых скобок. Целое число представляет значение корня, а пара круглых скобок содержит дочернее бинарное дерево с той же структурой.
Вы всегда начинаете строить левый дочерний узел родителя сначала, если он существует.
Пример:
👨💻 Алгоритм:
1⃣ Извлечение числа:
Определите функцию getNumber, которая извлекает целое число из текущей строки, начиная с указанного индекса. Учтите знак числа, если он есть.
2⃣ Построение поддерева:
Определите рекурсивную функцию str2treeInternal, которая принимает строку и текущий индекс в качестве входных данных и возвращает пару: узел TreeNode и следующий индекс для обработки.
Внутри функции извлеките значение для корневого узла текущего поддерева, создайте узел, а затем рекурсивно постройте левое и правое поддеревья, если они существуют.
3⃣ Основная функция:
Определите основную функцию str2tree, которая вызывает рекурсивную функцию str2treeInternal и возвращает построенное дерево.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам нужно построить бинарное дерево из строки, состоящей из круглых скобок и целых чисел.
Весь ввод представляет собой бинарное дерево. Он содержит целое число, за которым следуют ноль, одна или две пары круглых скобок. Целое число представляет значение корня, а пара круглых скобок содержит дочернее бинарное дерево с той же структурой.
Вы всегда начинаете строить левый дочерний узел родителя сначала, если он существует.
Пример:
Input: s = "4(2(3)(1))(6(5))"
Output: [4,2,6,3,1,5]
Определите функцию getNumber, которая извлекает целое число из текущей строки, начиная с указанного индекса. Учтите знак числа, если он есть.
Определите рекурсивную функцию str2treeInternal, которая принимает строку и текущий индекс в качестве входных данных и возвращает пару: узел TreeNode и следующий индекс для обработки.
Внутри функции извлеките значение для корневого узла текущего поддерева, создайте узел, а затем рекурсивно постройте левое и правое поддеревья, если они существуют.
Определите основную функцию str2tree, которая вызывает рекурсивную функцию str2treeInternal и возвращает построенное дерево.
class TreeNode {
public:
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
TreeNode* str2tree(string s) {
return str2treeInternal(s, 0).first;
}
private:
pair<int, int> getNumber(const string& s, int index) {
bool isNegative = false;
if (s[index] == '-') {
isNegative = true;
index++;
}
int number = 0;
while (index < s.size() && isdigit(s[index])) {
number = number * 10 + (s[index] - '0');
index++;
}
return {isNegative ? -number : number, index};
}
pair<TreeNode*, int> str2treeInternal(const string& s, int index) {
if (index == s.size()) return {nullptr, index};
auto numberData = getNumber(s, index);
int value = numberData.first;
index = numberData.second;
TreeNode* node = new TreeNode(value);
if (index < s.size() && s[index] == '(') {
auto leftData = str2treeInternal(s, index + 1);
node->left = leftData.first;
index = leftData.second;
}
if (index < s.size() && s[index] == '(') {
auto rightData = str2treeInternal(s, index + 1);
node->right = rightData.first;
index = rightData.second;
}
return {node, index < s.size() && s[index] == ')' ? index + 1 : index};
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1190. Reverse Substrings Between Each Pair of Parentheses
Сложность: medium
Дана строка s, состоящая из строчных букв английского алфавита и скобок.
Переверните строки в каждой паре соответствующих скобок, начиная с самой внутренней.
Ваш результат не должен содержать скобок.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте пустой стек openParenthesesIndices для отслеживания начальных точек разворота и пустую строку result для построения выходного результата.
2⃣ Для каждого символа currentChar во входной строке:
Если это '(', добавьте длину строки result в openParenthesesIndices, чтобы отметить потенциальную начальную точку разворота.
Если это ')', извлеките значение из openParenthesesIndices и переверните result от извлеченного индекса для выполнения необходимого разворота.
В противном случае добавьте currentChar к result для построения строки.
3⃣ Верните result как окончательную строку со всеми примененными разворотами.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана строка s, состоящая из строчных букв английского алфавита и скобок.
Переверните строки в каждой паре соответствующих скобок, начиная с самой внутренней.
Ваш результат не должен содержать скобок.
Пример:
Input: s = "(abcd)"
Output: "dcba"
Если это '(', добавьте длину строки result в openParenthesesIndices, чтобы отметить потенциальную начальную точку разворота.
Если это ')', извлеките значение из openParenthesesIndices и переверните result от извлеченного индекса для выполнения необходимого разворота.
В противном случае добавьте currentChar к result для построения строки.
class Solution {
public:
string reverseParentheses(string s) {
stack<int> openParenthesesIndices;
string result;
for (char currentChar : s) {
if (currentChar == '(') {
openParenthesesIndices.push(result.size());
} else if (currentChar == ')') {
int start = openParenthesesIndices.top();
openParenthesesIndices.pop();
reverse(result.begin() + start, result.end());
} else {
result.push_back(currentChar);
}
}
return result;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 908. Smallest Range I
Сложность: easy
Вам дан целочисленный массив nums и целое число k. За одну операцию вы можете выбрать любой индекс i, где 0 <= i < nums.length, и изменить nums[i] на nums[i] + x, где x - целое число из диапазона [-k, k]. Эту операцию можно применять не более одного раза для каждого индекса i. Оценка nums - это разница между максимальным и минимальным элементами в nums. Верните минимальную оценку nums после применения указанной операции не более одного раза для каждого индекса в нем.
Пример:
👨💻 Алгоритм:
1⃣ Найти минимальное и максимальное значения массива nums.
2⃣ Рассчитать потенциальные новые минимальные и максимальные значения после применения операции.
3⃣ Вычислить минимальную оценку, сравнивая разницу между всеми возможными новыми минимальными и максимальными значениями.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам дан целочисленный массив nums и целое число k. За одну операцию вы можете выбрать любой индекс i, где 0 <= i < nums.length, и изменить nums[i] на nums[i] + x, где x - целое число из диапазона [-k, k]. Эту операцию можно применять не более одного раза для каждого индекса i. Оценка nums - это разница между максимальным и минимальным элементами в nums. Верните минимальную оценку nums после применения указанной операции не более одного раза для каждого индекса в нем.
Пример:
Input: nums = [1], k = 0
Output: 0
class Solution {
public:
int smallestRangeI(vector<int>& nums, int k) {
int minVal = *min_element(nums.begin(), nums.end());
int maxVal = *max_element(nums.begin(), nums.end());
return max(0, (maxVal - k) - (minVal + k));
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 441. Arranging Coins
Сложность: easy
У вас есть n монет, и вы хотите построить лестницу из этих монет. Лестница состоит из k рядов, где i-й ряд содержит ровно i монет. Последний ряд лестницы может быть неполным.
Дано целое число n, верните количество полных рядов лестницы, которые вы сможете построить.
Пример:
👨💻 Алгоритм:
1⃣ Если мы глубже посмотрим на формулу задачи, мы можем решить её с помощью математики, без использования итераций.
2⃣ Напомним, что условие задачи можно выразить следующим образом: k(k + 1) ≤ 2N.
3⃣ Это можно решить методом выделения полного квадрата, (k + 1/2)² - 1/4 ≤ 2N. Что приводит к следующему ответу: k = [sqrt(2N + 1/4) - 1/2].
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
У вас есть n монет, и вы хотите построить лестницу из этих монет. Лестница состоит из k рядов, где i-й ряд содержит ровно i монет. Последний ряд лестницы может быть неполным.
Дано целое число n, верните количество полных рядов лестницы, которые вы сможете построить.
Пример:
Input: n = 5
Output: 2
Explanation: Because the 3rd row is incomplete, we return 2.
class Solution {
public:
int arrangeCoins(int n) {
return (int)(sqrt(2.0 * n + 0.25) - 0.5);
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 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
class Solution : public GuessGame {
public:
int guessNumber(int n) {
int low = 1, 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;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊1
Задача: 1055. Shortest Way to Form String
Сложность: medium
Подпоследовательность строки - это новая строка, которая образуется из исходной строки путем удаления некоторых (можно ни одного) символов без нарушения взаимного расположения оставшихся символов. (например, "ace" является подпоследовательностью "abcde", а "aec" - нет). Если даны две строки source и target, верните минимальное количество подпоследовательностей source, чтобы их объединение равнялось target. Если задача невыполнима, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Используй два указателя для отслеживания текущих позиций в строках source и target.
2⃣ Перебирай символы строки source, пока не найдешь совпадающий символ в target.
Если ты прошел всю строку source и не нашел все символы target, увеличь счетчик количества подпоследовательностей и начни снова с начала source.
3⃣ Повтори шаги 2 и 3 до тех пор, пока не пройдешь всю строку target.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Подпоследовательность строки - это новая строка, которая образуется из исходной строки путем удаления некоторых (можно ни одного) символов без нарушения взаимного расположения оставшихся символов. (например, "ace" является подпоследовательностью "abcde", а "aec" - нет). Если даны две строки source и target, верните минимальное количество подпоследовательностей source, чтобы их объединение равнялось target. Если задача невыполнима, верните -1.
Пример:
Input: source = "abc", target = "abcbc"
Output: 2
Если ты прошел всю строку source и не нашел все символы target, увеличь счетчик количества подпоследовательностей и начни снова с начала source.
class Solution {
public:
int minSubsequences(string source, string target) {
int subsequencesCount = 0;
int targetIndex = 0;
while (targetIndex < target.size()) {
int sourceIndex = 0;
subsequencesCount++;
int startIndex = targetIndex;
while (sourceIndex < source.size() && targetIndex < target.size()) {
if (source[sourceIndex] == target[targetIndex]) {
targetIndex++;
}
sourceIndex++;
}
if (targetIndex == startIndex) {
return -1;
}
}
return subsequencesCount;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 741. Cherry Pickup
Сложность: hard
Вам дана сетка n x n, представляющая поле вишен. Каждая клетка - одно из трех возможных целых чисел. 0 означает, что клетка пуста, и вы можете пройти через нее, 1 означает, что клетка содержит вишню, которую вы можете сорвать и пройти через нее, или -1 означает, что клетка содержит шип, который преграждает вам путь. Верните максимальное количество вишен, которое вы можете собрать, следуя следующим правилам: Начиная с позиции (0, 0) и достигая (n - 1, n - 1) путем перемещения вправо или вниз через допустимые клетки пути (клетки со значением 0 или 1).
После достижения (n - 1, n - 1) вернитесь в (0, 0), двигаясь влево или вверх по клеткам с действительными путями. Проходя через клетку пути, содержащую вишню, вы поднимаете ее, и клетка становится пустой клеткой 0. Если между (0, 0) и (n - 1, n - 1) нет действительного пути, то вишни собрать нельзя.
Пример:
👨💻 Алгоритм:
1⃣ Используйте динамическое программирование для подсчета максимального количества вишен, которые можно собрать при движении от (0, 0) до (n - 1, n - 1).
2⃣ Примените еще один проход с использованием динамического программирования для движения обратно от (n - 1, n - 1) до (0, 0), чтобы учитывать вишни, собранные на обратном пути.
3⃣ Объедините результаты двух проходов, чтобы найти максимальное количество вишен, которые можно собрать.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дана сетка n x n, представляющая поле вишен. Каждая клетка - одно из трех возможных целых чисел. 0 означает, что клетка пуста, и вы можете пройти через нее, 1 означает, что клетка содержит вишню, которую вы можете сорвать и пройти через нее, или -1 означает, что клетка содержит шип, который преграждает вам путь. Верните максимальное количество вишен, которое вы можете собрать, следуя следующим правилам: Начиная с позиции (0, 0) и достигая (n - 1, n - 1) путем перемещения вправо или вниз через допустимые клетки пути (клетки со значением 0 или 1).
После достижения (n - 1, n - 1) вернитесь в (0, 0), двигаясь влево или вверх по клеткам с действительными путями. Проходя через клетку пути, содержащую вишню, вы поднимаете ее, и клетка становится пустой клеткой 0. Если между (0, 0) и (n - 1, n - 1) нет действительного пути, то вишни собрать нельзя.
Пример:
Input: grid = [[0,1,-1],[1,0,-1],[1,1,1]]
Output: 5
class Solution {
public:
int cherryPickup(vector<vector<int>>& grid) {
int n = grid.size();
vector<vector<vector<int>>> dp(n, vector<vector<int>>(n, vector<int>(2 * n - 1, INT_MIN)));
dp[0][0][0] = grid[0][0];
for (int k = 1; k < 2 * n - 1; ++k) {
for (int i1 = max(0, k - n + 1); i1 <= min(n - 1, k); ++i1) {
for (int i2 = max(0, k - n + 1); i2 <= min(n - 1, k); ++i2) {
int j1 = k - i1, j2 = k - i2;
if (j1 < n && j2 < n && grid[i1][j1] != -1 && grid[i2][j2] != -1) {
int maxCherries = INT_MIN;
if (i1 > 0 && i2 > 0) maxCherries = max(maxCherries, dp[i1 - 1][i2 - 1][k - 1]);
if (i1 > 0) maxCherries = max(maxCherries, dp[i1 - 1][i2][k - 1]);
if (i2 > 0) maxCherries = max(maxCherries, dp[i1][i2 - 1][k - 1]);
maxCherries = max(maxCherries, dp[i1][i2][k - 1]);
if (maxCherries != INT_MIN) {
dp[i1][i2][k] = maxCherries + grid[i1][j1];
if (i1 != i2) dp[i1][i2][k] += grid[i2][j2];
}
}
}
}
}
return max(0, dp[n - 1][n - 1][2 * (n - 1)]);
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 332. Reconstruct Itinerary
Сложность: hard
Вам дан список авиабилетов, где tickets[i] = [fromi, toi] представляют собой аэропорты отправления и прибытия одного рейса. Восстановите маршрут в порядке следования и верните его.
Все билеты принадлежат человеку, который вылетает из "JFK", поэтому маршрут должен начинаться с "JFK". Если существует несколько возможных маршрутов, вы должны вернуть маршрут, который имеет наименьший лексикографический порядок при чтении как одна строка.
Например, маршрут ["JFK", "LGA"] имеет меньший лексикографический порядок, чем ["JFK", "LGB"].
Вы можете предположить, что все билеты формируют хотя бы один действительный маршрут. Вы должны использовать все билеты один раз и только один раз.
Пример:
👨💻 Алгоритм:
1⃣ Построение графа и сортировка:
Создайте граф flightMap, где ключи - это аэропорты отправления, а значения - это списки аэропортов прибытия.
Пройдите по всем билетам и заполните flightMap соответствующими значениями.
Отсортируйте списки аэропортов прибытия в лексикографическом порядке.
2⃣ Пост-упорядоченный обход (DFS):
Создайте функцию DFS, которая будет рекурсивно проходить по всем ребрам (рейсам), начиная с аэропорта "JFK".
Во время обхода удаляйте использованные рейсы из графа, чтобы не проходить по ним повторно.
3⃣ Формирование маршрута:
По мере завершения обхода добавляйте текущий аэропорт в начало списка результата.
После завершения DFS верните сформированный маршрут.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дан список авиабилетов, где tickets[i] = [fromi, toi] представляют собой аэропорты отправления и прибытия одного рейса. Восстановите маршрут в порядке следования и верните его.
Все билеты принадлежат человеку, который вылетает из "JFK", поэтому маршрут должен начинаться с "JFK". Если существует несколько возможных маршрутов, вы должны вернуть маршрут, который имеет наименьший лексикографический порядок при чтении как одна строка.
Например, маршрут ["JFK", "LGA"] имеет меньший лексикографический порядок, чем ["JFK", "LGB"].
Вы можете предположить, что все билеты формируют хотя бы один действительный маршрут. Вы должны использовать все билеты один раз и только один раз.
Пример:
Input: tickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]]
Output: ["JFK","MUC","LHR","SFO","SJC"]
Создайте граф flightMap, где ключи - это аэропорты отправления, а значения - это списки аэропортов прибытия.
Пройдите по всем билетам и заполните flightMap соответствующими значениями.
Отсортируйте списки аэропортов прибытия в лексикографическом порядке.
Создайте функцию DFS, которая будет рекурсивно проходить по всем ребрам (рейсам), начиная с аэропорта "JFK".
Во время обхода удаляйте использованные рейсы из графа, чтобы не проходить по ним повторно.
По мере завершения обхода добавляйте текущий аэропорт в начало списка результата.
После завершения DFS верните сформированный маршрут.
class Solution {
public:
unordered_map<string, priority_queue<string, vector<string>, greater<string>>> flightMap;
deque<string> result;
vector<string> findItinerary(vector<vector<string>>& tickets) {
for (auto& ticket : tickets) {
flightMap[ticket[0]].push(ticket[1]);
}
dfs("JFK");
return vector<string>(result.begin(), result.end());
}
void dfs(const string& origin) {
auto& destList = flightMap[origin];
while (!destList.empty()) {
string nextDest = destList.top();
destList.pop();
dfs(nextDest);
}
result.push_front(origin);
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 746. Min Cost Climbing Stairs
Сложность: easy
Вам дан целочисленный массив cost, где cost[i] - стоимость i-й ступеньки на лестнице. После оплаты стоимости вы можете подняться на одну или две ступеньки. Вы можете начать со ступеньки с индексом 0 или со ступеньки с индексом 1. Верните минимальную стоимость достижения вершины этажа.
Пример:
👨💻 Алгоритм:
1⃣ Создать массив dp, где dp[i] хранит минимальную стоимость достижения i-й ступеньки.
2⃣ Инициализировать dp[0] и dp[1] как cost[0] и cost[1] соответственно. Заполнить dp используя минимальную стоимость подъема с предыдущих ступенек.
3⃣ Вернуть минимальную стоимость достижения вершины.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам дан целочисленный массив cost, где cost[i] - стоимость i-й ступеньки на лестнице. После оплаты стоимости вы можете подняться на одну или две ступеньки. Вы можете начать со ступеньки с индексом 0 или со ступеньки с индексом 1. Верните минимальную стоимость достижения вершины этажа.
Пример:
Input: cost = [10,15,20]
Output: 15
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size();
vector<int> dp = cost;
for (int i = 2; i < n; i++) {
dp[i] += min(dp[i - 1], dp[i - 2]);
}
return min(dp[n - 1], dp[n - 2]);
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1242. Web Crawler Multithreaded
Сложность: medium
Учитывая URL startUrl и интерфейс HtmlParser, реализуйте многопоточный веб-краулер, который будет просматривать все ссылки, находящиеся под тем же именем хоста, что и startUrl. Верните все URL, полученные вашим веб-краулером, в любом порядке.
Ваш краулер должен: Начинать со страницы: startUrl Вызывать HtmlParser.getUrls(url), чтобы получить все URL с веб-страницы данного URL. Не просматривать одну и ту же ссылку дважды. Исследовать только те ссылки, которые находятся под тем же именем хоста, что и startUrl.
Пример:
👨💻 Алгоритм:
1⃣ Извлечь имя хоста из startUrl.
Использовать многопоточность для обработки URL-адресов.
2⃣ Хранить посещенные URL-адреса, чтобы избежать повторного посещения.
3⃣ Использовать HtmlParser для получения URL-адресов с веб-страниц.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Учитывая URL startUrl и интерфейс HtmlParser, реализуйте многопоточный веб-краулер, который будет просматривать все ссылки, находящиеся под тем же именем хоста, что и startUrl. Верните все URL, полученные вашим веб-краулером, в любом порядке.
Ваш краулер должен: Начинать со страницы: startUrl Вызывать HtmlParser.getUrls(url), чтобы получить все URL с веб-страницы данного URL. Не просматривать одну и ту же ссылку дважды. Исследовать только те ссылки, которые находятся под тем же именем хоста, что и startUrl.
Пример:
Input:
urls = [
"https://news.yahoo.com",
"https://news.yahoo.com/news",
"https://news.yahoo.com/news/topics/",
"https://news.google.com",
"https://news.yahoo.com/us"
]
edges = [[2,0],[2,1],[3,2],[3,1],[0,4]]
startUrl = "https://news.yahoo.com/news/topics/"
Output: [
"https://news.yahoo.com",
"https://news.yahoo.com/news",
"https://news.yahoo.com/news/topics/",
"https://news.yahoo.com/us"
]
Использовать многопоточность для обработки URL-адресов.
class HtmlParser {
public:
std::vector<std::string> getUrls(const std::string& url);
};
std::string extractHostname(const std::string& url) {
auto pos = url.find("//");
pos = (pos == std::string::npos) ? 0 : pos + 2;
auto end = url.find('/', pos);
return url.substr(pos, end - pos);
}
class Solution {
public:
std::vector<std::string> crawl(std::string startUrl, HtmlParser htmlParser) {
std::string hostname = extractHostname(startUrl);
std::unordered_set<std::string> visited;
std::mutex mtx;
std::condition_variable cv;
std::queue<std::string> q;
q.push(startUrl);
visited.insert(startUrl);
std::vector<std::future<void>> futures;
auto worker = [&]() {
while (true) {
std::string url;
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [&]() { return !q.empty(); });
url = q.front();
q.pop();
}
for (const auto& nextUrl : htmlParser.getUrls(url)) {
if (extractHostname(nextUrl) == hostname) {
std::unique_lock<std::mutex> lock(mtx);
if (visited.insert(nextUrl).second) {
q.push(nextUrl);
cv.notify_all();
}
}
}
}
};
for (int i = 0; i < 10; ++i) {
futures.push_back(std::async(std::launch::async, worker));
}
for (auto& future : futures) {
future.wait();
}
return std::vector<std::string>(visited.begin(), visited.end());
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 338. Counting Bits
Сложность: easy
Дано целое число n, верните массив ans длиной n + 1, такой что для каждого i (0 <= i <= n), ans[i] будет равняться количеству единиц в двоичном представлении числа i.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация массива:
Создайте массив ans длиной n + 1, заполненный нулями. Этот массив будет содержать количество единиц в двоичном представлении каждого числа от 0 до n.
2⃣ Итерация и вычисление:
Пройдите в цикле по всем числам от 1 до n. Для каждого числа x используйте битовую операцию x & (x - 1), чтобы убрать последнюю установленную биту, и добавьте 1 к значению ans для этого результата. Это количество единиц в двоичном представлении числа x.
3⃣ Возврат результата:
Верните заполненный массив ans, который содержит количество единиц для каждого числа от 0 до n.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано целое число n, верните массив ans длиной n + 1, такой что для каждого i (0 <= i <= n), ans[i] будет равняться количеству единиц в двоичном представлении числа i.
Пример:
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
Создайте массив ans длиной n + 1, заполненный нулями. Этот массив будет содержать количество единиц в двоичном представлении каждого числа от 0 до n.
Пройдите в цикле по всем числам от 1 до n. Для каждого числа x используйте битовую операцию x & (x - 1), чтобы убрать последнюю установленную биту, и добавьте 1 к значению ans для этого результата. Это количество единиц в двоичном представлении числа x.
Верните заполненный массив ans, который содержит количество единиц для каждого числа от 0 до n.
class Solution {
public:
vector<int> countBits(int num) {
vector<int> ans(num + 1, 0);
for (int x = 1; x <= num; ++x) {
ans[x] = ans[x & (x - 1)] + 1;
}
return ans;
}
};Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM