C/C++ | LeetCode
رفتن به کانال در Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv
نمایش بیشتر3 235
مشترکین
-124 ساعت
-37 روز
-1930 روز
در حال بارگیری داده...
کانالهای مشابه
ابر برچسبها
اشارات ورودی و خروجی
---
---
---
---
---
---
جذب مشترکین
ژوئیه '26
ژوئیه '26
+16
در 0 کانالها
ژوئن '26
+30
در 0 کانالها
Get PRO
مه '26
+35
در 0 کانالها
Get PRO
آوریل '26
+35
در 0 کانالها
Get PRO
مارس '26
+32
در 0 کانالها
Get PRO
فوریه '26
+45
در 0 کانالها
Get PRO
ژانویه '26
+35
در 0 کانالها
Get PRO
دسامبر '25
+37
در 0 کانالها
Get PRO
نوامبر '25
+84
در 0 کانالها
Get PRO
اکتبر '25
+43
در 0 کانالها
Get PRO
سپتامبر '25
+35
در 0 کانالها
Get PRO
اوت '25
+40
در 0 کانالها
Get PRO
ژوئیه '25
+40
در 1 کانالها
Get PRO
ژوئن '25
+43
در 0 کانالها
Get PRO
مه '25
+44
در 0 کانالها
Get PRO
آوریل '25
+61
در 0 کانالها
Get PRO
مارس '25
+60
در 1 کانالها
Get PRO
فوریه '25
+179
در 3 کانالها
Get PRO
ژانویه '25
+79
در 53 کانالها
Get PRO
دسامبر '24
+64
در 0 کانالها
Get PRO
نوامبر '24
+91
در 1 کانالها
Get PRO
اکتبر '24
+424
در 13 کانالها
Get PRO
سپتامبر '24
+1 488
در 331 کانالها
Get PRO
اوت '24
+91
در 0 کانالها
Get PRO
ژوئیه '24
+826
در 219 کانالها
Get PRO
ژوئن '24
+1 211
در 232 کانالها
| تاریخ | رشد مشترکین | اشارات | کانالها | |
| 14 ژوئیه | +1 | |||
| 13 ژوئیه | +1 | |||
| 12 ژوئیه | +1 | |||
| 11 ژوئیه | +2 | |||
| 10 ژوئیه | 0 | |||
| 09 ژوئیه | +1 | |||
| 08 ژوئیه | +2 | |||
| 07 ژوئیه | 0 | |||
| 06 ژوئیه | 0 | |||
| 05 ژوئیه | +1 | |||
| 04 ژوئیه | +6 | |||
| 03 ژوئیه | +1 | |||
| 02 ژوئیه | 0 | |||
| 01 ژوئیه | 0 |
پستهای کانال
Задача: 1064. Fixed Point
Сложность: easy
Дан массив различных целых чисел arr, отсортированный в порядке возрастания. Верните наименьший индекс i, который удовлетворяет условию arr[i] == i. Если такого индекса нет, верните -1.
Пример:
Input: arr = [-10,-5,0,3,7]
Output: 3
Explanation: For the given array, arr[0] = -10, arr[1] = -5, arr[2] = 0, arr[3] = 3, thus the output is 3.
👨💻 Алгоритм:
1⃣Инициализируйте значение left как 0, right как N - 1 и answer как -1.
2⃣Пока размер области поиска не равен нулю, то есть left <= right, выполните следующие шаги: найдите mid как mid = (left + right) / 2. Сравните arr[mid] и mid: если arr[mid] = mid, сохраните mid в answer и перейдите в левую часть, изменив right на mid - 1; если arr[mid] < mid, перейдите в правую часть, изменив left на mid + 1; если arr[mid] > mid, перейдите в левую часть, изменив right на mid - 1.
3⃣Верните answer.
😎 Решение:
class Solution {
public:
int fixedPoint(vector<int>& arr) {
int left = 0, right = arr.size() - 1;
int answer = -1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == mid) {
answer = mid;
right = mid - 1;
} else if (arr[mid] < mid) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return answer;
}
};
Ставь 👍 и забирай 📚 Базу знаний| 2 | Задача: 1329. Sort the Matrix Diagonally
Сложность: medium
Диагональ матрицы — это диагональная линия ячеек, начинающаяся с какой-либо ячейки в самой верхней строке или в самом левом столбце и идущая в направлении вниз-вправо до конца матрицы. Например, диагональ матрицы, начинающаяся с mat[2][0], где mat — это матрица размером 6 x 3, включает ячейки mat[2][0], mat[3][1] и mat[4][2].
Дана матрица mat размером m x n, состоящая из целых чисел. Отсортируйте каждую диагональ матрицы по возрастанию и верните полученную матрицу.
Пример:
Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]
👨💻 Алгоритм:
1⃣Сохраните размеры матрицы m и n. Создайте хеш-карту из минимальных куч для хранения элементов диагоналей.
2⃣Вставьте значения в хеш-карту, используя разность между индексами строки и столбца как ключ, чтобы собирать элементы на одной и той же диагонали.
3⃣Извлеките значения из хеш-карты и обновите матрицу, заполняя ее отсортированными значениями диагоналей. Верните отсортированную матрицу.
😎 Решение:
class Solution {
public:
vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {
size_t m = mat.size();
size_t n = mat[0].size();
map<int, priority_queue<int, vector<int>, greater<int>>> diagonals;
for (size_t row = 0; row < m; row++) {
for (size_t col = 0; col < n; col++) {
diagonals[row - col].push(mat[row][col]);
}
}
for (size_t row = 0; row < m; row++) {
for (size_t col = 0; col < n; col++) {
mat[row][col] = diagonals[row - col].top();
diagonals[row - col].pop();
}
}
return mat;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 229 |
| 3 | АЙТИШНИКИ, ХВАТИТ сливать время на прилизанные новости и бесполезные курсы
Проект «ИИнтеллигенция» стал главным каналом для тех, кто использует нейросети на уровне разработки, автоматизации и опенсорса, а не просто балуется в чатах. Здесь собирают только то, что реально экономит человеко-часы и работает в проде.
🎓 Готовые ИИ-сервисы, промпты и ИИ-агенты для автоматизации рутины
📚 Разборы полезных ИИ-инструментов, локальных LLM и опенсорс-репозиториев
🛠 Практические кейсы, гайды по деплою моделей и интеграции ИИ в пайплайны
⚡️ Технические ИТ-новости без маркетинговой воды и душных отчетов
Обучение и прокачка в реальном времени: работа с API (Claude, GPT), локалки (Ollama, vLLM), автоматизация кода, опенсорс-утилиты, AI-агенты и др.
Ценишь время и работаешь с ИИ, подпишись: @clucai | 204 |
| 4 | Задача: 41. First Missing Positive
Сложность: hard
Дан неотсортированный массив целых чисел nums. Верните наименьшее положительное целое число, которого нет в массиве nums.
Необходимо реализовать алгоритм, который работает за время O(n) и использует O(1) дополнительной памяти.
Пример:
Input: nums = [3,4,-1,1] Output: 2
👨💻 Алгоритм:
1⃣Перебрать массив и попытаться разместить каждое число в правильной позиции: nums[i] должен быть равен i + 1
2⃣Используем swap, чтобы поставить каждый элемент на его "правильное" место, если это возможно
3⃣После расстановки — находим первый индекс, где nums[i] != i + 1. Возвращаем i + 1
😎 Решение:
int firstMissingPositive(std::vector<int>& nums) {
for (int i = 0; i < nums.size(); ) {
if (nums[i] <= 0 || nums[i] > nums.size()) {
++i;
continue;
}
if (nums[i] == i + 1) {
++i;
continue;
}
int j = nums[i];
if (nums[j - 1] == nums[i]) {
++i;
continue;
}
std::swap(nums[j - 1], nums[i]);
}
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return nums.size() + 1;
}
Ставь 👍 и забирай 📚 Базу знаний | 330 |
| 5 | Задача: 667. Beautiful Arrangement II
Сложность: medium
Даны два целых числа n и k, составьте список answer, содержащий n различных положительных чисел в диапазоне от 1 до n, который соответствует следующему требованию:
Предположим, что этот список answer = [a1, a2, a3, ... , an], тогда список [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] имеет ровно k различных чисел. Верните список answer. Если существует несколько допустимых ответов, верните любой из них.
Пример:
Input: n = 3, k = 1
Output: [1,2,3]
Explanation: The [1,2,3] has three different positive integers ranging from 1 to 3, and the [1,1] has exactly 1 distinct integer: 1
👨💻 Алгоритм:
1⃣Инициализация списка:
Начните с создания списка от 1 до n: [1, 2, 3, ..., n].
2⃣Конструирование шаблона с k различиями:
Для обеспечения k различных значений разностей используйте следующий подход:
Включайте числа попеременно с конца и начала списка, начиная с n и 1, чтобы создать как можно больше уникальных разностей.
Если требуется меньше k, оставшиеся числа просто добавляйте в порядке возрастания, чтобы не увеличивать количество уникальных разностей.
3⃣Заполнение списка:
Заполните оставшуюся часть списка последовательными числами, чтобы сохранить уникальные числа в диапазоне от 1 до n.
😎 Решение:
class Solution {
public:
vector<int> constructArray(int n, int k) {
vector<int> answer;
int left = 1, right = n;
for (int i = 0; i <= k; i++) {
if (i % 2 == 0) {
answer.push_back(left++);
} else {
answer.push_back(right--);
}
}
if (k % 2 == 0) {
for (int i = right; i >= left; i--) {
answer.push_back(i);
}
} else {
for (int i = left; i <= right; i++) {
answer.push_back(i);
}
}
return answer;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 285 |
| 6 | Задача: 436. Find Right Interval
Сложность: medium
Дан массив интервалов, где intervals[i] = [starti, endi] и каждый starti уникален.
Правый интервал для интервала i - это интервал j, такой что startj >= endi и startj минимален. Обратите внимание, что i может быть равен j.
Верните массив индексов правых интервалов для каждого интервала i. Если правого интервала для интервала i не существует, то поставьте -1 в индекс i.
Пример:
Input: intervals = [[1,2]]
Output: [-1]
Explanation: There is only one interval in the collection, so it outputs -1.
👨💻 Алгоритм:
1⃣Интуиция за этим подходом такова: если мы будем поддерживать два массива - intervals, который отсортирован по начальным точкам, и endIntervals, который отсортирован по конечным точкам. Когда мы выбираем первый интервал (или, скажем, i-ый интервал) из массива endIntervals, мы можем определить подходящий интервал, удовлетворяющий критериям правого интервала, просматривая интервалы в массиве intervals слева направо, так как массив intervals отсортирован по начальным точкам. Допустим, индекс выбранного элемента из массива intervals окажется j.
2⃣Теперь, когда мы выбираем следующий интервал (скажем, (i+1)-ый интервал) из массива endIntervals, нам не нужно начинать сканирование массива intervals с первого индекса. Вместо этого мы можем начать прямо с индекса j, где мы остановились в последний раз в массиве intervals. Это потому, что конечная точка, соответствующая endIntervals[i+1], больше, чем та, которая соответствует endIntervals[i], и ни один из интервалов из intervals[k], таких что 0 < k < j, не удовлетворяет критериям правого соседа с endIntervals[i], а значит, и с endIntervals[i+1] тоже.
3⃣Если в какой-то момент мы достигнем конца массива, т.е. j = intervals.length, и ни один элемент, удовлетворяющий критериям правого интервала, не будет доступен в массиве intervals, мы ставим -1 в соответствующую запись res. То же самое касается всех оставшихся элементов массива endIntervals, конечные точки которых даже больше, чем у предыдущего интервала. Также мы используем хеш-таблицу hash изначально, чтобы сохранить индексы, соответствующие интервалам, даже после сортировки.
😎 Решение:
class Solution {
public:
vector<int> findRightInterval(vector<vector<int>>& intervals) {
vector<vector<int>> endIntervals = intervals;
unordered_map<vector<int>, int> hash;
for (int i = 0; i < intervals.size(); ++i) {
hash[intervals[i]] = i;
}
sort(intervals.begin(), intervals.end(), [](vector<int>& a, vector<int>& b) { return a[0] < b[0]; });
sort(endIntervals.begin(), endIntervals.end(), [](vector<int>& a, vector<int>& b) { return a[1] < b[1]; });
int j = 0;
vector<int> res(intervals.size());
for (int i = 0; i < endIntervals.size(); ++i) {
while (j < intervals.size() && intervals[j][0] < endIntervals[i][1]) {
j++;
}
res[hash[endIntervals[i]]] = j == intervals.size() ? -1 : hash[intervals[j]];
}
return res;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 215 |
| 7 | Задача: 1015. Smallest Integer Divisible by K
Сложность: medium
Задано целое положительное число k, необходимо найти длину наименьшего целого положительного числа n, такого, что n делится на k, и n содержит только цифру 1. Верните длину n. Если такого n не существует, верните -1. Примечание: n может не поместиться в 64-битное знаковое целое число.
Пример:
Input: k = 1
Output: 1
👨💻 Алгоритм:
1⃣Использование остатка для нахождения числа с цифрами 1:
Создайте переменную num и установите ее равной 1.
Создайте переменную length и установите ее равной 1 для отслеживания длины числа.
2⃣Итеративное нахождение числа:
Используйте цикл, чтобы умножать num на 10 и добавлять 1 в каждой итерации, и каждый раз вычисляйте остаток от деления num на k.
Увеличивайте length на 1 в каждой итерации.
Если в какой-то итерации num % k == 0, верните length.
3⃣Проверка бесконечного цикла:
Если цикл длится слишком долго (например, 10^6 итераций), верните -1, чтобы предотвратить бесконечный цикл для случаев, когда решение не существует.
😎 Решение:
class Solution {
public:
int smallestRepunitDivByK(int k) {
int num = 1, length = 1;
unordered_set<int> seen;
while (num % k != 0) {
if (seen.count(num % k)) {
return -1;
}
seen.insert(num % k);
num = (num * 10 + 1) % k;
length++;
}
return length;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 210 |
| 8 | Задача: 942. DI String Match
Сложность: easy
Перестановка perm из n + 1 целых чисел всех целых чисел в диапазоне [0, n] может быть представлена в виде строки s длины n, где: s[i] == 'I', если perm[i] < perm[i + 1], и s[i] == 'D', если perm[i] > perm[i + 1]. Получив строку s, восстановите перестановку perm и верните ее. Если существует несколько допустимых перестановок perm, верните любую из них.
Пример:
Input: s = "IDID"
Output: [0,4,1,3,2]
👨💻 Алгоритм:
1⃣Инициализировать два указателя low и high для отслеживания минимального и максимального числа, которые можно использовать в перестановке.
2⃣Создать массив perm длиной n + 1.
Пройти по строке s:
Если текущий символ равен 'I', добавить low в текущую позицию perm и увеличить low.
Если текущий символ равен 'D', добавить high в текущую позицию perm и уменьшить high.
Добавить оставшееся значение (low или high, так как они будут равны) в последнюю позицию perm.
3⃣Вернуть массив perm.
😎 Решение:
class Solution {
public:
vector<int> diStringMatch(string s) {
int n = s.size();
int low = 0, high = n;
vector<int> perm(n + 1);
for (int i = 0; i < n; ++i) {
if (s[i] == 'I') {
perm[i] = low++;
} else {
perm[i] = high--;
}
}
perm[n] = low;
return perm;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 231 |
| 9 | Осталось 3 часа до конца акции:
«Пожизненный PRO тариф — по цене 1 года»
Поиск работы отнимает силы, время и веру в себя, но не у тех кто использует easyoffer PRO. Успей сделать самую выгодную инвестицию в развитие своей карьеры.
Акция закончится уже сегодня 23 июня 23:59 по мск:
👉 https://easyoffer.ru/pro | 71 |
| 10 | Задача: 865. Smallest Subtree with all the Deepest Nodes
Сложность: medium
Дан корень бинарного дерева, глубина каждого узла — это кратчайшее расстояние до корня.
Верните наименьшее поддерево, которое содержит все самые глубокие узлы в исходном дереве.
Узел называется самым глубоким, если у него наибольшая возможная глубина среди всех узлов в дереве.
Поддерево узла — это дерево, состоящее из этого узла и всех его потомков.
Пример:
Input: root = [3,5,1,6,2,0,8,null,null,7,4]
Output: [2,7,4]
Explanation: We return the node with value 2, colored in yellow in the diagram.
The nodes coloured in blue are the deepest nodes of the tree.
Notice that nodes 5, 3 and 2 contain the deepest nodes in the tree but node 2 is the smallest subtree among them, so we return it.
👨💻 Алгоритм:
1⃣В первой фазе используем поиск в глубину (DFS), чтобы аннотировать узлы. Каждый узел будет хранить информацию о своей глубине и о самой большой глубине среди его потомков.
2⃣Во второй фазе также используем DFS для функции answer(node), которая возвращает наименьшее поддерево, содержащее все самые глубокие узлы. Функция сравнивает глубины левых и правых поддеревьев узла для определения наименьшего поддерева.
3⃣Функция answer(node) возвращает поддерево, которое содержит все самые глубокие узлы всего дерева, а не только рассматриваемого поддерева.
😎 Решение:
class Solution {
public:
TreeNode* subtreeWithAllDeepest(TreeNode* root) {
unordered_map<TreeNode*, int> depth = {{nullptr, -1}};
dfs(root, nullptr, depth);
int maxDepth = max_element(depth.begin(), depth.end(), [](const auto& a, const auto& b) {
return a.second < b.second;
})->second;
return answer(root, depth, maxDepth);
}
private:
void dfs(TreeNode* node, TreeNode* parent, unordered_map<TreeNode*, int>& depth) {
if (node) {
depth[node] = depth[parent] + 1;
dfs(node->left, node, depth);
dfs(node->right, node, depth);
}
}
TreeNode* answer(TreeNode* node, unordered_map<TreeNode*, int>& depth, int maxDepth) {
if (!node || depth[node] == maxDepth) return node;
TreeNode* L = answer(node->left, depth, maxDepth);
TreeNode* R = answer(node->right, depth, maxDepth);
return L && R ? node : L ? L : R;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 260 |
| 11 | Последний день акции:
«Пожизненный PRO тариф — по цене 1 года»
🚀 PRO включает:
– Полный доступ ко всем грейдам и профессиям
– База live-coding задач и вопросов из технических собеседований с вероятностью их встречи
– Примеры лучших ответов от Senior разработчиков
– 1100+ записи реальных собеседований, в том числе в топовые компании (Сбер, Авито, Яндекс, WB, OZON, МТС и др.)
– База 400+ тестовых заданий от компаний.
– Автоотклики на вакансии в хедхантер
– Аналитика ТОП-требований из вакансий для лучшего написания резюме и прохождения ATS систем рекрутеров
– Генератор уникального резюме и CV под каждую вакансию
– Тренажеры подготовки к собеседованию: «Реальное собеседование» и «Проработка вопросов» по методике интервальных повторений (как Anki)
– (скоро) Агрегатор вакансий
– (скоро) Сообщество
Акция закончится уже сегодня 23 июня 23:59 по мск:
👉 https://easyoffer.ru/pro | 136 |
| 12 | Задача: 1162. As Far from Land as Possible
Сложность: medium
Дана сетка размером n x n, содержащая только значения 0 и 1, где 0 представляет воду, а 1 представляет землю. Найдите ячейку с водой, такое что её расстояние до ближайшей ячейки с землёй максимально, и верните это расстояние. Если в сетке нет ни земли, ни воды, верните -1.
Расстояние, используемое в этой задаче, - это манхэттенское расстояние: расстояние между двумя ячейками (x0, y0) и (x1, y1) равно |x0 - x1| + |y0 - y1|.
Пример:
Input: grid = [[1,0,1],[0,0,0],[1,0,1]]
Output: 2
Explanation: The cell (1, 1) is as far as possible from all the land with distance 2.
👨💻 Алгоритм:
1⃣Итерируйте по матрице и вставьте координаты ячеек с землёй в очередь. Инициализируйте переменную distance значением -1 для хранения текущего шага обхода в ширину (BFS). Также создайте копию матрицы visited для пометки ячеек с водой как посещённые, чтобы не вставлять их снова в очередь.
2⃣Выполните BFS: Обходите текущие элементы в очереди и для каждого элемента проверяйте координаты в четырёх направлениях, являются ли они ячейками с водой (0). Если да, вставьте их в очередь и измените их на ячейки с землёй (1) в матрице visited. После каждого пройденного уровня (внутренний цикл while завершён), увеличьте переменную distance.
3⃣Повторяйте, пока очередь не станет пустой. Верните значение distance. Если оно равно 0, это означает, что не было ячеек с водой и обход завершился после первого шага, поэтому верните -1. Если в матрице не было ячеек с землёй, цикл while вообще не начнётся, и переменная distance останется с начальным значением (-1).
😎 Решение:
class Solution {
public:
const pair<int, int> direction[4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int maxDistance(vector<vector<int>>& grid) {
int visited[grid.size()][grid[0].size()];
queue<pair<int, int>> q;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
visited[i][j] = grid[i][j];
if (grid[i][j]) {
q.push({i, j});
}
}
}
int distance = -1;
while (!q.empty()) {
int qSize = q.size();
while (qSize--) {
pair<int, int> landCell = q.front();
q.pop();
for (pair<int, int> dir : direction) {
int x = landCell.first + dir.first;
int y = landCell.second + dir.second;
if (x >= 0 && y >= 0 && x < grid.size() && y < grid[0].size() && visited[x][y] == 0) {
visited[x][y] = 1;
q.push({x, y});
}
}
}
distance++;
}
return distance == 0 ? -1 : distance;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 222 |
| 13 | Пожизненный PRO тариф — по цене 1 года.
Покупаешь один раз — пользуешься всю жизнь:
👉 https://easyoffer.ru/pro
🚀 PRO-доступ закроет 99% проблем на пути к офферу:
1. Полный доступ ко всем грейдам и профессиям. Не важно, Junior вы или Senior, Тестировщик, Разработчик, Проджект — вы получите материалы под ваш текущий уровень и цели, без ограничений.
2. База live-coding задач и вопросов с реальных собесов с уникальной системой вероятности их встречи. Вы будете готовиться не вслепую, а точечно по тем темам, которые спрашивают чаще всего.
3. Эталонные ответы от Senior-разработчиков. Никакой воды и догадок — только четкие, структурированные решения, за которые дают «зеленый свет» к офферу
4. 1100+ записей реальных собеседований (включая топы: Сбер, Авито, Яндекс, WB, OZON, МТС). Вы увидите всё изнутри: как спрашивают, как отвечают сильные кандидаты и на каких ошибках проваливаются 80% проходящих.
5. База 400+ тестовых заданий. Если вы еще студент, то практикуйтесь на решении задач, которые помогут попасть на собес
6. Автоотклики на Хедхантере — пока вы спите, ваше резюме летит к рекрутерам автоматически. Это экономия сотен часов ручного кликанья.
7. Аналитика ТОП-требований из вакансий. Мы парсим рынок и показываем, какие скиллы сейчас в цене. Это позволит вам точечно апгрейдить резюме и проходить суровые ATS-фильтры (которые отсеивают до 75% резюме еще до просмотра рекрутером).
8. Генератор уникального резюме и CV под каждую вакансию. Забудьте про «универсальное» резюме — нейросеть адаптирует ваш опыт под конкретную позицию за минуту, повышая шансы на приглашение в разы.
9. Тренажеры подготовки к собеседованию:
«Реальное собеседование» — сценарий вопросов из реальных интервью
«Проработка вопросов» — флеш карточки с вопросами/ответами по методике интервальных повторений (как Anki)
10. (Скоро) Агрегатор вакансий — все вакансии из HH, Telegram, LinkedIn и других площадок в одной ленте.
11. (Скоро) Закрытое комьюнити — нетворкинг и помощь в сложных вопросах от таких же целеустремленных айтишников.
Завтра последний день акции:
👉 https://easyoffer.ru/pro | 157 |
| 14 | Задача: 852. Peak Index in a Mountain Array
Сложность: medium
Вам дан целочисленный массив горы arr длины n, где значения увеличиваются до пикового элемента, а затем уменьшаются.
Верните индекс пикового элемента.
Ваша задача — решить это с временной сложностью O(log(n)).
Пример:
Input: arr = [0,1,0]
Output: 1
👨💻 Алгоритм:
1⃣Создайте целочисленную переменную i и инициализируйте её значением 0.
2⃣Используя цикл while, проверьте, если текущий элемент, на который указывает i, меньше следующего элемента на индексе i + 1. Если arr[i] < arr[i + 1], увеличьте i на 1.
3⃣В противном случае, если arr[i] > arr[i + 1], верните i.
😎 Решение:
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int i = 0;
while (arr[i] < arr[i + 1]) {
i++;
}
return i;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 201 |
| 15 | Задача: 208. Implement Trie (Prefix Tree)
Сложность: medium
Реализуйте структуру данных Trie (префиксное дерево), поддерживающую следующие операции:
insert(word) — вставка слова
search(word) — проверка, было ли слово вставлено
startsWith(prefix) — проверка, начинается ли хоть одно вставленное слово с заданного префикса
Пример:
Input: ["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
Output: [null, null, true, false, true, null, true]
👨💻 Алгоритм:
1⃣Инициализация и вставка:
Каждый узел (TrieNode) содержит массив из 26 указателей (по одной на каждую букву алфавита) и флаг isEnd.
Метод insert создает недостающие узлы и в конце устанавливает isEnd = true для последнего символа слова.
2⃣Поиск строки:
Метод search использует вспомогательную функцию searchPrefix, которая проходит по всем символам слова. Если найденный узел существует и отмечен как конец слова, возвращаем true.
3⃣Проверка префикса:
Метод startsWith использует searchPrefix, и возвращает true, если удалось дойти до конца заданного префикса.
😎 Решение:
#include <vector>
#include <string>
class TrieNode {
private:
TrieNode* links[26];
bool isEnd;
public:
TrieNode() : isEnd(false) {
for (int i = 0; i < 26; ++i) {
links[i] = nullptr;
}
}
bool containsKey(char ch) {
return links[ch - 'a'] != nullptr;
}
TrieNode* get(char ch) {
return links[ch - 'a'];
}
void put(char ch, TrieNode* node) {
links[ch - 'a'] = node;
}
void setEnd() {
isEnd = true;
}
bool isEndNode() {
return isEnd;
}
};
class Trie {
private:
TrieNode* root;
TrieNode* searchPrefix(const std::string& word) {
TrieNode* node = root;
for (char ch : word) {
if (node->containsKey(ch)) {
node = node->get(ch);
} else {
return nullptr;
}
}
return node;
}
public:
Trie() {
root = new TrieNode();
}
void insert(const std::string& word) {
TrieNode* node = root;
for (char ch : word) {
if (!node->containsKey(ch)) {
node->put(ch, new TrieNode());
}
node = node->get(ch);
}
node->setEnd();
}
bool search(const std::string& word) {
TrieNode* node = searchPrefix(word);
return node != nullptr && node->isEndNode();
}
bool startsWith(const std::string& prefix) {
return searchPrefix(prefix) != nullptr;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 199 |
| 16 | Задача: 243. Shortest Word Distance
Сложность: easy
Дан массив строк и два слова. Нужно вернуть минимальное расстояние между ними в массиве.
Пример:
Input: wordsDict = ["practice", "makes", "perfect", "coding", "makes"], word1 = "coding", word2 = "practice" Output: 3
👨💻 Алгоритм:
1⃣Проходим по массиву один раз, запоминая последние индексы, где встречались word1 и word2
2⃣При каждом новом вхождении одного из слов, если другое уже найдено — обновляем минимальное расстояние
3⃣Возвращаем минимальное расстояние
😎 Решение:
class Solution {
public:
int shortestDistance(vector<string>& words, string word1, string word2) {
int idx1 = -1, idx2 = -1, minDist = words.size();
for (int i = 0; i < words.size(); ++i) {
if (words[i] == word1) idx1 = i;
else if (words[i] == word2) idx2 = i;
if (idx1 != -1 && idx2 != -1) {
minDist = min(minDist, abs(idx1 - idx2));
}
}
return minDist;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 228 |
| 17 | Привет, ребята!
У нас для вас отличные новости — на easyoffer вышло сразу несколько крупных обновлений:
1. Автоотклики на HeadHunter
Снова работают в полную силу — можно смело возвращаться к активному поиску.
2. Новый раздел «Резюмейкер»
Теперь вы можете быстро создавать уникальные резюме, адаптированные под каждую вакансию, и сразу добавлять сопроводительное письмо. Это заметно повышает шансы получить приглашение на собеседование.
3. База вопросов стала чище
Мы навели порядок и удалили около 30% дубликатов.
Ориентироваться стало проще.
––––––––––––––––––
🔥 Акция в честь обновления
Пожизненный тариф easyoffer PRO — по цене одного года.
Успейте до 23 июня:
👉 https://easyoffer.ru/pro
––––––––––––––––––
Что дальше?
В ближайшие пару недель добавим ещё два раздела:
1. Сообщество с чатами по всем профессиональным направлениям.
2. Агрегатор вакансий, чтобы поиск работы стал ещё удобнее. | 161 |
| 18 | Задача: 944. Delete Columns to Make Sorted
Сложность: easy
Учитывая массив строк words, верните наименьшую строку, которая содержит каждую строку в words в качестве подстроки. Если существует несколько допустимых строк наименьшей длины, верните любую из них. Вы можете предположить, что ни одна строка в words не является подстрокой другой строки в words.
Пример:
Input: strs = ["cba","daf","ghi"]
Output: 1
👨💻 Алгоритм:
1⃣Инициализировать переменную count для отслеживания количества столбцов, которые нужно удалить.
2⃣Пройти по каждому столбцу от 0 до длины строки.
Для каждого столбца проверить, отсортированы ли символы лексикографически.
Если столбец не отсортирован, увеличить count.
3⃣Вернуть count.
😎 Решение:
class Solution {
public:
int minDeletionSize(vector<string>& strs) {
int count = 0;
int rows = strs.size();
int cols = strs[0].size();
for (int col = 0; col < cols; col++) {
for (int row = 1; row < rows; row++) {
if (strs[row][col] < strs[row - 1][col]) {
count++;
break;
}
}
}
return count;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 235 |
| 19 | Задача: 1673. Find the Most Competitive Subsequence
Сложность: medium
Дан целочисленный массив nums и положительное целое число k. Верните наиболее конкурентоспособную подпоследовательность массива nums размера k.
Подпоследовательность массива — это результирующая последовательность, полученная путем удаления некоторых (возможно, нуля) элементов из массива.
Мы определяем, что подпоследовательность a более конкурентоспособна, чем подпоследовательность b (одинаковой длины), если в первой позиции, где они различаются, подпоследовательность a имеет число меньше, чем соответствующее число в b. Например, [1,3,4] более конкурентоспособна, чем [1,3,5], потому что первая позиция, где они различаются, это последнее число, и 4 меньше, чем 5.
Пример:
Input: nums = [3,5,2,6], k = 2
Output: [2,6]
Explanation: Among the set of every possible subsequence: {[3,5], [3,2], [3,6], [5,2], [5,6], [2,6]}, [2,6] is the most competitive.
👨💻 Алгоритм:
1⃣Создайте двустороннюю очередь (deque), которая будет хранить выбранную подпоследовательность.
2⃣Переберите массив nums, выбирая наиболее конкурентоспособные элементы и добавляя их в очередь. Сравнивайте последний элемент в очереди с текущим элементом, удаляя из очереди более крупные элементы, если можно удалить больше элементов, чем необходимо для достижения размера k.
3⃣В конце получите первые k элементов из очереди и создайте результирующий массив.
😎 Решение:
class Solution {
public:
vector<int> mostCompetitive(vector<int>& nums, int k) {
deque<int> queue;
int additionalCount = nums.size() - k;
for (int num : nums) {
while (!queue.empty() && queue.back() > num && additionalCount > 0) {
queue.pop_back();
additionalCount--;
}
queue.push_back(num);
}
return vector<int>(queue.begin(), queue.begin() + k);
}
};
Ставь 👍 и забирай 📚 Базу знаний | 251 |
| 20 | Задача: 421. Maximum XOR of Two Numbers in an Array
Сложность: medium
Дан целочисленный массив nums, верните максимальный результат nums[i] XOR nums[j], где 0 <= i <= j < n.
Пример:
Input: nums = [3,10,5,25,2,8]
Output: 28
Explanation: The maximum result is 5 XOR 25 = 28.
👨💻 Алгоритм:
1⃣Вычислите количество битов L для использования. Это длина максимального числа в двоичном представлении. Инициализируйте max_xor = 0.
2⃣Запустите цикл от i = L−1 до i = 0 (от самого левого бита L−1 до самого правого бита 0):
Сдвигайте max_xor влево, чтобы освободить следующий бит.
Инициализируйте переменную curr_xor = max_xor | 1, установив 1 в самом правом бите max_xor. Теперь проверьте, можно ли выполнить curr_xor, используя доступные префиксы.
3⃣Вычислите все возможные префиксы длины L−i, итерируя по nums:
Поместите в HashSet префиксы префикс текущего числа длиной L−i: num >> i.
Итерируйте по всем префиксам и проверьте, можно ли выполнить curr_xor, используя два из них: p1 ^ p2 == curr_xor. Используя свойство самопреобразования XOR p1 ^ p2 ^ p2 = p1, можно переписать это как p1 == curr_xor ^ p2 и просто проверить для каждого p, если curr_xor ^ p есть в префиксах. Если так, установите max_xor равным curr_xor, т.е. установите 1-бит в самом правом бите. В противном случае, пусть max_xor оставит 0-бит в самом правом бите.
😎 Решение:
#include <vector>
#include <unordered_set>
using namespace std;
class Solution {
public:
int findMaximumXOR(vector<int>& nums) {
int maxNum = nums[0];
for (int num : nums) maxNum = max(maxNum, num);
int L = 32 - __builtin_clz(maxNum);
int maxXor = 0, currXor;
unordered_set<int> prefixes;
for (int i = L - 1; i >= 0; --i) {
maxXor <<= 1;
currXor = maxXor | 1;
prefixes.clear();
for (int num : nums) prefixes.insert(num >> i);
for (int p : prefixes) {
if (prefixes.count(currXor ^ p)) {
maxXor = currXor;
break;
}
}
}
return maxXor;
}
};
Ставь 👍 и забирай 📚 Базу знаний | 247 |
