Задача: 659. Split Array into Consecutive Subsequences
Сложность: medium
Вам дан отсортированный в неубывающем порядке массив целых чисел nums.
Определите, можно ли разделить nums на одну или несколько подпоследовательностей так, чтобы выполнялись оба следующих условия:
Каждая подпоследовательность является последовательностью последовательных возрастающих чисел (то есть каждое целое число на 1 больше предыдущего).
Все подпоследовательности имеют длину 3 или более.
Верните true, если можно разделить nums согласно вышеуказанным условиям, или false в противном случае.
Подпоследовательность массива — это новый массив, который формируется из исходного массива путем удаления некоторых (может быть, ни одного) элементов без нарушения относительных позиций оставшихся элементов. (например, [1,3,5] является подпоследовательностью [1,2,3,4,5], тогда как [1,3,2] не является).
Пример:
👨💻 Алгоритм:
1⃣ Подсчет частоты элементов:
Создайте хеш-таблицу для подсчета количества вхождений каждого элемента в массиве nums.
2⃣ Создание подпоследовательностей:
Создайте хеш-таблицу для отслеживания количества подпоследовательностей, которые могут быть продолжены для каждого элемента.
Пройдите по каждому элементу в массиве и выполните следующие действия:
Если элемент можно добавить к существующей подпоследовательности (проверяя хеш-таблицу подпоследовательностей), добавьте его и обновите хеш-таблицу.
Если элемент нельзя добавить к существующей подпоследовательности, начните новую последовательность длиной 3 или более элементов.
Если ни одно из условий не выполнено, верните false.
3⃣ Проверка результата:
Верните true, если все элементы успешно распределены по подпоследовательностям.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан отсортированный в неубывающем порядке массив целых чисел nums.
Определите, можно ли разделить nums на одну или несколько подпоследовательностей так, чтобы выполнялись оба следующих условия:
Каждая подпоследовательность является последовательностью последовательных возрастающих чисел (то есть каждое целое число на 1 больше предыдущего).
Все подпоследовательности имеют длину 3 или более.
Верните true, если можно разделить nums согласно вышеуказанным условиям, или false в противном случае.
Подпоследовательность массива — это новый массив, который формируется из исходного массива путем удаления некоторых (может быть, ни одного) элементов без нарушения относительных позиций оставшихся элементов. (например, [1,3,5] является подпоследовательностью [1,2,3,4,5], тогда как [1,3,2] не является).
Пример:
Input: nums = [1,2,3,3,4,5]
Output: true
Создайте хеш-таблицу для подсчета количества вхождений каждого элемента в массиве nums.
Создайте хеш-таблицу для отслеживания количества подпоследовательностей, которые могут быть продолжены для каждого элемента.
Пройдите по каждому элементу в массиве и выполните следующие действия:
Если элемент можно добавить к существующей подпоследовательности (проверяя хеш-таблицу подпоследовательностей), добавьте его и обновите хеш-таблицу.
Если элемент нельзя добавить к существующей подпоследовательности, начните новую последовательность длиной 3 или более элементов.
Если ни одно из условий не выполнено, верните false.
Верните true, если все элементы успешно распределены по подпоследовательностям.
func isPossible(nums []int) bool {
freq := make(map[int]int)
need := make(map[int]int)
for _, num := range nums {
freq[num]++
}
for _, num := range nums {
if freq[num] == 0 {
continue
}
if need[num] > 0 {
need[num]--
need[num+1]++
} else if freq[num+1] > 0 && freq[num+2] > 0 {
freq[num+1]--
freq[num+2]--
need[num+3]++
} else {
return false
}
freq[num]--
}
return true
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 684. Redundant Connection
Сложность: medium
В этой задаче дерево — это неориентированный граф, который является связным и не содержит циклов.
Вам дан граф, который изначально был деревом с n узлами, пронумерованными от 1 до n, и к которому добавили одно дополнительное ребро. Добавленное ребро соединяет две разные вершины, выбранные из 1 до n, и это ребро не существовало ранее. Граф представлен массивом edges длины n, где edges[i] = [ai, bi] указывает на то, что существует ребро между узлами ai и bi в графе.
Верните ребро, которое можно удалить, чтобы результирующий граф стал деревом из n узлов. Если существует несколько ответов, верните тот, который встречается последним в исходных данных.
Пример:
👨💻 Алгоритм:
1⃣ Для каждого ребра (u, v) создайте представление графа с использованием списка смежности. Это позволит легко выполнять обход в глубину (DFS) для проверки соединений между узлами.
2⃣ Выполняйте обход в глубину для каждого ребра, временно удаляя его из графа. Проверьте, можно ли соединить узлы u и v с помощью обхода в глубину. Если узлы остаются соединенными, значит, это ребро является дублирующимся.
3⃣ Верните дублирующееся ребро, которое встречается последним в исходных данных. Это обеспечит корректность решения, даже если существует несколько ответов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
В этой задаче дерево — это неориентированный граф, который является связным и не содержит циклов.
Вам дан граф, который изначально был деревом с n узлами, пронумерованными от 1 до n, и к которому добавили одно дополнительное ребро. Добавленное ребро соединяет две разные вершины, выбранные из 1 до n, и это ребро не существовало ранее. Граф представлен массивом edges длины n, где edges[i] = [ai, bi] указывает на то, что существует ребро между узлами ai и bi в графе.
Верните ребро, которое можно удалить, чтобы результирующий граф стал деревом из n узлов. Если существует несколько ответов, верните тот, который встречается последним в исходных данных.
Пример:
Input: edges = [[1,2],[1,3],[2,3]]
Output: [2,3]
package main
func findRedundantConnection(edges [][]int) []int {
const MAX_EDGE_VAL = 1000
graph := make([][]int, MAX_EDGE_VAL+1)
for i := range graph {
graph[i] = make([]int, 0)
}
seen := make(map[int]bool)
var dfs func(source, target int) bool
dfs = func(source, target int) bool {
if !seen[source] {
seen[source] = true
if source == target {
return true
}
for _, nei := range graph[source] {
if dfs(nei, target) {
return true
}
}
}
return false
}
for _, edge := range edges {
seen = make(map[int]bool)
if len(graph[edge[0]]) > 0 && len(graph[edge[1]]) > 0 && dfs(edge[0], edge[1]) {
return edge
}
graph[edge[0]] = append(graph[edge[0]], edge[1])
graph[edge[1]] = append(graph[edge[1]], edge[0])
}
return nil
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 107. Binary Tree Level Order Traversal II
Сложность: medium
Дан корень бинарного дерева. Верните обход значений узлов снизу вверх по уровням (то есть слева направо, уровень за уровнем, от листа к корню).
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте список вывода levels. Длина этого списка определяет, какой уровень в данный момент обновляется. Вам следует сравнить этот уровень len(levels) с уровнем узла level, чтобы убедиться, что вы добавляете узел на правильный уровень. Если вы все еще находитесь на предыдущем уровне, добавьте новый уровень, вставив новый список в levels.
2⃣ Добавьте значение узла в последний уровень в levels.
3⃣ Рекурсивно обработайте дочерние узлы, если они не равны None, используя функцию helper(node.left / node.right, level + 1).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан корень бинарного дерева. Верните обход значений узлов снизу вверх по уровням (то есть слева направо, уровень за уровнем, от листа к корню).
Пример:
Input: root = [3,9,20,null,null,15,7]
Output: [[15,7],[9,20],[3]]
func levelOrderBottom(root *TreeNode) [][]int {
levels := make([][]int, 0)
var helper func(node *TreeNode, level int)
helper = func(node *TreeNode, level int) {
if node == nil {
return
}
if len(levels) == level {
levels = append(levels, []int{})
}
levels[level] = append(levels[level], node.Val)
if node.Left != nil {
helper(node.Left, level+1)
}
if node.Right != nil {
helper(node.Right, level+1)
}
}
helper(root, 0)
for i := 0; i < len(levels)/2; i++ {
levels[i], levels[len(levels)-1-i] = levels[len(levels)-1-i], levels[i]
}
return levels
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 168. Excel Sheet Column Title
Сложность: easy
Дано целое число columnNumber, верните соответствующий заголовок столбца, как он отображается в таблице Excel.
Например:
A -> 1
B -> 2
C -> 3
Z -> 26
AA -> 27
AB -> 28
Пример:
👨💻 Алгоритм:
1⃣ Инициализация пустой строки ans:
Создайте пустую строку ans, которая будет хранить заголовок столбца.
2⃣ Циклическое преобразование числа в буквы:
Пока columnNumber больше 0, выполняйте следующие действия:
- Вычтите 1 из columnNumber для корректировки индекса (Excel использует 1-индексацию).
- Найдите символ, соответствующий остатку от деления columnNumber на 26, и добавьте его в начало строки ans.
- Присвойте columnNumber значение от деления columnNumber на 26.
3⃣ Переворот и возврат результата:
Так как символы добавляются в начало строки, то по завершению цикла строка ans содержит заголовок столбца в обратном порядке.
Переверните строку ans, чтобы представить её в правильном порядке.
Верните полученный заголовок столбца.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано целое число columnNumber, верните соответствующий заголовок столбца, как он отображается в таблице Excel.
Например:
A -> 1
B -> 2
C -> 3
Z -> 26
AA -> 27
AB -> 28
Пример:
Input: columnNumber = 1
Output: "A"
Создайте пустую строку ans, которая будет хранить заголовок столбца.
Пока columnNumber больше 0, выполняйте следующие действия:
- Вычтите 1 из columnNumber для корректировки индекса (Excel использует 1-индексацию).
- Найдите символ, соответствующий остатку от деления columnNumber на 26, и добавьте его в начало строки ans.
- Присвойте columnNumber значение от деления columnNumber на 26.
Так как символы добавляются в начало строки, то по завершению цикла строка ans содержит заголовок столбца в обратном порядке.
Переверните строку ans, чтобы представить её в правильном порядке.
Верните полученный заголовок столбца.
func convertToTitle(columnNumber int) string {
ans := ""
for columnNumber > 0 {
columnNumber = columnNumber - 1
ans = string(rune((columnNumber)%26+'A')) + ans
columnNumber = (columnNumber) / 26
}
return ans
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 291. Word Pattern II
Сложность: medium
Дан шаблон и строка s, вернуть true, если строка s соответствует шаблону.
Строка s соответствует шаблону, если существует биективное отображение отдельных символов на непустые строки так, что если каждый символ в шаблоне заменить на строку, которой он отображается, то результирующая строка будет равна s. Биективное отображение означает, что ни два символа не отображаются на одну и ту же строку, и ни один символ не отображается на две разные строки.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация структур данных и определение рекурсивной функции:
Создайте хеш-таблицу symbolMap для отображения символов шаблона на подстроки строки s.
Создайте множество wordSet для хранения уникальных подстрок строки s, которые были отображены на символ.
Определите рекурсивную функцию isMatch, принимающую индексы в строке s (sIndex) и в шаблоне (pIndex), чтобы определить, соответствует ли строка s шаблону.
2⃣ Рекурсивная проверка соответствия:
Базовый случай: если pIndex равно длине шаблона, верните true, если sIndex равно длине строки s; иначе верните false.
Получите символ из шаблона по индексу pIndex.
Если символ уже ассоциирован с подстрокой, проверьте, совпадают ли следующие символы в строке s с этой подстрокой. Если нет, верните false. Если совпадают, вызовите isMatch для следующего символа в шаблоне.
3⃣ Отображение новых подстрок:
Если символ новый, попробуйте сопоставить его с новыми подстроками строки s, начиная с sIndex и до конца строки.
Для каждой новой подстроки проверьте, существует ли она уже в `
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан шаблон и строка s, вернуть true, если строка s соответствует шаблону.
Строка s соответствует шаблону, если существует биективное отображение отдельных символов на непустые строки так, что если каждый символ в шаблоне заменить на строку, которой он отображается, то результирующая строка будет равна s. Биективное отображение означает, что ни два символа не отображаются на одну и ту же строку, и ни один символ не отображается на две разные строки.
Пример:
Input: pattern = "abab", s = "redblueredblue"
Output: true
Explanation: One possible mapping is as follows:
'a' -> "red"
'b' -> "blue"
Создайте хеш-таблицу symbolMap для отображения символов шаблона на подстроки строки s.
Создайте множество wordSet для хранения уникальных подстрок строки s, которые были отображены на символ.
Определите рекурсивную функцию isMatch, принимающую индексы в строке s (sIndex) и в шаблоне (pIndex), чтобы определить, соответствует ли строка s шаблону.
Базовый случай: если pIndex равно длине шаблона, верните true, если sIndex равно длине строки s; иначе верните false.
Получите символ из шаблона по индексу pIndex.
Если символ уже ассоциирован с подстрокой, проверьте, совпадают ли следующие символы в строке s с этой подстрокой. Если нет, верните false. Если совпадают, вызовите isMatch для следующего символа в шаблоне.
Если символ новый, попробуйте сопоставить его с новыми подстроками строки s, начиная с sIndex и до конца строки.
Для каждой новой подстроки проверьте, существует ли она уже в `
package main
func wordPatternMatch(pattern string, s string) bool {
symbolMap := make(map[rune]string)
wordSet := make(map[string]bool)
return isMatch(s, 0, pattern, 0, symbolMap, wordSet)
}
func isMatch(s string, sIndex int, pattern string, pIndex int,
symbolMap map[rune]string, wordSet map[string]bool) bool {
if pIndex == len(pattern) {
return sIndex == len(s)
}
symbol := rune(pattern[pIndex])
if word, ok := symbolMap[symbol]; ok {
if !startsWith(s, sIndex, word) {
return false
}
return isMatch(s, sIndex+len(word), pattern, pIndex+1, symbolMap, wordSet)
}
for k := sIndex + 1; k <= len(s); k++ {
newWord := s[sIndex:k]
if wordSet[newWord] {
continue
}
symbolMap[symbol] = newWord
wordSet[newWord] = true
if isMatch(s, k, pattern, pIndex+1, symbolMap, wordSet) {
return true
}
delete(symbolMap, symbol)
delete(wordSet, newWord)
}
return false
}
func startsWith(s string, sIndex int, word string) bool {
if len(s)-sIndex < len(word) {
return false
}
for i := 0; i < len(word); i++ {
if s[sIndex+i] != word[i] {
return false
}
}
return true
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1249. Minimum Remove to Make Valid Parentheses
Сложность: medium
Дана строка s из '(' , ')' и строчных английских символов. Ваша задача - удалить минимальное количество скобок ( '(' или ')' в любых позициях), чтобы полученная строка со скобками была допустимой, и вернуть любую допустимую строку. Формально строка со скобками допустима тогда и только тогда, когда: она пустая, содержит только строчные символы, или может быть записана как AB (A, конкатенированная с B), где A и B - допустимые строки, или может быть записана как (A), где A - допустимая строка.
Пример:
👨💻 Алгоритм:
1⃣ Пройдите по строке s и сохраните индексы всех открывающих скобок '(' в стек. При встрече закрывающей скобки ')', удалите соответствующую открытую скобку из стека. Если в стеке нет соответствующей открывающей скобки, пометьте эту закрывающую скобку для удаления.
2⃣ После первого прохода, все оставшиеся в стеке открывающие скобки пометьте для удаления.
3⃣ Создайте новую строку, удалив все помеченные скобки.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана строка s из '(' , ')' и строчных английских символов. Ваша задача - удалить минимальное количество скобок ( '(' или ')' в любых позициях), чтобы полученная строка со скобками была допустимой, и вернуть любую допустимую строку. Формально строка со скобками допустима тогда и только тогда, когда: она пустая, содержит только строчные символы, или может быть записана как AB (A, конкатенированная с B), где A и B - допустимые строки, или может быть записана как (A), где A - допустимая строка.
Пример:
Input: s = "lee(t(c)o)de)"
Output: "lee(t(c)o)de"func minRemoveToMakeValid(s string) string {
stack := []int{}
res := []byte(s)
for i := 0; i < len(res); i++ {
if res[i] == '(' {
stack = append(stack, i)
} else if res[i] == ')' {
if len(stack) > 0 {
stack = stack[:len(stack)-1]
} else {
res[i] = '*'
}
}
}
for len(stack) > 0 {
res[stack[len(stack)-1]] = '*'
stack = stack[:len(stack)-1]
}
return strings.ReplaceAll(string(res), "*", "")
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 270. Closest Binary Search Tree Value
Сложность: easy
Дано корень бинарного дерева поиска и целевое значение. Верните значение в дереве, которое ближе всего к целевому. Если существует несколько ответов, выведите наименьшее.
Пример:
👨💻 Алгоритм:
1⃣ Построить массив с помощью inorder обхода:
Выполнить inorder обход дерева и собрать элементы в отсортированный массив.
2⃣ Найти ближайший элемент:
Пройти по массиву и определить элемент, наиболее близкий к целевому значению.
3⃣ Выбрать наименьший из ближайших элементов:
Если несколько элементов одинаково близки к целевому значению, выбрать наименьший из них.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано корень бинарного дерева поиска и целевое значение. Верните значение в дереве, которое ближе всего к целевому. Если существует несколько ответов, выведите наименьшее.
Пример:
Input: root = [4,2,5,1,3], target = 3.714286
Output: 4
Выполнить inorder обход дерева и собрать элементы в отсортированный массив.
Пройти по массиву и определить элемент, наиболее близкий к целевому значению.
Если несколько элементов одинаково близки к целевому значению, выбрать наименьший из них.
package main
import "math"
func closestValue(root *TreeNode, target float64) int {
closest := root.Val
for root != nil {
if math.Abs(float64(root.Val)-target) < math.Abs(float64(closest)-target) {
closest = root.Val
} else if math.Abs(float64(root.Val)-target) == math.Abs(float64(closest)-target) {
if root.Val < closest {
closest = root.Val
}
}
if target < float64(root.Val) {
root = root.Left
} else {
root = root.Right
}
}
return closest
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Задача: 101. Symmetric Tree
Сложность: easy
Дан корень бинарного дерева. Проверьте, является ли это дерево зеркальным отражением самого себя (то есть симметричным относительно своего центра).
Пример:
👨💻 Алгоритм:
1⃣ Дерево симметрично, если его левое и правое поддеревья — зеркальные копии друг друга.
2⃣ Два дерева являются зеркальными, если корни равны, правое поддерево одного — это зеркальное отражение левого поддерева другого, и наоборот.
3️⃣ Проверку удобно реализовать через рекурсивную функцию, сравнивающую два поддерева на симметричность.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан корень бинарного дерева. Проверьте, является ли это дерево зеркальным отражением самого себя (то есть симметричным относительно своего центра).
Пример:
Input: root = [1,2,2,3,4,4,3]
Output: true
func isSymmetric(root *TreeNode) bool {
return isMirror(root, root)
}
func isMirror(t1 *TreeNode, t2 *TreeNode) bool {
if t1 == nil && t2 == nil {
return true
}
if t1 == nil || t2 == nil {
return false
}
return (t1.Val == t2.Val) &&
isMirror(t1.Right, t2.Left) &&
isMirror(t1.Left, t2.Right)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 85. Maximal Rectangle
Сложность: hard
Дана бинарная матрица размером rows x cols, заполненная 0 и 1. Найдите наибольший прямоугольник, содержащий только 1, и верните его площадь.
Пример:
👨💻 Алгоритм:
1⃣ Вычисление максимальной ширины прямоугольника для каждой координаты: Для каждой ячейки в каждой строке сохраняем количество последовательных единиц. При прохождении по строке обновляем максимально возможную ширину в этой точке, используя формулу row[i] = row[i - 1] + 1, если row[i] == '1'.
2⃣ Определение максимальной площади прямоугольника с нижним правым углом в данной точке: При итерации вверх по столбцу максимальная ширина прямоугольника от исходной точки до текущей точки является минимальным значением среди всех максимальных ширин, с которыми мы сталкивались. Используем формулу maxWidth = min(maxWidth, widthHere) и curArea = maxWidth * (currentRow - originalRow + 1), затем обновляем maxArea = max(maxArea, curArea).
3⃣ Применение алгоритма для каждой точки ввода для глобального максимума: Преобразуя входные данные в набор гистограмм, где каждый столбец является новой гистограммой, мы вычисляем максимальную площадь для каждой гистограммы.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Дана бинарная матрица размером rows x cols, заполненная 0 и 1. Найдите наибольший прямоугольник, содержащий только 1, и верните его площадь.
Пример:
Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
Output: 6
Explanation: The maximal rectangle is shown in the above picture.
func maximalRectangle(matrix [][]byte) int {
if len(matrix) == 0 {
return 0
}
maxarea := 0
dp := make([][]int, len(matrix))
for i := range dp {
dp[i] = make([]int, len(matrix[0]))
}
for i := 0; i < len(matrix); i++ {
for j := 0; j < len(matrix[0]); j++ {
if matrix[i][j] == '1' {
dp[i][j] = 1
if j != 0 {
dp[i][j] += dp[i][j-1]
}
width := dp[i][j]
for k := i; k >= 0; k-- {
width = min(width, dp[k][j])
maxarea = max(maxarea, width*(i-k+1))
}
}
}
}
return maxarea
}
func min(x, y int) int {
if x < y {
return x
}
return y
}
func max(x, y int) int {
if x > y {
return x
}
return y
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 681. Next Closest Time
Сложность: medium
Дано время, представленное в формате "ЧЧ:ММ". Сформируйте ближайшее следующее время, используя текущие цифры. Количество раз, которое можно использовать цифру, не ограничено.
Можно предположить, что заданная строка всегда корректна. Например, "01:34", "12:09" являются корректными. "1:34", "12:9" являются некорректными.
Пример:
👨💻 Алгоритм:
1⃣ Симулируйте ход часов, увеличивая время на одну минуту. Каждый раз, когда время увеличивается, если все цифры допустимы, верните текущее время.
2⃣ Представьте время как целое число t в диапазоне 0 <= t < 24 * 60. Тогда часы равны t / 60, минуты равны t % 60.
3⃣ Найдите каждую цифру часов и минут: часы / 10, часы % 10 и т.д.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано время, представленное в формате "ЧЧ:ММ". Сформируйте ближайшее следующее время, используя текущие цифры. Количество раз, которое можно использовать цифру, не ограничено.
Можно предположить, что заданная строка всегда корректна. Например, "01:34", "12:09" являются корректными. "1:34", "12:9" являются некорректными.
Пример:
Input: time = "19:34"
Output: "19:39"
Explanation: The next closest time choosing from digits 1, 9, 3, 4, is 19:39, which occurs 5 minutes later.
It is not 19:33, because this occurs 23 hours and 59 minutes later.
package main
import (
"fmt"
"strconv"
"strings"
)
func nextClosestTime(time string) string {
cur := 60*atoi(time[:2]) + atoi(time[3:])
allowed := make(map[int]bool)
for _, c := range time {
if c != ':' {
allowed[int(c-'0')] = true
}
}
for {
cur = (cur + 1) % (24 * 60)
digits := []int{cur / 60 / 10, cur / 60 % 10, cur % 60 / 10, cur % 60 % 10}
valid := true
for _, d := range digits {
if !allowed[d] {
valid = false
break
}
}
if valid {
return fmt.Sprintf("%02d:%02d", cur/60, cur%60)
}
}
}
func atoi(s string) int {
i, _ := strconv.Atoi(s)
return i
}
func main() {
fmt.Println(nextClosestTime("19:34"))
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1533. Find the Index of the Large Integer
Сложность: medium
У нас есть целочисленный массив arr, в котором все элементы равны, кроме одного элемента, который больше остальных. Вам не будет предоставлен прямой доступ к массиву, вместо этого у вас будет API ArrayReader, который имеет следующие функции:
int compareSub(int l, int r, int x, int y): где 0 <= l, r, x, y < ArrayReader.length(), l <= r и x <= y. Функция сравнивает сумму подмассива arr[l..r] с суммой подмассива arr[x..y] и возвращает:
1, если arr[l] + arr[l+1] + ... + arr[r] > arr[x] + arr[x+1] + ... + arr[y].
0, если arr[l] + arr[l+1] + ... + arr[r] == arr[x] + arr[x+1] + ... + arr[y].
-1, если arr[l] + arr[l+1] + ... + arr[r] < arr[x] + arr[x+1] + ... + arr[y].
int length(): Возвращает размер массива.
Вам разрешено вызывать compareSub() не более 20 раз. Вы можете предположить, что обе функции работают за O(1) время.
Верните индекс массива arr, который содержит наибольший элемент.
Пример:
👨💻 Алгоритм:
1⃣ Установите left = 0 и length = reader.length. left - это самый левый индекс нашего поискового пространства, а length - это размер нашего поискового пространства. Индекс большего числа всегда должен находиться в пределах [left, left + length).
2⃣ Пока length > 1:
— Обновите length до length / 2.
— Установите cmp равным reader.compareSub(left, left + length - 1, left + length, left + length + length - 1).
— Если cmp равно 0, верните left + length + length, так как оставшийся элемент является большим числом. Это возможно только если текущее поисковое пространство имеет нечетную длину, поэтому если у нас четная длина, мы не беспокоимся об этом случае.
— Если cmp равно -1, увеличьте left на length.
— Если cmp равно 1, ничего не делайте, так как наш left остается прежним и мы уже разделили length на 2.
3⃣ Верните left. Это стандартная процедура для бинарного поиска, когда если поиск завершается без возврата, то левая граница указывает на ответ.
😎 Решение
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
У нас есть целочисленный массив arr, в котором все элементы равны, кроме одного элемента, который больше остальных. Вам не будет предоставлен прямой доступ к массиву, вместо этого у вас будет API ArrayReader, который имеет следующие функции:
int compareSub(int l, int r, int x, int y): где 0 <= l, r, x, y < ArrayReader.length(), l <= r и x <= y. Функция сравнивает сумму подмассива arr[l..r] с суммой подмассива arr[x..y] и возвращает:
1, если arr[l] + arr[l+1] + ... + arr[r] > arr[x] + arr[x+1] + ... + arr[y].
0, если arr[l] + arr[l+1] + ... + arr[r] == arr[x] + arr[x+1] + ... + arr[y].
-1, если arr[l] + arr[l+1] + ... + arr[r] < arr[x] + arr[x+1] + ... + arr[y].
int length(): Возвращает размер массива.
Вам разрешено вызывать compareSub() не более 20 раз. Вы можете предположить, что обе функции работают за O(1) время.
Верните индекс массива arr, который содержит наибольший элемент.
Пример:
Input: arr = [7,7,7,7,10,7,7,7]
Output: 4
Explanation: The following calls to the API
reader.compareSub(0, 0, 1, 1) // returns 0 this is a query comparing the sub-array (0, 0) with the sub array (1, 1), (i.e. compares arr[0] with arr[1]).
Thus we know that arr[0] and arr[1] doesn't contain the largest element.
reader.compareSub(2, 2, 3, 3) // returns 0, we can exclude arr[2] and arr[3].
reader.compareSub(4, 4, 5, 5) // returns 1, thus for sure arr[4] is the largest element in the array.
Notice that we made only 3 calls, so the answer is valid.
— Обновите length до length / 2.
— Установите cmp равным reader.compareSub(left, left + length - 1, left + length, left + length + length - 1).
— Если cmp равно 0, верните left + length + length, так как оставшийся элемент является большим числом. Это возможно только если текущее поисковое пространство имеет нечетную длину, поэтому если у нас четная длина, мы не беспокоимся об этом случае.
— Если cmp равно -1, увеличьте left на length.
— Если cmp равно 1, ничего не делайте, так как наш left остается прежним и мы уже разделили length на 2.
type ArrayReader struct{}
func (ar *ArrayReader) CompareSub(l, r, x, y int) int {
return 0
}
func (ar *ArrayReader) Length() int {
return 0
}
type Solution struct{}
func (s *Solution) GetIndex(reader *ArrayReader) int {
left := 0
length := reader.Length()
for length > 1 {
length /= 2
cmp := reader.CompareSub(left, left+length-1, left+length, left+2*length-1)
if cmp == 0 {
return left + 2*length
}
if cmp < 0 {
left += length
}
}
return left
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 971. Flip Binary Tree To Match Preorder Traversal
Сложность: medium
Дано корневое дерево с n узлами, где каждому узлу уникально присвоено значение от 1 до n. Также дана последовательность из n значений voyage, которая является желаемым обходом дерева в порядке pre-order.
Любой узел в бинарном дереве можно перевернуть, поменяв местами его левое и правое поддеревья. Например, переворот узла 1 будет иметь следующий эффект:
Переверните минимальное количество узлов, чтобы обход дерева в порядке pre-order соответствовал voyage.
Верните список значений всех перевернутых узлов. Вы можете вернуть ответ в любом порядке. Если невозможно перевернуть узлы в дереве, чтобы сделать обход в порядке pre-order соответствующим voyage, верните список [-1].
Пример:
👨💻 Алгоритм:
1⃣ Выполните поиск в глубину. Если в каком-либо узле значение узла не соответствует значению в voyage, верните [-1].
2⃣ Иначе определите, когда нужно перевернуть: если следующее ожидаемое число в voyage (voyage[i]) отличается от следующего потомка.
3⃣ Переверните узел, добавьте его значение в список перевернутых узлов и продолжите обход дерева, пока весь порядок обхода pre-order не будет соответствовать voyage.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано корневое дерево с n узлами, где каждому узлу уникально присвоено значение от 1 до n. Также дана последовательность из n значений voyage, которая является желаемым обходом дерева в порядке pre-order.
Любой узел в бинарном дереве можно перевернуть, поменяв местами его левое и правое поддеревья. Например, переворот узла 1 будет иметь следующий эффект:
Переверните минимальное количество узлов, чтобы обход дерева в порядке pre-order соответствовал voyage.
Верните список значений всех перевернутых узлов. Вы можете вернуть ответ в любом порядке. Если невозможно перевернуть узлы в дереве, чтобы сделать обход в порядке pre-order соответствующим voyage, верните список [-1].
Пример:
Input: root = [1,2], voyage = [2,1]
Output: [-1]
Explanation: It is impossible to flip the nodes such that the pre-order traversal matches voyage.
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
type Solution struct {
flipped []int
index int
voyage []int
}
func (s *Solution) flipMatchVoyage(root *TreeNode, voyage []int) []int {
s.flipped = []int{}
s.index = 0
s.voyage =Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 277. Find the Celebrity
Сложность: medium
Предположим, вы находитесь на вечеринке с n людьми, обозначенными от 0 до n - 1, и среди них может быть один знаменитость. Определение знаменитости: все остальные n - 1 человек знают знаменитость, но знаменитость не знает никого из них.
Теперь вы хотите выяснить, кто является знаменитостью, или убедиться, что ее нет. Вам разрешено задавать вопросы типа: "Привет, A. Ты знаешь B?", чтобы получить информацию о том, знает ли A B. Вам нужно найти знаменитость (или убедиться, что ее нет), задав как можно меньше вопросов (в асимптотическом смысле).
Вам предоставлена вспомогательная функция bool knows(a, b), которая сообщает, знает ли a b. Реализуйте функцию int findCelebrity(n). На вечеринке будет ровно одна знаменитость, если она есть.
Верните метку знаменитости, если она есть на вечеринке. Если знаменитости нет, верните -1.
Пример:
👨💻 Алгоритм:
1⃣ Найти потенциального кандидата на знаменитость:
Использовать один проход через всех людей, чтобы определить возможного кандидата.
Если человек a знает человека b, то a не может быть знаменитостью, и переключаем кандидата на b.
2⃣ Реализовать функцию isCelebrity(candidate):
Проверить, знает ли кандидат кого-либо из людей (исключая самих себя).
Проверить, знают ли все остальные кандидата (исключая самого кандидата).
Если кандидат знает кого-то, или кто-то не знает кандидата, то кандидат не является знаменитостью.
3⃣ Возвращение результата:
Если кандидат проходит все проверки в isCelebrity(candidate), вернуть его метку.
В противном случае вернуть -1.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Предположим, вы находитесь на вечеринке с n людьми, обозначенными от 0 до n - 1, и среди них может быть один знаменитость. Определение знаменитости: все остальные n - 1 человек знают знаменитость, но знаменитость не знает никого из них.
Теперь вы хотите выяснить, кто является знаменитостью, или убедиться, что ее нет. Вам разрешено задавать вопросы типа: "Привет, A. Ты знаешь B?", чтобы получить информацию о том, знает ли A B. Вам нужно найти знаменитость (или убедиться, что ее нет), задав как можно меньше вопросов (в асимптотическом смысле).
Вам предоставлена вспомогательная функция bool knows(a, b), которая сообщает, знает ли a b. Реализуйте функцию int findCelebrity(n). На вечеринке будет ровно одна знаменитость, если она есть.
Верните метку знаменитости, если она есть на вечеринке. Если знаменитости нет, верните -1.
Пример:
Input: graph = [[1,1,0],[0,1,0],[1,1,1]]
Output: 1
Explanation: There are three persons labeled with 0, 1 and 2. graph[i][j] = 1 means person i knows person j, otherwise graph[i][j] = 0 means person i does not know person j. The celebrity is the person labeled as 1 because both 0 and 2 know him but 1 does not know anybody.
Использовать один проход через всех людей, чтобы определить возможного кандидата.
Если человек a знает человека b, то a не может быть знаменитостью, и переключаем кандидата на b.
Проверить, знает ли кандидат кого-либо из людей (исключая самих себя).
Проверить, знают ли все остальные кандидата (исключая самого кандидата).
Если кандидат знает кого-то, или кто-то не знает кандидата, то кандидат не является знаменитостью.
Если кандидат проходит все проверки в isCelebrity(candidate), вернуть его метку.
В противном случае вернуть -1.
type Solution struct {
n int
cache map[pair]bool
}
type pair struct {
a, b int
}
func (s *Solution) findCelebrity(n int) int {
s.n = n
s.cache = make(map[pair]bool)
celebrityCandidate := 0
for i := 1; i < n; i++ {
if s.cachedKnows(celebrityCandidate, i) {
celebrityCandidate = i
}
}
if s.isCelebrity(celebrityCandidate) {
return celebrityCandidate
}
return -1
}
func (s *Solution) isCelebrity(i int) bool {
for j := 0; j < s.n; j++ {
if i == j {
continue
}
if s.cachedKnows(i, j) || !s.cachedKnows(j, i) {
return false
}
}
return true
}
func (s *Solution) cachedKnows(a, b int) bool {
key := pair{a, b}
if _, exists := s.cache[key]; !exists {
s.cache[key] = knows(a, b)
}
return s.cache[key]
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1247. Minimum Swaps to Make Strings Equal
Сложность: hard
Вам даны две строки s1 и s2 одинаковой длины, состоящие только из букв "x" и "y". Ваша задача - сделать эти две строки равными друг другу. Вы можете поменять местами любые два символа, принадлежащие разным строкам, что означает: поменять местами s1[i] и s2[j]. Верните минимальное количество обменов, необходимое для того, чтобы сделать s1 и s2 равными, или верните -1, если это невозможно сделать.
Пример:
👨💻 Алгоритм:
1⃣ Подсчет несоответствующих пар:
Пройдите по строкам s1 и s2, чтобы подсчитать количество пар xy и yx. Пара xy возникает, когда s1[i] равно 'x', а s2[i] равно 'y'. Пара yx возникает, когда s1[i] равно 'y', а s2[i] равно 'x'.
2⃣ Проверка четности:
Если сумма количества пар xy и yx нечетная, то невозможно сделать строки равными, поскольку каждая замена уменьшает сумму несоответствующих пар на 2. В этом случае верните -1.
3⃣ Вычисление минимального количества замен:
Если количество пар xy четное и количество пар yx четное, то каждые две пары xy и каждые две пары yx можно обменять за один ход. Поэтому минимальное количество замен равно xy // 2 + yx // 2.
Если количество пар xy нечетное и количество пар yx нечетное, то мы можем обменять одну пару xy и одну пару yx за два хода. Поэтому минимальное количество замен равно xy // 2 + yx // 2 + 2.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам даны две строки s1 и s2 одинаковой длины, состоящие только из букв "x" и "y". Ваша задача - сделать эти две строки равными друг другу. Вы можете поменять местами любые два символа, принадлежащие разным строкам, что означает: поменять местами s1[i] и s2[j]. Верните минимальное количество обменов, необходимое для того, чтобы сделать s1 и s2 равными, или верните -1, если это невозможно сделать.
Пример:
Input: arr = [1,2]
Output: 2Пройдите по строкам s1 и s2, чтобы подсчитать количество пар xy и yx. Пара xy возникает, когда s1[i] равно 'x', а s2[i] равно 'y'. Пара yx возникает, когда s1[i] равно 'y', а s2[i] равно 'x'.
Если сумма количества пар xy и yx нечетная, то невозможно сделать строки равными, поскольку каждая замена уменьшает сумму несоответствующих пар на 2. В этом случае верните -1.
Если количество пар xy четное и количество пар yx четное, то каждые две пары xy и каждые две пары yx можно обменять за один ход. Поэтому минимальное количество замен равно xy // 2 + yx // 2.
Если количество пар xy нечетное и количество пар yx нечетное, то мы можем обменять одну пару xy и одну пару yx за два хода. Поэтому минимальное количество замен равно xy // 2 + yx // 2 + 2.
func minimumSwap(s1 string, s2 string) int {
xy, yx := 0, 0
for i := 0; i < len(s1); i++ {
if s1[i] == 'x' && s2[i] == 'y' {
xy++
} else if s1[i] == 'y' && s2[i] == 'x' {
yx++
}
}
if (xy+yx)%2 != 0 {
return -1
}
return xy/2 + yx/2 + (xy%2)*2
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1365. How Many Numbers Are Smaller Than the Current Number
Сложность: easy
Дан массив nums. Для каждого элемента nums[i] определите, сколько чисел в массиве меньше его. То есть, для каждого nums[i] вам нужно посчитать количество допустимых j, таких что j != i и nums[j] < nums[i].
Верните ответ в виде массива.
Пример:
👨💻 Алгоритм:
1⃣ Создание копии и сортировка массива:
Создайте отсортированную копию массива nums, чтобы легко находить количество элементов, меньших текущего.
2⃣ Поиск индекса каждого элемента:
Для каждого элемента nums[i] найдите его индекс в отсортированной копии массива. Этот индекс указывает количество элементов, меньших nums[i].
3⃣ Формирование ответа:
Сформируйте массив ответов, где каждый элемент будет соответствовать количеству чисел, меньших текущего.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан массив nums. Для каждого элемента nums[i] определите, сколько чисел в массиве меньше его. То есть, для каждого nums[i] вам нужно посчитать количество допустимых j, таких что j != i и nums[j] < nums[i].
Верните ответ в виде массива.
Пример:
Input: nums = [6,5,4,8]
Output: [2,1,0,3]
Создайте отсортированную копию массива nums, чтобы легко находить количество элементов, меньших текущего.
Для каждого элемента nums[i] найдите его индекс в отсортированной копии массива. Этот индекс указывает количество элементов, меньших nums[i].
Сформируйте массив ответов, где каждый элемент будет соответствовать количеству чисел, меньших текущего.
import "sort"
func smallerNumbersThanCurrent(nums []int) []int {
sortedNums := append([]int(nil), nums...)
sort.Ints(sortedNums)
result := make([]int, len(nums))
for i, num := range nums {
result[i] = indexOf(sortedNums, num)
}
return result
}
func indexOf(nums []int, target int) int {
for i, num := range nums {
if num == target {
return i
}
}
return -1
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 954. Array of Doubled Pairs
Сложность: easy
Если задан целочисленный массив четной длины arr, верните true, если можно переупорядочить arr так, чтобы arr[2 * i + 1] = 2 * arr[2 * i] для каждого 0 <= i < len(arr) / 2, или false в противном случае.
Пример:
👨💻 Алгоритм:
1⃣ Подсчитать частоту каждого элемента в массиве.
Отсортировать массив по абсолютным значениям элементов.
2⃣ Для каждого элемента в отсортированном массиве:
Проверить, можно ли сопоставить его с элементом, равным его удвоенному значению.
Уменьшить счетчик обоих элементов в словаре частот.
3⃣ Если для каждого элемента можно найти пару, вернуть true, иначе вернуть false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Если задан целочисленный массив четной длины arr, верните true, если можно переупорядочить arr так, чтобы arr[2 * i + 1] = 2 * arr[2 * i] для каждого 0 <= i < len(arr) / 2, или false в противном случае.
Пример:
Input: arr = [3,1,3,6]
Output: false
Отсортировать массив по абсолютным значениям элементов.
Проверить, можно ли сопоставить его с элементом, равным его удвоенному значению.
Уменьшить счетчик обоих элементов в словаре частот.
package main
import (
"sort"
)
func canReorderDoubled(arr []int) bool {
count := make(map[int]int)
for _, num := range arr {
count[num]++
}
sort.Slice(arr, func(i, j int) bool {
return abs(arr[i]) < abs(arr[j])
})
for _, num := range arr {
if count[num] == 0 {
continue
}
if count[2*num] == 0 {
return false
}
count[num]--
count[2*num]--
}
return true
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 100. Same Tree
Сложность: easy
Даны корни двух бинарных деревьев
Два бинарных дерева считаются одинаковыми, если они структурно идентичны и узлы имеют одинаковые значения.
Пример:
👨💻 Алгоритм:
1⃣ Проверка на nil:
- Если оба узла
- Если один
2⃣ Проверка значений:
- Если значения узлов различаются, деревья разные.
3⃣ Рекурсивная проверка:
- Повторяем ту же проверку для левых и правых поддеревьев.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны корни двух бинарных деревьев
p и q. Напишите функцию, чтобы проверить, одинаковы ли они. Два бинарных дерева считаются одинаковыми, если они структурно идентичны и узлы имеют одинаковые значения.
Пример:
Input: p = [1,2,3], q = [1,2,3]
Output: true
- Если оба узла
nil, они равны. - Если один
nil, а другой — нет, деревья разные. - Если значения узлов различаются, деревья разные.
- Повторяем ту же проверку для левых и правых поддеревьев.
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func isSameTree(p *TreeNode, q *TreeNode) bool {
if p == nil && q == nil {
return true
}
if p == nil || q == nil {
return false
}
if p.Val != q.Val {
return false
}
return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Задача: 238. Product of Array Except Self
Сложность: medium
Дан массив целых чисел nums, верните массив answer такой, что answer[i] равен произведению всех элементов массива nums, кроме nums[i].
Произведение любого префикса или суффикса массива nums гарантированно помещается в 32-битное целое число.
Вы должны написать алгоритм, который работает за время O(n) и не использует операцию деления.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация массивов L и R: Инициализируйте два пустых массива L и R. Массив L будет содержать произведение всех чисел слева от i, а массив R будет содержать произведение всех чисел справа от i. Заполните массив L, установив L[0] равным 1, а для остальных элементов используйте формулу L[i] = L[i-1] * nums[i-1]. Заполните массив R, установив R[length-1] равным 1, а для остальных элементов используйте формулу R[i] = R[i+1] * nums[i+1].
2⃣ Заполнение массивов L и R: Пройдите два цикла для заполнения массивов L и R. В первом цикле заполните массив L, начиная с L[0] и двигаясь вправо. Во втором цикле заполните массив R, начиная с R[length-1] и двигаясь влево.
3⃣ Формирование результата: Пройдите по исходному массиву и для каждого элемента i вычислите произведение всех элементов, кроме nums[i], используя L[i] * R[i]. Сохраните результат в массиве answer и верните его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив целых чисел nums, верните массив answer такой, что answer[i] равен произведению всех элементов массива nums, кроме nums[i].
Произведение любого префикса или суффикса массива nums гарантированно помещается в 32-битное целое число.
Вы должны написать алгоритм, который работает за время O(n) и не использует операцию деления.
Пример:
Input: nums = [1,2,3,4]
Output: [24,12,8,6]
func productExceptSelf(nums []int) []int {
length := len(nums)
L := make([]int, length)
R := make([]int, length)
answer := make([]int, length)
L[0] = 1
for i := 1; i < length; i++ {
L[i] = nums[i-1] * L[i-1]
}
R[length-1] = 1
for i := length - 2; i >= 0; i-- {
R[i] = nums[i+1] * R[i+1]
}
for i := 0; i < length; i++ {
answer[i] = L[i] * R[i]
}
return answer
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 666. Path Sum IV
Сложность: medium
Если глубина дерева меньше 5, то это дерево можно представить в виде массива трехзначных чисел. Для каждого числа в этом массиве:
Сотни представляют глубину d этого узла, где 1 <= d <= 4.
Десятки представляют позицию p этого узла на уровне, которому он принадлежит, где 1 <= p <= 8. Позиция соответствует позиции в полном бинарном дереве.
Единицы представляют значение v этого узла, где 0 <= v <= 9.
Дан массив возрастающих трехзначных чисел nums, представляющих бинарное дерево с глубиной меньше 5. Верните сумму всех путей от корня к листьям.
Гарантируется, что данный массив представляет собой валидное связанное бинарное дерево.
Пример:
👨💻 Алгоритм:
1⃣ Создание структуры дерева:
Пройдите по массиву nums и для каждого элемента создайте узел дерева.
Сохраните узлы в словаре для удобного доступа по их позиции.
2⃣ Связывание узлов:
Пройдите по массиву и свяжите узлы друг с другом, исходя из их позиции и глубины.
Найдите левого и правого ребенка для каждого узла и установите соответствующие связи.
3⃣ Подсчет суммы путей:
Выполните обход дерева (например, используя DFS) и подсчитайте сумму всех путей от корня к листьям.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если глубина дерева меньше 5, то это дерево можно представить в виде массива трехзначных чисел. Для каждого числа в этом массиве:
Сотни представляют глубину d этого узла, где 1 <= d <= 4.
Десятки представляют позицию p этого узла на уровне, которому он принадлежит, где 1 <= p <= 8. Позиция соответствует позиции в полном бинарном дереве.
Единицы представляют значение v этого узла, где 0 <= v <= 9.
Дан массив возрастающих трехзначных чисел nums, представляющих бинарное дерево с глубиной меньше 5. Верните сумму всех путей от корня к листьям.
Гарантируется, что данный массив представляет собой валидное связанное бинарное дерево.
Пример:
Input: nums = [113,215,221]
Output: 12
Explanation: The tree that the list represents is shown.
The path sum is (3 + 5) + (3 + 1) = 12.
Пройдите по массиву nums и для каждого элемента создайте узел дерева.
Сохраните узлы в словаре для удобного доступа по их позиции.
Пройдите по массиву и свяжите узлы друг с другом, исходя из их позиции и глубины.
Найдите левого и правого ребенка для каждого узла и установите соответствующие связи.
Выполните обход дерева (например, используя DFS) и подсчитайте сумму всех путей от корня к листьям.
func pathSum(nums []int) int {
tree := make(map[int]int)
for _, num := range nums {
depth := num / 100
pos := (num / 10) % 10
val := num % 10
tree[depth*10+pos] = val
}
return dfs(tree, 1, 1, 0)
}
func dfs(tree map[int]int, depth, pos, currentSum int) int {
key := depth*10 + pos
if _, exists := tree[key]; !exists {
return 0
}
currentSum += tree[key]
leftChild := (depth + 1) * 10 + 2*pos - 1
rightChild := (depth + 1) * 10 + 2*pos
if _, leftExists := tree[leftChild]; !leftExists && !tree[rightChild] {
return currentSum
}
return dfs(tree, depth+1, 2*pos-1, currentSum) + dfs(tree, depth+1, 2*pos, currentSum)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
Задача: 484. Find Permutation
Сложность: medium
Перестановка
-
-
Дана строка
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Создайте пустой стек
2⃣ Для каждого числа
Если текущий символ в строке
Если текущий символ равен
3⃣ Завершение
Добавьте
Верните список
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Перестановка
perm из n целых чисел всех чисел в диапазоне [1, n] может быть представлена в виде строки s длиной n - 1, где:-
s[i] == 'I', если perm[i] < perm[i + 1]-
s[i] == 'D', если perm[i] > perm[i + 1]Дана строка
s, восстановите лексикографически наименьшую перестановку perm и верните её.Пример:
Input: s = "I"
Output: [1,2]
Explanation: [1,2] is the only legal permutation that can be represented by s, where the number 1 and 2 construct an increasing relationship.
Создайте пустой стек
stack. Создайте пустой список result для хранения конечной перестановки.i Если текущий символ в строке
s равен 'D', добавьте i в стек. Если текущий символ равен
'I', добавьте i в стек, затем извлеките все элементы из стека и добавьте их в result.Добавьте
n в стек и извлеките все элементы из стека, добавив их в result. Верните список
result, который представляет лексикографически наименьшую перестановку.func findPermutation(s string) []int {
res := make([]int, len(s)+1)
stack := []int{}
j := 0
for i := 1; i <= len(s); i++ {
if s[i-1] == 'I' {
stack = append(stack, i)
for len(stack) > 0 {
res[j] = stack[len(stack)-1]
stack = stack[:len(stack)-1]
j++
}
} else {
stack = append(stack, i)
}
}
stack = append(stack, len(s)+1)
for len(stack) > 0 {
res[j] = stack[len(stack)-1]
stack = stack[:len(stack)-1]
j++
}
return res
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM