Задача: 1219. Path with Maximum Gold
Сложность: medium
В золотом руднике размером m x n каждая ячейка содержит целое число, представляющее количество золота в этой ячейке, или 0, если она пуста.
Верните максимальное количество золота, которое вы можете собрать при следующих условиях:
- Каждый раз, когда вы находитесь в ячейке, вы собираете всё золото из этой ячейки.
- Из вашей позиции вы можете сделать один шаг влево, вправо, вверх или вниз.
- Вы не можете посещать одну и ту же ячейку более одного раза.
- Никогда не посещайте ячейку с 0 золотом.
- Вы можете начинать и прекращать сбор золота с любой позиции в сетке, которая содержит золото.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и подготовка:
Инициализируйте константный массив DIRECTIONS для направления перемещений.
Определите количество строк и столбцов в сетке.
Инициализируйте переменную maxGold для хранения максимального количества собранного золота.
2⃣ Функция DFS и обратный трек:
Реализуйте функцию dfsBacktrack для поиска пути с максимальным золотом с помощью DFS и обратного трека.
Обрабатывайте базовый случай, проверяя выход за пределы сетки или ячейки без золота.
Пометьте текущую ячейку как посещённую и сохраните её значение.
Исследуйте каждую из четырёх смежных ячеек и обновите максимальное количество золота, если найден лучший путь.
Сбросьте текущую ячейку до её исходного значения для дальнейших исследований.
3⃣ Поиск максимального золота:
Используйте вложенные циклы для каждой ячейки в сетке, чтобы найти максимальное количество золота, начиная с этой ячейки, с помощью функции dfsBacktrack.
Обновите maxGold при нахождении лучшего пути.
Верните maxGold.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
В золотом руднике размером m x n каждая ячейка содержит целое число, представляющее количество золота в этой ячейке, или 0, если она пуста.
Верните максимальное количество золота, которое вы можете собрать при следующих условиях:
- Каждый раз, когда вы находитесь в ячейке, вы собираете всё золото из этой ячейки.
- Из вашей позиции вы можете сделать один шаг влево, вправо, вверх или вниз.
- Вы не можете посещать одну и ту же ячейку более одного раза.
- Никогда не посещайте ячейку с 0 золотом.
- Вы можете начинать и прекращать сбор золота с любой позиции в сетке, которая содержит золото.
Пример:
Input: grid = [[0,6,0],[5,8,7],[0,9,0]]
Output: 24
Explanation:
[[0,6,0],
[5,8,7],
[0,9,0]]
Path to get the maximum gold, 9 -> 8 -> 7.
Инициализируйте константный массив DIRECTIONS для направления перемещений.
Определите количество строк и столбцов в сетке.
Инициализируйте переменную maxGold для хранения максимального количества собранного золота.
Реализуйте функцию dfsBacktrack для поиска пути с максимальным золотом с помощью DFS и обратного трека.
Обрабатывайте базовый случай, проверяя выход за пределы сетки или ячейки без золота.
Пометьте текущую ячейку как посещённую и сохраните её значение.
Исследуйте каждую из четырёх смежных ячеек и обновите максимальное количество золота, если найден лучший путь.
Сбросьте текущую ячейку до её исходного значения для дальнейших исследований.
Используйте вложенные циклы для каждой ячейки в сетке, чтобы найти максимальное количество золота, начиная с этой ячейки, с помощью функции dfsBacktrack.
Обновите maxGold при нахождении лучшего пути.
Верните maxGold.
type Solution struct{}
func (s *Solution) getMaximumGold(grid [][]int) int {
directions := []int{0, 1, 0, -1, 0}
rows, cols := len(grid), len(grid[0])
maxGold := 0
var dfsBacktrack func(grid [][]int, rows, cols, row, col int) int
dfsBacktrack = func(grid [][]int, rows, cols, row, col int) int {
if row < 0 || col < 0 || row >= rows || col >= cols || grid[row][col] == 0 {
return 0
}
originalVal := grid[row][col]
grid[row][col] = 0
maxGold := 0
for i := 0; i < 4; i++ {
maxGold = max(maxGold, dfsBacktrack(grid, rows, cols, row+directions[i], col+directions[i+1]))
}
grid[row][col] = originalVal
return maxGold + originalVal
}
for row := 0; row < rows; row++ {
for col := 0; col < cols; col++ {
maxGold = max(maxGold, dfsBacktrack(grid, rows, cols, row, col))
}
}
return maxGold
}
func max(a, b int) int {
if a > b {
return a
}
return b
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Новая фича на easyoffer – Автоотлики
Вы автоматически откликаетесь на подходящие вам вакансии. Попробуйте её бесплатно и начните получать больше предложений о работе.
🚀 Запуск занимаем всего 3 минуты, а экономит очень много времени
🛡 Это безопасно: easyoffer официально одобрен HeadHunter и прошел его модерацию.
🥷🏻 Автоотклик незаметен для рекртера. Автоотклик ничем не отличается от обычного отклика, который вы делаете вручную
Рекрутеры давно используют автоматизацию для поиска кандидатов. Так почему вы должны откликаться вручную?
💡Совет – Добавьте шаблон сопроводительного письма, чтобы откликаться на большее количество вакансий (на некоторые вакансии нельзя откликнуться без сопроводительного)
Попробовать бесплатно → https://easyoffer.ru/autoapply
Вы автоматически откликаетесь на подходящие вам вакансии. Попробуйте её бесплатно и начните получать больше предложений о работе.
🚀 Запуск занимаем всего 3 минуты, а экономит очень много времени
🛡 Это безопасно: easyoffer официально одобрен HeadHunter и прошел его модерацию.
🥷🏻 Автоотклик незаметен для рекртера. Автоотклик ничем не отличается от обычного отклика, который вы делаете вручную
Рекрутеры давно используют автоматизацию для поиска кандидатов. Так почему вы должны откликаться вручную?
💡Совет – Добавьте шаблон сопроводительного письма, чтобы откликаться на большее количество вакансий (на некоторые вакансии нельзя откликнуться без сопроводительного)
Попробовать бесплатно → https://easyoffer.ru/autoapply
🤔1
Задача: 1051. Height Checker
Сложность: easy
Школа пытается сделать ежегодную фотографию всех учеников. Учеников просят встать в одну шеренгу в неубывающем порядке по росту. Пусть этот порядок представлен целочисленным массивом expected, где expected[i] - ожидаемый рост i-го студента в очереди. Вам дан целочисленный массив heights, представляющий текущий порядок, в котором стоят студенты. Каждый heights[i] - это высота i-го студента в очереди (с индексом 0). Верните количество индексов, в которых heights[i] != expected[i].
Пример:
👨💻 Алгоритм:
1⃣ Создай отсортированную копию массива heights, чтобы получить ожидаемый порядок высот.
2⃣ Пройди по обоим массивам и сравни элементы.
3⃣ Подсчитай количество индексов, где элементы двух массивов не равны
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Школа пытается сделать ежегодную фотографию всех учеников. Учеников просят встать в одну шеренгу в неубывающем порядке по росту. Пусть этот порядок представлен целочисленным массивом expected, где expected[i] - ожидаемый рост i-го студента в очереди. Вам дан целочисленный массив heights, представляющий текущий порядок, в котором стоят студенты. Каждый heights[i] - это высота i-го студента в очереди (с индексом 0). Верните количество индексов, в которых heights[i] != expected[i].
Пример:
Input: heights = [1,1,4,2,1,3]
Output: 3
package main
import (
"fmt"
"sort"
)
func heightChecker(heights []int) int {
expected := make([]int, len(heights))
copy(expected, heights)
sort.Ints(expected)
count := 0
for i := range heights {
if heights[i] != expected[i] {
count++
}
}
return count
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Задача: 260. Single Number III
Сложность: medium
Дан целочисленный массив nums, в котором ровно два элемента встречаются только один раз, а все остальные элементы встречаются ровно дважды. Найдите два элемента, которые встречаются только один раз. Вы можете вернуть ответ в любом порядке.
Вы должны написать алгоритм, который работает за линейное время и использует только постоянное дополнительное пространство..
Пример:
👨💻 Алгоритм:
1⃣ Выполните XOR для всех элементов массива nums. Это даст результат, который является XOR двух уникальных чисел.
2⃣ Найдите бит, который отличается в этих двух числах, чтобы разделить все числа в массиве на две группы.
3⃣ Выполните XOR для каждой группы, чтобы найти два уникальных числа.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан целочисленный массив nums, в котором ровно два элемента встречаются только один раз, а все остальные элементы встречаются ровно дважды. Найдите два элемента, которые встречаются только один раз. Вы можете вернуть ответ в любом порядке.
Вы должны написать алгоритм, который работает за линейное время и использует только постоянное дополнительное пространство..
Пример:
Input: nums = [1,2,1,3,2,5]
Output: [3,5]
Explanation: [5, 3] is also a valid answer.
func singleNumber(nums []int) []int {
xor := 0
for _, num := range nums {
xor ^= num
}
diff := xor & -xor
res := []int{0, 0}
for _, num := range nums {
if num&diff == 0 {
res[0] ^= num
} else {
res[1] ^= num
}
}
return res
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1404. Number of Steps to Reduce a Number in Binary Representation to One
Сложность: medium
Дано бинарное представление целого числа в виде строки s. Верните количество шагов, необходимых для его сокращения до 1 по следующим правилам:
Если текущее число четное, его нужно разделить на 2.
Если текущее число нечетное, нужно прибавить к нему 1.
Гарантируется, что для всех тестовых случаев всегда можно достичь единицы.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменную operations значением 0.
2⃣ Повторяйте операции, пока длина строки s больше 1:
Если последний бит строки s равен 0, это означает, что число четное; примените операцию деления на 2, удалив последний бит.
В противном случае это означает, что число, представленное строкой, нечетное; добавьте 1 к числу, изменив строку, чтобы выполнить эту операцию.
3⃣ Верните количество операций.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано бинарное представление целого числа в виде строки s. Верните количество шагов, необходимых для его сокращения до 1 по следующим правилам:
Если текущее число четное, его нужно разделить на 2.
Если текущее число нечетное, нужно прибавить к нему 1.
Гарантируется, что для всех тестовых случаев всегда можно достичь единицы.
Пример:
Input: s = "1101"
Output: 6
Explanation: "1101" corressponds to number 13 in their decimal representation.
Step 1) 13 is odd, add 1 and obtain 14.
Step 2) 14 is even, divide by 2 and obtain 7.
Step 3) 7 is odd, add 1 and obtain 8.
Step 4) 8 is even, divide by 2 and obtain 4.
Step 5) 4 is even, divide by 2 and obtain 2.
Step 6) 2 is even, divide by 2 and obtain 1.
Если последний бит строки s равен 0, это означает, что число четное; примените операцию деления на 2, удалив последний бит.
В противном случае это означает, что число, представленное строкой, нечетное; добавьте 1 к числу, изменив строку, чтобы выполнить эту операцию.
func numSteps(s string) int {
str := []byte(s)
operations := 0
for len(str) > 1 {
if str[len(str)-1] == '0' {
str = str[:len(str)-1]
} else {
i := len(str) - 1
for i >= 0 && str[i] == '1' {
str[i] = '0'
i--
}
if i < 0 {
str = append([]byte{'1'}, str...)
} else {
str[i] = '1'
}
}
operations++
}
return operations
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1531. String Compression II
Сложность: hard
Дана строка s и целое число k. Необходимо удалить не более k символов из s так, чтобы длина сжатой версии строки s с использованием RLE была минимальной.
Найдите минимальную длину сжатой версии строки s после удаления не более k символов.
Пример:
👨💻 Алгоритм:
1⃣ Обходим символы строки слева направо, решая для каждого символа, включать его в сжатую строку или нет. Это создает состояния (строка, оставшиеся для включения символы), которые можно представить в виде бинарного дерева, где левые потомки означают включение символов, а правые — их пропуск. Многочисленные повторяющиеся подзадачи указывают на необходимость использования динамического программирования.
2⃣ Для определения состояния DP используем следующие параметры: количество пройденных символов (чтобы знать, какой символ обрабатывать следующим), последний добавленный символ в сжатую строку (чтобы определить изменение сжатия при добавлении нового символа), количество последнего символа (для правильного изменения длины сжатия при добавлении символа) и количество оставшихся символов, которые можно удалить.
3⃣ Связываем состояния друг с другом: удаление нового символа увеличивает i на один и уменьшает k на один; включение нового символа оставляет длину сжатия неизменной (кроме случаев, когда частота последнего символа 1, 9 или 99) или увеличивает длину на один, если новый символ не равен последнему символу сжатия.
😎 Решение
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дана строка s и целое число k. Необходимо удалить не более k символов из s так, чтобы длина сжатой версии строки s с использованием RLE была минимальной.
Найдите минимальную длину сжатой версии строки s после удаления не более k символов.
Пример:
Input: s = "aaabcccd", k = 2
Output: 4
Explanation: Compressing s without deleting anything will give us "a3bc3d" of length 6. Deleting any of the characters 'a' or 'c' would at most decrease the length of the compressed string to 5, for instance delete 2 'a' then we will have s = "abcccd" which compressed is abc3d. Therefore, the optimal way is to delete 'b' and 'd', then the compressed version of s will be "a3c3" of length 4.
package main
import "math"
type Solution struct {
memo map[int]int
add map[int]struct{}
}
func Constructor() Solution {
return Solution{memo: make(map[int]int), add: map[int]struct{}{1: {}, 9: {}, 99: {}}}
}
func (this *Solution) GetLengthOfOptimalCompression(s string, k int) int {
return this.dp(s, 0, byte('a'+26), 0, k)
}
func (this *Solution) dp(s string, idx int, lastChar byte, lastCharCount int, k int) int {
if k < 0 {
return math.MaxInt32 / 2
}
if idx == len(s) {
return 0
}
key := idx*101*27*101 + int(lastChar-'a')*101*101 + lastCharCount*101 + k
if res, found := this.memo[key]; found {
return res
}
deleteChar := this.dp(s, idx+1, lastChar, lastCharCount, k-1)
var keepChar int
if s[idx] == lastChar {
keepChar = this.dp(s, idx+1, lastChar, lastCharCount+1, k)
if _, found := this.add[lastCharCount]; found {
keepChar++
}
} else {
keepChar = this.dp(s, idx+1, s[idx], 1, k) + 1
}
res := min(deleteChar, keepChar)
this.memo[key] = res
return res
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 293. Flip Game
Сложность: easy
Вы играете в игру Flip со своим другом.
Вам дана строка currentState, которая содержит только символы '+' и '-'. Вы и ваш друг по очереди переворачиваете две последовательные "++" в "--". Игра заканчивается, когда один из игроков больше не может сделать ход, и, следовательно, другой игрок становится победителем.
Верните все возможные состояния строки currentState после одного допустимого хода. Вы можете вернуть ответы в любом порядке. Если допустимых ходов нет, верните пустой список [].
Пример:
👨💻 Алгоритм:
1⃣ Создайте пустой массив nextPossibleStates для хранения всех возможных следующих состояний после одного хода.
2⃣ Запустите цикл от index = 0 до currentState.size() - 1. Для каждого индекса:
Если символы на позициях index и index + 1 равны '+':
Создайте новую строку nextState, заменив две последовательные '+' на '--'.
Используйте конкатенацию строк для создания nextState из подстроки до первого '+', "--" и подстроки после второго '+' до конца.
Сохраните созданное nextState в массив nextPossibleStates.
3⃣ После цикла верните массив nextPossibleStates, содержащий все возможные следующие состояния.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вы играете в игру Flip со своим другом.
Вам дана строка currentState, которая содержит только символы '+' и '-'. Вы и ваш друг по очереди переворачиваете две последовательные "++" в "--". Игра заканчивается, когда один из игроков больше не может сделать ход, и, следовательно, другой игрок становится победителем.
Верните все возможные состояния строки currentState после одного допустимого хода. Вы можете вернуть ответы в любом порядке. Если допустимых ходов нет, верните пустой список [].
Пример:
Input: currentState = "++++"
Output: ["--++","+--+","++--"]
Если символы на позициях index и index + 1 равны '+':
Создайте новую строку nextState, заменив две последовательные '+' на '--'.
Используйте конкатенацию строк для создания nextState из подстроки до первого '+', "--" и подстроки после второго '+' до конца.
Сохраните созданное nextState в массив nextPossibleStates.
package main
func generatePossibleNextMoves(currentState string) []string {
var nextPossibleStates []string
for i := 0; i < len(currentState)-1; i++ {
if currentState[i] == '+' && currentState[i+1] == '+' {
nextState := currentState[:i] + "--" + currentState[i+2:]
nextPossibleStates = append(nextPossibleStates, nextState)
}
}
return nextPossibleStates
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 651. 4 Keys Keyboard
Сложность: medium
Представьте, что у вас есть специальная клавиатура со следующими клавишами: A: Напечатать одну букву "A" на экране. Ctrl-A: Выделить весь экран. Ctrl-C: Скопировать выделение в буфер. Ctrl-V: Печать буфера на экране с добавлением его после того, что уже было напечатано. Учитывая целое число n, верните максимальное количество букв 'A', которые можно напечатать на экране при нажатии не более n клавиш.
Пример:
👨💻 Алгоритм:
1⃣ Используйте динамическое программирование для отслеживания максимального количества букв 'A' на экране после каждого числа нажатий клавиш.
2⃣ Итерируйтесь от 1 до n, вычисляя максимальное количество 'A' для каждой позиции, учитывая возможность вставки скопированного текста.
3⃣ Возвращайте значение из таблицы динамического программирования для n нажатий клавиш.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Представьте, что у вас есть специальная клавиатура со следующими клавишами: A: Напечатать одну букву "A" на экране. Ctrl-A: Выделить весь экран. Ctrl-C: Скопировать выделение в буфер. Ctrl-V: Печать буфера на экране с добавлением его после того, что уже было напечатано. Учитывая целое число n, верните максимальное количество букв 'A', которые можно напечатать на экране при нажатии не более n клавиш.
Пример:
Input: root = [1,2,3,4,null,2,4,null,null,4]
Output: [[2,4],[4]]
package main
import (
"fmt"
)
func maxA(n int) int {
dp := make([]int, n+1)
for i := 1; i <= n; i++ {
dp[i] = dp[i-1] + 1
for j := 2; j < i; j++ {
dp[i] = max(dp[i], dp[j-2]*(i-j+1))
}
}
return dp[n]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊1
Задача: 1438. Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit
Сложность: medium
Дан массив целых чисел nums и целое число limit. Вернуть размер самой длинной непустой подстроки, такая что абсолютная разница между любыми двумя элементами этой подстроки меньше или равна limit.
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать два дека (minDeque и maxDeque) для хранения минимальных и максимальных значений в текущем окне и переменную left для начала окна.
2⃣ Итеративно добавлять элементы в дек, поддерживая условие абсолютной разницы между максимальным и минимальным элементом в окне, чтобы она была не больше limit, при необходимости сдвигая left.
3⃣ Обновлять maxLength, проверяя максимальную длину текущего окна, и возвращать maxLength как результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел nums и целое число limit. Вернуть размер самой длинной непустой подстроки, такая что абсолютная разница между любыми двумя элементами этой подстроки меньше или равна limit.
Пример:
Input: nums = [8,2,4,7], limit = 4
Output: 2
Explanation: All subarrays are:
[8] with maximum absolute diff |8-8| = 0 <= 4.
[8,2] with maximum absolute diff |8-2| = 6 > 4.
[8,2,4] with maximum absolute diff |8-2| = 6 > 4.
[8,2,4,7] with maximum absolute diff |8-2| = 6 > 4.
[2] with maximum absolute diff |2-2| = 0 <= 4.
[2,4] with maximum absolute diff |2-4| = 2 <= 4.
[2,4,7] with maximum absolute diff |2-7| = 5 > 4.
[4] with maximum absolute diff |4-4| = 0 <= 4.
[4,7] with maximum absolute diff |4-7| = 3 <= 4.
[7] with maximum absolute diff |7-7| = 0 <= 4.
Therefore, the size of the longest subarray is 2.
package main
import (
"container/heap"
)
type IntHeap []int
func (h IntHeap) Len() int { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x interface{}) { *h = append(*h, x.(int)) }
func (h *IntHeap) Pop() interface{} { old := *h; n := len(old); x := old[n-1]; *h = old[0 : n-1]; return x }
type MaxHeap struct{ IntHeap }
func (h MaxHeap) Less(i, j int) bool { return h.IntHeap[i] > h.IntHeap[j] }
func longestSubarray(nums []int, limit int) int {
maxHeap := &MaxHeap{}
minHeap := &IntHeap{}
heap.Init(maxHeap)
heap.Init(minHeap)
left, maxLength := 0, 0
for right, num := range nums {
heap.Push(maxHeap, num)
heap.Push(minHeap, num)
for (*maxHeap)[0]-(*minHeap)[0] > limit {
if (*maxHeap)[0] == nums[left] {
heap.Pop(maxHeap)
}
if (*minHeap)[0] == nums[left] {
heap.Pop(minHeap)
}
left++
}
if maxLength < right-left+1 {
maxLength = right-left+1
}
}
return maxLength
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1258. Synonymous Sentences
Сложность: medium
Вам дан список эквивалентных пар строк synonyms, где synonyms[i] = [si, ti] означает, что si и ti являются эквивалентными строками. Вам также дан текст предложения. Верните все возможные синонимичные предложения, отсортированные лексикографически.
Пример:
👨💻 Алгоритм:
1⃣ Построить граф синонимов, используя структуру данных, такую как Union-Find или просто с использованием DFS/BFS.
2⃣ Пройти по каждому слову в предложении и найти все возможные синонимы.
Сгенерировать все возможные комбинации предложений.
3⃣ Отсортировать полученные предложения лексикографически.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан список эквивалентных пар строк synonyms, где synonyms[i] = [si, ti] означает, что si и ti являются эквивалентными строками. Вам также дан текст предложения. Верните все возможные синонимичные предложения, отсортированные лексикографически.
Пример:
Input: synonyms = [["happy","joy"],["sad","sorrow"],["joy","cheerful"]], text = "I am happy today but was sad yesterday"
Output: ["I am cheerful today but was sad yesterday","I am cheerful today but was sorrow yesterday","I am happy today but was sad yesterday","I am happy today but was sorrow yesterday","I am joy today but was sad yesterday","I am joy today but was sorrow yesterday"]
Сгенерировать все возможные комбинации предложений.
import (
"sort"
"strings"
)
func generateSentences(synonyms [][]string, text string) []string {
graph := make(map[string]map[string]bool)
for _, pair := range synonyms {
if _, ok := graph[pair[0]]; !ok {
graph[pair[0]] = make(map[string]bool)
}
if _, ok := graph[pair[1]]; !ok {
graph[pair[1]] = make(map[string]bool)
}
graph[pair[0]][pair[1]] = true
graph[pair[1]][pair[0]] = true
}
words := strings.Split(text, " ")
synonymGroups := make([][]string, len(words))
for i, word := range words {
synonymGroups[i] = findSynonyms(graph, word)
}
var sentences []string
generate(&sentences, synonymGroups, []string{}, 0)
sort.Strings(sentences)
return sentences
}
func findSynonyms(graph map[string]map[string]bool, word string) []string {
synonyms := make(map[string]bool)
stack := []string{word}
for len(stack) > 0 {
w := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if !synonyms[w] {
synonyms[w] = true
for neighbor := range graph[w] {
stack = append(stack, neighbor)
}
}
}
var result []string
for synonym := range synonyms {
result = append(result, synonym)
}
sort.Strings(result)
return result
}
func generate(sentences *[]string, groups [][]string, sentence []string, index int) {
if index == len(groups) {
*sentences = append(*sentences, strings.Join(sentence, " "))
return
}
for _, word := range groups[index] {
generate(sentences, groups, append(sentence, word), index+1)
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1000. Minimum Cost to Merge Stones
Сложность: hard
Имеется n кучек камней, расположенных в ряд. В i-й куче находятся камни stones[i]. Ход состоит в объединении ровно k последовательных куч в одну кучу, и стоимость этого хода равна общему количеству камней в этих k кучах. Верните минимальную стоимость объединения всех куч камней в одну кучу. Если это невозможно, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Проверка на возможность объединения:
Проверьте, можно ли объединить все кучи в одну, если количество куч n не равно 1 по модулю k-1. Если нет, верните -1.
2⃣ Инициализация и динамическое программирование:
Создайте таблицу dp для хранения минимальных затрат на объединение подмассивов камней.
Используйте таблицу prefix для хранения префиксных сумм камней, чтобы быстро вычислять сумму камней в подмассиве.
3⃣ Заполнение таблицы dp:
Заполните таблицу dp минимальными затратами на объединение подмассивов камней, используя динамическое программирование.
Для каждого подмассива длиной от k до n, найдите минимальную стоимость его объединения.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Имеется n кучек камней, расположенных в ряд. В i-й куче находятся камни stones[i]. Ход состоит в объединении ровно k последовательных куч в одну кучу, и стоимость этого хода равна общему количеству камней в этих k кучах. Верните минимальную стоимость объединения всех куч камней в одну кучу. Если это невозможно, верните -1.
Пример:
Input: stones = [3,2,4,1], k = 2
Output: 20
Проверьте, можно ли объединить все кучи в одну, если количество куч n не равно 1 по модулю k-1. Если нет, верните -1.
Создайте таблицу dp для хранения минимальных затрат на объединение подмассивов камней.
Используйте таблицу prefix для хранения префиксных сумм камней, чтобы быстро вычислять сумму камней в подмассиве.
Заполните таблицу dp минимальными затратами на объединение подмассивов камней, используя динамическое программирование.
Для каждого подмассива длиной от k до n, найдите минимальную стоимость его объединения.
func mergeStones(stones []int, k int) int {
n := len(stones)
if (n-1)%(k-1) != 0 {
return -1
}
prefix := make([]int, n+1)
for i := 0; i < n; i++ {
prefix[i+1] = prefix[i] + stones[i]
}
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, n)
}
for m := k; m <= n; m++ {
for i := 0; i <= n-m; i++ {
j := i + m - 1
dp[i][j] = int(^uint(0) >> 1) // max int
for t := i; t < j; t += k - 1 {
dp[i][j] = min(dp[i][j], dp[i][t]+dp[t+1][j])
}
if (j-i)%(k-1) == 0 {
dp[i][j] += prefix[j+1] - prefix[i]
}
}
}
return dp[0][n-1]
}
func min(a, b int) int {
if a < b {
return a
}
return b
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 762. Prime Number of Set Bits in Binary Representation
Сложность: hard
Если даны два целых числа left и right, верните количество чисел в диапазоне [left, right], имеющих простое число битов в двоичном представлении. Напомним, что число битов в двоичном представлении - это количество единиц, присутствующих в числе 1. Например, 21 в двоичном представлении - это 10101, которое имеет 3 бита.
Пример:
👨💻 Алгоритм:
1⃣ Создайте функцию для подсчета количества единиц в двоичном представлении числа.
2⃣ Создайте функцию для проверки, является ли число простым.
3⃣ Пройдите через все числа в диапазоне [left, right] и подсчитайте числа, у которых количество битов в двоичном представлении является простым числом.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Если даны два целых числа left и right, верните количество чисел в диапазоне [left, right], имеющих простое число битов в двоичном представлении. Напомним, что число битов в двоичном представлении - это количество единиц, присутствующих в числе 1. Например, 21 в двоичном представлении - это 10101, которое имеет 3 бита.
Пример:
Input: left = 10, right = 15
Output: 5
package main
import (
"math"
"strconv"
)
func countPrimeSetBits(left int, right int) int {
count := 0
for num := left; num <= right; num++ {
if isPrime(bitCount(num)) {
count++
}
}
return count
}
func bitCount(x int) int {
return strconv.FormatInt(int64(x), 2)
}
func isPrime(x int) bool {
if x < 2 {
return false
}
for i := 2; i <= int(math.Sqrt(float64(x))); i++ {
if x % i == 0 {
return false
}
}
return true
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: №25. Reverse Nodes in k-Group
Сложность: hard
Учитывая заголовок связанного списка, поменяйте местами узлы списка
Вы не можете изменять значения в узлах списка, можно изменять только сами узлы.
Пример:
👨💻 Алгоритм:
1⃣ Подсчитать количество узлов в списке, чтобы обрабатывать только полные группы
2⃣ Использовать итеративный метод для переворота узлов в каждой группе
3⃣ Обновлять указатели после переворота, чтобы соединить обработанные части списка.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Учитывая заголовок связанного списка, поменяйте местами узлы списка
k за раз и верните измененный список. k — целое положительное число, меньшее или равное длине связанного списка. Если количество узлов не кратно k, то пропущенные узлы в конечном итоге должны остаться такими, какие они есть. Вы не можете изменять значения в узлах списка, можно изменять только сами узлы.
Пример:
Input: head = [1,2,3,4,5], k = 3
Output: [3,2,1,4,5]
k. k. func reverseKGroup(head *ListNode, k int) *ListNode {
if head == nil || k == 1 {
return head
}
dummy := &ListNode{Next: head}
prev, curr := dummy, head
count := 0
for curr != nil {
count++
curr = curr.Next
}
for count >= k {
curr = prev.Next
next := curr.Next
for i := 1; i < k; i++ {
curr.Next = next.Next
next.Next = prev.Next
prev.Next = next
next = curr.Next
}
prev = curr
count -= k
}
return dummy.Next
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 845. Longest Mountain in Array
Сложность: medium
Вы можете вспомнить, что массив arr является горным массивом тогда и только тогда, когда:
длина массива arr >= 3
Существует индекс i (счёт начинается с 0) такой, что:
arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
Дан целочисленный массив arr, верните длину самой длинной подпоследовательности, которая является горной. Верните 0, если такой подпоследовательности нет.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменные для отслеживания текущего основания и максимальной длины горного массива.
2⃣ Для каждого индекса, который может быть началом горного массива, определите пиковый элемент и найдите правую границу горного массива.
3⃣ Если найден горный массив, обновите максимальную длину и переместите основание на конец текущего горного массива.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вы можете вспомнить, что массив arr является горным массивом тогда и только тогда, когда:
длина массива arr >= 3
Существует индекс i (счёт начинается с 0) такой, что:
arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
arr[i] > arr[i + 1] > ... > arr[arr.length - 1]
Дан целочисленный массив arr, верните длину самой длинной подпоследовательности, которая является горной. Верните 0, если такой подпоследовательности нет.
Пример:
Input: arr = [2,1,4,7,3,2,5]
Output: 5
Explanation: The largest mountain is [1,4,7,3,2] which has length 5.
func longestMountain(arr []int) int {
n := len(arr)
ans := 0
base := 0
for base < n {
end := base
if end+1 < n && arr[end] < arr[end+1] {
for end+1 < n && arr[end] < arr[end+1] {
end++
}
if end+1 < n && arr[end] > arr[end+1] {
for end+1 < n && arr[end] > arr[end+1] {
end++
}
ans = max(ans, end-base+1)
}
}
base = max(end, base+1)
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 861. Score After Flipping Matrix
Сложность: medium
Вам дана бинарная матрица grid размером m x n.
Ход состоит из выбора любой строки или столбца и переключения каждого значения в этой строке или столбце (т.е. изменение всех 0 на 1, и всех 1 на 0).
Каждая строка матрицы интерпретируется как двоичное число, и счёт матрицы — это сумма этих чисел.
Верните наивысший возможный счёт после выполнения любого количества ходов (включая ноль ходов).
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменные: m и n для количества строк и столбцов в grid, score для хранения максимального счёта матрицы. Пройдитесь по первому столбцу матрицы. Если элемент равен 0, переверните всю строку.
2⃣ Пройдитесь по матрице от второго до последнего столбца. Для каждого столбца посчитайте количество нулей (countZero). Если количество нулей больше, переверните весь столбец.
3⃣ Пройдитесь по модифицированной матрице. Для каждого элемента добавьте его к score, сдвинув влево на значение текущего столбца. Верните score, который хранит наивысший возможный счёт матрицы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана бинарная матрица grid размером m x n.
Ход состоит из выбора любой строки или столбца и переключения каждого значения в этой строке или столбце (т.е. изменение всех 0 на 1, и всех 1 на 0).
Каждая строка матрицы интерпретируется как двоичное число, и счёт матрицы — это сумма этих чисел.
Верните наивысший возможный счёт после выполнения любого количества ходов (включая ноль ходов).
Пример:
Input: grid = [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
Output: 39
Explanation: 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
func matrixScore(grid [][]int) int {
m, n := len(grid), len(grid[0])
for i := 0; i < m; i++ {
if grid[i][0] == 0 {
for j := 0; j < n; j++ {
grid[i][j] ^= 1
}
}
}
for j := 1; j < n; j++ {
countZero := 0
for i := 0; i < m; i++ {
if grid[i][j] == 0 {
countZero++
}
}
if countZero > m/2 {
for i := 0; i < m; i++ {
grid[i][j] ^= 1
}
}
}
score := 0
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if grid[i][j] == 1 {
score += 1 << (n - j - 1)
}
}
}
return score
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 378. Kth Smallest Element in a Sorted Matrix
Сложность: medium
Дана матрица размером n x n, где каждая строка и каждый столбец отсортированы в порядке возрастания. Верните k-й наименьший элемент в матрице.
Заметьте, что это k-й наименьший элемент в отсортированном порядке, а не k-й уникальный элемент.
Вы должны найти решение с использованием памяти лучше, чем O(n²).
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать мин-кучу H. В нашем решении мы будем рассматривать каждую строку как отдельный список. Поскольку столбцы также отсортированы, мы можем рассматривать каждый столбец как отдельный список.
2⃣ Взять первые элементы из min(N, K) строк, где N представляет количество строк, и добавить каждый из этих элементов в кучу. Важно знать, к какой строке и столбцу принадлежит элемент, чтобы в дальнейшем перемещаться по соответствующему списку.
3⃣ Мин-куча будет содержать тройки информации (значение, строка, столбец). Куча будет упорядочена по значениям, и мы будем использовать номера строк и столбцов для добавления следующего элемента, если текущий элемент будет удален из кучи.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана матрица размером n x n, где каждая строка и каждый столбец отсортированы в порядке возрастания. Верните k-й наименьший элемент в матрице.
Заметьте, что это k-й наименьший элемент в отсортированном порядке, а не k-й уникальный элемент.
Вы должны найти решение с использованием памяти лучше, чем O(n²).
Пример:
Input: matrix = [[-5]], k = 1
Output: -5
package main
import (
"strings"
)
type Solution struct{}
func (s Solution) dfs(word string, length int, visited []bool, dictionary map[string]bool) bool {
if length == len(word) {
return true
}
if visited[length] {
return false
}
visited[length] = true
for i := len(word) - 1; i > length; i-- {
if dictionary[word[length:i]] && s.dfs(word, i, visited, dictionary) {
return true
}
}
return false
}
func (s Solution) findAllConcatenatedWordsInADict(words []string) []string {
dictionary := make(map[string]bool)
for _, word := range words {
dictionary[word] = true
}
var answer []string
for _, word := range words {
visited := make([]bool, len(word))
if s.dfs(word, 0, visited, dictionary) {
answer = append(answer, word)
}
}
return answer
}
func main() {
solution := Solution{}
words := []string{"cat", "cats", "catsdogcats", "dog", "dogcatsdog", "hippopotamuses", "rat", "ratcatdogcat"}
result := solution.findAllConcatenatedWordsInADict(words)
for _, word := range result {
println(word)
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1255. Maximum Score Words Formed by Letters
Сложность: hard
Даны список слов, список отдельных букв (могут повторяться) и оценка каждого символа. Верните максимальную оценку любого правильного набора слов, образованного с помощью заданных букв (words[i] не может быть использовано два или более раз). Не обязательно использовать все символы в буквах, каждая буква может быть использована только один раз. Оценка букв 'a', 'b', 'c', ... , 'z' задаются значениями score[0], score[1], ... , score[25] соответственно.
Пример:
👨💻 Алгоритм:
1⃣ Создайте функцию для вычисления оценки слова.
2⃣ Используйте метод перебора подмножеств (или битовое представление всех подмножеств) для нахождения всех возможных комбинаций слов.
Для каждой комбинации проверяйте, можно ли составить каждое слово из доступных букв.
3⃣ Вычислите суммарную оценку для каждой допустимой комбинации слов и сохраните максимальную оценку.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Даны список слов, список отдельных букв (могут повторяться) и оценка каждого символа. Верните максимальную оценку любого правильного набора слов, образованного с помощью заданных букв (words[i] не может быть использовано два или более раз). Не обязательно использовать все символы в буквах, каждая буква может быть использована только один раз. Оценка букв 'a', 'b', 'c', ... , 'z' задаются значениями score[0], score[1], ... , score[25] соответственно.
Пример:
Input: words = ["dog","cat","dad","good"], letters = ["a","a","c","d","d","d","g","o","o"], score = [1,0,9,5,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0]
Output: 23Для каждой комбинации проверяйте, можно ли составить каждое слово из доступных букв.
func maxScoreWords(words []string, letters []byte, score []int) int {
letterCount := make(map[byte]int)
for _, ch := range letters {
letterCount[ch]++
}
wordScore := func(word string) int {
total := 0
for i := 0; i < len(word); i++ {
total += score[word[i] - 'a']
}
return total
}
canFormWord := func(word string, letterCount map[byte]int) bool {
count := make(map[byte]int)
for i := 0; i < len(word); i++ {
count[word[i]]++
if count[word[i]] > letterCount[word[i]] {
return false
}
}
return true
}
maxScore := 0
n := len(words)
for i := 1; i < (1 << n); i++ {
currScore := 0
usedLetters := make(map[byte]int)
valid := true
for j := 0; j < n; j++ {
if i & (1 << j) != 0 {
word := words[j]
if canFormWord(word, letterCount) {
currScore += wordScore(word)
for k := 0; k < len(word); k++ {
usedLetters[word[k]]++
}
} else {
valid = false
break
}
}
}
if valid {
if currScore > maxScore {
maxScore = currScore
}
}
}
return maxScore
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 892. Surface Area of 3D Shapes
Сложность: easy
Вам дана сетка n x n, на которой вы разместили несколько кубиков 1 x 1 x 1. Каждое значение v = grid[i][j] представляет собой башню из v кубиков, размещенных на вершине ячейки (i, j). После размещения кубиков вы решили склеить все непосредственно прилегающие кубики друг с другом, образовав несколько неправильных 3D-фигур. Верните общую площадь поверхности получившихся фигур. Примечание: нижняя грань каждой фигуры учитывается в площади ее поверхности.
Пример:
👨💻 Алгоритм:
1⃣ Пройти по всей сетке и для каждой башни (ячейки) посчитать начальную площадь поверхности: добавить площадь верхней и нижней граней, а также четыре боковые грани.
2⃣ Для каждой башни уменьшить площадь боковых граней, которые прилегают к соседним башням, с учетом высоты соседних башен.
3⃣ Просуммировать все значения площадей для получения итоговой площади поверхности.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: 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
func surfaceArea(grid [][]int) int {
n := len(grid)
area := 0
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if grid[i][j] > 0 {
area += (grid[i][j] * 4) + 2
}
if i > 0 {
area -= min(grid[i][j], grid[i-1][j]) * 2
}
if j > 0 {
area -= min(grid[i][j], grid[i][j-1]) * 2
}
}
}
return area
}
func min(a, b int) int {
if a < b {
return a
}
return b
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 370. Range Addition
Сложность: medium
Дано целое число length и массив updates, где updates[i] = [startIdxi, endIdxi, inci].
У вас есть массив arr длины length, заполненный нулями. Вам нужно применить некоторые операции к arr. В i-й операции следует увеличить все элементы arr[startIdxi], arr[startIdxi + 1], ..., arr[endIdxi] на inci.
Верните arr после применения всех обновлений.
Пример:
👨💻 Алгоритм:
1⃣ Для каждого обновления (start, end, val) выполните две операции:
Увеличьте значение в позиции start на val: arr[start] = arr[start] + val.
Уменьшите значение в позиции end + 1 на val: arr[end + 1] = arr[end + 1] - val.
2⃣ Примените конечное преобразование: вычислите кумулятивную сумму всего массива (с индексами, начиная с 0).
3⃣ Верните обновленный массив arr.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано целое число length и массив updates, где updates[i] = [startIdxi, endIdxi, inci].
У вас есть массив arr длины length, заполненный нулями. Вам нужно применить некоторые операции к arr. В i-й операции следует увеличить все элементы arr[startIdxi], arr[startIdxi + 1], ..., arr[endIdxi] на inci.
Верните arr после применения всех обновлений.
Пример:
Input: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]
Output: [-2,0,3,5,3]
Увеличьте значение в позиции start на val: arr[start] = arr[start] + val.
Уменьшите значение в позиции end + 1 на val: arr[end + 1] = arr[end + 1] - val.
fun getModifiedArray(length: Int, updates: Array<IntArray>): IntArray {
val result = IntArray(length)
for (update in updates) {
val start = update[0]
val end = update[1]
val `val` = update[2]
result[start] += `val`
if (end + 1 < length) {
result[end + 1] -= `val`
}
}
for (i in 1 until length) {
result[i] += result[i - 1]
}
return result
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: №26. Remove Duplicates from Sorted Array
Сложность: easy
Учитывая целочисленный массив
Относительный порядок элементов должен оставаться неизменным. Затем верните количество уникальных элементов.
Пример:
👨💻 Алгоритм:
1⃣ Использовать два указателя:
2⃣ Если
3⃣ По завершении вернуть
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Учитывая целочисленный массив
nums, отсортированный в неубывающем порядке, удалите дубликаты на месте так, чтобы каждый уникальный элемент появлялся только один раз. Относительный порядок элементов должен оставаться неизменным. Затем верните количество уникальных элементов.
Пример:
Input: nums = [1,1,2]
Output: 2
i для отслеживания позиции последнего уникального элемента и j для итерации по массиву. nums[j] не равен nums[i], записать nums[j] на nums[i+1] и сдвинуть i. i+1 как количество уникальных элементов. func removeDuplicates(nums []int) int {
if len(nums) == 0 {
return 0
}
i := 0
for j := 1; j < len(nums); j++ {
if nums[j] != nums[i] {
i++
nums[i] = nums[j]
}
}
return i + 1
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM