uk
Feedback

Не попадись на ботовода! Telemetrio знаходить і позначає такі канали мітками 👉 Хочеш бачити мітку, оформляй підписку

PHP | LeetCode

PHP | LeetCode

Відкрити в Telegram

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads

Показати більше
1 318
Підписники
-424 години
-97 днів
-2530 днів
Архів дописів
👀 Вы все еще не слышали про канал Путь в IT? Автор (Илья) на своем примере показывает, через что приходится проходить начина
👀 Вы все еще не слышали про канал Путь в IT? Автор (Илья) на своем примере показывает, через что приходится проходить начинающему специалисту. 😉 Почему такого контента вы еще не видели? Илья создает уникальные видео, совмещая тренировки, бытовые моменты и рабочий процесс. Сейчас начинающий специалист поступил в вуз и переехал в другой город, поэтому контент будет еще интересней. Если хочешь узнать админа лучше, зайди в закреп его канала. 👋 Подписывайся, данный канал будет разжигать в тебе огонь. Путь в IT

#medium Задача: 230. Kth Smallest Element in a BST Дан корень бинарного дерева поиска и целое число k. Верните k-ое по величине значение (нумерация с 1) среди всех значений узлов в дереве. Пример:
Input: root = [3,1,4,null,2], k = 1
Output: 1
👨‍💻 Алгоритм: 1⃣Инициализация стека и обход в глубину: Инициализируйте стек для хранения узлов дерева. Начните обход дерева в глубину, начиная с корня, и перемещайтесь влево, добавляя каждый узел в стек, пока не достигнете самого левого узла. 2⃣Извлечение узлов и проверка: Когда достигнете самого левого узла, извлеките узел из стека и уменьшите значение k на 1. Если k становится равным нулю, верните значение текущего узла, так как это и есть k-ое по величине значение. 3⃣Переход к правому поддереву: Если k не равен нулю, переместитесь к правому поддереву текущего узла и продолжайте обход, повторяя шаги 1 и 2, пока не найдете k-ое по величине значение. 😎 Решение:
class Solution {
    function kthSmallest($root, $k) {
        $stack = [];
        
        while (true) {
            while ($root !== null) {
                array_push($stack, $root);
                $root = $root->left;
            }
            $root = array_pop($stack);
            if (--$k == 0) return $root->val;
            $root = $root->right;
        }
    }
}
Ставь 👍 и забирай 📚 Базу знаний

#medium Задача: 474. Ones and Zeroes Дан массив двоичных строк strs и два целых числа m и n. Верните размер наибольшего подмножества strs, такого что в подмножестве содержится не более m нулей и n единиц. Множество x является подмножеством множества y, если все элементы множества x также являются элементами множества y. Пример:
Input: strs = ["10","0001","111001","1","0"], m = 5, n = 3
Output: 4
Explanation: The largest subset with at most 5 0's and 3 1's is {"10", "0001", "1", "0"}, so the answer is 4.
Other valid but smaller subsets include {"0001", "1"} and {"10", "1", "0"}.
{"111001"} is an invalid subset because it contains 4 1's, greater than the maximum of 3.
👨‍💻 Алгоритм: 1⃣Рассматриваем все возможные подмножества, прерывая цикл, если количество нулей превышает m или количество единиц превышает n. 2⃣Считаем количество нулей и единиц в каждом подмножестве. 3⃣Выбираем наибольшее подмножество, соответствующее условиям, и возвращаем его размер. 😎 Решение:
class Solution {
    function findMaxForm($strs, $m, $n) {
        $maxlen = 0;
        for ($i = 0; $i < (1 << count($strs)); $i++) {
            $zeroes = 0;
            $ones = 0;
            $len = 0;
            for ($j = 0; $j < 32; $j++) {
                if (($i & (1 << $j)) != 0) {
                    $count = $this->countZeroesOnes($strs[$j]);
                    $zeroes += $count[0];
                    $ones += $count[1];
                    if ($zeroes > $m || $ones > $n)
                        break;
                    $len++;
                }
            }
            if ($zeroes <= $m && $ones <= $n)
                $maxlen = max($maxlen, $len);
        }
        return $maxlen;
    }

