ch
Feedback
C# | LeetCode

C# | LeetCode

前往频道在 Telegram
3 263
订阅者
-324 小时
-197
-3830
吸引订阅者
六月 '26
六月 '26
+15
在0个频道中
五月 '26
+13
在0个频道中
Get PRO
四月 '26
+23
在0个频道中
Get PRO
三月 '26
+21
在0个频道中
Get PRO
二月 '26
+21
在0个频道中
Get PRO
一月 '26
+23
在0个频道中
Get PRO
十二月 '25
+24
在0个频道中
Get PRO
十一月 '25
+74
在0个频道中
Get PRO
十月 '25
+55
在0个频道中
Get PRO
九月 '25
+46
在0个频道中
Get PRO
八月 '25
+63
在0个频道中
Get PRO
七月 '25
+65
在1个频道中
Get PRO
六月 '25
+82
在0个频道中
Get PRO
五月 '25
+78
在0个频道中
Get PRO
四月 '25
+111
在0个频道中
Get PRO
三月 '25
+230
在2个频道中
Get PRO
二月 '25
+314
在3个频道中
Get PRO
一月 '25
+186
在53个频道中
Get PRO
十二月 '24
+64
在0个频道中
Get PRO
十一月 '24
+104
在0个频道中
Get PRO
十月 '24
+287
在12个频道中
Get PRO
九月 '24
+1 084
在331个频道中
Get PRO
八月 '24
+170
在0个频道中
Get PRO
七月 '24
+761
在219个频道中
Get PRO
六月 '24
+835
在232个频道中
日期
订阅者增长
提及
频道
24 六月+1
23 六月0
22 六月0
21 六月0
20 六月+2
19 六月+1
18 六月0
17 六月0
16 六月0
15 六月0
14 六月+3
13 六月+1
12 六月+1
11 六月0
10 六月0
09 六月0
08 六月+1
07 六月0
06 六月0
05 六月+2
04 六月0
03 六月+1
02 六月+2
01 六月0
频道帖子
Задача: 935. Knight Dialer Сложность: medium Шахматный конь обладает уникальным движением: он может перемещаться на две клетки по вертикали и одну клетку по горизонтали, или на две клетки по горизонтали и одну клетку по вертикали (при этом обе клетки образуют форму буквы L). Возможные движения шахматного коня показаны на этой диаграмме: Шахматный конь может двигаться так, как показано на шахматной диаграмме ниже: У нас есть шахматный конь и телефонная панель, как показано ниже, конь может стоять только на числовой клетке (то есть на синей клетке). Учитывая целое число n, верните, сколько различных телефонных номеров длины n мы можем набрать. Вам разрешается сначала поставить коня на любую цифровую клетку, а затем выполнить n - 1 прыжков, чтобы набрать номер длины n. Все прыжки должны быть правильными прыжками коня. Поскольку ответ может быть очень большим, верните ответ по модулю 10^9 + 7. Пример:
Input: n = 1
Output: 10
👨‍💻 Алгоритм: 1⃣Определить возможные движения коня с каждой цифровой клетки. Использовать динамическое программирование для хранения количества способов достижения каждой цифровой клетки на каждом шаге. 2⃣Инициализировать массив DP количеством способов набора телефонного номера длины 1 для каждой цифровой клетки (это просто 1). На каждом шаге обновлять массив DP, переходя по всем возможным движениям коня. 3⃣Вернуть сумму всех значений в массиве DP на последнем шаге. 😎 Решение:
public class Solution {
    public int KnightDialer(int n) {
        int MOD = 1000000007;
        int[][] moves = new int[][] {
            new int[] {4, 6},
            new int[] {6, 8},
            new int[] {7, 9},
            new int[] {4, 8},
            new int[] {0, 3, 9},
            new int[0],
            new int[] {0, 1, 7},
            new int[] {2, 6},
            new int[] {1, 3},
            new int[] {2, 4}
        };
        
        int[] dp = new int[10];
        Array.Fill(dp, 1);
        
        for (int step = 1; step < n; step++) {
            int[] newDp = new int[10];
            for (int i = 0; i < 10; i++) {
                foreach (int move in moves[i]) {
                    newDp[move] = (newDp[move] + dp[i]) % MOD;
                }
            }
            dp = newDp;
        }
        
        int sum = 0;
        foreach (int count in dp) {
            sum = (sum + count) % MOD;
        }
        return sum;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

2
Осталось 3 часа до конца акции: «Пожизненный PRO тариф — по цене 1 года» Поиск работы отнимает силы, время и веру в себя, но
Осталось 3 часа до конца акции: «Пожизненный PRO тариф — по цене 1 года» Поиск работы отнимает силы, время и веру в себя, но не у тех кто использует easyoffer PRO. Успей сделать самую выгодную инвестицию в развитие своей карьеры. Акция закончится уже сегодня 23 июня 23:59 по мск: 👉 https://easyoffer.ru/pro
81
3
Последний день акции: «Пожизненный PRO тариф — по цене 1 года» 🚀 PRO включает: – Полный доступ ко всем грейдам и профессиям
Последний день акции: «Пожизненный PRO тариф — по цене 1 года» 🚀 PRO включает: – Полный доступ ко всем грейдам и профессиям – База live-coding задач и вопросов из технических собеседований с вероятностью их встречи – Примеры лучших ответов от Senior разработчиков – 1100+ записи реальных собеседований, в том числе в топовые компании (Сбер, Авито, Яндекс, WB, OZON, МТС и др.) – База 400+ тестовых заданий от компаний. – Автоотклики на вакансии в хедхантер – Аналитика ТОП-требований из вакансий для лучшего написания резюме и прохождения ATS систем рекрутеров – Генератор уникального резюме и CV под каждую вакансию – Тренажеры подготовки к собеседованию: «Реальное собеседование» и «Проработка вопросов» по методике интервальных повторений (как Anki) – (скоро) Агрегатор вакансий – (скоро) Сообщество Акция закончится уже сегодня 23 июня 23:59 по мск: 👉 https://easyoffer.ru/pro
166
4
Задача: 684. Redundant Connection Сложность: medium В этой задаче дерево — это неориентированный граф, который является связным и не содержит циклов. Вам дан граф, который изначально был деревом с n узлами, пронумерованными от 1 до n, и к которому добавили одно дополнительное ребро. Добавленное ребро соединяет две разные вершины, выбранные из 1 до n, и это ребро не существовало ранее. Граф представлен массивом edges длины n, где edges[i] = [ai, bi] указывает на то, что существует ребро между узлами ai и bi в графе. Верните ребро, которое можно удалить, чтобы результирующий граф стал деревом из n узлов. Если существует несколько ответов, верните тот, который встречается последним в исходных данных. Пример: Input: edges = [[1,2],[1,3],[2,3]] Output: [2,3] 👨‍💻 Алгоритм: 1⃣Для каждого ребра (u, v) создайте представление графа с использованием списка смежности. Это позволит легко выполнять обход в глубину (DFS) для проверки соединений между узлами. 2⃣Выполняйте обход в глубину для каждого ребра, временно удаляя его из графа. Проверьте, можно ли соединить узлы u и v с помощью обхода в глубину. Если узлы остаются соединенными, значит, это ребро является дублирующимся. 3⃣Верните дублирующееся ребро, которое встречается последним в исходных данных. Это обеспечит корректность решения, даже если существует несколько ответов. 😎 Решение: using System; using System.Collections.Generic; public class Solution { HashSet<int> seen = new HashSet<int>(); const int MAX_EDGE_VAL = 1000; public int[] FindRedundantConnection(int[][] edges) { List<int>[] graph = new List<int>[MAX_EDGE_VAL + 1]; for (int i = 0; i <= MAX_EDGE_VAL; i++) { graph[i] = new List<int>(); } foreach (var edge in edges) { seen.Clear(); if (graph[edge[0]].Count > 0 && graph[edge[1]].Count > 0 && Dfs(graph, edge[0], edge[1])) { return edge; } graph[edge[0]].Add(edge[1]); graph[edge[1]].Add(edge[0]); } throw new InvalidOperationException("No redundant connection found"); } public bool Dfs(List<int>[] graph, int source, int target) { if (!seen.Contains(source)) { seen.Add(source); if (source == target) return true; foreach (int nei in graph[source]) { if (Dfs(graph, nei, target)) return true; } } return false; } } Ставь 👍 и забирай 📚 Базу знаний
172
5
Пожизненный PRO тариф — по цене 1 года. Покупаешь один раз — пользуешься всю жизнь: 👉 https://easyoffer.ru/pro 🚀 PRO-доступ
Пожизненный 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
162
6
Задача: 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. 😎 Решение: public class Solution { public int MinDeletionSize(string[] strs) { int count = 0; int rows = strs.Length; int cols = strs[0].Length; 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; } } Ставь 👍 и забирай 📚 Базу знаний
200
7
Задача: 1260. Shift 2D Grid Сложность: easy Дана двумерная сетка размером m x n и целое число k. Требуется сдвинуть сетку k раз. За одну операцию сдвига: элемент в grid[i][j] перемещается в grid[i][j + 1]. Элемент в grid[i][n - 1] перемещается в grid[i + 1][0]. Элемент в grid[m - 1][n - 1] перемещается в grid[0][0]. Верните двумерную сетку после применения операции сдвига k раз. Пример: Input: grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1 Output: [[9,1,2],[3,4,5],[6,7,8]] 👨‍💻 Алгоритм: 1⃣Преобразовать двумерную сетку в одномерный массив. 2⃣Выполнить сдвиг элементов в одномерном массиве. 3⃣Преобразовать одномерный массив обратно в двумерную сетку. 😎 Решение: public class Solution { public IList<IList<int>> ShiftGrid(int[][] grid, int k) { int m = grid.Length; int n = grid[0].Length; int total = m * n; k = k % total; if (k == 0) { return grid; } int[] flatArray = new int[total]; for (int i = 0; i < total; i++) { flatArray[i] = grid[i / n][i % n]; } int[] newArray = new int[total]; for (int i = 0; i < total; i++) { newArray[(i + k) % total] = flatArray[i]; } var newGrid = new List<IList<int>>(); for (int i = 0; i < m; i++) { var newRow = new List<int>(); for (int j = 0; j < n; j++) { newRow.Add(newArray[i * n + j]); } newGrid.Add(newRow); } return newGrid; } } Ставь 👍 и забирай 📚 Базу знаний
182
8
Привет, ребята! У нас для вас отличные новости — на easyoffer вышло сразу несколько крупных обновлений: 1. Автоотклики на HeadHunter Снова работают в полную силу — можно смело возвращаться к активному поиску. 2. Новый раздел «Резюмейкер» Теперь вы можете быстро создавать уникальные резюме, адаптированные под каждую вакансию, и сразу добавлять сопроводительное письмо. Это заметно повышает шансы получить приглашение на собеседование. 3. База вопросов стала чище Мы навели порядок и удалили около 30% дубликатов. Ориентироваться стало проще. –––––––––––––––––– 🔥 Акция в честь обновления Пожизненный тариф easyoffer PRO — по цене одного года. Успейте до 23 июня: 👉 https://easyoffer.ru/pro –––––––––––––––––– Что дальше? В ближайшие пару недель добавим ещё два раздела: 1. Сообщество с чатами по всем профессиональным направлениям. 2. Агрегатор вакансий, чтобы поиск работы стал ещё удобнее.
167
9
Задача: 507. Perfect Number Сложность: easy Совершенное число — это положительное целое число, которое равно сумме своих положительных делителей, исключая само число. Делитель целого числа x — это целое число, которое может делить x нацело. Дано целое число n, верните true, если n является совершенным числом, в противном случае верните false. Пример: Input: num = 28 Output: true Explanation: 28 = 1 + 2 + 4 + 7 + 14 1, 2, 4, 7, and 14 are all divisors of 28. 👨‍💻 Алгоритм: 1⃣Инициализация Если число num меньше или равно 0, вернуть false. Инициализируйте переменную sum значением 0. 2⃣Поиск делителей и вычисление суммы Переберите числа от 1 до квадратного корня num. Если число является делителем num, добавьте его к sum. Если делитель не равен квадратному корню num, добавьте к sum также результат деления num на делитель. 3⃣Проверка на совершенное число Вычтите num из sum. Если результат равен num, вернуть true, иначе вернуть false. 😎 Решение: public class Solution { public bool CheckPerfectNumber(int num) { if (num <= 0) return false; int sum = 0; for (int i = 1; i * i <= num; i++) { if (num % i == 0) { sum += i; if (i * i != num) { sum += num / i; } } } return sum - num == num; } } Ставь 👍 и забирай 📚 Базу знаний
171
10
Задача: 815. Bus Routes Сложность: hard Дан массив routes, представляющий автобусные маршруты, где routes[i] - это автобусный маршрут, который i-й автобус повторяет бесконечно. Например, если routes[0] = [1, 5, 7], это означает, что 0-й автобус путешествует в последовательности 1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ... бесконечно. Вы начинаете на автобусной остановке source (вы изначально не находитесь в автобусе) и хотите добраться до автобусной остановки target. Перемещаться между автобусными остановками можно только на автобусах. Верните наименьшее количество автобусов, которые вам нужно взять, чтобы доехать от source до target. Верните -1, если это невозможно. Пример: Input: routes = [[1,2,7],[3,6,7]], source = 1, target = 6 Output: 2 Explanation: The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6. 👨‍💻 Алгоритм: 1⃣Верните 0, если source и target совпадают. Инициализируйте пустую карту adjList, чтобы хранить ребра, где ключ - это автобусная остановка, а значение - список целых чисел, обозначающих индексы маршрутов, которые имеют эту остановку. Инициализируйте пустую очередь q и неупорядоченное множество vis, чтобы отслеживать посещенные маршруты. Вставьте начальные маршруты в очередь q и отметьте их посещенными в vis. 2⃣Итерация по очереди, пока она не пуста: извлеките маршрут из очереди, итерируйтесь по остановкам в маршруте. Если остановка равна target, верните busCount. В противном случае, итерируйтесь по маршрутам для этой остановки в карте adjList, добавьте непосещенные маршруты в очередь и отметьте их посещенными. 3⃣Верните -1 после завершения обхода в ширину (BFS). 😎 Решение: public class Solution { public int NumBusesToDestination(int[][] routes, int source, int target) { if (source == target) return 0; var adjList = new Dictionary<int, List<int>>(); for (int route = 0; route < routes.Length; route++) { foreach (int stop in routes[route]) { if (!adjList.ContainsKey(stop)) { adjList[stop] = new List<int>(); } adjList[stop].Add(route); } } var q = new Queue<int>(); var vis = new HashSet<int>(); foreach (int route in adjList.GetValueOrDefault(source, new List<int>())) { q.Enqueue(route); vis.Add(route); } int busCount = 1; while (q.Count > 0) { int size = q.Count; for (int i = 0; i < size; i++) { int route = q.Dequeue(); foreach (int stop in routes[route]) { if (stop == target) return busCount; foreach (int nextRoute in adjList.GetValueOrDefault(stop, new List<int>())) { if (!vis.Contains(nextRoute)) { vis.Add(nextRoute); q.Enqueue(nextRoute); } } } } busCount++; } return -1; } } Ставь 👍 и забирай 📚 Базу знаний
166
11
Задача: 258. Add Digits Сложность: easy Дано целое число num. Повторно складывайте все его цифры, пока результат не станет однозначным, и верните его. Пример: Input: num = 38 Output: 2 Explanation: The process is 38 --> 3 + 8 --> 11 11 --> 1 + 1 --> 2 Since 2 has only one digit, return it. 👨‍💻 Алгоритм: 1⃣Инициализируйте переменную digital_root значением 0. 2⃣В цикле, пока num больше 0: Добавьте к digital_root последнюю цифру num. Уменьшите num, удалив последнюю цифру. Если num равно 0 и digital_root больше 9, присвойте num значение digital_root и сбросьте digital_root в 0. 3⃣Верните значение digital_root. 😎 Решение: public class Solution { public int AddDigits(int num) { int digital_root = 0; while (num > 0) { digital_root += num % 10; num /= 10; if (num == 0 && digital_root > 9) { num = digital_root; digital_root = 0; } } return digital_root; } } Ставь 👍 и забирай 📚 Базу знаний
184
12
Задача: 868. Binary Gap Сложность: easy Дано положительное целое число n, найдите и верните наибольшее расстояние между любыми двумя соседними единицами в двоичном представлении числа n. Если нет двух соседних единиц, верните 0. Две единицы считаются соседними, если их разделяют только нули (возможно, никаких нулей нет). Расстояние между двумя единицами — это абсолютная разница между их позициями в битовом представлении. Например, две единицы в "1001" имеют расстояние 3. Пример: Input: n = 22 Output: 2 Explanation: 22 in binary is "10110". The first adjacent pair of 1's is "10110" with a distance of 2. The second adjacent pair of 1's is "10110" with a distance of 1. The answer is the largest of these two distances, which is 2. Note that "10110" is not a valid pair since there is a 1 separating the two 1's underlined. 👨‍💻 Алгоритм: 1⃣Создайте список A индексов i, таких что в двоичном представлении числа n i-й бит установлен в 1. 2⃣Используйте список A, чтобы найти максимальное расстояние между соседними значениями. Для этого пройдите по списку и вычислите разницу между каждым соседним элементом. 3⃣Верните найденное максимальное расстояние. 😎 Решение: public class Solution { public int BinaryGap(int N) { int[] A = new int[32]; int t = 0; for (int i = 0; i < 32; ++i) if (((N >> i) & 1) != 0) A[t++] = i; int ans = 0; for (int i = 0; i < t - 1; ++i) ans = Math.Max(ans, A[i + 1] - A[i]); return ans; } } Ставь 👍 и забирай 📚 Базу знаний
204
13
Задача: 1207. Unique Number of Occurrences Сложность: easy Дан массив целых чисел arr. Верните true, если количество вхождений каждого значения в массиве уникально, или false в противном случае. Пример: Input: arr = [1,2,2,1,1,3] Output: true Explanation: The value 1 has 3 occurrences, 2 has 2 and 3 has 1. No two values have the same number of occurrences. 👨‍💻 Алгоритм: 1⃣Сохраните частоты элементов массива arr в хэш-таблице freq. 2⃣Итерируйтесь по хэш-таблице freq и вставьте частоты всех уникальных элементов массива arr в хэш-набор freqSet. 3⃣Верните true, если размер хэш-набора freqSet равен размеру хэш-таблицы freq, иначе верните false. 😎 Решение: using System; using System.Collections.Generic; public class Solution { public bool UniqueOccurrences(int[] arr) { Dictionary<int, int> freq = new Dictionary<int, int>(); foreach (int num in arr) { if (freq.ContainsKey(num)) { freq[num]++; } else { freq[num] = 1; } } HashSet<int> freqSet = new HashSet<int>(freq.Values); return freq.Count == freqSet.Count; } } Ставь 👍 и забирай 📚 Базу знаний
210
14
Задача: 892. Surface Area of 3D Shapes Сложность: easy Вам дана сетка n x n, на которой вы разместили несколько кубиков 1 x 1 x 1. Каждое значение v = grid[i][j] представляет собой башню из v кубиков, размещенных на вершине ячейки (i, j). После размещения кубиков вы решили склеить все непосредственно прилегающие кубики друг с другом, образовав несколько неправильных 3D-фигур. Верните общую площадь поверхности получившихся фигур. Примечание: нижняя грань каждой фигуры учитывается в площади ее поверхности. Пример: Input: grid = [[1,2],[3,4]] Output: 34 👨‍💻 Алгоритм: 1⃣Пройти по всей сетке и для каждой башни (ячейки) посчитать начальную площадь поверхности: добавить площадь верхней и нижней граней, а также четыре боковые грани. 2⃣Для каждой башни уменьшить площадь боковых граней, которые прилегают к соседним башням, с учетом высоты соседних башен. 3⃣Просуммировать все значения площадей для получения итоговой площади поверхности. 😎 Решение: public int SurfaceArea(int[][] grid) { int n = grid.Length; int area = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] > 0) { area += (grid[i][j] * 4) + 2; } if (i > 0) { area -= Math.Min(grid[i][j], grid[i-1][j]) * 2; } if (j > 0) { area -= Math.Min(grid[i][j], grid[i][j-1]) * 2; } } } return area; } Ставь 👍 и забирай 📚 Базу знаний
212
15
Задача: 605. Can Place Flowers Сложность: Easy У вас есть длинная клумба, на которой некоторые участки засажены, а некоторые нет. Однако цветы нельзя сажать на соседних участках. Дан целочисленный массив flowerbed, содержащий 0 и 1, где 0 означает пустой участок, а 1 — занятый участок, и целое число n. Верните true, если n новых цветов можно посадить на клумбе, не нарушая правила о соседних цветах, и false в противном случае. Пример: Input: flowerbed = [1,0,0,0,1], n = 1 Output: true 👨‍💻 Алгоритм: 1⃣Решение очень простое. Мы можем определить максимальное количество дополнительных цветов, count, которые можно посадить для данного расположения клумбы. Для этого мы проходим по всем элементам массива flowerbed и находим те элементы, которые равны 0 (означает пустую позицию). 2⃣Для каждого такого элемента проверяем, пусты ли обе его соседние позиции. Если да, мы можем посадить цветок в текущей позиции, не нарушая правило соседних цветов. Для первого и последнего элементов не нужно проверять предыдущие и следующие соседние позиции соответственно. 3⃣Если полученное количество count больше или равно n, требуемому количеству цветов для посадки, мы можем посадить n цветов на пустые места, иначе - нет. 😎 Решение: public class Solution { public bool CanPlaceFlowers(int[] flowerbed, int n) { int count = 0; for (int i = 0; i < flowerbed.Length; i++) { if (flowerbed[i] == 0) { bool emptyLeft = i == 0 || flowerbed[i - 1] == 0; bool emptyRight = i == flowerbed.Length - 1 || flowerbed[i + 1] == 0; if (emptyLeft && emptyRight) { flowerbed[i] = 1; count++; } } } return count >= n; } } Ставь 👍 и забирай 📚 Базу знаний
205
16
Задача: 527. Word Abbreviation Сложность: hard Дано массив уникальных строк words, верните минимально возможные сокращения для каждого слова. Правила сокращения строки следующие: Первоначальное сокращение для каждого слова: первый символ, затем количество символов между первым и последним символом, затем последний символ. Если более одного слова имеют одинаковое сокращение, выполните следующее: Увеличьте префикс (символы в первой части) каждого из их сокращений на 1. Например, начнем с слов ["abcdef", "abndef"], оба изначально сокращены как "a4f". Последовательность операций будет следующей: ["a4f", "a4f"] -> ["ab3f", "ab3f"] -> ["abc2f", "abn2f"]. Эта операция повторяется до тех пор, пока каждое сокращение не станет уникальным. В конце, если сокращение не сделало слово короче, оставьте его в исходном виде. Пример: Input: words = ["like","god","internal","me","internet","interval","intension","face","intrusion"] Output: ["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"] 👨‍💻 Алгоритм: 1⃣ Инициализация и создание начальных сокращений: Создайте массив для хранения сокращений и массив для отслеживания длины префикса каждого слова. Для каждого слова создайте начальное сокращение с использованием первого символа, количества символов между первым и последним символом и последнего символа. 2⃣ Обработка коллизий: Для каждого слова проверьте, не совпадает ли его сокращение с уже существующими сокращениями. Если сокращение не уникально, увеличьте длину префикса и повторите проверку. 3⃣ Возврат результата: Верните окончательные сокращения для каждого слова, убедившись, что они минимально возможны и уникальны. 😎 Решение: public class Solution { public IList<string> WordsAbbreviation(IList<string> words) { int n = words.Count; string[] ans = new string[n]; int[] prefix = new int[n]; for (int i = 0; i < n; ++i) ans[i] = Abbrev(words[i], 0); for (int i = 0; i < n; ++i) { while (true) { HashSet<int> dupes = new HashSet<int>(); for (int j = i + 1; j < n; ++j) { if (ans[i] == ans[j]) dupes.Add(j); } if (dupes.Count == 0) break; dupes.Add(i); foreach (int k in dupes) ans[k] = Abbrev(words[k], ++prefix[k]); } } return ans.ToList(); } private string Abbrev(string word, int i) { int n = word.Length; if (n - i <= 3) return word; return word.Substring(0, i + 1) + (n - i - 2) + word[n - 1]; } } Ставь 👍 и забирай 📚 Базу знаний
200
17
Задача: 762. Prime Number of Set Bits in Binary Representation Сложность: hard Если даны два целых числа left и right, верните количество чисел в диапазоне [left, right], имеющих простое число битов в двоичном представлении. Напомним, что число битов в двоичном представлении - это количество единиц, присутствующих в числе 1. Например, 21 в двоичном представлении - это 10101, которое имеет 3 бита. Пример: Input: left = 10, right = 15 Output: 5 👨‍💻 Алгоритм: 1⃣Создайте функцию для подсчета количества единиц в двоичном представлении числа. 2⃣Создайте функцию для проверки, является ли число простым. 3⃣Пройдите через все числа в диапазоне [left, right] и подсчитайте числа, у которых количество битов в двоичном представлении является простым числом. 😎 Решение: public class Solution { public int CountPrimeSetBits(int left, int right) { int count = 0; for (int num = left; num <= right; num++) { if (IsPrime(BitCount(num))) { count++; } } return count; } private int BitCount(int x) { int count = 0; while (x > 0) { count += x & 1; x >>= 1; } return count; } private bool IsPrime(int x) { if (x < 2) return false; for (int i = 2; i * i <= x; i++) { if (x % i == 0) return false; } return true; } } Ставь 👍 и забирай 📚 Базу знаний
230
18
Задача: 1114. Print in Order Сложность: easy Предположим, у нас есть класс: public class Foo { public void first() { print("first"); } public void second() { print("second"); } public void third() { print("third"); } } Один и тот же экземпляр Foo будет передан трем разным потокам. Поток A вызовет first(), поток B вызовет second(), и поток C вызовет third(). Спроектируйте механизм и модифицируйте программу, чтобы гарантировать, что second() выполняется после first(), а third() выполняется после second(). Примечание: Мы не знаем, как потоки будут планироваться в операционной системе, даже если числа в вводе подразумевают порядок выполнения. Формат ввода, который вы видите, в основном предназначен для обеспечения полноты наших тестов. Пример: Input: nums = [1,2,3] Output: "firstsecondthird" Explanation: There are three threads being fired asynchronously. The input [1,2,3] means thread A calls first(), thread B calls second(), and thread C calls third(). "firstsecondthird" is the correct output. 👨‍💻 Алгоритм: 1⃣Инициализация переменных: Инициализируйте координационные переменные firstJobDone и secondJobDone, чтобы указать, что задания еще не выполнены. 2⃣Функция first(): В этой функции нет зависимости, поэтому можно сразу приступить к выполнению задания. В конце функции обновите переменную firstJobDone, чтобы указать, что первое задание выполнено. 3⃣Функции second() и third(): В функции second() проверьте статус firstJobDone. Если она не обновлена, подождите, иначе переходите к выполнению второго задания. В конце функции обновите переменную secondJobDone, чтобы отметить завершение второго задания. В функции third() проверьте статус secondJobDone. Аналогично функции second(), подождите сигнала secondJobDone перед тем, как приступить к выполнению третьего задания. 😎 Решение: using System; using System.Threading; public class Foo { private SemaphoreSlim firstJobDone = new SemaphoreSlim(0, 1); private SemaphoreSlim secondJobDone = new SemaphoreSlim(0, 1); public void First(Action printFirst) { printFirst(); firstJobDone.Release(); } public void Second(Action printSecond) { firstJobDone.Wait(); printSecond(); secondJobDone.Release(); } public void Third(Action printThird) { secondJobDone.Wait(); printThird(); } } Ставь 👍 и забирай 📚 Базу знаний
262
19
Задача: 55. Jump Game Сложность: medium Дан массив nums, где nums[i] — максимальная длина прыжка из позиции i. Нужно определить, можно ли добраться до последнего индекса. Пример: Input: nums = [2,3,1,1,4] Output: true Explanation: Прыгаем 1 шаг с `0` на `1`, затем 3 шага на последний индекс. 👨‍💻 Алгоритм: 1⃣Завести переменную maxReach— максимальное положение, до которого можно допрыгнуть. 2⃣Идти по массиву, обновляясь maxReachна каждом шаге. 3⃣Если текущий индекс рассчитывается maxReach— путь прерывается, иначе возвращается true при выполнении конца. 😎 Решение: public class Solution { public bool CanJump(int[] nums) { int maxReach = 0; for (int i = 0; i < nums.Length; i++) { if (i > maxReach) return false; maxReach = Math.Max(maxReach, i + nums[i]); if (maxReach >= nums.Length - 1) return true; } return false; } } Ставь 👍 и забирай 📚 Базу знаний
372
20
Задача: 635. Design Log Storage System Сложность: medium Вам дается несколько журналов, где каждый журнал содержит уникальный идентификатор и временную метку. Временная метка - это строка, имеющая следующий формат: Год:Месяц:День:Час:Минута:Секунда, например, 2017:01:01:23:59:59. Все домены - десятичные числа с нулевым добавлением. Реализация класса LogSystem: LogSystem() Инициализирует объект LogSystem. void put(int id, string timestamp) Сохраняет заданный журнал (id, timestamp) в вашей системе хранения. int[] retrieve(string start, string end, string granularity) Возвращает идентификаторы журналов, временные метки которых находятся в диапазоне от start до end включительно. start и end имеют тот же формат, что и timestamp, а granularity означает, насколько точным должен быть диапазон (т. е. с точностью до дня, минуты и т. д.). Например, start = "2017:01:01:23:59:59", end = "2017:01:02:23:59:59", а granularity = "Day" означает, что нам нужно найти журналы в диапазоне от 1 января 2017 года до 2 января 2017 года включительно, а час, минуту и секунду для каждой записи журнала можно игнорировать. Пример: Input ["LogSystem", "put", "put", "put", "retrieve", "retrieve"] [[], [1, "2017:01:01:23:59:59"], [2, "2017:01:01:22:59:59"], [3, "2016:01:01:00:00:00"], ["2016:01:01:01:01:01", "2017:01:01:23:00:00", "Year"], ["2016:01:01:01:01:01", "2017:01:01:23:00:00", "Hour"]] Output [null, null, null, null, [3, 2, 1], [2, 1]] 👨‍💻 Алгоритм: 1⃣Инициализация и хранение журналов Реализуйте метод put, который будет сохранять журнал с заданным id и timestamp в системе хранения. 2⃣Формирование диапазона Реализуйте метод retrieve, который будет формировать диапазон временных меток на основе заданного start, end и granularity. 3⃣Фильтрация и возврат результатов Используйте сформированный диапазон для фильтрации журналов и возврата идентификаторов тех журналов, чьи временные метки попадают в этот диапазон. 😎 Решение: using System; using System.Collections.Generic; public class LogSystem { private List<LogEntry> logs; public LogSystem() { logs = new List<LogEntry>(); } public void Put(int id, string timestamp) { logs.Add(new LogEntry(id, timestamp)); } public IList<int> Retrieve(string start, string end, string granularity) { int index = GetGranularityIndex(granularity); string startPrefix = start.Substring(0, index); string endPrefix = end.Substring(0, index); List<int> result = new List<int>(); foreach (var log in logs) { string timestampPrefix = log.Timestamp.Substring(0, index); if (startPrefix.CompareTo(timestampPrefix) <= 0 && timestampPrefix.CompareTo(endPrefix) <= 0) { result.Add(log.Id); } } return result; } private int GetGranularityIndex(string granularity) { switch (granularity) { case "Year": return 4; case "Month": return 7; case "Day": return 10; case "Hour": return 13; case "Minute": return 16; case "Second": return 19; default: return 19; } } private class LogEntry { public int Id { get; } public string Timestamp { get; } public LogEntry(int id, string timestamp) { Id = id; Timestamp = timestamp; } } } Ставь 👍 и забирай 📚 Базу знаний
302