Алгоритм: Two Pointers
Two Pointers - это техника, при которой два индекса двигаются по массиву, чтобы эффективно решать задачи без использования вложенных циклов.Я запомнил как read pointer и write pointer
➡️ Суть
- Один индекс начинает с одного конца, второй с другого. Они двигаются навстречу друг, другу или в одном направлении в зависимости от задачи;
- Позволяет решать многие задачи за
- Работает лучше всего на отсортированных данных или в задачах с поиском зависимостей между элементами.
➡️ Задача
443. String Compression
➡️ Условие
➡️ Пример
➡️ Решение
➡️ HW?
1⃣ begin – начальный индекс текущей группы (индекс чтения), count – длина ответа, сжатой строки (индекс записи). group - длинна группы
2⃣ Находим длину group
3⃣ input[count++] = input[begin] - не забыть скопировать элемент в индекс записи
5⃣ begin += group - сдвигаем (индекс записи) на начало следующей группы
5⃣ вставляем длину группы
#leetcode
#medium
#algorithm
#two_pointers
💡 Channel | ✏ Chat
Two Pointers - это техника, при которой два индекса двигаются по массиву, чтобы эффективно решать задачи без использования вложенных циклов.
- Один индекс начинает с одного конца, второй с другого. Они двигаются навстречу друг, другу или в одном направлении в зависимости от задачи;
- Позволяет решать многие задачи за
O(n)
вместо O(n²)
- Работает лучше всего на отсортированных данных или в задачах с поиском зависимостей между элементами.
443. String Compression
Задан массив символов chars, сжать его с помощью следующего алгоритма:
Дан массив символов chars, сжать его, используя следующий алгоритм:
Начать с пустой строки s. Для каждой группы последовательно повторяющихся символов в chars:
- Если длина группы равна 1, добавьте этот символ в s
- В противном случае добавьте символ - длина группы.
- Сжатая строка s не должна возвращаться отдельно, а должна храниться в массиве входных символов chars.
- Обратите имание, что длина группы, равная 10 или более, будет разбита на несколько символов в chars.
- После завершения модификации входного массива верните его новую длину.
- Вы должны написать алгоритм, который использует только постоянное дополнительное пространство.
Input: chars = ["a","a","b","b","c","c","c"]
Output: Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"]
Explanation: The groups are "aa", "bb", and "ccc". This compresses to "a2b2c3".
public static int Compress(char[] input)
{
var begin = 0;
var count = 0;
while (begin < input.Length)
{
var group = 1;
while (begin + group < input.Length && input[begin + group] == input[begin])
group++;
input[count++] = input[begin];
begin += group;
if (group > 1)
{
foreach (var ch in group.ToString())
input[count++] = ch;
}
}
return count;
}
#leetcode
#medium
#algorithm
#two_pointers
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2 2👨💻1
This media is not supported in your browser
VIEW IN TELEGRAM
3. Longest Substring Without Repeating Characters
➡ Задача
3. Longest Substring Without Repeating Characters
➡ Условие
➡ Пример
➡ Суть
➡ Решение
➡ HW?
1⃣ Обработка простых случаев
2⃣ Проход по строке с использованием правого указателя. Мы двигаем right (правый указатель), проходя по строке s.
3⃣ Проверка на повтор символа
Если s[right] уже есть в dict, значит символ повторяется. Берем сохраненный индекс index из dict[s[right]. Сдвигаем left, чтобы не было повторов: left = Math.Max(left, index + 1). Это предотвращает сдвиг left назад, если left уже ушел дальше повторного символа.
5⃣ Обновление словаря. Записываем в dict[s[right]] текущий индекс right — теперь этот символ встречается в позиции right.
5⃣ Обновление максимальной длины. Выбираем максимум между max и текущей длиной окна.
#leetcode
#medium
#algorithm
#sliding_window
💡 Channel | ✏ Chat
3. Longest Substring Without Repeating Characters
Given a string s, find the length of the longest substring without duplicate characters.
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Наивный способ - перебирать все подстроки O(n²). Это медленно для больших массивов.
Оптимальное решение - использовать Sliding Windows и HashSet
public int LengthOfLongestSubstring(string s)
{
if(s.Length <= 1)
return s.Length;
var left = 0;
var max = 0;
var dict = new Dictionary<char, int>();
for (var right = 0; right < s.Length; right++)
{
if (dict.TryGetValue(s[right], out var index))
{
left = Math.Max(left, index + 1);
}
dict[s[right]] = right;
max = Math.Max(max, right - left + 1);
}
return max;
}
Если s[right] уже есть в dict, значит символ повторяется. Берем сохраненный индекс index из dict[s[right]. Сдвигаем left, чтобы не было повторов: left = Math.Max(left, index + 1). Это предотвращает сдвиг left назад, если left уже ушел дальше повторного символа.
#leetcode
#medium
#algorithm
#sliding_window
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👨💻2
Snakes and Ladders
Мне попалась задача на
Нахлынули вьетнамские флешбэки 😱 и я в детстве всего пару раз играл в эту игру, это воспоминание было разблокировано, но толку от этого конечно 0 и короче не помогло мне это 😅
Кратко просто найти и написать код решения любой игры в змейку и лестницы с полем n x n 🥹
➡️ Задача
На вход подаётся игровое поле размера n x n, представленное в виде двумерного массива. Каждая клетка может быть обычной (-1), содержать лестницу (ведёт на более высокий номер клетки) или змею (ведёт на более низкий номер).
Ты начинаешь на клетке 1 и хочешь добраться до последней клетки n^2, бросая кубик (от 1 до 6). Найди минимальное количество бросков, необходимых для достижения цели, с учётом змей и лестниц.
Поле нумеруется зигзагообразно: первый ряд - слева направо, второй - справа налево и т.д.
Нужно пройти 216 из 216 чтобы задача будет решена
➡️ Сюжетная линия
Я говорил что не больше часа тратить на задачу....
прошло 4 часа короче и 3 из 216 тестов было пройдено😅
Боль приносит, что ходить надо зигзагом. Тут фаза отрицания подъехала.😔
Я пробил второе дно, когда написал, вроде как классное решение.. как же я ошибался 😅
было пройдено 1 из 216 тестов, yо ничего быстро пофиксил где-то прошло уже 50 из 216. Вообщем я полностью удалил своё решение и начал с начало.
Дальше становилось больнее, господи зигзагом ходить надо (кто вообще придумал 🫣 эту игру) <— тут была фаза торга 😜 до принятия ещё ой как далеко😭
Дальше я запомнил число 72 из 216. Почему запомнил? потому что тут появились циклы, ЦИКЛЫ из змей и лесенок, Карл! конечно они должны были быть подумал я и начал дальше допиливать код.
Перевал за сотню где то 101 из 216. Оказывается могут быть не оптимальные варианты и переход по змеям не даёт преймущество в ходах 😓
Вообщем решил я её где-то за 5.5 часов 😅 за
➡️ Решение
1⃣ минус одна боль, преобразование двумерную доску в одномерную,
По сути мы начинаем с нижней строки и чередуем направление: одна строка читается слева направо, следующая - справа налево, и так далее и получаем одномернный массив
2⃣ Поиск в ширину
Стартуем с клетки 0 (самая нижняя левая). На каждом шаге пробуем кинуть кубик на 1 - 6 клеток вперёд.
Если попадаем на клетку с лестницей или змеёй, то перемещаемся сразу на указанную клетку. Если нету ничего, тогда мы считаем себя прухлом и ходим будто выбросили 6
3⃣ Используем очередь, чтобы искать самый короткий путь (минимальное количество ходов).
5⃣ Массив visited нужен, чтобы не заходить повторно на уже посещённые клетки и не застрять в цикле.
5⃣ Если не удалось дойти до конца возвращаем -1
Сама задача
909. Snakes and Ladders
Решение C#
#leetcode
#medium
#snakesandladders
💡 Channel | ✏ Chat
Мне попалась задача на
LeetCode
про змеи и лестницы -_-Нахлынули вьетнамские флешбэки 😱 и я в детстве всего пару раз играл в эту игру, это воспоминание было разблокировано, но толку от этого конечно 0 и короче не помогло мне это 😅
Кратко просто найти и написать код решения любой игры в змейку и лестницы с полем n x n 🥹
На вход подаётся игровое поле размера n x n, представленное в виде двумерного массива. Каждая клетка может быть обычной (-1), содержать лестницу (ведёт на более высокий номер клетки) или змею (ведёт на более низкий номер).
Ты начинаешь на клетке 1 и хочешь добраться до последней клетки n^2, бросая кубик (от 1 до 6). Найди минимальное количество бросков, необходимых для достижения цели, с учётом змей и лестниц.
Поле нумеруется зигзагообразно: первый ряд - слева направо, второй - справа налево и т.д.
Нужно пройти 216 из 216 чтобы задача будет решена
Я говорил что не больше часа тратить на задачу....
прошло 4 часа короче и 3 из 216 тестов было пройдено😅
Боль приносит, что ходить надо зигзагом. Тут фаза отрицания подъехала.
Я пробил второе дно, когда написал, вроде как классное решение.. как же я ошибался 😅
было пройдено 1 из 216 тестов, yо ничего быстро пофиксил где-то прошло уже 50 из 216. Вообщем я полностью удалил своё решение и начал с начало.
Дальше становилось больнее, господи зигзагом ходить надо (кто вообще придумал 🫣 эту игру) <— тут была фаза торга 😜 до принятия ещё ой как далеко
Дальше я запомнил число 72 из 216. Почему запомнил? потому что тут появились циклы, ЦИКЛЫ из змей и лесенок, Карл! конечно они должны были быть подумал я и начал дальше допиливать код.
Перевал за сотню где то 101 из 216. Оказывается могут быть не оптимальные варианты и переход по змеям не даёт преймущество в ходах 😓
Вообщем решил я её где-то за 5.5 часов 😅 за
О(n^2)
по памяти, сверхлюди решают за O(k)
По сути мы начинаем с нижней строки и чередуем направление: одна строка читается слева направо, следующая - справа налево, и так далее и получаем одномернный массив
Стартуем с клетки 0 (самая нижняя левая). На каждом шаге пробуем кинуть кубик на 1 - 6 клеток вперёд.
Если попадаем на клетку с лестницей или змеёй, то перемещаемся сразу на указанную клетку. Если нету ничего, тогда мы считаем себя прухлом и ходим будто выбросили 6
Сама задача
909. Snakes and Ladders
Решение C#
public int SnakesAndLadders(int[][] board)
{
var flatBoard = new int [board.Length * board.Length];
var index = 0;
var rightToLeft = true;
for (var i = board.Length - 1; i >= 0; i--)
{
for (var j = 0; j < board.Length; j++)
{
if (rightToLeft)
flatBoard[index] = rightToLeft ? board[i][j] : board[i][board.Length - 1 - j];
else
flatBoard[index] = board[i][board.Length - 1 - j];
index++;
}
rightToLeft = !rightToLeft;
}
var result = BFS(flatBoard, 0);
return result;
}
private int BFS(int[] board, int start)
{
HashSet<int> visited = new();
Queue<(int position, int step)> queue = new();
queue.Enqueue((start, 0));
visited.Add(start);
while (queue.TryDequeue(out var item))
{
if (item.position >= board.Length - 1)
return item.step;
for (var dice = 1; dice <= 6; dice++)
{
var next = item.position + dice;
if (next > board.Length - 1)
break;
if (visited.Add(next))
{
if (board[next] != -1)
next = board[next] - 1;
queue.Enqueue((next, item.step + 1));
}
}
}
return -1;
}
#leetcode
#medium
#snakesandladders
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3 3 2