    function countZeroesOnes($s) {
        $c = array(0, 0);
        for ($i = 0; $i < strlen($s); $i++) {
            $c[$s[$i] - '0']++;
        }
        return $c;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

#hard Задача: 329. Longest Increasing Path in a Matrix Дана матрица целых чисел размером m x n. Верните длину самого длинного возрастающего пути в матрице. Из каждой ячейки можно перемещаться в четырех направлениях: влево, вправо, вверх или вниз. Перемещение по диагонали или выход за границы матрицы (т.е. замкнутые переходы) не допускается. Пример:
Input: matrix = [[9,9,4],[6,6,8],[2,1,1]]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9].
👨‍💻 Алгоритм: 1⃣Инициализация и создание матрицы: Инициализируйте размеры матрицы m и n. Создайте матрицу matrix с добавленными границами (нулевыми значениями) вокруг исходной матрицы, чтобы избежать выхода за пределы при обработке. Рассчитайте количество исходящих связей (outdegrees) для каждой клетки и сохраните их в outdegree. 2⃣Поиск начальных листьев: Найдите все клетки с нулевыми исходящими связями и добавьте их в список leaves. Эти клетки будут начальной точкой для "слоевого удаления". 3⃣Удаление слоев: Повторяйте процесс удаления клеток уровня за уровнем в порядке топологической сортировки, пока не останется листьев. Обновляйте количество исходящих связей и добавляйте новые листья на следующем уровне. Подсчитывайте количество уровней, что в итоге даст длину самого длинного возрастающего пути. 😎 Решение:
class Solution {
    private static $dir = [[0, 1], [1, 0], [0, -1], [-1, 0]];

