Задача: 313. Super Ugly Number
Сложность: medium
Супер некрасивое число — это положительное целое число, простые множители которого находятся в массиве primes.
Дано целое число n и массив целых чисел primes. Верните n-е супер некрасивое число.
Гарантируется, что n-е супер некрасивое число помещается в 32-битное знаковое целое число.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Создайте массив ugly_numbers длиной n для хранения супер некрасивых чисел. Создайте массив indices длиной primes для отслеживания позиций в массиве ugly_numbers. Создайте массив next_ugly длиной primes для хранения следующего возможного супер некрасивого числа для каждого простого числа из primes.
2⃣ Генерация супер некрасивых чисел
Установите первое значение в ugly_numbers как 1. Повторяйте до тех пор, пока не заполните массив ugly_numbers: Найдите минимальное значение в массиве next_ugly и добавьте его в ugly_numbers. Обновите соответствующий индекс в indices и пересчитайте значение в next_ugly.
3⃣ Возврат результата
Верните последнее значение в массиве ugly_numbers, которое будет n-м супер некрасивым числом.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Супер некрасивое число — это положительное целое число, простые множители которого находятся в массиве primes.
Дано целое число n и массив целых чисел primes. Верните n-е супер некрасивое число.
Гарантируется, что n-е супер некрасивое число помещается в 32-битное знаковое целое число.
Пример:
Input: n = 12, primes = [2,7,13,19]
Output: 32
Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12 super ugly numbers given primes = [2,7,13,19].
Создайте массив ugly_numbers длиной n для хранения супер некрасивых чисел. Создайте массив indices длиной primes для отслеживания позиций в массиве ugly_numbers. Создайте массив next_ugly длиной primes для хранения следующего возможного супер некрасивого числа для каждого простого числа из primes.
Установите первое значение в ugly_numbers как 1. Повторяйте до тех пор, пока не заполните массив ugly_numbers: Найдите минимальное значение в массиве next_ugly и добавьте его в ugly_numbers. Обновите соответствующий индекс в indices и пересчитайте значение в next_ugly.
Верните последнее значение в массиве ugly_numbers, которое будет n-м супер некрасивым числом.
func nthSuperUglyNumber(n int, primes []int) int {
ugly_numbers := make([]int, n)
ugly_numbers[0] = 1
indices := make([]int, len(primes))
next_ugly := append([]int(nil), primes...)
for i := 1; i < n; i++ {
next_val := min(next_ugly)
ugly_numbers[i] = next_val
for j := 0; j < len(primes); j++ {
if next_val == next_ugly[j] {
indices[j]++
next_ugly[j] = ugly_numbers[indices[j]] * primes[j]
}
}
}
return ugly_numbers[n-1]
}
func min(arr []int) int {
minVal := arr[0]
for _, val := range arr {
if val < minVal {
minVal = val
}
}
return minVal
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 408. Valid Word Abbreviation
Сложность: easy
Строку можно сократить, заменив любое количество не смежных, непустых подстрок их длинами. Длины не должны содержать ведущих нулей.
Например, строка "замена" может быть сокращена следующим образом (но не ограничивается этим): "s10n" ("s ubstitutio n") "sub4u4" ("sub stit u tion") "12" ("замена") "su3i1u2on" ("su bst i t u ti on") "substitution" (без замены подстрок) Следующие сокращения не являются допустимыми:
"s55n" ("s ubsti tutio n", заменяемые подстроки смежные) "s010n" (содержит ведущие нули) "s0ubstitution" (заменяет пустую подстроку) Если задано строковое слово и аббревиатура abbr, верните, соответствует ли строка заданной аббревиатуре.
Подстрока - это непрерывная непустая последовательность символов в строке.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте два указателя: один для строки word и один для аббревиатуры abbr. Начните сравнение символов строки и аббревиатуры с начала.
2⃣ Если символ аббревиатуры - это цифра, вычислите полное число и переместите указатель строки word на это количество символов. Если символ аббревиатуры - это буква, убедитесь, что он совпадает с текущим символом строки.
3⃣ Повторяйте шаг 2, пока оба указателя не достигнут конца строки и аббревиатуры соответственно. Если это так, верните true, иначе false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Строку можно сократить, заменив любое количество не смежных, непустых подстрок их длинами. Длины не должны содержать ведущих нулей.
Например, строка "замена" может быть сокращена следующим образом (но не ограничивается этим): "s10n" ("s ubstitutio n") "sub4u4" ("sub stit u tion") "12" ("замена") "su3i1u2on" ("su bst i t u ti on") "substitution" (без замены подстрок) Следующие сокращения не являются допустимыми:
"s55n" ("s ubsti tutio n", заменяемые подстроки смежные) "s010n" (содержит ведущие нули) "s0ubstitution" (заменяет пустую подстроку) Если задано строковое слово и аббревиатура abbr, верните, соответствует ли строка заданной аббревиатуре.
Подстрока - это непрерывная непустая последовательность символов в строке.
Пример:
Input: word = "internationalization", abbr = "i12iz4n"
Output: true
package main
import (
"strconv"
"unicode"
)
func validWordAbbreviation(word string, abbr string) bool {
i, j := 0, 0
for i < len(word) && j < len(abbr) {
if unicode.IsDigit(rune(abbr[j])) {
if abbr[j] == '0' {
return false
}
num := 0
for j < len(abbr) && unicode.IsDigit(rune(abbr[j])) {
n, _ := strconv.Atoi(string(abbr[j]))
num = num*10 + n
j++
}
i += num
} else {
if word[i] != abbr[j] {
return false
}
i++
j++
}
}
return i == len(word) && j == len(abbr)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 677. Map Sum Pairs
Сложность: medium
Создайте карту, которая позволяет выполнять следующие действия:
Отображает строковый ключ на заданное значение.
Возвращает сумму значений, у которых ключ имеет префикс, равный заданной строке.
Реализуйте класс MapSum:
MapSum() Инициализирует объект MapSum.
void insert(String key, int val) Вставляет пару ключ-значение в карту. Если ключ уже существовал, исходная пара ключ-значение будет заменена на новую.
int sum(string prefix) Возвращает сумму всех значений пар, у которых ключ начинается с данного префикса.
Пример:
👨💻 Алгоритм:
1⃣ Для каждого ключа в карте проверить, начинается ли этот ключ с данного префикса.
2⃣ Если ключ начинается с префикса, добавить его значение к ответу.
3⃣ Вернуть полученную сумму как результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Создайте карту, которая позволяет выполнять следующие действия:
Отображает строковый ключ на заданное значение.
Возвращает сумму значений, у которых ключ имеет префикс, равный заданной строке.
Реализуйте класс MapSum:
MapSum() Инициализирует объект MapSum.
void insert(String key, int val) Вставляет пару ключ-значение в карту. Если ключ уже существовал, исходная пара ключ-значение будет заменена на новую.
int sum(string prefix) Возвращает сумму всех значений пар, у которых ключ начинается с данного префикса.
Пример:
Input
["MapSum", "insert", "sum", "insert", "sum"]
[[], ["apple", 3], ["ap"], ["app", 2], ["ap"]]
Output
[null, null, 3, null, 5]
Explanation
MapSum mapSum = new MapSum();
mapSum.insert("apple", 3);
mapSum.sum("ap"); // return 3 (apple = 3)
mapSum.insert("app", 2);
mapSum.sum("ap"); // return 5 (apple + app = 3 + 2 = 5)
package main
import "strings"
type MapSum struct {
mapData map[string]int
}
func Constructor() MapSum {
return MapSum{mapData: make(map[string]int)}
}
func (this *MapSum) Insert(key string, val int) {
this.mapData[key] = val
}
func (this *MapSum) Sum(prefix string) int {
ans := 0
for key, val := range this.mapData {
if strings.HasPrefix(key, prefix) {
ans += val
}
}
return ans
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 936. Stamping The Sequence
Сложность: hard
Вам даны две строки stamp и target. Изначально имеется строка s длины target.length со всеми s[i] == '?'. За один ход вы можете поместить штамп над s и заменить каждую букву в s на соответствующую букву из штампа. Например, если штамп = "abc" и target = "abcba", то s изначально будет "?????". За один ход вы можете: поместить штамп в индекс 0 s, чтобы получить "abc??", поместить штамп в индекс 1 s, чтобы получить "?abc?", или поместить штамп в индекс 2 s, чтобы получить "??abc". Обратите внимание, что штамп должен полностью находиться в границах s, чтобы штамповать (то есть вы не можете поместить штамп в индекс 3 s). Мы хотим преобразовать s в цель, используя не более 10 * target.length ходов. Верните массив индекса самой левой буквы, которая штампуется на каждом ходу. Если мы не можем получить цель из s за 10 * target.length оборотов, верните пустой массив
Пример:
👨💻 Алгоритм:
1⃣ Инициализировать переменные:
s как массив символов '?', длиной target.length.
res как список для хранения результатов.
done как массив булевых значений для отслеживания того, какие позиции уже штампованы.
target как массив символов для удобства.
2⃣ Использовать функцию canStamp для проверки, можно ли штамповать stamp в target начиная с индекса i.
Использовать функцию doStamp для штампования stamp в target начиная с индекса i.
Повторять шаги, пока штампы возможны или достигнут максимум ходов (10 * target.length):
Перебрать все возможные начальные позиции для штампа.
Проверить, можно ли штамповать в текущей позиции.
Если можно, штамповать и добавить индекс в res.
3⃣ Если все символы в s соответствуют символам в target, вернуть массив res в обратном порядке. Иначе, вернуть пустой массив.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам даны две строки stamp и target. Изначально имеется строка s длины target.length со всеми s[i] == '?'. За один ход вы можете поместить штамп над s и заменить каждую букву в s на соответствующую букву из штампа. Например, если штамп = "abc" и target = "abcba", то s изначально будет "?????". За один ход вы можете: поместить штамп в индекс 0 s, чтобы получить "abc??", поместить штамп в индекс 1 s, чтобы получить "?abc?", или поместить штамп в индекс 2 s, чтобы получить "??abc". Обратите внимание, что штамп должен полностью находиться в границах s, чтобы штамповать (то есть вы не можете поместить штамп в индекс 3 s). Мы хотим преобразовать s в цель, используя не более 10 * target.length ходов. Верните массив индекса самой левой буквы, которая штампуется на каждом ходу. Если мы не можем получить цель из s за 10 * target.length оборотов, верните пустой массив
Пример:
Input: stamp = "abc", target = "ababc"
Output: [0,2]
s как массив символов '?', длиной target.length.
res как список для хранения результатов.
done как массив булевых значений для отслеживания того, какие позиции уже штампованы.
target как массив символов для удобства.
Использовать функцию doStamp для штампования stamp в target начиная с индекса i.
Повторять шаги, пока штампы возможны или достигнут максимум ходов (10 * target.length):
Перебрать все возможные начальные позиции для штампа.
Проверить, можно ли штамповать в текущей позиции.
Если можно, штамповать и добавить индекс в res.
package main
func movesToStamp(stamp string, target string) []int {
s, t := []rune(stamp), []rune(target)
m, n := len(s), len(t)
res := []int{}
done := make([]bool, n)
canStamp := func(i int) bool {
for j := 0; j < m; j++ {
if t[i + j] != '?' && t[i + j] != s[j] {
return false;
}
}
return true;
}
doStamp := func(i int) {
for j := 0; j < m; j++ {
t[i + j] = '?'
}
res = append(res, i)
done[i] = true
}
changed := true
for changed {
changed = false
for i := 0; i <= n - m; i++ {
if !done[i] && canStamp(i) {
doStamp(i)
changed = true
}
}
}
for _, c := range t {
if c != '?' {
return []int{}
}
}
for i, j := 0, len(res) - 1; i < j; i, j = i + 1, j - 1 {
res[i], res[j] = res[j], res[i]
}
return res
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 253. Meeting Rooms II
Сложность: medium
Дан массив интервалов времени встреч intervals, где intervals[i] = [starti, endi]. Верните минимальное количество необходимых конференц-залов.
Пример:
👨💻 Алгоритм:
1⃣ Отсортируйте встречи по времени их начала и инициализируйте мин-кучу с временем окончания первой встречи.
2⃣ Для каждой последующей встречи проверьте, свободна ли комната (сравните время начала встречи с минимальным временем окончания в куче):
Если свободна, обновите время окончания этой комнаты.
Если не свободна, добавьте новое время окончания в кучу.
3⃣ После обработки всех встреч размер кучи будет равен минимальному количеству необходимых комнат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив интервалов времени встреч intervals, где intervals[i] = [starti, endi]. Верните минимальное количество необходимых конференц-залов.
Пример:
Input: intervals = [[0,30],[5,10],[15,20]]
Output: 2
Если свободна, обновите время окончания этой комнаты.
Если не свободна, добавьте новое время окончания в кучу.
package main
import (
"container/heap"
"sort"
)
type MinHeap []int
func (h MinHeap) Len() int { return len(h) }
func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *MinHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func minMeetingRooms(intervals [][]int) int {
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][0] < intervals[j][0]
})
h := &MinHeap{intervals[0][1]}
heap.Init(h)
for i := 1; i < len(intervals); i++) {
if intervals[i][0] >= (*h)[0] {
heap.Pop(h)
}
heap.Push(h, intervals[i][1])
}
return h.Len()
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 162. Find Peak Element
Сложность: medium
Пиковым элементом называется элемент, который строго больше своих соседей.
Для массива целых чисел nums с индексацией с нуля найдите пиковый элемент и верните его индекс. Если в массиве несколько пиков, верните индекс любого из пиков.
Вы можете представить, что nums[-1] = nums[n] = -∞. Другими словами, элемент всегда считается строго большим, чем сосед, находящийся за пределами массива.
Необходимо написать алгоритм, который работает за время O(log n).
Пример:
👨💻 Алгоритм:
1⃣ Начальная проверка:
Определяем средний элемент массива mid как mid = low + (high - low) / 2. Это помогает предотвратить возможное переполнение при больших значениях индексов.
2⃣ Определение направления поиска:
Сравниваем элемент nums[mid] с его правым соседом nums[mid + 1]. Если nums[mid] меньше nums[mid + 1], это указывает на наличие восходящей последовательности, и мы двигаемся вправо, устанавливая low = mid + 1. Это потому, что пик гарантированно находится в правой части.
Если nums[mid] больше nums[mid + 1], это указывает на наличие нисходящей последовательности, и пик находится либо в mid, либо слева от него, тогда устанавливаем high = mid.
3⃣ Завершение поиска:
Процесс продолжается до тех пор, пока low не станет равным high, что означает сужение поисковой области до одного элемента, который и является пиком, поскольку мы исключили все другие возможности.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Пиковым элементом называется элемент, который строго больше своих соседей.
Для массива целых чисел nums с индексацией с нуля найдите пиковый элемент и верните его индекс. Если в массиве несколько пиков, верните индекс любого из пиков.
Вы можете представить, что nums[-1] = nums[n] = -∞. Другими словами, элемент всегда считается строго большим, чем сосед, находящийся за пределами массива.
Необходимо написать алгоритм, который работает за время O(log n).
Пример:
Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.
Определяем средний элемент массива mid как mid = low + (high - low) / 2. Это помогает предотвратить возможное переполнение при больших значениях индексов.
Сравниваем элемент nums[mid] с его правым соседом nums[mid + 1]. Если nums[mid] меньше nums[mid + 1], это указывает на наличие восходящей последовательности, и мы двигаемся вправо, устанавливая low = mid + 1. Это потому, что пик гарантированно находится в правой части.
Если nums[mid] больше nums[mid + 1], это указывает на наличие нисходящей последовательности, и пик находится либо в mid, либо слева от него, тогда устанавливаем high = mid.
Процесс продолжается до тех пор, пока low не станет равным high, что означает сужение поисковой области до одного элемента, который и является пиком, поскольку мы исключили все другие возможности.
func findPeakElement(nums []int) int {
return search(nums, 0, len(nums)-1)
}
func search(nums []int, l int, r int) int {
if l == r {
return l
}
mid := (l + r) / 2
if nums[mid] > nums[mid+1] {
return search(nums, l, mid)
}
return search(nums, mid+1, r)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 482. License Key Formatting
Сложность: easy
Вам дан лицензионный ключ, представленный в виде строки
Мы хотим переформатировать строку
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Установите
2⃣ Итерация по входной строке в обратном порядке
Пропускайте символы
3⃣ Завершение
Проверьте, есть ли в конце строки
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам дан лицензионный ключ, представленный в виде строки
s, которая состоит только из буквенно-цифровых символов и тире. Строка разделена на n + 1 групп с помощью n тире. Вам также дано целое число k.Мы хотим переформатировать строку
s так, чтобы каждая группа содержала ровно k символов, за исключением первой группы, которая может быть короче k, но все же должна содержать хотя бы один символ. Кроме того, между двумя группами должно быть вставлено тире, и все строчные буквы следует преобразовать в прописные.Пример:
Input: s = "5F3Z-2e-9-w", k = 4
Output: "5F3Z-2E9W"
Explanation: The string s has been split into two parts, each part has 4 characters. Note that the two extra dashes are not needed and can be removed.
Установите
count в 0 для подсчета символов в текущей группе. Установите ans в пустую строку для хранения конечного результата.Пропускайте символы
'-'. Если текущий символ не '-', добавьте его в ans и увеличьте count на 1. Если count достигает k, добавьте '-' в ans и сбросьте count.Проверьте, есть ли в конце строки
ans тире, и удалите его, если оно есть. Переверните строку ans и верните её.package main
import (
"strings"
"unicode"
)
func licenseKeyFormatting(s string, k int) string {
count := 0
var ans strings.Builder
for i := len(s) - 1; i >= 0; i-- {
if s[i] != '-' {
ans.WriteByte(byte(unicode.ToUpper(rune(s[i]))))
count++
if count == k {
ans.WriteByte('-')
count = 0
}
}
}
res := ans.String()
if len(res) > 0 && res[len(res)-1] == '-' {
res = res[:len(res)-1]
}
runes := []rune(res)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1342. Number of Steps to Reduce a Number to Zero
Сложность: easy
Дано целое число num, вернуть количество шагов, необходимых для его сокращения до нуля.
На каждом шаге, если текущее число четное, его нужно разделить на 2, в противном случае, вы должны вычесть из него 1.
Пример:
👨💻 Алгоритм:
1⃣ На каждом шаге проверяйте, четное ли текущее число, используя оператор остатка от деления (%). Если число четное (number % 2 == 0), разделите его на 2.
2⃣ Если число нечетное (number % 2 == 1), вычтите из него 1.
3⃣ После выполнения каждого из этих действий увеличивайте счетчик шагов на 1, чтобы в конце вернуть его значение.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано целое число num, вернуть количество шагов, необходимых для его сокращения до нуля.
На каждом шаге, если текущее число четное, его нужно разделить на 2, в противном случае, вы должны вычесть из него 1.
Пример:
Input: num = 14
Output: 6
Explanation:
Step 1) 14 is even; divide by 2 and obtain 7.
Step 2) 7 is odd; subtract 1 and obtain 6.
Step 3) 6 is even; divide by 2 and obtain 3.
Step 4) 3 is odd; subtract 1 and obtain 2.
Step 5) 2 is even; divide by 2 and obtain 1.
Step 6) 1 is odd; subtract 1 and obtain 0.
func numberOfSteps(num int) int {
steps := 0
for num != 0 {
if num % 2 == 0 {
num /= 2
} else {
num--
}
steps++
}
return steps
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 242. Valid Anagram
Сложность: easy
Даны две строки s и t, верните true, если t является анаграммой s, и false в противном случае.
Анаграмма — это слово или фраза, сформированная путём перестановки букв другого слова или фразы, обычно используя все исходные буквы ровно один раз.
Пример:
👨💻 Алгоритм:
1⃣ Создайте массив размером 26 для подсчета частот каждой буквы (поскольку s и t содержат только буквы от 'a' до 'z').
2⃣ Пройдитесь по строке s, увеличивая счетчик соответствующей буквы. Затем пройдитесь по строке t, уменьшая счетчик для каждой буквы.
3⃣ Проверьте, не опустился ли счетчик ниже нуля во время обхода строки t. Если это произошло, значит в t есть лишняя буква, которой нет в s, и следует вернуть false. Если после проверки всех букв все счетчики равны нулю, возвращайте true, указывая на то, что t является анаграммой s.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны две строки s и t, верните true, если t является анаграммой s, и false в противном случае.
Анаграмма — это слово или фраза, сформированная путём перестановки букв другого слова или фразы, обычно используя все исходные буквы ровно один раз.
Пример:
Input: s = "anagram", t = "nagaram"
Output: true
func isAnagram(s string, t string) bool {
if len(s) != len(t) {
return false
}
count := [26]int{}
for i := range s {
count[s[i]-'a']++
count[t[i]-'a']--
}
for _, c := range count {
if c != 0 {
return false
}
}
return true
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 405. Convert a Number to Hexadecimal
Сложность: easy
Если задано целое число num, верните строку, представляющую его шестнадцатеричное представление. Для отрицательных целых чисел используется метод дополнения до двух. Все буквы в строке ответа должны быть строчными, и в ответе не должно быть никаких ведущих нулей, кроме самого нуля. Примечание: Вам не разрешается использовать какие-либо встроенные библиотечные методы для непосредственного решения этой задачи.
Пример:
👨💻 Алгоритм:
1⃣ Определите, является ли число отрицательным. Если да, преобразуйте его в положительное число с помощью метода дополнения до двух. Для этого прибавьте к числу 2^32 и используйте битовую операцию И с маской 0xFFFFFFFF.
2⃣ Создайте строку с шестнадцатеричными символами. Последовательно делите число на 16 и добавляйте соответствующий символ к результату, пока число не станет равным нулю.
3⃣ Переверните строку результата и удалите ведущие нули, если они есть. Если строка пустая, верните "0".
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Если задано целое число num, верните строку, представляющую его шестнадцатеричное представление. Для отрицательных целых чисел используется метод дополнения до двух. Все буквы в строке ответа должны быть строчными, и в ответе не должно быть никаких ведущих нулей, кроме самого нуля. Примечание: Вам не разрешается использовать какие-либо встроенные библиотечные методы для непосредственного решения этой задачи.
Пример:
Input: num = 26
Output: "1a"
package main
import (
"fmt"
"strings"
)
func toHex(num int) string {
if num == 0 {
return "0"
}
hexChars := "0123456789abcdef"
if num < 0 {
num += 1 << 32
}
result := []byte{}
for num > 0 {
result = append(result, hexChars[num%16])
num /= 16
}
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
result[i], result[j] = result[j], result[i]
}
return string(result)
}
func main() {
fmt.Println(toHex(26))
fmt.Println(toHex(-1))
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1431. Kids With the Greatest Number of Candies
Сложность: easy
Дано n детей с конфетами. Вам дан целочисленный массив candies, где каждый candies[i] представляет количество конфет у i-го ребенка, и целое число extraCandies, обозначающее количество дополнительных конфет, которые у вас есть.
Вернуть булев массив result длиной n, где result[i] равно true, если, дав i-му ребенку все дополнительные конфеты, он будет иметь наибольшее количество конфет среди всех детей, или false в противном случае.
Обратите внимание, что несколько детей могут иметь наибольшее количество конфет.
Пример:
👨💻 Алгоритм:
1⃣ Найдите максимальное количество конфет в массиве candies, сохраняя его в переменной maxCandies.
2⃣ Создайте булев список answer и пройдитесь по массиву candies, добавляя в answer значение true, если текущий ребенок с добавленными extraCandies имеет количество конфет больше или равное maxCandies, иначе добавляйте false.
3⃣ Верните список answer.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано n детей с конфетами. Вам дан целочисленный массив candies, где каждый candies[i] представляет количество конфет у i-го ребенка, и целое число extraCandies, обозначающее количество дополнительных конфет, которые у вас есть.
Вернуть булев массив result длиной n, где result[i] равно true, если, дав i-му ребенку все дополнительные конфеты, он будет иметь наибольшее количество конфет среди всех детей, или false в противном случае.
Обратите внимание, что несколько детей могут иметь наибольшее количество конфет.
Пример:
Input: candies = [2,3,5,1,3], extraCandies = 3
Output: [true,true,true,false,true]
Explanation: If you give all extraCandies to:
- Kid 1, they will have 2 + 3 = 5 candies, which is the greatest among the kids.
- Kid 2, they will have 3 + 3 = 6 candies, which is the greatest among the kids.
- Kid 3, they will have 5 + 3 = 8 candies, which is the greatest among the kids.
- Kid 4, they will have 1 + 3 = 4 candies, which is not the greatest among the kids.
- Kid 5, they will have 3 + 3 = 6 candies, which is the greatest among the kids.
func kidsWithCandies(candies []int, extraCandies int) []bool {
maxCandies := 0
for _, candy := range candies {
if candy > maxCandies {
maxCandies = candy
}
}
result := make([]bool, len(candies))
for i, candy := range candies {
result[i] = candy + extraCandies >= maxCandies
}
return result
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 120. Triangle
Сложность: medium
Дан массив в виде треугольника, верните минимальную сумму пути сверху вниз.
На каждом шаге вы можете перейти к соседнему числу в строке ниже. Более формально, если вы находитесь на индексе i в текущей строке, вы можете перейти либо к индексу i, либо к индексу i + 1 в следующей строке.
Пример:
👨💻 Алгоритм:
1⃣ Простейший способ реализации этого заключается в перезаписи входных данных, то есть в использовании алгоритма "на месте". В подходе 2 мы рассмотрим, как модифицировать алгоритм так, чтобы он не перезаписывал входные данные, но при этом не требовал более чем O(n) дополнительного пространства.
2⃣ Когда этот алгоритм завершит свою работу, каждая ячейка (строка, столбец) входного треугольника будет перезаписана минимальной суммой пути от (0, 0) (вершины треугольника) до (строка, столбец) включительно.
Совет на собеседовании: Алгоритмы "на месте" перезаписывают входные данные для экономии места, но иногда это может вызвать проблемы. Вот несколько ситуаций, когда алгоритм "на месте" может быть неуместен.
3⃣ 1. Алгоритму необходимо работать в многопоточной среде, без эксклюзивного доступа к массиву. Другим потокам может потребоваться читать массив тоже, и они могут не ожидать, что он будет изменен.
2. Даже если поток один, или у алгоритма есть эксклюзивный доступ к массиву во время выполнения, массив может потребоваться повторно использовать позже или другим потоком после освобождения блокировки.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан массив в виде треугольника, верните минимальную сумму пути сверху вниз.
На каждом шаге вы можете перейти к соседнему числу в строке ниже. Более формально, если вы находитесь на индексе i в текущей строке, вы можете перейти либо к индексу i, либо к индексу i + 1 в следующей строке.
Пример:
Input: triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
Output: 11
Explanation: The triangle looks like:
2
3 4
6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).
Совет на собеседовании: Алгоритмы "на месте" перезаписывают входные данные для экономии места, но иногда это может вызвать проблемы. Вот несколько ситуаций, когда алгоритм "на месте" может быть неуместен.
2. Даже если поток один, или у алгоритма есть эксклюзивный доступ к массиву во время выполнения, массив может потребоваться повторно использовать позже или другим потоком после освобождения блокировки.
func minimumTotal(triangle [][]int) int {
for row := 1; row < len(triangle); row++ {
for col := 0; col <= row; col++ {
smallestAbove := math.MaxInt32
if col > 0 {
smallestAbove = triangle[row-1][col-1]
}
if col < row {
smallestAbove = min(smallestAbove, triangle[row-1][col])
}
triangle[row][col] += smallestAbove
}
}
return minSlice(triangle[len(triangle)-1])
}
func minSlice(slice []int) int {
minVal := slice[0]
for _, val := range slice {
minVal = min(minVal, val)
}
return minVal
}
func min(a int, b int) int {
if a < b {
return a
}
return b
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 338. Counting Bits
Сложность: easy
Дано целое число n, верните массив ans длиной n + 1, такой что для каждого i (0 <= i <= n), ans[i] будет равняться количеству единиц в двоичном представлении числа i.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация массива:
Создайте массив ans длиной n + 1, заполненный нулями. Этот массив будет содержать количество единиц в двоичном представлении каждого числа от 0 до n.
2⃣ Итерация и вычисление:
Пройдите в цикле по всем числам от 1 до n. Для каждого числа x используйте битовую операцию x & (x - 1), чтобы убрать последнюю установленную биту, и добавьте 1 к значению ans для этого результата. Это количество единиц в двоичном представлении числа x.
3⃣ Возврат результата:
Верните заполненный массив ans, который содержит количество единиц для каждого числа от 0 до n.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано целое число n, верните массив ans длиной n + 1, такой что для каждого i (0 <= i <= n), ans[i] будет равняться количеству единиц в двоичном представлении числа i.
Пример:
Input: n = 5
Output: [0,1,1,2,1,2]
Explanation:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
Создайте массив ans длиной n + 1, заполненный нулями. Этот массив будет содержать количество единиц в двоичном представлении каждого числа от 0 до n.
Пройдите в цикле по всем числам от 1 до n. Для каждого числа x используйте битовую операцию x & (x - 1), чтобы убрать последнюю установленную биту, и добавьте 1 к значению ans для этого результата. Это количество единиц в двоичном представлении числа x.
Верните заполненный массив ans, который содержит количество единиц для каждого числа от 0 до n.
func countBits(num int) []int {
ans := make([]int, num + 1)
for x := 1; x <= num; x++ {
ans[x] = ans[x & (x - 1)] + 1
}
return ans
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 868. Binary Gap
Сложность: easy
Дано положительное целое число n, найдите и верните наибольшее расстояние между любыми двумя соседними единицами в двоичном представлении числа n. Если нет двух соседних единиц, верните 0.
Две единицы считаются соседними, если их разделяют только нули (возможно, никаких нулей нет). Расстояние между двумя единицами — это абсолютная разница между их позициями в битовом представлении. Например, две единицы в "1001" имеют расстояние 3.
Пример:
👨💻 Алгоритм:
1⃣ Создайте список A индексов i, таких что в двоичном представлении числа n i-й бит установлен в 1.
2⃣ Используйте список A, чтобы найти максимальное расстояние между соседними значениями. Для этого пройдите по списку и вычислите разницу между каждым соседним элементом.
3⃣ Верните найденное максимальное расстояние.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дано положительное целое число n, найдите и верните наибольшее расстояние между любыми двумя соседними единицами в двоичном представлении числа n. Если нет двух соседних единиц, верните 0.
Две единицы считаются соседними, если их разделяют только нули (возможно, никаких нулей нет). Расстояние между двумя единицами — это абсолютная разница между их позициями в битовом представлении. Например, две единицы в "1001" имеют расстояние 3.
Пример:
Input: n = 22
Output: 2
Explanation: 22 in binary is "10110".
The first adjacent pair of 1's is "10110" with a distance of 2.
The second adjacent pair of 1's is "10110" with a distance of 1.
The answer is the largest of these two distances, which is 2.
Note that "10110" is not a valid pair since there is a 1 separating the two 1's underlined.
func binaryGap(N int) int {
A, t := make([]int, 0, 32), 0
for i := 0; i < 32; i++ {
if (N>>i)&1 != 0 {
A = append(A, i)
t++
}
}
ans := 0
for i := 0; i < t-1; i++ {
if A[i+1]-A[i] > ans {
ans = A[i+1] - A[i]
}
}
return ans
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 269. Alien Dictionary
Сложность: hard
Есть новый инопланетный язык, который использует английский алфавит. Однако порядок букв в нем неизвестен.
Вам дан список строк words из словаря инопланетного языка. Утверждается, что строки в words отсортированы лексикографически по правилам этого нового языка.
Если это утверждение неверно и данное расположение строк в words не может соответствовать никакому порядку букв, верните "".
В противном случае верните строку из уникальных букв нового инопланетного языка, отсортированных в лексикографическом порядке по правилам нового языка. Если существует несколько решений, верните любое из них.
Пример:
👨💻 Алгоритм:
1⃣ Извлечение отношений порядка и создание списков смежности:
Извлечь отношения порядка между буквами из слов.
Вставить их в список смежности, обрабатывая случаи, когда одно слово является префиксом другого.
2⃣ Подсчет числа входящих ребер:
Подсчитать количество входящих ребер (in-degree) для каждой буквы.
Построить исходящий список смежности и одновременно считать входящие ребра для каждой буквы.
3⃣ Обход в ширину (BFS):
Инициализировать очередь буквами с нулевым in-degree.
Выполнять BFS, добавляя буквы в результат, когда их in-degree становится нулевым.
Продолжать до тех пор, пока очередь не станет пустой.
Проверить наличие циклов и вернуть результат.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Есть новый инопланетный язык, который использует английский алфавит. Однако порядок букв в нем неизвестен.
Вам дан список строк words из словаря инопланетного языка. Утверждается, что строки в words отсортированы лексикографически по правилам этого нового языка.
Если это утверждение неверно и данное расположение строк в words не может соответствовать никакому порядку букв, верните "".
В противном случае верните строку из уникальных букв нового инопланетного языка, отсортированных в лексикографическом порядке по правилам нового языка. Если существует несколько решений, верните любое из них.
Пример:
Input: words = ["wrt","wrf","er","ett","rftt"]
Output: "wertf"
Извлечь отношения порядка между буквами из слов.
Вставить их в список смежности, обрабатывая случаи, когда одно слово является префиксом другого.
Подсчитать количество входящих ребер (in-degree) для каждой буквы.
Построить исходящий список смежности и одновременно считать входящие ребра для каждой буквы.
Инициализировать очередь буквами с нулевым in-degree.
Выполнять BFS, добавляя буквы в результат, когда их in-degree становится нулевым.
Продолжать до тех пор, пока очередь не станет пустой.
Проверить наличие циклов и вернуть результат.
package main
import (
"container/list"
"strings"
)
func alienOrder(words []string) string {
adjList := make(map[byte]map[byte]struct{})
inDegree := make(map[byte]int)
for _, word := range words {
for i := 0; i < len(word); i++ {
inDegree[word[i]] = 0
}
}
for i := 0; i < len(words)-1; i++ {
firstWord := words[i]
secondWord := words[i+1]
for j := 0; j < len(firstWord) && j < len(secondWord); j++ {
c := firstWord[j]
d := secondWord[j]
if c != d {
if _, exists := adjList[c]; !exists {
adjList[c] = make(map[byte]struct{})
}
if _, exists := adjList[c][d]; !exists {
adjList[c][d] = struct{}{}
inDegree[d]++
}
break
}
}
if len(secondWord) < len(firstWord) && strings.HasPrefix(firstWord, secondWord) {
return ""
}
}
queue := list.New()
for char, degree := range inDegree {
if degree == 0 {
queue.PushBack(char)
}
}
var output strings.Builder
for queue.Len() > 0 {
elem := queue.Front()
c := elem.Value.(byte)
queue.Remove(elem)
output.WriteByte(c)
if neighbors, exists := adjList[c]; exists {
for d := range neighbors {
inDegree[d]--
if inDegree[d] == 0 {
queue.PushBack(d)
}
}
}
}
if output.Len() < len(inDegree) {
return ""
}
return output.String()
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 239. Sliding Window Maximum
Сложность: hard
Вам дан массив целых чисел nums. Существует скользящее окно размера k, которое перемещается с самого левого конца массива до самого правого. Вы можете видеть только k чисел в окне. Каждый раз скользящее окно перемещается вправо на одну позицию.
Верните максимальные значения скользящего окна.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и заполнение первой части окна:
Создайте двустороннюю очередь dq для хранения индексов элементов и список res для хранения результатов.
Пройдите по первым k элементам массива nums (от i = 0 до k - 1). Для каждого элемента:
Удалите из dq все элементы, которые меньше или равны текущему элементу nums[i].
Добавьте текущий индекс i в конец dq.
Добавьте в res максимальный элемент первого окна, который находится в nums[dq[0]].
2⃣ Сканирование оставшейся части массива:
Пройдите по оставшимся элементам массива nums (от i = k до n - 1). Для каждого элемента:
Если индекс элемента на передней части dq равен i - k, удалите этот элемент из dq, так как он выходит за пределы текущего окна.
Удалите из dq все элементы, которые меньше или равны текущему элементу nums[i].
Добавьте текущий индекс i в конец dq.
Добавьте в res максимальный элемент текущего окна, который находится в nums[dq[0]].
3⃣ Возвращение результата:
Верните список res, содержащий максимальные элементы для каждого скользящего окна.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Вам дан массив целых чисел nums. Существует скользящее окно размера k, которое перемещается с самого левого конца массива до самого правого. Вы можете видеть только k чисел в окне. Каждый раз скользящее окно перемещается вправо на одну позицию.
Верните максимальные значения скользящего окна.
Пример:
Input: nums = [1], k = 1
Output: [1]
Создайте двустороннюю очередь dq для хранения индексов элементов и список res для хранения результатов.
Пройдите по первым k элементам массива nums (от i = 0 до k - 1). Для каждого элемента:
Удалите из dq все элементы, которые меньше или равны текущему элементу nums[i].
Добавьте текущий индекс i в конец dq.
Добавьте в res максимальный элемент первого окна, который находится в nums[dq[0]].
Пройдите по оставшимся элементам массива nums (от i = k до n - 1). Для каждого элемента:
Если индекс элемента на передней части dq равен i - k, удалите этот элемент из dq, так как он выходит за пределы текущего окна.
Удалите из dq все элементы, которые меньше или равны текущему элементу nums[i].
Добавьте текущий индекс i в конец dq.
Добавьте в res максимальный элемент текущего окна, который находится в nums[dq[0]].
Верните список res, содержащий максимальные элементы для каждого скользящего окна.
func maxSlidingWindow(nums []int, k int) []int {
dq := make([]int, 0)
res := make([]int, 0)
for i := 0; i < k; i++ {
for len(dq) > 0 && nums[i] >= nums[dq[len(dq)-1]] {
dq = dq[:len(dq)-1]
}
dq = append(dq, i)
}
res = append(res, nums[dq[0]])
for i := k; i < len(nums); i++ {
if dq[0] == i - k {
dq = dq[1:]
}
for len(dq) > 0 && nums[i] >= nums[dq[len(dq)-1]] {
dq = dq[:len(dq)-1]
}
dq = append(dq, i)
res = append(res, nums[dq[0]])
}
return res
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 290. Word Pattern
Сложность: easy
Дан шаблон и строка s, необходимо определить, следует ли строка s этому шаблону.
Здесь "следует" означает полное соответствие, такое что существует биекция между буквой в шаблоне и непустым словом в строке s.
Пример:
👨💻 Алгоритм:
1⃣ Разделение строки на слова:
Разделите строку s на отдельные слова.
Если количество слов не равно длине шаблона, возвращаем false.
2⃣ Создание отображений:
Создайте два словаря: один для отображения букв шаблона на слова, другой для слов на буквы шаблона.
3⃣ Проверка биекции:
Пройдите по каждому символу шаблона и соответствующему слову.
Если символ уже в словаре и не соответствует текущему слову или слово уже в словаре и не соответствует текущему символу, возвращаем false.
Иначе добавляем символ и слово в словари и продолжаем проверку. Если все проверки пройдены, возвращаем true.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан шаблон и строка s, необходимо определить, следует ли строка s этому шаблону.
Здесь "следует" означает полное соответствие, такое что существует биекция между буквой в шаблоне и непустым словом в строке s.
Пример:
Input: pattern = "abba", s = "dog cat cat dog"
Output: true
Разделите строку s на отдельные слова.
Если количество слов не равно длине шаблона, возвращаем false.
Создайте два словаря: один для отображения букв шаблона на слова, другой для слов на буквы шаблона.
Пройдите по каждому символу шаблона и соответствующему слову.
Если символ уже в словаре и не соответствует текущему слову или слово уже в словаре и не соответствует текущему символу, возвращаем false.
Иначе добавляем символ и слово в словари и продолжаем проверку. Если все проверки пройдены, возвращаем true.
package main
import (
"strings"
)
func wordPattern(pattern string, s string) bool {
mapChar := make(map[rune]string)
mapWord := make(map[string]rune)
words := strings.Split(s, " ")
if len(words) != len(pattern) {
return false
}
for i, c := range pattern {
w := words[i]
if _, ok := mapChar[c]; !ok {
if _, ok := mapWord[w]; ok {
return false
} else {
mapChar[c] = w
mapWord[w] = c
}
} else {
if mapChar[c] != w {
return false
}
}
}
return true
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 105. Construct Binary Tree from Preorder and Inorder Traversal
Сложность: easy
Даны два массива целых чисел: preorder и inorder, где preorder — это результат преордер обхода бинарного дерева, а inorder — результат инордер обхода того же дерева. Постройте и верните бинарное дерево.
Пример:
👨💻 Алгоритм:
1⃣ Создайте хеш-таблицу для записи соотношения значений и их индексов в массиве inorder, чтобы можно было быстро найти позицию корня.
2⃣ Инициализируйте переменную целочисленного типа preorderIndex для отслеживания элемента, который будет использоваться для создания корня. Реализуйте рекурсивную функцию arrayToTree, которая принимает диапазон массива inorder и возвращает построенное бинарное дерево:
Если диапазон пуст, возвращается null;
Инициализируйте корень элементом preorder[preorderIndex], затем увеличьте preorderIndex;
Рекурсивно используйте левую и правую части массива inorder для построения левого и правого поддеревьев.
3⃣ Просто вызовите функцию рекурсии с полным диапазоном массива inorder.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны два массива целых чисел: preorder и inorder, где preorder — это результат преордер обхода бинарного дерева, а inorder — результат инордер обхода того же дерева. Постройте и верните бинарное дерево.
Пример:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
Если диапазон пуст, возвращается null;
Инициализируйте корень элементом preorder[preorderIndex], затем увеличьте preorderIndex;
Рекурсивно используйте левую и правую части массива inorder для построения левого и правого поддеревьев.
func buildTree(preorder []int, inorder []int) *TreeNode {
preorderIndex := 0
inorderIndexMap := make(map[int]int)
for i := 0; i < len(inorder); i++ {
inorderIndexMap[inorder[i]] = i
}
var arrayToTree func(left int, right int) *TreeNode
arrayToTree = func(left int, right int) *TreeNode {
if left > right {
return nil
}
rootValue := preorder[preorderIndex]
preorderIndex++
root := &TreeNode{Val: rootValue}
root.Left = arrayToTree(left, inorderIndexMap[rootValue]-1)
root.Right = arrayToTree(inorderIndexMap[rootValue]+1, right)
return root
}
return arrayToTree(0, len(preorder)-1)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 865. Smallest Subtree with all the Deepest Nodes
Сложность: medium
Дан корень бинарного дерева, глубина каждого узла — это кратчайшее расстояние до корня.
Верните наименьшее поддерево, которое содержит все самые глубокие узлы в исходном дереве.
Узел называется самым глубоким, если у него наибольшая возможная глубина среди всех узлов в дереве.
Поддерево узла — это дерево, состоящее из этого узла и всех его потомков.
Пример:
👨💻 Алгоритм:
1⃣ В первой фазе используем поиск в глубину (DFS), чтобы аннотировать узлы. Каждый узел будет хранить информацию о своей глубине и о самой большой глубине среди его потомков.
2⃣ Во второй фазе также используем DFS для функции answer(node), которая возвращает наименьшее поддерево, содержащее все самые глубокие узлы. Функция сравнивает глубины левых и правых поддеревьев узла для определения наименьшего поддерева.
3⃣ Функция answer(node) возвращает поддерево, которое содержит все самые глубокие узлы всего дерева, а не только рассматриваемого поддерева.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан корень бинарного дерева, глубина каждого узла — это кратчайшее расстояние до корня.
Верните наименьшее поддерево, которое содержит все самые глубокие узлы в исходном дереве.
Узел называется самым глубоким, если у него наибольшая возможная глубина среди всех узлов в дереве.
Поддерево узла — это дерево, состоящее из этого узла и всех его потомков.
Пример:
Input: root = [3,5,1,6,2,0,8,null,null,7,4]
Output: [2,7,4]
Explanation: We return the node with value 2, colored in yellow in the diagram.
The nodes coloured in blue are the deepest nodes of the tree.
Notice that nodes 5, 3 and 2 contain the deepest nodes in the tree but node 2 is the smallest subtree among them, so we return it.
func subtreeWithAllDeepest(root *TreeNode) *TreeNode {
depth := map[*TreeNode]int{nil: -1}
var dfs func(node, parent *TreeNode)
dfs = func(node, parent *TreeNode) {
if node != nil {
depth[node] = depth[parent] + 1
dfs(node.Left, node)
dfs(node.Right, node)
}
}
dfs(root, nil)
maxDepth := -1
for _, d := range depth {
if d > maxDepth {
maxDepth = d
}
}
var answer func(node *TreeNode) *TreeNode
answer = func(node *TreeNode) *TreeNode {
if node == nil || depth[node] == maxDepth {
return node
}
L := answer(node.Left)
R := answer(node.Right)
if L != nil && R != nil {
return node
}
if L != nil {
return L
}
return R
}
return answer(root)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 687. Longest Univalue Path
Сложность: medium
Дано корень бинарного дерева, верните длину самого длинного пути, на котором все узлы имеют одинаковое значение. Этот путь может проходить через корень или не проходить.
Длина пути между двумя узлами представлена количеством рёбер между ними.
Пример:
👨💻 Алгоритм:
1⃣ Определить рекурсивную функцию solve(), принимающую текущий узел root и значение родительского узла parent. Если root равен NULL, вернуть 0. Рекурсивно вызвать solve() для левого и правого дочернего узлов, передав значение текущего узла как значение родительского узла.
2⃣ Обновить переменную ans, если сумма значений для левого и правого узлов больше текущего значения ans. Если значение текущего узла равно значению родительского узла, вернуть max(left, right) + 1, иначе вернуть 0.
3⃣ Вызвать solve() с корневым узлом и значением родительского узла -1. Вернуть максимальную длину пути ans..
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано корень бинарного дерева, верните длину самого длинного пути, на котором все узлы имеют одинаковое значение. Этот путь может проходить через корень или не проходить.
Длина пути между двумя узлами представлена количеством рёбер между ними.
Пример:
Input: root = [5,4,5,1,1,null,5]
Output: 2
Explanation: The shown image shows that the longest path of the same value (i.e. 5).
package main
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
type Solution struct {
ans int
}
func (s *Solution) solve(root *TreeNode, parent int) int {
if root == nil {
return 0
}
left := s.solve(root.Left, root.Val)
right := s.solve(root.Right, root.Val)
if s.ans < left+right {
s.ans = left + right
}
if root.Val == parent {
if left > right {
return left + 1
} else {
return right + 1
}
}
return 0
}
func (s *Solution) LongestUnivaluePath(root *TreeNode) int {
s.solve(root, -1)
return s.ans
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM