uz
Feedback
Java | LeetCode

Java | LeetCode

Kanalga Telegram’da o‘tish
6 661
Obunachilar
-424 soatlar
-177 kunlar
-4530 kunlar
Postlar arxiv
Задача: №29. Divide Two Integers Сложность: medium Даны два целых числа dividend и divisor. Выполните деление без использования операторов *, /, %. Результат должен быть усечён до целого и находиться в пределах 32-битного целого числа. Пример:
Input: dividend = 10, divisor = 3 Output: 3
Input: dividend = 7, divisor = -3 Output: -2
👨‍💻 Алгоритм: 1⃣Определить знак результата и привести dividend и divisor к положительным значениям типа long, чтобы избежать переполнения и упростить работу с отрицательными числами. 2⃣Найти максимальное кратное делителя (удваивая divisor и счётчик divide), не превышающее dividend. 3⃣Рекурсивно вызвать деление для остатка dividend - sum, сложить с текущим divide и вернуть результат с учётом знака. 😎 Решение:
public class Solution {
    public int divide(int dividend, int divisor) {
        long result = divideLong(dividend, divisor);
        return result > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)result;
    }

    private long divideLong(long dividend, long divisor) {
        boolean negative = dividend < 0 != divisor < 0;

        dividend = Math.abs(dividend);
        divisor = Math.abs(divisor);

        if (dividend < divisor) return 0;

        long sum = divisor;
        long divide = 1;
        while ((sum + sum) <= dividend) {
            sum += sum;
            divide += divide;
        }

        long remaining = divideLong(dividend - sum, divisor);
        return negative ? -(divide + remaining) : (divide + remaining);
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 417. Pacific Atlantic Water Flow Сложность: medium Имеется прямоугольный остров размером m x n, который граничит с Ти
Задача: 417. Pacific Atlantic Water Flow Сложность: medium Имеется прямоугольный остров размером m x n, который граничит с Тихим и Атлантическим океанами. Тихий океан касается левого и верхнего краев острова, а Атлантический океан - правого и нижнего краев. Остров разбит на сетку квадратных ячеек. Вам дана целочисленная матрица heights размером m x n, где heights[r][c] - высота над уровнем моря клетки с координатами (r, c). На острове выпадает много осадков, и дождевая вода может стекать в соседние клетки прямо на север, юг, восток и запад, если высота соседней клетки меньше или равна высоте текущей клетки. Вода может течь из любой клетки, прилегающей к океану, в океан. Верните двумерный список координат сетки result, где result[i] = [ri, ci] означает, что дождевая вода может течь из клетки (ri, ci) как в Тихий, так и в Атлантический океаны. Пример:
Input: heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]
Output: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]]
👨‍💻 Алгоритм: 1⃣Определите две матрицы для отслеживания клеток, из которых вода может течь в Тихий и Атлантический океаны, используя поиск в глубину (DFS) или поиск в ширину (BFS), начиная с границ, примыкающих к каждому океану. 2⃣Выполните поиск для каждого океана, обновляя матрицы достижимости. 3⃣Соберите координаты клеток, которые могут стекать в оба океана, проверяя пересечение двух матриц достижимости. 😎 Решение:
import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<List<Integer>> pacificAtlantic(int[][] heights) {
        int m = heights.length;
        int n = heights[0].length;
        boolean[][] pacific = new boolean[m][n];
        boolean[][] atlantic = new boolean[m][n];
        int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        
        for (int i = 0; i < m; i++) {
            dfs(i, 0, pacific, heights, directions);
            dfs(i, n - 1, atlantic, heights, directions);
        }
        for (int j = 0; j < n; j++) {
            dfs(0, j, pacific, heights, directions);
            dfs(m - 1, j, atlantic, heights, directions);
        }
        
        List<List<Integer>> result = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (pacific[i][j] && atlantic[i][j]) {
                    List<Integer> cell = new ArrayList<>();
                    cell.add(i);
                    cell.add(j);
                    result.add(cell);
                }
            }
        }
        return result;
    }
    
    private void dfs(int r, int c, boolean[][] ocean, int[][] heights, int[][] directions) {
        ocean[r][c] = true;
        for (int[] dir : directions) {
            int nr = r + dir[0], nc = c + dir[1];
            if (nr >= 0 && nc >= 0 && nr < heights.length && nc < heights[0].length && !ocean[nr][nc] && heights[nr][nc] >= heights[r][c]) {
                dfs(nr, nc, ocean, heights, directions);
            }
        }
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 965. Univalued Binary Tree Сложность: easy Бинарное дерево является одноценным, если каждый узел в дереве имеет одинаковое значение. Дан корень бинарного дерева, верните true, если данное дерево является одноценным, или false в противном случае. Пример:
Input: root = [1,1,1,1,1,null,1]
Output: true
👨‍💻 Алгоритм: 1⃣Выполните обход дерева в глубину (DFS), чтобы собрать все значения узлов в список. 2⃣Проверьте, что все значения в списке одинаковы. 3⃣Если все значения одинаковы, верните true, иначе верните false. 😎 Решение:
class Solution {
    List<Integer> vals;
    public boolean isUnivalTree(TreeNode root) {
        vals = new ArrayList();
        dfs(root);
        for (int v: vals)
            if (v != vals.get(0))
                return false;
        return true;
    }

    public void dfs(TreeNode node) {
        if (node != null) {
            vals.add(node.val);
            dfs(node.left);
            dfs(node.right);
        }
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 959. Regions Cut By Slashes Сложность: medium n x n сетка состоит из квадратов размером 1 x 1, где каждый квадрат 1 x 1 содержит '/', '', или пустое пространство ' '. Эти символы делят квадрат на смежные области. Дана сетка grid, представленная в виде строкового массива. Верните количество областей. Обратите внимание, что обратные слеши экранированы, поэтому '' представлен как '\'. Пример:
Input: grid = [" /","/ "]
Output: 2
👨‍💻 Алгоритм: 1⃣Создайте 4*N*N узлов для каждой ячейки сетки и соедините их в соответствии с описанием. 2⃣Используйте структуру объединения-поиска (DSU), чтобы найти количество связанных компонентов. 3⃣Пройдите по всем узлам и посчитайте количество корневых узлов, которые представляют количество областей. 😎 Решение:
class Solution {
    public int regionsBySlashes(String[] grid) {
        int N = grid.length;
        DSU dsu = new DSU(4 * N * N);
        for (int r = 0; r < N; ++r)
            for (int c = 0; c < N; ++c) {
                int root = 4 * (r * N + c);
                char val = grid[r].charAt(c);
                if (val != '\\') {
                    dsu.union(root + 0, root + 1);
                    dsu.union(root + 2, root + 3);
                }
                if (val != '/') {
                    dsu.union(root + 0, root + 2);
                    dsu.union(root + 1, root + 3);
                }

                if (r + 1 < N)
                    dsu.union(root + 3, (root + 4 * N) + 0);
                if (r - 1 >= 0)
                    dsu.union(root + 0, (root - 4 * N) + 3);
                if (c + 1 < N)
                    dsu.union(root + 2, (root + 4) + 1);
                if (c - 1 >= 0)
                    dsu.union(root + 1, (root - 4) + 2);
            }

        int ans = 0;
        for (int x = 0; x < 4 * N * N; ++x) {
            if (dsu.find(x) == x)
                ans++;
        }

        return ans;
    }
}

class DSU {
    int[] parent;
    public DSU(int N) {
        parent = new int[N];
        for (int i = 0; i < N; ++i)
            parent[i] = i;
    }
    public int find(int x) {
        if (parent[x] != x) parent[x] = find(parent[x]);
        return parent[x];
    }
    public void union(int x, int y) {
        parent[find(x)] = find(y);
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 299. Bulls and Cows Сложность: medium Вы играете в игру "Быки и коровы" со своим другом. Вы записываете секретное чис
Задача: 299. Bulls and Cows Сложность: medium Вы играете в игру "Быки и коровы" со своим другом. Вы записываете секретное число и просите своего друга угадать, что это за число. Когда ваш друг делает предположение, вы даете ему подсказку со следующей информацией: Количество "быков", то есть цифры в предположении, которые находятся на правильной позиции. Количество "коров", то есть цифры в предположении, которые есть в вашем секретном числе, но находятся на неправильной позиции. Конкретно, это не-бычьи цифры в предположении, которые можно переставить так, чтобы они стали быками. Дано секретное число secret и предположение вашего друга guess, верните подсказку для предположения вашего друга. Подсказка должна быть в формате "xAyB", где x — количество быков, а y — количество коров. Обратите внимание, что и secret, и guess могут содержать повторяющиеся цифры. Пример:
Input: secret = "1807", guess = "7810"
Output: "1A3B"
Explanation: Bulls are connected with a '|' and cows are underlined:
"1807"
  |
"7810"
👨‍💻 Алгоритм: 1⃣Инициализация счетчиков: Инициализируйте количество быков и коров значениями ноль. Создайте хеш-таблицу для хранения символов строки secret и их частот. 2⃣Обход строки guess: Для каждого символа ch в строке guess: Если ch присутствует в строке secret: Если текущий символ ch совпадает с символом на той же позиции в secret (ch == secret[idx]): Увеличьте количество быков: bulls += 1. Обновите количество коров, если количество текущего символа в хеш-таблице отрицательное или равно нулю (то есть этот символ уже использовался для коров): cows -= int(h[ch] <= 0). Если текущий символ ch не совпадает с символом на той же позиции в secret (ch != secret[idx]): Увеличьте количество коров, если количество текущего символа в хеш-таблице больше нуля: cows += int(h[ch] > 0). Обновите хеш-таблицу, помечая текущий символ как использованный: h[ch] -= 1. 3⃣Возврат результата: Верните количество быков и коров в формате "xAyB". 😎 Решение:
import java.util.HashMap;
import java.util.Map;

class Solution {
    public String getHint(String secret, String guess) {
        Map<Character, Integer> h = new HashMap<>();
        for (char ch : secret.toCharArray()) {
            h.put(ch, h.getOrDefault(ch, 0) + 1);
        }

        int bulls = 0;
        int cows = 0;
        int n = guess.length();
        char[] secretArray = secret.toCharArray();
        char[] guessArray = guess.toCharArray();

        for (int idx = 0; idx < n; idx++) {
            char ch = guessArray[idx];
            if (h.containsKey(ch)) {
                if (ch == secretArray[idx]) {
                    bulls++;
                    if (h.get(ch) <= 0) {
                        cows--;
                    }
                } else {
                    if (h.get(ch) > 0) {
                        cows++;
                    }
                }
                h.put(ch, h.get(ch) - 1);
            }
        }

        return bulls + "A" + cows + "B";
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Как навести порядок в работе? ✅ Вместо личных чатов — мессенджер только для коллег. ✅ Вместо ссылки на созвон и долгих поиско
Как навести порядок в работе? ✅ Вместо личных чатов — мессенджер только для коллег. ✅ Вместо ссылки на созвон и долгих поисков слотов — планерка в один клик. ✅ Вместо задачи на почте — задачка в трекере с четким чек-листом. ✅ Вместо страха белого листа — смелый креатив и рекомендации от ИИ-помощника. Вместо десятка программ — один Битрикс24. Зарегистрироваться #реклама 16+ office-online.bitrix24.ru О рекламодателе

Задача: 100. Same Tree Сложность: easy Даны корни двух бинарных деревьев p и q. Напишите функцию, чтобы проверить, одинаковы
Задача: 100. Same Tree Сложность: easy Даны корни двух бинарных деревьев p и q. Напишите функцию, чтобы проверить, одинаковы ли они. Два бинарных дерева считаются одинаковыми, если они структурно идентичны, и узлы имеют одинаковые значения. Пример:
Input: p = [1,2,3], q = [1,2,3]
Output: true
👨‍💻 Алгоритм: 1⃣Проверяем базовый случай: если оба узла p и q равны null, то они одинаковые. 2⃣Если один из узлов null, а другой нет — деревья различаются. 3⃣Если значения текущих узлов не совпадают — тоже возвращаем false. Иначе рекурсивно проверяем левое и правое поддерево. 😎 Решение:
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) return true;
        if (q == null || p == null) return false;
        if (p.val != q.val) return false;
        return isSameTree(p.right, q.right) && isSameTree(p.left, q.left);
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Как frontend-разработчику получить оффер в Bigtech? Ты вроде бы уже не джун, но всё равно чувствуешь, что топчешься на месте?
Как frontend-разработчику получить оффер в Bigtech? Ты вроде бы уже не джун, но всё равно чувствуешь, что топчешься на месте? Рынок перегрет, требований всё больше, а откликов — всё меньше? На собесах валят на алгоритмах или просят "нарисовать" архитектуру, как будто ты ведущий. При этом вокруг кто-то постоянно получает офферы в Яндекс или VK, а у тебя не получается даже дойти до финального этапа? Хочется стабильности, интересных задач и наконец-то попасть в сильную команду... Меня зовут Тихон, привет! Я — действующий Frontend-разработчик и ментор. Помогаю устроиться на хорошие позиции в Bigtech и сопровождаю на испытательном сроке. В своем канале: 👉 публикую видео с решением задач, которые прямо сейчас дают крупные компании на собеседованиях 👉даю примеры по прохождению собеседований 👉разбираю резюме и докручиваю резюме подписчиков 👉и просто создаю дружелюбное, комфортное сообщество, где коллеги всегда готовы подсказать и поддержать 🎁В закрепе тебя ждёт подборка из 60 задач, которые сейчас дают на собеседованиях Яндекс, Т-Банк и другие крупные IT игроки. Подписывайся и получай максимум пользы, а нас уже больше 3500 🤓: frontend_punks Реклама, erid:2W5zFGgUJCQ ИП Галактионов Тихон Витальевич, ИНН 771618975809

Задача: 948. Bag of Tokens Сложность: medium Вы начинаете с начальной силой, равной power, начальным счетом 0 и мешком жетонов, представленным в виде целочисленного массива tokens, где каждый tokens[i] обозначает значение tokeni. Ваша цель - максимизировать общее количество очков, стратегически разыгрывая эти жетоны. За один ход вы можете разыграть неразыгранный жетон одним из двух способов (но не обоими для одного и того же жетона): лицом вверх: Если ваша текущая сила не меньше жетонов[i], вы можете сыграть токени, потеряв силу жетонов[i] и получив 1 очко. Лицом вниз: Если ваш текущий счет не меньше 1, вы можете сыграть токени, получив силу токенов[i] и потеряв 1 счет. Верните максимально возможный счет, который вы можете получить, сыграв любое количество токенов. Пример:
Input: tokens = [100], power = 50

Output: 0
👨‍💻 Алгоритм: 1⃣Отсортировать массив tokens. Использовать два указателя: left и right, чтобы отслеживать начало и конец массива токенов. Инициализировать переменные для текущей силы power, текущего счета score и максимального счета maxScore 2⃣Повторять следующие шаги, пока left не превысит right: Если текущая сила power достаточна для разыгрывания токена tokens[left] лицом вверх, разыграть его и увеличить счет. Если текущая сила недостаточна, но счет больше 0, разыграть токен tokens[right] лицом вниз и уменьшить счет. Обновить максимальный счет, если текущий счет больше максимального. 3⃣Вернуть максимальный счет. 😎 Решение:
import java.util.Arrays;

class Solution {
    public int bagOfTokensScore(int[] tokens, int power) {
        Arrays.sort(tokens);
        int left = 0, right = tokens.length - 1;
        int score = 0, maxScore = 0;
        
        while (left <= right) {
            if (power >= tokens[left]) {
                power -= tokens[left];
                score++;
                left++;
                maxScore = Math.max(maxScore, score);
            } else if (score > 0) {
                power += tokens[right];
                score--;
                right--;
            } else {
                break;
            }
        }
        
        return maxScore;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

В Битрикс24 теперь можно сделать сайт за 30 секунд Серьёзно. Пишешь, что нужно, и AI сам всё собирает: тексты, картинки, офор
В Битрикс24 теперь можно сделать сайт за 30 секунд Серьёзно. Пишешь, что нужно, и AI сам всё собирает: тексты, картинки, оформление. ✨Никакой магии, просто умный помощник. Попробуйте — закайфуете от скорости! Попробовать #реклама 16+ sites-24.bitrix24.ru О рекламодателе

Задача: 300. Longest Increasing Subsequence Сложность: medium Дан массив целых чисел nums, верните длину самой длинной строго возрастающей подпоследовательности. Пример:
Input: nums = [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
👨‍💻 Алгоритм: 1⃣Инициализируйте массив dp длиной nums.length, все элементы которого равны 1. dp[i] представляет длину самой длинной возрастающей подпоследовательности, которая заканчивается элементом с индексом i. 2⃣Итерируйтесь от i = 1 до i = nums.length - 1. В каждой итерации используйте второй цикл for для итерации от j = 0 до j = i - 1 (все элементы перед i). Для каждого элемента перед i, проверьте, меньше ли этот элемент, чем nums[i]. Если да, установите dp[i] = max(dp[i], dp[j] + 1). 3⃣Верните максимальное значение из dp. 😎 Решение:
class Solution {
    public int lengthOfLIS(int[] nums) {
        if (nums.length == 0) return 0;

        int[] dp = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1;
        }

        for (int i = 1; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
        }

        int maxLength = 0;
        for (int length : dp) {
            maxLength = Math.max(maxLength, length);
        }

        return maxLength;
    }
Ставь 👍 и забирай 📚 Базу знаний

Задача: 1002. Find Common Characters Сложность: easy Если задан массив строк words, верните массив всех символов, которые встречаются во всех строках внутри слов (включая дубликаты). Вы можете вернуть ответ в любом порядке. Пример:
Input: words = ["bella","label","roller"]
Output: ["e","l","l"]
👨‍💻 Алгоритм: 1⃣Инициализация частотного массива: Создайте массив для хранения минимальной частоты каждого символа, который будет встречаться во всех словах. 2⃣Обработка каждого слова: Для каждого слова создайте временный массив для хранения частоты каждого символа в этом слове. Обновите основной частотный массив, сравнивая его с временным массивом и сохраняя минимальные частоты каждого символа. 3⃣Формирование результата: Создайте результирующий массив, добавляя каждый символ столько раз, сколько его минимальная частота. 😎 Решение:
public class Solution {
    public List<String> commonChars(String[] words) {
        int[] minFreq = new int[26];
        Arrays.fill(minFreq, Integer.MAX_VALUE);
        
        for (String word : words) {
            int[] freq = new int[26];
            for (char c : word.toCharArray()) {
                freq[c - 'a']++;
            }
            for (int i = 0; i < 26; i++) {
                minFreq[i] = Math.min(minFreq[i], freq[i]);
            }
        }
        
        List<String> result = new ArrayList<>();
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < minFreq[i]; j++) {
                result.add(Character.toString((char)('a' + i)));
            }
        }
        return result;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 1120. Maximum Average Subtree Сложность: medium Дан корень бинарного дерева. Верните максимальное среднее значение поддерева этого дерева. Ответы, отличающиеся от фактического ответа не более чем на 10^-5, будут приняты. Поддерево дерева — это любой узел этого дерева плюс все его потомки. Среднее значение дерева — это сумма его значений, деленная на количество узлов. Пример:
Input: root = [5,6,1]
Output: 6.00000
Explanation: 
For the node with value = 5 we have an average of (5 + 6 + 1) / 3 = 4.
For the node with value = 6 we have an average of 6 / 1 = 6.
For the node with value = 1 we have an average of 1 / 1 = 1.
So the answer is 6 which is the maximum.
👨‍💻 Алгоритм: 1⃣Инициализация и определение State: Определите класс State для хранения количества узлов в поддереве, суммы значений узлов в поддереве и максимального среднего значения поддерева. 2⃣Постобход (postorder traversal): Реализуйте функцию maxAverage, которая выполняет постобход дерева, вычисляя nodeCount, valueSum и maxAverage для каждого узла, начиная с дочерних узлов и продвигаясь к родительским узлам. 3⃣Вычисление максимального среднего значения: Используйте значения, полученные от дочерних узлов, для вычисления среднего значения для текущего узла и обновите maxAverage, если новое среднее значение больше текущего максимума. 😎 Решение:
class Solution {
    class State {
        int nodeCount;

        int valueSum;

        double maxAverage;

        State(int nodes, int sum, double maxAverage) {
            this.nodeCount = nodes;
            this.valueSum = sum;
            this.maxAverage = maxAverage;
        }
    }

    public double maximumAverageSubtree(TreeNode root) {
        return maxAverage(root).maxAverage;
    }

    State maxAverage(TreeNode root) {
        if (root == null) {
            return new State(0, 0, 0);
        }

        State left = maxAverage(root.left);
        State right = maxAverage(root.right);

        int nodeCount = left.nodeCount + right.nodeCount + 1;
        int sum = left.valueSum + right.valueSum + root.val;
        double maxAverage = Math.max(
                (1.0 * (sum)) / nodeCount,
                Math.max(right.maxAverage, left.maxAverage)
        );

        return new State(nodeCount, sum, maxAverage);
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 600. Non-negative Integers without Consecutive Ones Сложность: hard Дано положительное целое число n, верните количество чисел в диапазоне [0, n], бинарные представления которых не содержат последовательных единиц. Пример:
Input: n = 5
Output: 5
Explanation:
Here are the non-negative integers <= 5 with their corresponding binary representations:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule. 
👨‍💻 Алгоритм: 1⃣Простой метод заключается в переборе всех чисел от 1 до num. Для каждого текущего выбранного числа проверяем все соседние позиции, чтобы выяснить, содержит ли число две последовательные единицы. Если не содержит, увеличиваем количество чисел без последовательных единиц. 2⃣Чтобы проверить, существует ли 1 на позиции x (считая от младшего значащего бита), в текущем числе n, поступаем следующим образом. Сдвигаем двоичную 1 x−1 раз влево, чтобы получить число y, которое имеет 1 только на x-й позиции. Логическое И числа n и y даст результат 1 только если n содержит 1 на позиции x. 3⃣В конце подсчитываем и возвращаем количество чисел в диапазоне [0, n], не содержащих последовательных единиц. 😎 Решение:
public class Solution {
    public int findIntegers(int num) {
        int count = 0;
        for (int i = 0; i <= num; i++) {
            if (check(i)) {
                count++;
            }
        }
        return count;
    }

    public boolean check(int n) {
        int i = 31;
        while (i > 0) {
            if ((n & (1 << i)) != 0 && (n & (1 << (i - 1))) != 0) {
                return false;
            }
            i--;
        }
        return true;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: №44. Wildcard Matching Сложность: hard Учитывая входную строку s и шаблон p, реализуйте сопоставление шаблонов с подстановочными знаками с поддержкой: - '?' — соответствует любому одному символу - '*' — соответствует любой последовательности символов (включая пустую) Сопоставление должно охватывать всю строку s. Пример:
Input: s = "adceb", p = "*a*b" Output: true
👨‍💻 Алгоритм: 1⃣Создать двумерный булев массив dp размером (s.length + 1) × (p.length + 1), где dp[i][j] — true, если s[0..i-1] соответствует p[0..j-1]. 2⃣Инициализировать базовые случаи: - dp[0][0] = true - dp[0][j] = true, если p[0..j-1] состоит только из * (иначе — false) 3⃣Заполнить таблицу: - Если p[j-1] == s[i-1] или p[j-1] == '?'dp[i][j] = dp[i-1][j-1] - Если p[j-1] == '*'dp[i][j] = dp[i][j-1] || dp[i-1][j] - Иначе → dp[i][j] = false 😎 Решение:
class Solution {
    public boolean isMatch(String s, String p) {
        int n = s.length();
        int m = p.length();
        boolean[][] dp = new boolean[n + 1][m + 1];
        dp[0][0] = true;

        for (int i = 1; i <= m; i++) {
            if (p.charAt(i - 1) == '*') {
                dp[0][i] = dp[0][i - 1];
            }
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
                    dp[i][j] = dp[i - 1][j - 1];
                } else if (p.charAt(j - 1) == '*') {
                    dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
                } else {
                    dp[i][j] = false;
                }
            }
        }

        return dp[n][m];
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 863. All Nodes Distance K in Binary Tree Сложность: medium Дан корень бинарного дерева, значение целевого узла target и целое число k. Верните массив значений всех узлов, которые находятся на расстоянии k от целевого узла. Ответ можно вернуть в любом порядке. Пример:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, k = 2
Output: [7,4,1]
Explanation: The nodes that are a distance 2 from the target node (with value 5) have values 7, 4, and 1.
👨‍💻 Алгоритм: 1⃣Определите рекурсивную функцию add_parent(cur, parent), чтобы рекурсивно добавлять указатель на родителя к узлу cur. Если cur не пустой, добавьте указатель на parent: cur.parent = parent. Затем рекурсивно вызовите add_parent для левого и правого детей cur: add_parent(cur.left, cur) и add_parent(cur.right, cur). Вызовите add_parent(root, None), чтобы добавить все указатели на родителей (корневой узел не имеет родителя). 2⃣Инициализируйте пустой массив answer и пустое множество visited. Определите рекурсивную функцию dfs(cur, distance) для поиска всех узлов на расстоянии k от узла target. Если cur пустой или уже был посещён, вернитесь. Добавьте cur в visited, чтобы его не посещали повторно. Если distance = k, добавьте cur в answer и вернитесь. 3⃣Рекурсивно вызовите dfs для детей и родителя cur. Вызовите dfs(target, 0), чтобы найти все узлы на расстоянии k. Верните answer после завершения DFS. 😎 Решение:
class Solution {
    public List<Integer> distanceK(TreeNode root, TreeNode target, int k) {
        addParent(root, null);
        
        List<Integer> answer = new ArrayList<>();
        Set<TreeNode> visited = new HashSet<>();
        
        dfs(target, k, visited, answer);
        return answer;
    }
    
    private void addParent(TreeNode cur, TreeNode parent) {
        if (cur != null) {
            cur.parent = parent;
            addParent(cur.left, cur);
            addParent(cur.right, cur);
        }
    }
    
    private void dfs(TreeNode cur, int distance, Set<TreeNode> visited, List<Integer> answer) {
        if (cur == null || visited.contains(cur)) return;
        visited.add(cur);
        if (distance == 0) {
            answer.add(cur.val);
            return;
        }
        dfs(cur.parent, distance - 1, visited, answer);
        dfs(cur.left, distance - 1, visited, answer);
        dfs(cur.right, distance - 1, visited, answer);
    }
}

class TreeNode {
    int val;
    TreeNode left, right, parent;
    TreeNode(int x) { val = x; }
}
Ставь 👍 и забирай 📚 Базу знаний

Задача: 1229. Meeting Scheduler Сложность: medium Даны массивы доступных временных слотов slots1 и slots2 для двух человек и продолжительность встречи duration, верните самый ранний временной слот, который подходит обоим и имеет продолжительность duration. Если нет общего временного слота, который удовлетворяет требованиям, верните пустой массив. Формат временного слота — это массив из двух элементов [start, end], представляющий инклюзивный временной диапазон от start до end. Гарантируется, что никакие два доступных временных слота одного и того же человека не пересекаются друг с другом. То есть для любых двух временных слотов [start1, end1] и [start2, end2] одного и того же человека либо start1 > end2, либо start2 > end1. Пример:
Input: slots1 = [[10,50],[60,120],[140,210]], slots2 = [[0,15],[60,70]], duration = 8
Output: [60,68]
👨‍💻 Алгоритм: 1⃣Отсортируйте оба массива slots1 и slots2 по времени начала. 2⃣Инициализируйте два указателя, указывающие на начало slots1 и slots2 соответственно. 3⃣Перебирайте, пока указатель1 не достигнет конца slots1 или указатель2 не достигнет конца slots2: Найдите общий слот между slots1[pointer1] и slots2[pointer2]. Если общий слот больше или равен duration, верните результат. В противном случае найдите слот, который заканчивается раньше, и передвиньте указатель. Если общий слот не найден, верните пустой массив. 😎 Решение:
class Solution {
    public List<Integer> minAvailableDuration(int[][] slots1, int[][] slots2, int duration) {
        Arrays.sort(slots1, (a, b) -> a[0] - b[0]);
        Arrays.sort(slots2, (a, b) -> a[0] - b[0]);

        int pointer1 = 0, pointer2 = 0;

        while (pointer1 < slots1.length && pointer2 < slots2.length) {
            int intersectLeft = Math.max(slots1[pointer1][0], slots2[pointer2][0]);
            int intersectRight = Math.min(slots1[pointer1][1], slots2[pointer2][1]);
            if (intersectRight - intersectLeft >= duration) {
                return new ArrayList<Integer>(Arrays.asList(intersectLeft, intersectLeft + duration));
            }
            if (slots1[pointer1][1] < slots2[pointer2][1]) {
                pointer1++;
            } else {
                pointer2++;
            }
        }
        return new ArrayList<Integer>();
    }
}
Ставь 👍 и забирай 📚 Базу знаний

REKONFA Live 6 ноября приглашаем всех, кто имеет отношение к маркетингу и рекламным технологиям, обсудить рынок, тренды, вызо
REKONFA Live 6 ноября приглашаем всех, кто имеет отношение к маркетингу и рекламным технологиям, обсудить рынок, тренды, вызовы и их решения. С докладами на актуальные темы выступят лидеры индустрии и медийные спикеры. Принять участие можно офлайн и онлайн. Мероприятие бесплатное, нужно только зарегистрироваться. Зарегистрироваться #реклама 18+ ya.rekonfa.ru О рекламодателе

Задача: 487. Max Consecutive Ones II Сложность: medium Дан бинарный массив nums, верните максимальное количество последовательных единиц в массиве, если можно перевернуть не более одного нуля. Пример:
Input: nums = [1,0,1,1,0]
Output: 4
Explanation: 
- If we flip the first zero, nums becomes [1,1,1,1,0] and we have 4 consecutive ones.
- If we flip the second zero, nums becomes [1,0,1,1,1] and we have 3 consecutive ones.
The max number of consecutive ones is 4.
👨‍💻 Алгоритм: 1⃣Для каждого возможного начала последовательности в массиве nums начните считать количество нулей. 2⃣Для каждой последовательности проверяйте, сколько нулей содержится в ней. Если количество нулей не превышает одного, обновите максимальную длину последовательности единиц. 3⃣Продолжайте проверять все возможные последовательности в массиве, и верните максимальную длину последовательности единиц, удовлетворяющую условию. 😎 Решение:
class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int longestSequence = 0;
        for (int left = 0; left < nums.length; left++) {
            int numZeroes = 0;

            for (int right = left; right < nums.length; right++) {
                if (nums[right] == 0) {
                    numZeroes += 1;
                }
                if (numZeroes <= 1) {
                    longestSequence = Math.max(longestSequence, right - left + 1);
                }
            }
        }
        return longestSequence;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Не дайте хакерам использовать утечки против вас Преступники активно используют слитые данные компаний, чтобы получить несанкционированный доступ. А объем таких утечек за 2024 год вырос на 64%. На вебинаре расскажем, как действовать на опережение и не допустить масштабных взломов с крупными финансовыми потерями. Подключайтесь 7 октября, чтобы узнать: Как утечки открывают хакерам двери в инфраструктуру; Как отслеживать сливы с помощью сервиса мониторинга Solar AURA; Как базы утечек могут быть использованы для пентестов. Присоединяйтесь, чтобы научиться закрывать уязвимости раньше, чем их используют хакеры. К тому же мы разыграем три билета на SOC Forum 2025 — главное событие этой осени в российском ИБ-мире. Зарегистрироваться #реклама 16+ rt-solar.ru О рекламодателе