    function longestIncreasingPath($matrix) {
        $m = count($matrix);
        if ($m == 0) return 0;
        $n = count($matrix[0]);
        $outdegree = array_fill(0, $m + 2, array_fill(0, $n + 2, 0));
        $newMatrix = array_fill(0, $m + 2, array_fill(0, $n + 2, 0));

        for ($i = 0; $i < $m; ++$i) {
            for ($j = 0; $j < $n; ++$j) {
                $newMatrix[$i + 1][$j + 1] = $matrix[$i][$j];
            }
        }

        foreach ($newMatrix as $i => $row) {
            if ($i == 0 || $i == $m + 1) continue;
            foreach ($row as $j => $cell) {
                if ($j == 0 || $j == $n + 1) continue;
                foreach (self::$dir as $d) {
                    if ($newMatrix[$i][$j] < $newMatrix[$i + $d[0]][$j + $d[1]]) {
                        $outdegree[$i][$j]++;
                    }
                }
            }
        }

        $leaves = [];
        for ($i = 1; $i <= $m; ++$i) {
            for ($j = 1; $j <= $n; ++$j) {
                if ($outdegree[$i][$j] == 0) $leaves[] = [$i, $j];
            }
        }

        $height = 0;
        while (!empty($leaves)) {
            $height++;
            $newLeaves = [];
            foreach ($leaves as $node) {
                foreach (self::$dir as $d) {
                    $x = $node[0] + $d[0];
                    $y = $node[1] + $d[1];
                    if ($newMatrix[$node[0]][$node[1]] > $newMatrix[$x][$y]) {
                        $outdegree[$x][$y]--;
                        if ($outdegree[$x][$y] == 0) $newLeaves[] = [$x, $y];
                    }
                }
            }
            $leaves = $newLeaves;
        }
Ставь 👍 и забирай 📚 Базу знаний

#medium Задача: 229. Majority Element II Дан массив целых чисел размера n, найдите все элементы, которые встречаются более ⌊ n/3 ⌋ раз. Пример:
Input: nums = [3,2,3]
Output: [3]
👨‍💻 Алгоритм: 1⃣Поиск кандидатов: Пройдите через массив, используя алгоритм Бойера-Мура для поиска двух потенциальных кандидатов, которые могут встречаться более ⌊ n/3 ⌋ раз. Поддерживайте два счётчика и двух кандидатов. Если текущий элемент равен одному из кандидатов, увеличьте соответствующий счётчик. Если счётчик равен нулю, установите текущий элемент как кандидата и установите счётчик в 1. Если текущий элемент не совпадает ни с одним из кандидатов, уменьшите оба счётчика. 2⃣Подсчёт голосов: После определения двух кандидатов, пройдите через массив снова, чтобы посчитать фактическое количество появлений каждого кандидата. 3⃣Проверка порога: Проверьте, превышает ли количество появлений каждого кандидата порог ⌊ n/3 ⌋. Если да, добавьте кандидата в результат. 😎 Решение:
class Solution {
    function majorityElement($nums) {
        $count1 = 0;
        $count2 = 0;
        $candidate1 = null;
        $candidate2 = null;
        
        foreach ($nums as $n) {
            if ($candidate1 !== null && $candidate1 == $n) {
                $count1++;
            } else if ($candidate2 !== null && $candidate2 == $n) {
                $count2++;
            } else if ($count1 == 0) {
                $candidate1 = $n;
                $count1 = 1;
            } else if ($count2 == 0) {
                $candidate2 = $n;
                $count2 = 1;
            } else {
                $count1--;
                $count2--;
            }
        }
        
        $count1 = 0;
        $count2 = 0;
        
        foreach ($nums as $n) {
            if ($candidate1 !== null && $candidate1 == $n) $count1++;
            if ($candidate2 !== null && $candidate2 == $n) $count2++;
        }
        
        $result = [];
        $nLength = count($nums);
        if ($count1 > $nLength / 3) $result[] = $candidate1;
        if ($count2 > $nLength / 3) $result[] = $candidate2;
        
        return $result;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

😂 На одном кодинге уже давно не вывезешь, перспектива 2024 года - Информационная Безопасность Ловите два канала на тему ИБ и
😂 На одном кодинге уже давно не вывезешь, перспектива 2024 года - Информационная Безопасность Ловите два канала на тему ИБ и хакинга Арсенал Безопасника - Проект по кибербезопасности - сборник лучших инструментов и утилит по OSINT, хакингу и деанону Бункер Хакера - Все что необходимо, для того чтобы начать свой путь в безопасности - инструменты, книги, справочники, гайды и ресурсы.

#easy Задача: 228. Summary Ranges Вам дан отсортированный массив уникальных целых чисел nums. Диапазон [a,b] - это множество всех целых чисел от a до b (включительно). Верните наименьший отсортированный список диапазонов, которые покрывают все числа в массиве точно. То есть, каждый элемент nums покрывается ровно одним из диапазонов, и не существует такого целого числа x, чтобы x находился в одном из диапазонов, но не находился в nums. Каждый диапазон [a,b] в списке должен быть представлен в формате: "a->b" если a != b "a" если a == b Пример:
Input: nums = [0,1,2,4,5,7]
Output: ["0->2","4->5","7"]
Explanation: The ranges are:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"
👨‍💻 Алгоритм: 1⃣Создайте список строк ranges, который будет содержать решение задачи, и начните итерацию по всем элементам nums с указателем i = 0. Каждая итерация внешнего цикла представляет собой поиск одного диапазона. Для начала сохраните начало текущего диапазона в start = nums[i]. 2⃣Проверьте, отличается ли следующий элемент в nums на индексе i + 1 от nums[i] на 1 или больше. Если следующий элемент отличается на 1, увеличьте i на 1, чтобы включить (i+1)-й элемент в этот диапазон и продолжайте проверку следующего элемента. Продолжайте добавлять элементы в этот диапазон, пока последовательные элементы отличаются на 1, используя цикл while для выполнения этой логики. 3⃣Если следующий элемент отличается более чем на 1 или если все элементы в nums уже обработаны, проверьте, равен ли start значению nums[i]. Если start == nums[i], добавьте только start как строку в ranges, так как у нас есть только один элемент в этом диапазоне. Если start != nums[i], добавьте строку start->nums[i] в ranges. Увеличьте i на 1, чтобы начать новый диапазон. 😎 Решение:
class Solution {
    function summaryRanges($nums) {
        $ranges = [];
        $i = 0;
        while ($i < count($nums)) {
            $start = $nums[$i];
            while ($i + 1 < count($nums) && $nums[$i] + 1 == $nums[$i + 1]) {
                $i++;
            }
            if ($start != $nums[$i]) {
                $ranges[] = $start . "->" . $nums[$i];
            } else {
                $ranges[] = (string)$start;
            }
            $i++;
        }
        return $ranges;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

#medium Задача: 473. Matchsticks to Square Дано целочисленный массив спичек, где matchsticks[i] — это длина i-й спички. Необходимо использовать все спички для создания одного квадрата. Нельзя ломать никакую спичку, но можно соединять их, при этом каждая спичка должна быть использована ровно один раз. Вернуть true, если можно составить квадрат, и false в противном случае. Пример:
Input: matchsticks = [1,1,2,2,2]
Output: true
Explanation: You can form a square with length 2, one side of the square came two sticks with length 1.
👨‍💻 Алгоритм: 1⃣Определяем рекурсивную функцию, которая принимает текущий индекс обрабатываемой спички и количество сторон квадрата, которые уже полностью сформированы. Базовый случай для рекурсии: если все спички использованы и сформировано 4 стороны, возвращаем True. 2⃣Для текущей спички рассматриваем 4 варианта: она может быть частью любой из сторон квадрата. Пробуем каждый из 4 вариантов, вызывая рекурсию для них. 3⃣Если какой-либо из рекурсивных вызовов возвращает True, возвращаем True, в противном случае возвращаем False. 😎 Решение:
class Solution {
    private $nums;
    private $sums;
    private $possibleSquareSide;

    function __construct() {
        $this->sums = array_fill(0, 4, 0);
    }

    private function dfs($index) {
        if ($index == count($this->nums)) {
            return $this->sums[0] == $this->sums[1] && $this->sums[1] == $this->sums[2] && $this->sums[2] == $this->sums[3];
        }

        $element = $this->nums[$index];

        for ($i = 0; $i < 4; $i++) {
            if ($this->sums[$i] + $element <= $this->possibleSquareSide) {
                $this->sums[$i] += $element;
                if ($this->dfs($index + 1)) {
                    return true;
                }
                $this->sums[$i] -= $element;
            }
        }

        return false;
    }

    function makesquare($nums) {
        if (empty($nums)) {
            return false;
        }

        $perimeter = array_sum($nums);
        $this->possibleSquareSide = intval($perimeter / 4);
        if ($this->possibleSquareSide * 4 != $perimeter) {
            return false;
        }

        rsort($nums);
        $this->nums = $nums;
        return $this->dfs(0);
    }
}
Ставь 👍 и забирай 📚 Базу знаний

📺 Уникальная база записей IT собеседований 180+ записей реальных собеседований на программиста, тестировщика, аналитика и прочие IT профы. Записи собесов от ведущих компаний: Сбер, Яндекс, ВТБ, Тинькофф, Озон, Wildberries и т.д. 🎯 Переходи по ссылке и присоединяйся к базе, чтобы прокачать свои шансы на успешное трудоустройство! У тебя есть запись собеседования? Мы готовы ее купить и заплатим до 3000 руб. за каждую

#medium Задача: 227. Basic Calculator II Дана строка s, представляющая выражение. Вычислите это выражение и верните его значение. Целочисленное деление должно округляться к нулю. Вы можете предположить, что данное выражение всегда является допустимым. Все промежуточные результаты будут находиться в диапазоне [-2^31, 2^31 - 1]. Примечание: Запрещено использовать какие-либо встроенные функции, которые вычисляют строки как математические выражения, такие как eval(). Пример:
Input: s = "3+2*2"
Output: 7
👨‍💻 Алгоритм: 1⃣Вместо использования стека, используем переменную lastNumber для отслеживания значения последнего вычисленного выражения. 2⃣Если операция сложения (+) или вычитания (-), добавляем lastNumber к результату вместо того, чтобы помещать его в стек. Текущее значение currentNumber будет обновлено на lastNumber для следующей итерации. 3⃣Если операция умножения (*) или деления (/), вычисляем выражение lastNumber * currentNumber и обновляем lastNumber с результатом выражения. Это значение будет добавлено к результату после сканирования всей строки. 😎 Решение:
class Solution {
    function calculate($s) {
        $length = strlen($s);
        if ($length == 0) return 0;
        $currentNumber = 0;
        $lastNumber = 0;
        $result = 0;
        $sign = '+';
        
        for ($i = 0; $i < $length; $i++) {
            $currentChar = $s[$i];
            if (ctype_digit($currentChar)) {
                $currentNumber = ($currentNumber * 10) + intval($currentChar);
            }
            if (!ctype_digit($currentChar) && !ctype_space($currentChar) || $i == $length - 1) {
                if ($sign == '+' || $sign == '-') {
                    $result += $lastNumber;
                    $lastNumber = ($sign == '+') ? $currentNumber : -$currentNumber;
                } else if ($sign == '*') {
                    $lastNumber *= $currentNumber;
                } else if ($sign == '/') {
                    $lastNumber /= $currentNumber;
                }
                $sign = $currentChar;
                $currentNumber = 0;
            }
        }
        $result += $lastNumber;
        return $result;  
    }
}
Ставь 👍 и забирай 📚 Базу знаний

#medium Задача: 328. Odd Even Linked List Дан заголовок односвязного списка. Сгруппируйте все узлы с нечетными индексами вместе, а затем узлы с четными индексами, и верните упорядоченный список. Первый узел считается нечетным, второй узел — четным и так далее. Учтите, что относительный порядок внутри обеих групп (четной и нечетной) должен оставаться таким же, как в исходном списке. Вы должны решить задачу с дополнительной сложностью по памяти O(1) и временной сложностью O(n). Пример:
Input: head = [2,1,3,5,6,4,7]
Output: [2,3,6,7,1,5,4]
👨‍💻 Алгоритм: 1⃣Инициализация указателей: Создайте указатели odd и even для работы с нечетными и четными узлами, соответственно. Инициализируйте odd началом списка head, а even — следующим узлом head.next. Также создайте указатель evenHead для сохранения начала четного списка. 2⃣Разделение списка: Используйте цикл для прохождения списка, перенаправляя нечетные узлы в oddList, а четные узлы в evenList. Обновляйте указатели odd и even в процессе итерации. 3⃣Соединение списков: После окончания цикла соедините конец нечетного списка с началом четного списка, используя указатель evenHead. 😎 Решение:
class ListNode {
    public $val = 0;
    public $next = null;
    function __construct($val = 0, $next = null) {
        $this->val = $val;
        $this->next = $next;
    }
}

class Solution {
    function oddEvenList($head) {
        if ($head === null) return null;
        $odd = $head;
        $even = $head->next;
        $evenHead = $even;
        
        while ($even !== null && $even->next !== null) {
            $odd->next = $even->next;
            $odd = $odd->next;
            $even->next = $odd->next;
            $even = $even->next;
        }
        $odd->next = $evenHead;
        return $head;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Перец на канале «Записки необычного препода» делает невозможное! А именно — встраивает мышление на английском взрослым людям. Как обычно пытаются научить «думать на языке»? Методом «бери больше, кидай дальше». Слушайте песни, смотрите фильмы, читайте книги в оригинале, и оно само как-нибудь запустится. Тут всё совсем не так. Тут происходит встраивание языка на кардинально других принципах. В результате вы ощущаете грамматику и слова «изнутри». Так, как бы вы их ощущали, будь вы носителем английского языка. Почитать подробнее про эту технологию можно тут. Есть конкретный механизм мышления. Он состоит из визуального слоя, слоя смыслов и слоя слов. Механизм разбивается на элементы. Каждый элемент тренируется отдельно. Оттренированные элементы стыкуются друг с другом с помощью специальных упражнений. Здесь: - Пошаговая технология; - Разбор механик мышления на языке; - Простота — любое сложное упражнение должно быть разбито на простые. - Измеримость — все упражнения тренируются до норматива (как правило в секундах). Норматив гарантирует освоение упражнения на уровне навыка. - Сумма упражнений неизбежно приводит к мышлению на языке. Так же, как правильно собранные вместе детали создают автомобиль. Вот, например: - как найти английские артикли в русском; - как освоить что угодно в 10 раз быстрее; - как взломать английскую грамматику. Подписывайся, чтобы узнать больше.

#hard Задача: 352. Data Stream as Disjoint Intervals Дано поступление данных из последовательности неотрицательных целых чисел a1, a2, ..., an, необходимо обобщить увиденные числа в виде списка непересекающихся интервалов. Реализуйте класс SummaryRanges: SummaryRanges() Инициализирует объект с пустым потоком. void addNum(int value) Добавляет целое число в поток. int[][] getIntervals() Возвращает обобщение текущих чисел в потоке в виде списка непересекающихся интервалов [starti, endi]. Ответ должен быть отсортирован по starti. Пример:
Input
["SummaryRanges", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals"]
[[], [1], [], [3], [], [7], [], [2], [], [6], []]
Output
[null, null, [[1, 1]], null, [[1, 1], [3, 3]], null, [[1, 1], [3, 3], [7, 7]], null, [[1, 3], [7, 7]], null, [[1, 3], [6, 7]]]
👨‍💻 Алгоритм: 1⃣Инициализировать структуру данных TreeSet для хранения значений. 2⃣addNum(int value) Просто добавить value в values. Если эквивалент TreeSet вашего языка программирования позволяет дублировать значения, как например SortedList в Python, нужно также проверить, что value не существует в values, так как дубликаты нарушат алгоритм. 3⃣getIntervals Если values пуст, вернуть пустой массив. Создать пустой список интервалов. Установить left = right = -1. left представляет левую границу текущего интервала, а right представляет правую границу. Итерировать по values. На каждой итерации: Если left < 0, установить left = right = value. Иначе, если value = right + 1, установить right = value, так как мы можем продолжить текущий интервал. Иначе, мы не можем продолжить текущий интервал. Вставить [left, right] в intervals и установить left = right = value для начала нового интервала. Вставить [left, right] в intervals и вернуть intervals. 😎 Решение:
<?php

class SummaryRanges {
    private $values;

    public function __construct() {
        $this->values = [];
    }

    public function addNum($value) {
        $this->values[$value] = true;
    }

    public function getIntervals() {
        if (empty($this->values)) {
            return [];
        }

        $sortedValues = array_keys($this->values);
        sort($sortedValues);

        $intervals = [];
        $left = -1;
        $right = -1;

        foreach ($sortedValues as $value) {
            if ($left < 0) {
                $left = $right = $value;
            } elseif ($value == $right + 1) {
                $right = $value;
            } else {
                $intervals[] = [$left, $right];
                $left = $right = $value;
            }
        }

        $intervals[] = [$left, $right];
        return $intervals;
    }
}

// Example usage
$sr = new SummaryRanges();
$sr->addNum(1);
$sr->addNum(3);
$sr->addNum(7);
$sr->addNum(2);
$sr->addNum(6);
$intervals = $sr->getIntervals();
foreach ($intervals as $interval) {
    echo $interval[0] . " " . $interval[1] . "\n";
}
?>
Ставь 👍 и забирай 📚 Базу знаний

#medium Задача: 289. Game of Life Согласно статье Википедии: "Игра Жизнь, также известная просто как Жизнь, — это клеточный автомат, созданный британским математиком Джоном Хортоном Конуэем в 1970 году." Доска состоит из сетки клеток размером m x n, где каждая клетка имеет начальное состояние: живая (представляется числом 1) или мёртвая (представляется числом 0). Каждая клетка взаимодействует с восемью соседями (по горизонтали, вертикали и диагоналям) согласно следующим четырём правилам (взято из вышеупомянутой статьи Википедии): Любая живая клетка с менее чем двумя живыми соседями умирает, как будто из-за недостатка населения. Любая живая клетка с двумя или тремя живыми соседями остаётся живой до следующего поколения. Любая живая клетка с более чем тремя живыми соседями умирает, как будто из-за перенаселения. Любая мёртвая клетка с ровно тремя живыми соседями становится живой, как будто вследствие размножения. Следующее состояние создаётся путем одновременного применения вышеупомянутых правил ко всем клеткам в текущем состоянии, где рождения и смерти происходят одновременно. Дано текущее состояние сетки m x n, верните следующее состояние. Пример:
Input: board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
Output: [[0,0,0],[1,0,1],[0,1,1],[0,1,0]]
👨‍💻 Алгоритм: 1⃣Итерация по клеткам доски: Пройдите через каждую клетку на доске. Для каждой клетки подсчитайте количество живых соседей, проверяя все восемь соседних клеток. 2⃣Применение правил: На основе количества живых соседей и текущего состояния клетки примените правила игры: Любая живая клетка с менее чем двумя живыми соседями умирает (становится -1). Любая живая клетка с двумя или тремя живыми соседями остаётся живой (без изменений). Любая живая клетка с более чем тремя живыми соседями умирает (становится -1). Любая мёртвая клетка с ровно тремя живыми соседями становится живой (становится 2). 3⃣Обновление доски: Пройдите через доску ещё раз и обновите состояния клеток: Если значение клетки больше 0, установите её в 1 (живая). Если значение клетки меньше или равно 0, установите её в 0 (мёртвая). 😎 Решение:
class Solution {
    function gameOfLife(&$board) {
        $neighbors = [0, 1, -1];
        $rows = count($board);
        $cols = count($board[0]);

        for ($row = 0; $row < $rows; $row++) {
            for ($col = 0; $col < $cols; $col++) {
                $liveNeighbors = 0;

                for ($i = 0; $i < 3; $i++) {
                    for ($j = 0; $j < 3; $j++) {
                        if (!($neighbors[$i] == 0 && $neighbors[$j] == 0)) {
                            $r = $row + $neighbors[$i];
                            $c = $col + $neighbors[$j];

                            if (($r < $rows && $r >= 0) && ($c < $cols && $c >= 0) && (abs($board[$r][$c]) == 1)) {
                                $liveNeighbors++;
                            }
                        }
                    }
                }

                if (($board[$row][$col] == 1) && ($liveNeighbors < 2 || $liveNeighbors > 3)) {
                    $board[$row][$col] = -1;
                }
                if ($board[$row][$col] == 0 && $liveNeighbors == 3) {
                    $board[$row][$col] = 2;
                }
            }
        }

        for ($row = 0; $row < $rows; $row++) {
            for ($col = 0; $col < $cols; $col++) {
                $board[$row][$col] = $board[$row][$col] > 0 ? 1 : 0;
            }
        }
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Программист — лекарство от больных тимлидов, тупых багов и тех самых митов в 10 утра ☠️ Здесь собирают лучшие мемы про айтишников, чтобы спасти вашу психику от died'осов на работе. Идеально зачиллить вечерком и скинуть друзьям: @progeri

#easy Задача: 459. Repeated Substring Pattern Дана строка s, проверьте, может ли она быть построена путем взятия подстроки и добавления нескольких копий этой подстроки друг за другом. Пример:
Input: heights = [2,1,5,6,2,3]
Output: 10
Explanation: The above is a histogram where width of each bar is 1.
The largest rectangle is shown in the red area, which has an area = 10 units.
👨‍💻 Алгоритм: 1⃣Создайте целочисленную переменную n, равную длине строки s. 2⃣Итерация по всем префиксным подстрокам длины i от 1 до n/2: Если i делит n, объявите пустую строку pattern. Используйте внутренний цикл, который выполняется n/i раз для конкатенации подстроки, сформированной из первых i символов строки s. Если pattern равен s, вернуть true. 3⃣Если нет подстроки, которую можно повторить для формирования s, вернуть false. 😎 Решение:
class Solution {
    public function repeatedSubstringPattern($s) {
        $n = strlen($s);
        for ($i = 1; $i <= $n / 2; $i++) {
            if ($n % $i == 0) {
                $pattern = "";
                $substr = substr($s, 0, $i);
                for ($j = 0; $j < $n / $i; $j++) {
                    $pattern .= $substr;
                }
                if ($s == $pattern) {
                    return true;
                }
            }
        }
        return false;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

#medium Задача: 288. Unique Word Abbreviation Сокращение слова — это объединение его первой буквы, количества символов между первой и последней буквой и последней буквы. Если слово состоит только из двух символов, то оно является сокращением само по себе. Например: dog --> d1g, потому что между первой буквой 'd' и последней буквой 'g' одна буква. internationalization --> i18n, потому что между первой буквой 'i' и последней буквой 'n' 18 букв. it --> it, потому что любое слово из двух символов является своим собственным сокращением. Реализуйте класс ValidWordAbbr: ValidWordAbbr(String[] dictionary) Инициализирует объект со словарем слов. boolean isUnique(string word) Возвращает true, если выполняется одно из следующих условий (в противном случае возвращает false): В словаре нет слова, сокращение которого равно сокращению слова word. Для любого слова в словаре, сокращение которого равно сокращению слова word, это слово и word одинаковы. Пример:
Input
["ValidWordAbbr", "isUnique", "isUnique", "isUnique", "isUnique", "isUnique"]
[[["deer", "door", "cake", "card"]], ["dear"], ["cart"], ["cane"], ["make"], ["cake"]]
Output
[null, false, true, false, true, true]

Explanation
ValidWordAbbr validWordAbbr = new ValidWordAbbr(["deer", "door", "cake", "card"]);
validWordAbbr.isUnique("dear"); // return false, dictionary word "deer" and word "dear" have the same abbreviation "d2r" but are not the same.
validWordAbbr.isUnique("cart"); // return true, no words in the dictionary have the abbreviation "c2t".
validWordAbbr.isUnique("cane"); // return false, dictionary word "cake" and word "cane" have the same abbreviation  "c2e" but are not the same.
validWordAbbr.isUnique("make"); // return true, no words in the dictionary have the abbreviation "m2e".
validWordAbbr.isUnique("cake"); // return true, because "cake" is already in the dictionary and no other word in the dictionary has "c2e" abbreviation.
👨‍💻 Алгоритм: 1⃣Инициализация: Создайте словарь сокращений abbrDict, который будет хранить сокращения слов в виде ключей и булевы значения, указывающие, уникально ли сокращение. Создайте множество dict, содержащее все слова из словаря, чтобы быстро проверять наличие слова в словаре. 2⃣Генерация сокращений: При инициализации объекта ValidWordAbbr пройдите через каждое слово в словаре и создайте его сокращение. Если сокращение уже существует в abbrDict, установите значение в false (не уникальное). В противном случае установите значение в true (уникальное). 3⃣Проверка уникальности: Для метода isUnique создайте сокращение для входного слова и проверьте, есть ли это сокращение в abbrDict. Если сокращение отсутствует в abbrDict, возвращайте true. Если сокращение присутствует и оно уникально, проверьте, есть ли это слово в словаре. Если да, возвращайте true, в противном случае - false. 😎 Решение:
class ValidWordAbbr {
    private $abbrDict = [];
    private $dict;

    function __construct($dictionary) {
        $this->dict = array_flip($dictionary);
        foreach ($dictionary as $word) {
            $abbr = $this->toAbbr($word);
            $this->abbrDict[$abbr] = !isset($this->abbrDict[$abbr]);
        }
    }

    function isUnique($word) {
        $abbr = $this->toAbbr($word);
        $hasAbbr = isset($this->abbrDict[$abbr]);
        return !$hasAbbr || ($this->abbrDict[$abbr] && isset($this->dict[$word]));
    }

    private function toAbbr($word) {
        $n = strlen($word);
        if ($n <= 2) {
            return $word;
        }
        return $word[0] . ($n - 2) . $word[$n - 1];
    }
}
Ставь 👍 и забирай 📚 Базу знаний

⚡️ Вся база знаний по IT в одном месте! 🧑‍💻 IT База — краткие разборы самого важного из мира IT. Сотни мастхев-ресурсов, каждый день новые материалы по работе и подготовке к собеседованиям. Подойдёт как новичкам, так и состоявшимся айтишникам; 🖥 Frontend База — всё для фронтенд разработчиков. Готовые решения для проектов, полезные курсы по JS/HTML/CSS, готовые роадмапы для комфортного освоения в профессии и дальнейшего развития; 👣 Backend База — самое важное для бэкендеров. Всё о работе с PHP, MySQL, MongoDB, Golang и Rust в одном месте, плюс полные курсы и лайфхаки для работы на каждый день; 🖥 База Знаний — склад полезных курсов и материалов, где легко найти что-то нужное по хэштегам. Если вам что-то интересно про IT, то оно уже лежит на Базе, проверяйте. ⏲ Успей подписаться, чтобы не потерять!

#medium Задача: 287. Find the Duplicate Number Дан массив целых чисел nums, содержащий n + 1 целых чисел, где каждое число находится в диапазоне [1, n] включительно. В массиве есть только одно повторяющееся число, верните это повторяющееся число. Вы должны решить задачу, не изменяя массив nums и используя только постоянное дополнительное пространство. Пример:
Input: nums = [1,3,4,2,2]
Output: 2
👨‍💻 Алгоритм: 1⃣Определение дубликата: Итерируйте по массиву, оценивая каждый элемент (назовем его cur). Используйте абсолютное значение текущего элемента, чтобы получить индекс. Если элемент по индексу cur отрицательный, значит, мы уже встречали этот элемент ранее, и cur является дубликатом. Сохраните cur как дубликат и выйдите из цикла. Если элемент по индексу cur положительный, инвертируйте знак этого элемента, чтобы пометить его как встреченный, и перейдите к следующему элементу. 2⃣Восстановление массива: Пройдите по массиву и измените все отрицательные элементы обратно на положительные, чтобы восстановить исходное состояние массива. 3⃣Возврат результата: Верните найденный дубликат. 😎 Решение:
class Solution {
    function findDuplicate($nums) {
        $duplicate = -1;
        for ($i = 0; $i < count($nums); $i++) {
            $cur = abs($nums[$i]);
            if ($nums[$cur] < 0) {
                $duplicate = $cur;
                break;
            }
            $nums[$cur] *= -1;
        }
        for ($i = 0; $i < count($nums); $i++) {
            $nums[$i] = abs($nums[$i]);
        }
        return $duplicate;
    }
}
Ставь 👍 и забирай 📚 Базу знаний

#medium Задача: 286. Walls and Gates Вам дана сетка размером m x n, представляющая комнаты, инициализированные следующими значениями: -1: Стена или препятствие. 0: Ворота. INF: Бесконечность, обозначающая пустую комнату. Мы используем значение 2^31 - 1 = 2147483647 для представления INF, так как можно предположить, что расстояние до ворот меньше 2147483647. Заполните каждую пустую комнату расстоянием до ближайших ворот. Если невозможно добраться до ворот, комната должна быть заполнена значением INF. Пример:
Input: rooms = [[2147483647,-1,0,2147483647],[2147483647,2147483647,2147483647,-1],[2147483647,-1,2147483647,-1],[0,-1,2147483647,2147483647]]
Output: [[3,-1,0,1],[2,2,1,-1],[1,-1,2,-1],[0,-1,3,4]]
👨‍💻 Алгоритм: 1⃣Обход всех комнат: Пройдите через каждую клетку сетки, инициализируя очередь для BFS. Если клетка содержит ворота (0), добавьте её в очередь. 2⃣BFS для поиска кратчайшего пути: Используйте BFS для распространения из каждого ворот в соседние пустые комнаты. Обновите значение расстояния до ближайших ворот для каждой комнаты, которую вы посещаете, если это расстояние меньше текущего значения. 3⃣Проверка всех направлений: Для каждой клетки проверьте все возможные направления (вверх, вниз, влево, вправо) и добавляйте в очередь те, которые являются пустыми комнатами. 😎 Решение:
class Solution {
    const INF = 2147483647;
    private $directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];

    function wallsAndGates(&$rooms) {
        $m = count($rooms);
        if ($m == 0) return;
        $n = count($rooms[0]);
        $queue = new SplQueue();

        for ($i = 0; $i < $m; $i++) {
            for ($j = 0; $j < $n; $j++) {
                if ($rooms[$i][$j] == 0) {
                    $queue->enqueue([$i, $j]);
                }
            }
        }

        while (!$queue->isEmpty()) {
            list($x, $y) = $queue->dequeue();
            foreach ($this->directions as $direction) {
                $nx = $x + $direction[0];
                $ny = $y + $direction[1];
                if ($nx >= 0 && $ny >= 0 && $nx < $m && $ny < $n && $rooms[$nx][$ny] == self::INF) {
                    $rooms[$nx][$ny] = $rooms[$x][$y] + 1;
                    $queue->enqueue([$nx, $ny]);
                }
            }
        }
    }
}
Ставь 👍 и забирай 📚 Базу знаний