#easy
Задача: 674. Longest Continuous Increasing Subsequence
Дан неотсортированный массив целых чисел nums, верните длину самой длинной непрерывной возрастающей подпоследовательности (т.е. подмассива). Подпоследовательность должна быть строго возрастающей.
Непрерывная возрастающая подпоследовательность определяется двумя индексами l и r (l < r) так, что она имеет вид [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] и для каждого l <= i < r выполняется nums[i] < nums[i + 1].
Пример:
👨💻 Алгоритм:
1⃣ Каждая (непрерывная) возрастающая подпоследовательность не пересекается, и граница каждой такой подпоследовательности возникает, когда nums[i-1] >= nums[i]. В этом случае начинается новая возрастающая подпоследовательность с nums[i], и мы сохраняем такой i в переменной anchor.
2⃣ Например, если nums = [7, 8, 9, 1, 2, 3], то anchor начинается с 0 (nums[anchor] = 7) и затем устанавливается на anchor = 3 (nums[anchor] = 1). Независимо от значения anchor, мы записываем кандидата на ответ длиной i - anchor + 1, длина подмассива nums[anchor], nums[anchor+1], ..., nums[i], и наш ответ обновляется соответствующим образом.
3⃣ Возвращаем максимальную длину найденной непрерывной возрастающей подпоследовательности.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 674. Longest Continuous Increasing Subsequence
Дан неотсортированный массив целых чисел nums, верните длину самой длинной непрерывной возрастающей подпоследовательности (т.е. подмассива). Подпоследовательность должна быть строго возрастающей.
Непрерывная возрастающая подпоследовательность определяется двумя индексами l и r (l < r) так, что она имеет вид [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] и для каждого l <= i < r выполняется nums[i] < nums[i + 1].
Пример:
Input: nums = [1,3,5,4,7]
Output: 3
Explanation: The longest continuous increasing subsequence is [1,3,5] with length 3.
Even though [1,3,5,7] is an increasing subsequence, it is not continuous as elements 5 and 7 are separated by element
4.
func findLengthOfLCIS(nums []int) int {
ans, anchor := 0, 0
for i := 0; i < len(nums); i++ {
if i > 0 && nums[i-1] >= nums[i] {
anchor = i
}
if i-anchor+1 > ans {
ans = i - anchor + 1
}
}
return ans
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 675. Cut Off Trees for Golf Event
Вам необходимо срубить все деревья в лесу для проведения гольф-мероприятия. Лес представлен в виде матрицы m x n. В этой матрице:
- 0 означает, что ячейка непроходима.
- 1 представляет собой пустую проходимую ячейку.
- Число больше 1 представляет собой дерево в ячейке, и это число обозначает высоту дерева.
За один шаг вы можете передвигаться в любом из четырех направлений: север, восток, юг и запад. Если вы стоите в ячейке с деревом, вы можете выбрать, срубить его или нет.
Вы должны срубить деревья в порядке от самого низкого до самого высокого. Когда вы срубаете дерево, значение в его ячейке становится 1 (пустая ячейка).
Начиная с точки (0, 0), верните минимальное количество шагов, необходимых для того, чтобы срубить все деревья. Если невозможно срубить все деревья, верните -1.
Примечание: Входные данные сформированы так, что нет двух деревьев с одинаковой высотой, и нужно срубить как минимум одно дерево.
Пример:
👨💻 Алгоритм:
1⃣ Начиная с (0, 0), для каждого дерева в порядке возрастания высоты будем вычислять расстояние от текущего местоположения до следующего дерева (и перемещаться туда), добавляя это расстояние к ответу.
2⃣ Формулируем задачу как предоставление функции расстояния dist(forest, sr, sc, tr, tc), которая вычисляет расстояние от точки (sr, sc) до цели (tr, tc) с учетом препятствий, где dist[i][j] == 0. (Эта функция расстояния вернет -1, если путь невозможен.)
3⃣ Далее следует код и анализ сложности, которые общие для всех трех подходов. Затем алгоритмы, представленные в наших подходах, будут сосредоточены только на предоставлении нашей функции dist.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 675. Cut Off Trees for Golf Event
Вам необходимо срубить все деревья в лесу для проведения гольф-мероприятия. Лес представлен в виде матрицы m x n. В этой матрице:
- 0 означает, что ячейка непроходима.
- 1 представляет собой пустую проходимую ячейку.
- Число больше 1 представляет собой дерево в ячейке, и это число обозначает высоту дерева.
За один шаг вы можете передвигаться в любом из четырех направлений: север, восток, юг и запад. Если вы стоите в ячейке с деревом, вы можете выбрать, срубить его или нет.
Вы должны срубить деревья в порядке от самого низкого до самого высокого. Когда вы срубаете дерево, значение в его ячейке становится 1 (пустая ячейка).
Начиная с точки (0, 0), верните минимальное количество шагов, необходимых для того, чтобы срубить все деревья. Если невозможно срубить все деревья, верните -1.
Примечание: Входные данные сформированы так, что нет двух деревьев с одинаковой высотой, и нужно срубить как минимум одно дерево.
Пример:
Input: forest = [[1,2,3],[0,0,4],[7,6,5]]
Output: 6
Explanation: Following the path above allows you to cut off the trees from shortest to tallest in 6 steps.
func cutOffTree(forest [][]int) int {
type Tree struct {
height, r, c int
}
var trees []Tree
for r, row := range forest {
for c, v := range row {
if v > 1 {
trees = append(trees, Tree{v, r, c})
}
}
}
sort.Slice(trees, func(i, j int) bool {
return trees[i].height < trees[j].height
})
sr, sc, ans := 0, 0, 0
for _, tree := range trees {
tr, tc := tree.r, tree.c
d := dist(forest, sr, sc, tr, tc)
if d < 0 {
return -1
}
ans += d
sr, sc = tr, tc
}
return ans
}
func dist(forest [][]int, sr, sc, tr, tc int) int {
// Implement the distance function here
return 0
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
#hard
Задача: 312. Burst Balloons
Дано n воздушных шаров, пронумерованных от 0 до n - 1. Каждый шарик окрашен в число, представленное массивом nums. Вам нужно лопнуть все шарики.
Если вы лопаете шарик i, вы получите nums[i - 1] * nums[i] * nums[i + 1] монет. Если i - 1 или i + 1 выходит за границы массива, то считайте, что там находится шарик с числом 1.
Верните максимальное количество монет, которое можно собрать, лопая шарики с умом.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и подготовка данных
Добавьте по одному шару с числом 1 в начало и конец массива nums, чтобы упростить обработку граничных случаев. Определите функцию dp(left, right), которая будет возвращать максимальное количество монет, если лопнуть все шары на интервале [left, right] включительно.
2⃣ Вычисление значений для всех интервалов
Для каждого интервала [left, right] и каждого индекса i в этом интервале: Вычислите максимальные монеты, которые можно получить, сначала лопая все шары кроме i, а затем лопая i. Обновите dp(left, right) максимальной суммой этих монет.
3⃣ Возврат результата
Верните значение dp(1, n - 2), которое будет содержать максимальное количество монет, которое можно собрать, лопнув все шары с умом, исключая добавленные нами шары.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 312. Burst Balloons
Дано n воздушных шаров, пронумерованных от 0 до n - 1. Каждый шарик окрашен в число, представленное массивом nums. Вам нужно лопнуть все шарики.
Если вы лопаете шарик i, вы получите nums[i - 1] * nums[i] * nums[i + 1] монет. Если i - 1 или i + 1 выходит за границы массива, то считайте, что там находится шарик с числом 1.
Верните максимальное количество монет, которое можно собрать, лопая шарики с умом.
Пример:
Input: nums = [1,5]
Output: 10
Добавьте по одному шару с числом 1 в начало и конец массива nums, чтобы упростить обработку граничных случаев. Определите функцию dp(left, right), которая будет возвращать максимальное количество монет, если лопнуть все шары на интервале [left, right] включительно.
Для каждого интервала [left, right] и каждого индекса i в этом интервале: Вычислите максимальные монеты, которые можно получить, сначала лопая все шары кроме i, а затем лопая i. Обновите dp(left, right) максимальной суммой этих монет.
Верните значение dp(1, n - 2), которое будет содержать максимальное количество монет, которое можно собрать, лопнув все шары с умом, исключая добавленные нами шары.
func maxCoins(nums []int) int {
n := len(nums)
newNums := make([]int, n+2)
newNums[0] = 1
newNums[n+1] = 1
for i := 0; i < n; i++ {
newNums[i+1] = nums[i]
}
dp := make([][]int, n+2)
for i := range dp {
dp[i] = make([]int, n+2)
}
for length := 2; length < n+2; length++ {
for left := 0; left < n+2-length; left++ {
right := left + length
for i := left + 1; i < right; i++ {
dp[left][right] = max(dp[left][right],
newNums[left]*newNums[i]*newNums[right] + dp[left][i] + dp[i][right])
}
}
}
return dp[0][n+1]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 313. Super Ugly Number
Супер некрасивое число — это положительное целое число, простые множители которого находятся в массиве 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-м супер некрасивым числом.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 313. Super Ugly Number
Супер некрасивое число — это положительное целое число, простые множители которого находятся в массиве 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
#medium
Задача: 633. Sum of Square Numbers
Учитывая целое неотрицательное число c, решите, существуют ли два целых числа a и b такие, что a2 + b2 = c.
Пример:
👨💻 Алгоритм:
1⃣ Проверка границ
Проверьте, если c меньше 0, немедленно верните false, так как сумма квадратов двух целых чисел не может быть отрицательной.
2⃣ Инициализация указателей
Используйте два указателя a и b. Инициализируйте a на 0 и b на значение квадратного корня из c. Поиск решения: Используйте цикл для поиска a и b, таких что a^2 + b^2 == c: Если a^2 + b^2 равно c, верните true. Если a^2 + b^2 меньше c, увеличьте a на 1. Если a^2 + b^2 больше c, уменьшите b на 1.
3⃣ Возвращение результата
Если цикл завершится без нахождения подходящих a и b, верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 633. Sum of Square Numbers
Учитывая целое неотрицательное число c, решите, существуют ли два целых числа a и b такие, что a2 + b2 = c.
Пример:
Input: c = 5
Output: true
Проверьте, если c меньше 0, немедленно верните false, так как сумма квадратов двух целых чисел не может быть отрицательной.
Используйте два указателя a и b. Инициализируйте a на 0 и b на значение квадратного корня из c. Поиск решения: Используйте цикл для поиска a и b, таких что a^2 + b^2 == c: Если a^2 + b^2 равно c, верните true. Если a^2 + b^2 меньше c, увеличьте a на 1. Если a^2 + b^2 больше c, уменьшите b на 1.
Если цикл завершится без нахождения подходящих a и b, верните false.
package main
import (
"math"
"fmt"
)
func judgeSquareSum(c int) bool {
a := 0
b := int(math.Sqrt(float64(c)))
for a <= b {
total := a * a + b * b
if total == c {
return true
} else if total < c {
a++
} else {
b--
}
}
return false
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#medium
Задача: 634. Find the Derangement of An Array
В комбинаторной математике отклонение - это перестановка элементов множества таким образом, что ни один элемент не оказывается на прежнем месте. Вам дано целое число n. Изначально имеется массив, состоящий из n целых чисел от 1 до n в порядке возрастания, верните количество отклонений, которые он может породить. Поскольку ответ может быть огромным, верните его по модулю 109 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация массива для хранения результатов
Создайте массив dp для хранения количества отклонений для каждого значения от 0 до n. Установите начальные значения: dp[0] = 1 и dp[1] = 0.
2⃣ Вычисление количества отклонений
Используйте динамическое программирование для вычисления количества отклонений для каждого значения от 2 до n. Формула для вычисления: dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD.
3⃣ Возвращение результата
Верните значение dp[n], которое будет количеством отклонений для n элементов, по модулю 10^9 + 7.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 634. Find the Derangement of An Array
В комбинаторной математике отклонение - это перестановка элементов множества таким образом, что ни один элемент не оказывается на прежнем месте. Вам дано целое число n. Изначально имеется массив, состоящий из n целых чисел от 1 до n в порядке возрастания, верните количество отклонений, которые он может породить. Поскольку ответ может быть огромным, верните его по модулю 109 + 7.
Пример:
Input: n = 3
Output: 2
Создайте массив dp для хранения количества отклонений для каждого значения от 0 до n. Установите начальные значения: dp[0] = 1 и dp[1] = 0.
Используйте динамическое программирование для вычисления количества отклонений для каждого значения от 2 до n. Формула для вычисления: dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) % MOD.
Верните значение dp[n], которое будет количеством отклонений для n элементов, по модулю 10^9 + 7.
package main
import "fmt"
func countDerangements(n int) int {
const MOD = 1000000007
if n == 0 {
return 1
}
if n == 1 {
return 0
}
dp := make([]int, n+1)
dp[0] = 1
dp[1] = 0
for i := 2; i <= n; i++ {
dp[i] = (i - 1) * (dp[i-1] + dp[i-2]) % MOD
}
return dp[n]
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 635. Design Log Storage System
Вам дается несколько журналов, где каждый журнал содержит уникальный идентификатор и временную метку. Временная метка - это строка, имеющая следующий формат: Год:Месяц:День:Час:Минута:Секунда, например, 2017:01:01:23:59:59. Все домены - десятичные числа с нулевым добавлением. Реализация класса LogSystem: LogSystem() Инициализирует объект LogSystem. void put(int id, string timestamp) Сохраняет заданный журнал (id, timestamp) в вашей системе хранения.
int[] retrieve(string start, string end, string granularity) Возвращает идентификаторы журналов, временные метки которых находятся в диапазоне от start до end включительно. start и end имеют тот же формат, что и timestamp, а granularity означает, насколько точным должен быть диапазон (т. е. с точностью до дня, минуты и т. д.). Например, start = "2017:01:01:23:59:59", end = "2017:01:02:23:59:59", а granularity = "Day" означает, что нам нужно найти журналы в диапазоне от 1 января 2017 года до 2 января 2017 года включительно, а час, минуту и секунду для каждой записи журнала можно игнорировать.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и хранение журналов
Реализуйте метод put, который будет сохранять журнал с заданным id и timestamp в системе хранения.
2⃣ Формирование диапазона
Реализуйте метод retrieve, который будет формировать диапазон временных меток на основе заданного start, end и granularity.
3⃣ Фильтрация и возврат результатов
Используйте сформированный диапазон для фильтрации журналов и возврата идентификаторов тех журналов, чьи временные метки попадают в этот диапазон.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 635. Design Log Storage System
Вам дается несколько журналов, где каждый журнал содержит уникальный идентификатор и временную метку. Временная метка - это строка, имеющая следующий формат: Год:Месяц:День:Час:Минута:Секунда, например, 2017:01:01:23:59:59. Все домены - десятичные числа с нулевым добавлением. Реализация класса LogSystem: LogSystem() Инициализирует объект LogSystem. void put(int id, string timestamp) Сохраняет заданный журнал (id, timestamp) в вашей системе хранения.
int[] retrieve(string start, string end, string granularity) Возвращает идентификаторы журналов, временные метки которых находятся в диапазоне от start до end включительно. start и end имеют тот же формат, что и timestamp, а granularity означает, насколько точным должен быть диапазон (т. е. с точностью до дня, минуты и т. д.). Например, start = "2017:01:01:23:59:59", end = "2017:01:02:23:59:59", а granularity = "Day" означает, что нам нужно найти журналы в диапазоне от 1 января 2017 года до 2 января 2017 года включительно, а час, минуту и секунду для каждой записи журнала можно игнорировать.
Пример:
Input
["LogSystem", "put", "put", "put", "retrieve", "retrieve"]
[[], [1, "2017:01:01:23:59:59"], [2, "2017:01:01:22:59:59"], [3, "2016:01:01:00:00:00"], ["2016:01:01:01:01:01", "2017:01:01:23:00:00", "Year"], ["2016:01:01:01:01:01", "2017:01:01:23:00:00", "Hour"]]
Output
[null, null, null, null, [3, 2, 1], [2, 1]]
Реализуйте метод put, который будет сохранять журнал с заданным id и timestamp в системе хранения.
Реализуйте метод retrieve, который будет формировать диапазон временных меток на основе заданного start, end и granularity.
Используйте сформированный диапазон для фильтрации журналов и возврата идентификаторов тех журналов, чьи временные метки попадают в этот диапазон.
package main
import (
"strings"
)
type LogSystem struct {
logs []Log
granularity map[string]int
}
type Log struct {
id int
timestamp string
}
func Constructor() LogSystem {
return LogSystem{
logs: []Log{},
granularity: map[string]int{
"Year": 4,
"Month": 7,
"Day": 10,
"Hour": 13,
"Minute": 16,
"Second": 19,
},
}
}
func (this *LogSystem) Put(id int, timestamp string) {
this.logs = append(this.logs, Log{id, timestamp})
}
func (this *LogSystem) Retrieve(start string, end string, granularity string) []int {
length := this.granularity[granularity]
start = start[:length]
end = end[:length]
var result []int
for _, log := range this.logs {
ts := log.timestamp[:length]
if start <= ts && ts <= end {
result = append(result, log.id)
}
}
return result
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 636. Exclusive Time of Functions
На однопоточном процессоре выполняется программа, содержащая n функций. Каждая функция имеет уникальный ID от 0 до n-1. Вызовы функций хранятся в стеке вызовов: когда начинается вызов функции, ее ID заталкивается в стек, а когда вызов функции заканчивается, ее ID выгружается из стека. Функция, чей идентификатор находится в верхней части стека, является текущей выполняемой функцией. Каждый раз, когда функция запускается или завершается, мы пишем лог с идентификатором, началом или завершением и меткой времени. Вам предоставляется список logs, где logs[i] представляет собой i-е сообщение лога, отформатированное как строка "{function_id}:{"start" | "end"}:{timestamp}". Например, "0:start:3" означает, что вызов функции с идентификатором 0 начался в начале временной метки 3, а "1:end:2" означает, что вызов функции с идентификатором 1 завершился в конце временной метки 2. Обратите внимание, что функция может быть вызвана несколько раз, возможно, рекурсивно. Исключительное время функции - это сумма времен выполнения всех вызовов функции в программе. Например, если функция вызывается дважды, причем один вызов выполняется за 2 единицы времени, а другой - за 1 единицу, то эксклюзивное время равно 2 + 1 = 3. Верните эксклюзивное время каждой функции в массив, где значение по i-му индексу представляет собой эксклюзивное время для функции с идентификатором i.
Пример:
👨💻 Алгоритм:
1⃣ Парсинг логов
Пройдитесь по каждому логу, чтобы распознать действие (start или end) и идентификатор функции вместе с временной меткой.
2⃣ Использование стека
Используйте стек для отслеживания текущих вызовов функций. Если лог содержит start, добавьте функцию в стек и начните отсчет времени. Если лог содержит end, снимите функцию со стека и обновите эксклюзивное время.
3⃣ Обновление времени выполнения
Когда функция завершает выполнение, обновите ее эксклюзивное время и также учитывайте время выполнения вложенных функций.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 636. Exclusive Time of Functions
На однопоточном процессоре выполняется программа, содержащая n функций. Каждая функция имеет уникальный ID от 0 до n-1. Вызовы функций хранятся в стеке вызовов: когда начинается вызов функции, ее ID заталкивается в стек, а когда вызов функции заканчивается, ее ID выгружается из стека. Функция, чей идентификатор находится в верхней части стека, является текущей выполняемой функцией. Каждый раз, когда функция запускается или завершается, мы пишем лог с идентификатором, началом или завершением и меткой времени. Вам предоставляется список logs, где logs[i] представляет собой i-е сообщение лога, отформатированное как строка "{function_id}:{"start" | "end"}:{timestamp}". Например, "0:start:3" означает, что вызов функции с идентификатором 0 начался в начале временной метки 3, а "1:end:2" означает, что вызов функции с идентификатором 1 завершился в конце временной метки 2. Обратите внимание, что функция может быть вызвана несколько раз, возможно, рекурсивно. Исключительное время функции - это сумма времен выполнения всех вызовов функции в программе. Например, если функция вызывается дважды, причем один вызов выполняется за 2 единицы времени, а другой - за 1 единицу, то эксклюзивное время равно 2 + 1 = 3. Верните эксклюзивное время каждой функции в массив, где значение по i-му индексу представляет собой эксклюзивное время для функции с идентификатором i.
Пример:
Input: n = 2, logs = ["0:start:0","1:start:2","1:end:5","0:end:6"]
Output: [3,4]
Пройдитесь по каждому логу, чтобы распознать действие (start или end) и идентификатор функции вместе с временной меткой.
Используйте стек для отслеживания текущих вызовов функций. Если лог содержит start, добавьте функцию в стек и начните отсчет времени. Если лог содержит end, снимите функцию со стека и обновите эксклюзивное время.
Когда функция завершает выполнение, обновите ее эксклюзивное время и также учитывайте время выполнения вложенных функций.
package main
import (
"fmt"
"strconv"
"strings"
)
func exclusiveTime(n int, logs []string) []int {
stack := []int{}
times := make([]int, n)
prevTime := 0
for _, log := range logs {
parts := strings.Split(log, ":")
fid, _ := strconv.Atoi(parts[0])
typ := parts[1]
time, _ := strconv.Atoi(parts[2])
if typ == "start" {
if len(stack) > 0 {
times[stack[len(stack)-1]] += time - prevTime
}
stack = append(stack, fid)
prevTime = time
} else {
times[stack[len(stack)-1]] += time - prevTime + 1
stack = stack[:len(stack)-1]
prevTime = time + 1
}
}
return times
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#easy
Задача: 637. Average of Levels in Binary Tree
Учитывая корень бинарного дерева, верните среднее значение узлов на каждом уровне в виде массива. Принимаются ответы в пределах 10-5 от фактического ответа.
Пример:
👨💻 Алгоритм:
1⃣ Обход дерева
Используйте обход в ширину (BFS) для обхода каждого уровня дерева.
2⃣ Подсчет среднего значения
Для каждого уровня дерева подсчитайте сумму значений узлов и количество узлов, чтобы вычислить среднее значение.
3⃣ Сохранение результата
Сохраните среднее значение каждого уровня в массив и верните его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 637. Average of Levels in Binary Tree
Учитывая корень бинарного дерева, верните среднее значение узлов на каждом уровне в виде массива. Принимаются ответы в пределах 10-5 от фактического ответа.
Пример:
Input: root = [3,9,20,null,null,15,7]
Output: [3.00000,14.50000,11.00000]
Используйте обход в ширину (BFS) для обхода каждого уровня дерева.
Для каждого уровня дерева подсчитайте сумму значений узлов и количество узлов, чтобы вычислить среднее значение.
Сохраните среднее значение каждого уровня в массив и верните его.
package main
import (
"container/list"
)
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func averageOfLevels(root *TreeNode) []float64 {
var result []float64
queue := list.New()
queue.PushBack(root)
for queue.Len() > 0 {
levelSum := 0
levelCount := queue.Len()
for i := 0; i < levelCount; i++ {
node := queue.Remove(queue.Front()).(*TreeNode)
levelSum += node.Val
if node.Left != nil {
queue.PushBack(node.Left)
}
if node.Right != nil {
queue.PushBack(node.Right)
}
}
result = append(result, float64(levelSum)/float64(levelCount))
}
return result
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 638. Shopping Offers
В магазине LeetCode Store есть n предметов для продажи. Каждый товар имеет свою цену. Однако существуют специальные предложения, и специальное предложение состоит из одного или нескольких различных видов товаров с распродажной ценой. Вам дан целочисленный массив price, где price[i] - цена i-го товара, и целочисленный массив needs, где needs[i] - количество штук i-го товара, который вы хотите купить. Вам также дан массив special, где special[i] имеет размер n + 1, где special[i][j] - количество штук j-го товара в i-м предложении, а special[i][n] (т.е., Возвращает наименьшую цену, которую вы можете заплатить за определенный товар из заданных, где вы могли бы оптимально использовать специальные предложения. Вам не разрешается покупать больше товаров, чем вы хотите, даже если это снизит общую цену. Вы можете использовать любое из специальных предложений столько раз, сколько захотите.
Пример:
👨💻 Алгоритм:
1⃣ Рекурсивное вычисление стоимости
Определите функцию, которая рекурсивно вычисляет минимальную стоимость для оставшихся нужд, используя динамическое программирование для запоминания уже вычисленных значений.
2⃣ Использование специальных предложений
Для каждой комбинации товаров в специальных предложениях, определите, можно ли использовать это предложение без превышения нужд. Если можно, вычислите новую стоимость, учитывая это предложение.
3⃣ Выбор минимальной стоимости
Сравните стоимость при использовании специальных предложений и стоимость при покупке товаров по индивидуальным ценам, выбирая минимальную стоимость.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 638. Shopping Offers
В магазине LeetCode Store есть n предметов для продажи. Каждый товар имеет свою цену. Однако существуют специальные предложения, и специальное предложение состоит из одного или нескольких различных видов товаров с распродажной ценой. Вам дан целочисленный массив price, где price[i] - цена i-го товара, и целочисленный массив needs, где needs[i] - количество штук i-го товара, который вы хотите купить. Вам также дан массив special, где special[i] имеет размер n + 1, где special[i][j] - количество штук j-го товара в i-м предложении, а special[i][n] (т.е., Возвращает наименьшую цену, которую вы можете заплатить за определенный товар из заданных, где вы могли бы оптимально использовать специальные предложения. Вам не разрешается покупать больше товаров, чем вы хотите, даже если это снизит общую цену. Вы можете использовать любое из специальных предложений столько раз, сколько захотите.
Пример:
Input: price = [2,5], special = [[3,0,5],[1,2,10]], needs = [3,2]
Output: 14
Определите функцию, которая рекурсивно вычисляет минимальную стоимость для оставшихся нужд, используя динамическое программирование для запоминания уже вычисленных значений.
Для каждой комбинации товаров в специальных предложениях, определите, можно ли использовать это предложение без превышения нужд. Если можно, вычислите новую стоимость, учитывая это предложение.
Сравните стоимость при использовании специальных предложений и стоимость при покупке товаров по индивидуальным ценам, выбирая минимальную стоимость.
package main
import (
"fmt"
"strconv"
"strings"
)
func shoppingOffers(price []int, special [][]int, needs []int) int {
memo := make(map[string]int)
return dfs(price, special, needs, memo)
}
func dfs(price []int, special [][]int, needs []int, memo map[string]int) int {
key := serialize(needs)
if val, exists := memo[key]; exists {
return val
}
minPrice := 0
for i := 0; i < len(needs); i++ {
minPrice += needs[i] * price[i]
}
for _, offer := range special {
newNeeds := make([]int, len(needs))
valid := true
for i := 0; i < len(needs); i++ {
if needs[i] < offer[i] {
valid = false
break
}
newNeeds[i] = needs[i] - offer[i]
}
if valid {
minPrice = min(minPrice, offer[len(needs)]+dfs(price, special, newNeeds, memo))
}
}
memo[key] = minPrice
return minPrice
}
func serialize(needs []int) string {
var sb strings.Builder
for _, need := range needs {
sb.WriteString(strconv.Itoa(need))
sb.WriteString(",")
}
return sb.String()
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 639. Decode Ways II
Сообщение, содержащее буквы от A-Z, может быть закодировано в цифры с помощью следующего отображения: 'A' -> "1" 'B' -> "2" ... 'Z' -> "26" Чтобы декодировать закодированное сообщение, все цифры должны быть сгруппированы, а затем снова преобразованы в буквы с помощью обратного отображения (может быть несколько способов). Например, "11106" может быть преобразовано в: "AAJF" с группировкой (1 1 10 6) "KJF" с группировкой (11 10 6) Обратите внимание, что группировка (1 11 06) недействительна, поскольку "06" не может быть преобразовано в "F", так как "6" отличается от "06". В дополнение к вышеуказанным преобразованиям кодированное сообщение может содержать символ "*", который может представлять любую цифру от "1" до "9" ("0" исключается). Например, кодированное сообщение "1*" может представлять любое из кодированных сообщений "11", "12", "13", "14", "15", "16", "17", "18" или "19". Декодирование "1*" эквивалентно декодированию любого из кодированных сообщений, которые оно может представлять. Если задана строка s, состоящая из цифр и символов '*', верните количество способов ее декодирования. Поскольку ответ может быть очень большим, верните его по модулю 109 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Создайте массив dp, где dp[i] представляет количество способов декодирования подстроки s[0:i]. Установите начальные значения dp[0] = 1 (пустая строка имеет один способ декодирования).
2⃣ Обход строки
Используйте цикл для обхода строки и вычисления количества способов декодирования для каждого символа, включая обработку символа '*'.
3⃣ Модульное вычисление
Поскольку количество способов декодирования может быть большим, вычисляйте результаты по модулю 10^9 + 7.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 639. Decode Ways II
Сообщение, содержащее буквы от A-Z, может быть закодировано в цифры с помощью следующего отображения: 'A' -> "1" 'B' -> "2" ... 'Z' -> "26" Чтобы декодировать закодированное сообщение, все цифры должны быть сгруппированы, а затем снова преобразованы в буквы с помощью обратного отображения (может быть несколько способов). Например, "11106" может быть преобразовано в: "AAJF" с группировкой (1 1 10 6) "KJF" с группировкой (11 10 6) Обратите внимание, что группировка (1 11 06) недействительна, поскольку "06" не может быть преобразовано в "F", так как "6" отличается от "06". В дополнение к вышеуказанным преобразованиям кодированное сообщение может содержать символ "*", который может представлять любую цифру от "1" до "9" ("0" исключается). Например, кодированное сообщение "1*" может представлять любое из кодированных сообщений "11", "12", "13", "14", "15", "16", "17", "18" или "19". Декодирование "1*" эквивалентно декодированию любого из кодированных сообщений, которые оно может представлять. Если задана строка s, состоящая из цифр и символов '*', верните количество способов ее декодирования. Поскольку ответ может быть очень большим, верните его по модулю 109 + 7.
Пример:
Input: s = "*"
Output: 9
Создайте массив dp, где dp[i] представляет количество способов декодирования подстроки s[0:i]. Установите начальные значения dp[0] = 1 (пустая строка имеет один способ декодирования).
Используйте цикл для обхода строки и вычисления количества способов декодирования для каждого символа, включая обработку символа '*'.
Поскольку количество способов декодирования может быть большим, вычисляйте результаты по модулю 10^9 + 7.
package main
import (
"fmt"
)
func numDecodings(s string) int {
const MOD = 1000000007
n := len(s)
dp := make([]int, n+1)
dp[0] = 1
for i := 1; i <= n; i++ {
if s[i-1] == '*' {
dp[i] = 9 * dp[i-1]
} else if s[i-1] != '0' {
dp[i] = dp[i-1]
}
if i > 1 {
if s[i-2] == '*' {
if s[i-1] == '*' {
dp[i] += 15 * dp[i-2]
} else if s[i-1] >= '0' && s[i-1] <= '6' {
dp[i] += 2 * dp[i-2]
} else {
dp[i] += dp[i-2]
}
} else if s[i-2] == '1' {
if s[i-1] == '*' {
dp[i] += 9 * dp[i-2]
} else {
dp[i] += dp[i-2]
}
} else if s[i-2] == '2' {
if s[i-1] == '*' {
dp[i] += 6 * dp[i-2]
} else if s[i-1] >= '0' && s[i-1] <= '6' {
dp[i] += dp[i-2]
}
}
}
dp[i] %= MOD
}
return dp[n]
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#medium
Задача: 640. Solve the Equation
Решите заданное уравнение и верните значение 'x' в виде строки "x=#value". Уравнение содержит только операции '+', '-', переменную 'x' и ее коэффициент. Вы должны вернуть "No solution", если для уравнения нет решения, или "Infinite solutions", если для уравнения существует бесконечное количество решений. Если для уравнения существует ровно одно решение, мы убеждаемся, что значение 'x' является целым числом.
Пример:
👨💻 Алгоритм:
1⃣ Разделение уравнения
Разделите уравнение на левую и правую части относительно знака равенства '='.
2⃣ Парсинг и упрощение
Пройдитесь по каждой части уравнения, упрощая ее до суммы коэффициентов 'x' и числовых значений.
3⃣ Решение уравнения
Используйте уравнение вида ax + b = cx + d, чтобы решить для 'x'. Если коэффициенты 'x' равны и числовые значения равны, уравнение имеет бесконечное количество решений. Если коэффициенты 'x' равны, но числовые значения различны, решения нет. В противном случае вычислите значение 'x'.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 640. Solve the Equation
Решите заданное уравнение и верните значение 'x' в виде строки "x=#value". Уравнение содержит только операции '+', '-', переменную 'x' и ее коэффициент. Вы должны вернуть "No solution", если для уравнения нет решения, или "Infinite solutions", если для уравнения существует бесконечное количество решений. Если для уравнения существует ровно одно решение, мы убеждаемся, что значение 'x' является целым числом.
Пример:
Input: s = "*"
Output: 9
Разделите уравнение на левую и правую части относительно знака равенства '='.
Пройдитесь по каждой части уравнения, упрощая ее до суммы коэффициентов 'x' и числовых значений.
Используйте уравнение вида ax + b = cx + d, чтобы решить для 'x'. Если коэффициенты 'x' равны и числовые значения равны, уравнение имеет бесконечное количество решений. Если коэффициенты 'x' равны, но числовые значения различны, решения нет. В противном случае вычислите значение 'x'.
package main
import (
"fmt"
"strconv"
"strings"
)
func solveEquation(equation string) string {
parse := func(s string) (int, int) {
coeff, constPart, sign, num := 0, 0, 1, 0
i := 0
for i < len(s) {
if s[i] == '+' {
sign = 1
i++
} else if s[i] == '-' {
sign = -1
i++
} else if s[i] >= '0' && s[i] <= '9' {
num = 0
for i < len(s) && s[i] >= '0' && s[i] <= '9' {
num = num*10 + int(s[i]-'0')
i++
}
if i < len(s) && s[i] == 'x' {
coeff += sign * num
i++
} else {
constPart += sign * num
}
} else if s[i] == 'x' {
coeff += sign
i++
}
}
return coeff, constPart
}
left, right := equation[:strings.Index(equation, "=")], equation[strings.Index(equation, "=")+1:]
leftCoeff, leftConst := parse(left)
rightCoeff, rightConst := parse(right)
coeff := leftCoeff - rightCoeff
constPart := rightConst - leftConst
if coeff == 0 {
if constPart == 0 {
return "Infinite solutions"
}
return "No solution"
}
return "x=" + strconv.Itoa(constPart/coeff)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
#easy
Задача: 566. Reshape the Matrix
В MATLAB есть удобная функция под названием reshape, которая может преобразовать матрицу размером m x n в новую матрицу с другим размером r x c, сохраняя исходные данные.
Вам дана матрица m x n mat и два целых числа r и c, представляющие количество строк и столбцов желаемой преобразованной матрицы.
Преобразованная матрица должна быть заполнена всеми элементами исходной матрицы в том же порядке обхода строк, в котором они были.
Если операция преобразования с заданными параметрами возможна и допустима, выведите новую преобразованную матрицу; в противном случае выведите исходную матрицу.
Пример:
👨💻 Алгоритм:
1⃣ Проверить, можно ли преобразовать матрицу с заданными параметрами r и c. Это возможно, если произведение m * n равно произведению r * c. Если преобразование невозможно, вернуть исходную матрицу.
2⃣ Создать новый массив для хранения преобразованной матрицы. Перебрать все элементы исходной матрицы и вставить их в новый массив в порядке обхода строк.
3⃣ Вернуть преобразованную матрицу, если преобразование возможно, иначе вернуть исходную матрицу.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 566. Reshape the Matrix
В MATLAB есть удобная функция под названием reshape, которая может преобразовать матрицу размером m x n в новую матрицу с другим размером r x c, сохраняя исходные данные.
Вам дана матрица m x n mat и два целых числа r и c, представляющие количество строк и столбцов желаемой преобразованной матрицы.
Преобразованная матрица должна быть заполнена всеми элементами исходной матрицы в том же порядке обхода строк, в котором они были.
Если операция преобразования с заданными параметрами возможна и допустима, выведите новую преобразованную матрицу; в противном случае выведите исходную матрицу.
Пример:
Input: mat = [[1,2],[3,4]], r = 1, c = 4
Output: [[1,2,3,4]]
func matrixReshape(mat [][]int, r int, c int) [][]int {
m, n := len(mat), len(mat[0])
if m*n != r*c {
return mat
}
reshapedMatrix := make([][]int, r)
for i := range reshapedMatrix {
reshapedMatrix[i] = make([]int, c)
}
row, col := 0, 0
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
reshapedMatrix[row][col] = mat[i][j]
col++
if col == c {
col = 0
row++
}
}
}
return reshapedMatrix
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 641. Design Circular Deque
Разработайте свою реализацию круговой двусторонней очереди (deque). Реализуйте класс MyCircularDeque: MyCircularDeque(int k) Инициализирует deque с максимальным размером k. boolean insertFront() Добавляет элемент в переднюю часть Deque. Возвращает true, если операция прошла успешно, или false в противном случае. boolean insertLast() Добавляет элемент в заднюю часть Deque. Возвращает true, если операция выполнена успешно, или false в противном случае. boolean deleteFront() Удаляет элемент из передней части Deque. Возвращает true, если операция прошла успешно, или false в противном случае. boolean deleteLast() Удаляет элемент из задней части Deque. Возвращает true, если операция прошла успешно, или false в противном случае. int getFront() Возвращает передний элемент из Deque. Возвращает -1, если Deque пуст. int getRear() Возвращает последний элемент из Deque. Возвращает -1, если Deque пуст. boolean isEmpty() Возвращает true, если Deque пуст, или false в противном случае. boolean isFull() Возвращает true, если Deque полон, или false в противном случае.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и проверка состояний
Реализуйте конструктор для инициализации кольцевой двусторонней очереди заданного размера и методы для проверки пустоты и полноты очереди.
2⃣ Операции вставки
Реализуйте методы вставки элементов в переднюю и заднюю части очереди с учетом кольцевой структуры.
3⃣ Операции удаления
Реализуйте методы удаления элементов из передней и задней частей очереди с учетом кольцевой структуры и методы для получения переднего и заднего элементов очереди.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 641. Design Circular Deque
Разработайте свою реализацию круговой двусторонней очереди (deque). Реализуйте класс MyCircularDeque: MyCircularDeque(int k) Инициализирует deque с максимальным размером k. boolean insertFront() Добавляет элемент в переднюю часть Deque. Возвращает true, если операция прошла успешно, или false в противном случае. boolean insertLast() Добавляет элемент в заднюю часть Deque. Возвращает true, если операция выполнена успешно, или false в противном случае. boolean deleteFront() Удаляет элемент из передней части Deque. Возвращает true, если операция прошла успешно, или false в противном случае. boolean deleteLast() Удаляет элемент из задней части Deque. Возвращает true, если операция прошла успешно, или false в противном случае. int getFront() Возвращает передний элемент из Deque. Возвращает -1, если Deque пуст. int getRear() Возвращает последний элемент из Deque. Возвращает -1, если Deque пуст. boolean isEmpty() Возвращает true, если Deque пуст, или false в противном случае. boolean isFull() Возвращает true, если Deque полон, или false в противном случае.
Пример:
Input
["MyCircularDeque", "insertLast", "insertLast", "insertFront", "insertFront", "getRear", "isFull", "deleteLast", "insertFront", "getFront"]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
Output
[null, true, true, true, false, 2, true, true, true, 4]
Реализуйте конструктор для инициализации кольцевой двусторонней очереди заданного размера и методы для проверки пустоты и полноты очереди.
Реализуйте методы вставки элементов в переднюю и заднюю части очереди с учетом кольцевой структуры.
Реализуйте методы удаления элементов из передней и задней частей очереди с учетом кольцевой структуры и методы для получения переднего и заднего элементов очереди.
package main
type MyCircularDeque struct {
deque []int
front int
rear int
size int
capacity int
}
func Constructor(k int) MyCircularDeque {
return MyCircularDeque{
deque: make([]int, k),
front: 0,
rear: 0,
size: 0,
capacity: k,
}
}
func (this *MyCircularDeque) InsertFront(value int) bool {
if this.IsFull() {
return false
}
this.front = (this.front - 1 + this.capacity) % this.capacity
this.deque[this.front] = value
this.size++
return true
}
func (this *MyCircularDeque) InsertLast(value int) bool {
if this.IsFull() {
return false
}
this.deque[this.rear] = value
this.rear = (this.rear + 1) % this.capacity
this.size++
return true
}
func (this *MyCircularDeque) DeleteFront() bool {
if this.IsEmpty() {
return false
}
this.front = (this.front + 1) % this.capacity
this.size--
return true
}
func (this *MyCircularDeque) DeleteLast() bool {
if this.IsEmpty() {
return false
}
this.rear = (this.rear - 1 + this.capacity) % this.capacity
this.size--
return true
}
func (this *MyCircularDeque) GetFront() int {
if this.IsEmpty() {
return -1
}
return this.deque[this.front]
}
func (this *MyCircularDeque) GetRear() int {
if this.IsEmpty() {
return -1
}
return this.deque[(this.rear-1+this.capacity)%this.capacity]
}
func (this *MyCircularDeque) IsEmpty() bool {
return this.size == 0
}
func (this *MyCircularDeque) IsFull() bool {
return this.size == this.capacity
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 567. Permutation in String
Даны две строки s1 и s2. Верните true, если s2 содержит перестановку s1, или false в противном случае.
Другими словами, верните true, если одна из перестановок s1 является подстрокой s2.
Пример:
👨💻 Алгоритм:
1⃣ Создать массив для подсчета символов в строке s1. Затем создать аналогичный массив для первых len(s1) символов строки s2.
2⃣ Использовать скользящее окно для перемещения по строке s2. Для каждой позиции окна обновлять массив подсчета символов и сравнивать его с массивом для строки s1.
3⃣ Если массивы совпадают на любом этапе, вернуть true. Если окно достигает конца строки s2 и совпадений не найдено, вернуть false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 567. Permutation in String
Даны две строки s1 и s2. Верните true, если s2 содержит перестановку s1, или false в противном случае.
Другими словами, верните true, если одна из перестановок s1 является подстрокой s2.
Пример:
Input: s1 = "ab", s2 = "eidbaooo"
Output: true
Explanation: s2 contains one permutation of s1 ("ba").
func checkInclusion(s1 string, s2 string) bool {
s1Len, s2Len := len(s1), len(s2)
if s1Len > s2Len {
return false
}
s1Count, s2Count := make([]int, 26), make([]int, 26)
for i := 0; i < s1Len; i++ {
s1Count[s1[i]-'a']++
s2Count[s2[i]-'a']++
}
for i := 0; i < s2Len-s1Len; i++ {
if equal(s1Count, s2Count) {
return true
}
s2Count[s2[i]-'a']--
s2Count[s2[i+s1Len]-'a']++
}
return equal(s1Count, s2Count)
}
func equal(a, b []int) bool {
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#hard
Задача: 568. Maximum Vacation Days
LeetCode хочет предоставить одному из своих лучших сотрудников возможность путешествовать по n городам для сбора задач по алгоритмам. Однако, как говорится, "делу время, потехе час". Вы можете брать отпуска в некоторых конкретных городах и неделях. Ваша задача — спланировать поездку, чтобы максимально увеличить количество дней отпуска, которые вы сможете взять, соблюдая при этом определенные правила и ограничения.
Правила и ограничения:
Вы можете путешествовать только между n городами, обозначенными индексами от 0 до n-1. Изначально вы находитесь в городе с индексом 0 в понедельник.
Города связаны рейсами. Рейсы представлены матрицей n x n, называемой flights, представляющей статус авиалинии от города i до города j. Если рейса из города i в город j нет, flights[i][j] == 0; иначе flights[i][j] == 1. Также для всех i выполняется flights[i][i] == 0.
У вас есть k недель (каждая неделя состоит из семи дней) для путешествий. Вы можете летать не более одного раза в день и можете летать только утром каждого понедельника. Время полета настолько короткое, что его влияние не учитывается.
Для каждого города у вас есть ограниченные дни отпуска в разные недели, заданные матрицей n x k, называемой days. Значение days[i][j] представляет максимальное количество дней отпуска, которые вы можете взять в городе i на неделе j.
Даны две матрицы flights и days, верните максимальное количество дней отпуска, которые вы можете взять в течение k недель.
Пример:
👨💻 Алгоритм:
1⃣ Использовать функцию dfs (поиск в глубину), которая возвращает количество отпускных дней, которые можно взять, начиная с текущего города cur_city и текущей недели weekno. В каждом вызове функции проходить по всем городам и находить все города, которые связаны с текущим городом. Такой город обозначен 1 в соответствующей позиции flights[cur_city][i].
2⃣ Для текущего города можно либо остаться в нем, либо поехать в связанный город. Обозначим город, в который меняется расположение, как j. После смены города нужно найти количество отпускных дней, которые можно взять, начиная с нового города и с новой недели. Это количество отпускных дней можно представить как: days[j][weekno] + dfs(flights, days, j, weekno + 1).
3⃣ Для текущего города необходимо найти максимальное количество отпускных дней, выбирая различные города в качестве следующего местоположения. Из всех вариантов отпускных дней выбираем максимальное значение, которое и будет возвращено для каждого вызова функции dfs.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Задача: 568. Maximum Vacation Days
LeetCode хочет предоставить одному из своих лучших сотрудников возможность путешествовать по n городам для сбора задач по алгоритмам. Однако, как говорится, "делу время, потехе час". Вы можете брать отпуска в некоторых конкретных городах и неделях. Ваша задача — спланировать поездку, чтобы максимально увеличить количество дней отпуска, которые вы сможете взять, соблюдая при этом определенные правила и ограничения.
Правила и ограничения:
Вы можете путешествовать только между n городами, обозначенными индексами от 0 до n-1. Изначально вы находитесь в городе с индексом 0 в понедельник.
Города связаны рейсами. Рейсы представлены матрицей n x n, называемой flights, представляющей статус авиалинии от города i до города j. Если рейса из города i в город j нет, flights[i][j] == 0; иначе flights[i][j] == 1. Также для всех i выполняется flights[i][i] == 0.
У вас есть k недель (каждая неделя состоит из семи дней) для путешествий. Вы можете летать не более одного раза в день и можете летать только утром каждого понедельника. Время полета настолько короткое, что его влияние не учитывается.
Для каждого города у вас есть ограниченные дни отпуска в разные недели, заданные матрицей n x k, называемой days. Значение days[i][j] представляет максимальное количество дней отпуска, которые вы можете взять в городе i на неделе j.
Даны две матрицы flights и days, верните максимальное количество дней отпуска, которые вы можете взять в течение k недель.
Пример:
Input: flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[1,3,1],[6,0,3],[3,3,3]]
Output: 12
Explanation:
One of the best strategies is:
1st week : fly from city 0 to city 1 on Monday, and play 6 days and work 1 day.
(Although you start at city 0, we could also fly to and start at other cities since it is Monday.)
2nd week : fly from city 1 to city 2 on Monday, and play 3 days and work 4 days.
3rd week : stay at city 2, and play 3 days and work 4 days.
Ans = 6 + 3 + 3 = 12.
func maxVacationDays(flights [][]int, days [][]int) int {
n, k := len(flights), len(days[0])
memo := make([][]int, n)
for i := range memo {
memo[i] = make([]int, k)
for j := range memo[i] {
memo[i][j] = -1
}
}
return dfs(flights, days, memo, 0, 0)
}
func dfs(flights [][]int, days [][]int, memo [][]int, curCity, weekNo int) int {
n, k := len(flights), len(days[0])
if weekNo == k {
return 0
}
if memo[curCity][weekNo] != -1 {
return memo[curCity][weekNo]
}
maxVac := 0
for nextCity := 0; nextCity < n; nextCity++ {
if curCity == nextCity || flights[curCity][nextCity] == 1 {
maxVac = max(maxVac, days[nextCity][weekNo]+dfs(flights, days, memo, nextCity, weekNo+1))
}
}
memo[curCity][weekNo] = maxVac
return maxVac
}
func max(a, b int) int {
if a > b {
return a
}
return b
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
#easy
Задача: CodeTestcaseTest ResultTest Result1523. Count Odd Numbers in an Interval Range
### Условие задачи
Даны два неотрицательных целых числа low и high. Верните количество нечётных чисел между low и high (включительно).
Пример:
👨💻 Алгоритм:
1️⃣ Проверьте, является ли число low нечётным. Это можно легко сделать с помощью оператора %, но мы используем побитовый оператор &, так как он более эффективен.
2️⃣ Если low нечётное, увеличьте его на 1.
3️⃣ Верните (high - low) / 2 + 1. Важный момент здесь - проверить, не стало ли low больше, чем high после увеличения. Это произойдёт, если low = high, и в этом случае следует вернуть 0.
😎 Решение🐍
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых
Задача: CodeTestcaseTest ResultTest Result1523. Count Odd Numbers in an Interval Range
### Условие задачи
Даны два неотрицательных целых числа low и high. Верните количество нечётных чисел между low и high (включительно).
Пример:
Input: low = 3, high = 7
Output: 3
Explanation: The odd numbers between 3 and 7 are [3,5,7].
func countOdds(low int, high int) int {
if (low & 1 == 0 {
low++
}
if low > high {
return 0
}
return (high - low) / 2 + 1
}Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
#medium
Задача: 1522. Diameter of N-Ary Tree
Дано корневое дерево N-арности, нужно вычислить длину диаметра дерева.
Диаметр N-арного дерева - это длина самого длинного пути между любыми двумя узлами в дереве. Этот путь может проходить или не проходить через корень.
(Входная сериализация N-арного дерева представлена их обходом в порядке уровней, каждая группа дочерних узлов разделена значением null.)
Пример:
👨💻 Алгоритм:
1️⃣ Определите функцию height(node), которая возвращает высоту узла. Функция может быть реализована рекурсивно, основываясь на вычислении максимальной высоты среди всех дочерних узлов плюс один.
2️⃣ Внутри функции height(node) выберите две наибольшие высоты среди дочерних узлов. Эти два значения помогут вычислить длину пути, которая будет кандидатом на диаметр всего дерева.
3️⃣ Существует два подхода для выбора двух наибольших высот:
— Первый способ заключается в хранении высот всех дочерних узлов в массиве, последующей сортировке массива и выборе двух наибольших элементов.
— Второй способ использует две переменные, которые отслеживают текущие два наибольших значения. Во время итерации по всем высотам эти переменные обновляются соответствующим образом.
😎 Решение🐍
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых
Задача: 1522. Diameter of N-Ary Tree
Дано корневое дерево N-арности, нужно вычислить длину диаметра дерева.
Диаметр N-арного дерева - это длина самого длинного пути между любыми двумя узлами в дереве. Этот путь может проходить или не проходить через корень.
(Входная сериализация N-арного дерева представлена их обходом в порядке уровней, каждая группа дочерних узлов разделена значением null.)
Пример:
Input: root = [1,null,3,2,4,null,5,6]
Output: 3
Explanation: Diameter is shown in red color.
— Первый способ заключается в хранении высот всех дочерних узлов в массиве, последующей сортировке массива и выборе двух наибольших элементов.
— Второй способ использует две переменные, которые отслеживают текущие два наибольших значения. Во время итерации по всем высотам эти переменные обновляются соответствующим образом.
type Node struct {
Val int
Children []*Node
}
type Solution struct {
diameter int
}
func (s *Solution) height(node *Node) int {
if len(node.Children) == 0 {
return 0
}
maxHeight1, maxHeight2 := 0, 0
for _, child := range node.Children {
parentHeight := s.height(child) + 1
if parentHeight > maxHeight1 {
maxHeight2 = maxHeight1
maxHeight1 = parentHeight
} else if parentHeight > maxHeight2 {
maxHeight2 = parentHeight
}
distance := maxHeight1 + maxHeight2
if distance > s.diameter {
s.diameter = distance
}
}
return maxHeight1
}
func (s *Solution) Diameter(root *Node) int {
s.diameter = 0
s.height(root)
return s.diameter
}Please open Telegram to view this post
VIEW IN TELEGRAM
#medium
Задача: 1519. Number of Nodes in the Sub-Tree With the Same Label
Вам дано дерево (т.е. связный неориентированный граф без циклов), состоящее из n узлов, пронумерованных от 0 до n - 1, и ровно n - 1 ребра. Корнем дерева является узел 0, и каждый узел дерева имеет метку, которая является строчной буквой, указанной в строке labels (т.е. узел с номером i имеет метку labels[i]).
Массив edges дан в форме edges[i] = [ai, bi], что означает, что существует ребро между узлами ai и bi в дереве.
Верните массив размера n, где ans[i] — это количество узлов в поддереве узла i, которые имеют ту же метку, что и узел i.
Поддерево дерева T — это дерево, состоящее из узла в T и всех его дочерних узлов.
Пример:
👨💻 Алгоритм:
1️⃣ Создайте список смежности, где adj[X] содержит всех соседей узла X.
2️⃣ Инициализируйте массив ans, хранящий ответ для каждого узла, и заполните его нулями.
3️⃣ Начните обход в глубину (DFS).
😎 Решение🐍
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых
Задача: 1519. Number of Nodes in the Sub-Tree With the Same Label
Вам дано дерево (т.е. связный неориентированный граф без циклов), состоящее из n узлов, пронумерованных от 0 до n - 1, и ровно n - 1 ребра. Корнем дерева является узел 0, и каждый узел дерева имеет метку, которая является строчной буквой, указанной в строке labels (т.е. узел с номером i имеет метку labels[i]).
Массив edges дан в форме edges[i] = [ai, bi], что означает, что существует ребро между узлами ai и bi в дереве.
Верните массив размера n, где ans[i] — это количество узлов в поддереве узла i, которые имеют ту же метку, что и узел i.
Поддерево дерева T — это дерево, состоящее из узла в T и всех его дочерних узлов.
Пример:
Input: n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], labels = "abaedcd"
Output: [2,1,1,1,1,1,1]
Explanation: Node 0 has label 'a' and its sub-tree has node 2 with label 'a' as well, thus the answer is 2. Notice that any node is part of its sub-tree.
Node 1 has a label 'b'. The sub-tree of node 1 contains nodes 1,4 and 5, as nodes 4 and 5 have different labels than node 1, the answer is just 1 (the node itself).
func dfs(node, parent int, adj map[int][]int, labels string, ans []int) []int {
nodeCounts := make([]int, 26)
nodeCounts[labels[node]-'a'] = 1
for _, child := range adj[node] {
if child == parent {
continue
}
childCounts := dfs(child, node, adj, labels, ans)
for i := 0; i < 26; i++ {
nodeCounts[i] += childCounts[i]
}
}
ans[node] = nodeCounts[labels[node]-'a']
return nodeCounts
}
func countSubTrees(n int, edges [][]int, labels string) []int {
adj := make(map[int][]int)
for _, edge := range edges {
adj[edge[0]] = append(adj[edge[0]], edge[1])
adj[edge[1]] = append(adj[edge[1]], edge[0])
}
ans := make([]int, n)
dfs(0, -1, adj, labels, ans)
return ans
}Please open Telegram to view this post
VIEW IN TELEGRAM
#easy
Задача: 1518. Water Bottles
Есть numBottles бутылок с водой, которые изначально наполнены водой. Вы можете обменять numExchange пустых бутылок на одну полную бутылку воды на рынке.
Операция питья полной бутылки воды превращает её в пустую бутылку.
Даны два целых числа numBottles и numExchange. Верните максимальное количество бутылок с водой, которые вы можете выпить.
Пример:
👨💻 Алгоритм:
1️⃣ Инициализируйте переменную ответа consumedBottles значением 0.
2️⃣ Продолжайте выполнять следующие действия, пока количество numBottles больше или равно numExchange:
— Выпейте numExchange количество полных бутылок, т.е. добавьте numExchange к consumedBottles.
— Уменьшите numExchange от доступных полных бутылок numBottles.
— Обменяйте пустые бутылки на одну полную бутылку, т.е. увеличьте numBottles на одну.
3️⃣ Верните consumedBottles + numBottles.
😎 Решение🐍
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовых
Задача: 1518. Water Bottles
Есть numBottles бутылок с водой, которые изначально наполнены водой. Вы можете обменять numExchange пустых бутылок на одну полную бутылку воды на рынке.
Операция питья полной бутылки воды превращает её в пустую бутылку.
Даны два целых числа numBottles и numExchange. Верните максимальное количество бутылок с водой, которые вы можете выпить.
Пример:
Input: numBottles = 9, numExchange = 3
Output: 13
Explanation: You can exchange 3 empty bottles to get 1 full water bottle.
Number of water bottles you can drink: 9 + 3 + 1 = 13.
— Выпейте numExchange количество полных бутылок, т.е. добавьте numExchange к consumedBottles.
— Уменьшите numExchange от доступных полных бутылок numBottles.
— Обменяйте пустые бутылки на одну полную бутылку, т.е. увеличьте numBottles на одну.
func numWaterBottles(numBottles int, numExchange int) int {
consumedBottles := 0
for numBottles >= numExchange {
consumedBottles += numExchange
numBottles -= numExchange
numBottles++
}
return consumedBottles + numBottles
}Please open Telegram to view this post
VIEW IN TELEGRAM
👍1