Задача: 906. Super Palindromes
Сложность: hard
Если задан целочисленный массив nums, переместите все четные числа в начало массива, а затем все нечетные. Верните любой массив, удовлетворяющий этому условию.
Пример:
👨💻 Алгоритм:
1⃣ Найти все палиндромы до корня из right.
2⃣ Проверить, являются ли квадраты этих палиндромов палиндромами и лежат ли в диапазоне [left, right].
3⃣ Подсчитать количество таких суперпалиндромов.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Если задан целочисленный массив nums, переместите все четные числа в начало массива, а затем все нечетные. Верните любой массив, удовлетворяющий этому условию.
Пример:
Input: left = "4", right = "1000"
Output: 4
class Solution {
func isPalindrome(_ x: Int) -> Bool {
let s = String(x)
return s == String(s.reversed())
}
func superpalindromesInRange(_ left: String, _ right: String) -> Int {
let left = Int(left)!
let right = Int(right)!
var count = 0
for i in 1...100000 {
let s = String(i)
let palin1 = Int(s + String(s.reversed()))!
let palin2 = Int(s + String(s.dropLast().reversed()))!
if palin1 * palin1 > right {
break
}
if palin1 * palin1 >= left && isPalindrome(palin1 * palin1) {
count += 1
}
if palin2 * palin2 >= left && palin2 * palin2 <= right && isPalindrome(palin2 * palin2) {
count += 1
}
}
return count
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 206. Reverse Linked List
Сложность: easy
Дан односвязный список, разверните этот список и верните развернутый список.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте две переменные: prev как nullptr и curr как head списка. Эти переменные будут использоваться для отслеживания предыдущего и текущего узлов в процессе разворота списка.
2⃣ Пройдитесь по списку с помощью цикла:
Сохраните ссылку на следующий узел curr в переменную nextTemp.
Измените ссылку next текущего узла curr на prev, чтобы развернуть направление ссылки.
Переместите prev на текущий узел curr и переместите curr на следующий узел nextTemp.
3⃣ После завершения цикла верните prev как новую голову развернутого списка.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Дан односвязный список, разверните этот список и верните развернутый список.
Пример:
Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]
Сохраните ссылку на следующий узел curr в переменную nextTemp.
Измените ссылку next текущего узла curr на prev, чтобы развернуть направление ссылки.
Переместите prev на текущий узел curr и переместите curr на следующий узел nextTemp.
class ListNode {
var val: Int
var next: ListNode?
init(_ val: Int) {
self.val = val
self.next = nil
}
}
class Solution {
func reverseList(_ head: ListNode?) -> ListNode? {
var prev: ListNode? = nil
var curr = head
while curr != nil {
let nextTemp = curr?.next
curr?.next = prev
prev = curr
curr = nextTemp
}
return prev
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 304. Range Sum Query 2D - Immutable
Сложность: medium
Дана двумерная матрица matrix. Обработайте несколько запросов следующего типа:
Вычислите сумму элементов матрицы внутри прямоугольника, определенного его верхним левым углом (row1, col1) и нижним правым углом (row2, col2).
Реализуйте класс NumMatrix:
- NumMatrix(int[][] matrix) Инициализирует объект целочисленной матрицей matrix.- int sumRegion(int row1, int col1, int row2, int col2) Возвращает сумму элементов матрицы внутри прямоугольника, определенного его верхним левым углом (row1, col1) и нижним правым углом (row2, col2).
Необходимо разработать алгоритм, где метод sumRegion работает за O(1) по времени.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация:
Создайте двумерный массив sums размером (m + 1) x (n + 1), где m и n — размеры исходной матрицы matrix. Заполните этот массив нулями.
2⃣ Предварительное вычисление сумм:
Заполните массив sums, где каждый элемент sums[i][j] будет содержать сумму всех элементов матрицы от начала до позиции (i-1, j-1) включительно.
3⃣ Вычисление диапазонной суммы:
Для каждого запроса суммы элементов внутри прямоугольника, определенного его углами (row1, col1) и (row2, col2), используйте предварительно вычисленный массив sums для получения результата за O(1) времени.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дана двумерная матрица matrix. Обработайте несколько запросов следующего типа:
Вычислите сумму элементов матрицы внутри прямоугольника, определенного его верхним левым углом (row1, col1) и нижним правым углом (row2, col2).
Реализуйте класс NumMatrix:
- NumMatrix(int[][] matrix) Инициализирует объект целочисленной матрицей matrix.- int sumRegion(int row1, int col1, int row2, int col2) Возвращает сумму элементов матрицы внутри прямоугольника, определенного его верхним левым углом (row1, col1) и нижним правым углом (row2, col2).
Необходимо разработать алгоритм, где метод sumRegion работает за O(1) по времени.
Пример:
Input
["NumMatrix", "sumRegion", "sumRegion", "sumRegion"]
[[[[3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5], [4, 1, 0, 1, 7], [1, 0, 3, 0, 5]]], [2, 1, 4, 3], [1, 1, 2, 2], [1, 2, 2, 4]]
Создайте двумерный массив sums размером (m + 1) x (n + 1), где m и n — размеры исходной матрицы matrix. Заполните этот массив нулями.
Заполните массив sums, где каждый элемент sums[i][j] будет содержать сумму всех элементов матрицы от начала до позиции (i-1, j-1) включительно.
Для каждого запроса суммы элементов внутри прямоугольника, определенного его углами (row1, col1) и (row2, col2), используйте предварительно вычисленный массив sums для получения результата за O(1) времени.
class NumMatrix {
private var dp: [[Int]]
init(_ matrix: [[Int]]) {
if matrix.isEmpty || matrix[0].isEmpty {
dp = []
return
}
let m = matrix.count, n = matrix[0].count
dp = Array(repeating: Array(repeating: 0, count: n + 1), count: m + 1)
for r in 0..<m {
for c in 0..<n {
dp[r + 1][c + 1] = dp[r + 1][c] + dp[r][c + 1] + matrix[r][c] - dp[r][c]
}
}
}
func sumRegion(_ row1: Int, _ col1: Int, _ row2: Int, _ col2: Int) -> Int {
return dp[row2 + 1][col2 + 1] - dp[row1][col2 + 1] - dp[row2 + 1][col1] + dp[row1][col1]
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 869. Reordered Power of 2
Сложность: medium
Дано целое число n. Мы можем переставить цифры числа в любом порядке (включая исходный порядок), при этом ведущая цифра не должна быть нулем.
Верните true, если и только если мы можем сделать это так, чтобы полученное число было степенью двойки.
Пример:
👨💻 Алгоритм:
1⃣ Сгенерируйте все перестановки цифр числа, размещая любую цифру на первой позиции (start = 0), затем любую из оставшихся цифр на второй позиции (start = 1) и так далее. В Python можно использовать встроенную функцию itertools.permutations.
2⃣ Проверьте, что перестановка представляет собой степень двойки, убедившись, что в перестановке нет ведущего нуля, и удаляя все множители 2. Если результат равен 1 (то есть, он не содержал других множителей, кроме 2), то это была степень двойки. В Python можно использовать проверку bin(N).count('1') == 1.
3⃣ Верните true, если хотя бы одна перестановка является степенью двойки, иначе верните false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано целое число n. Мы можем переставить цифры числа в любом порядке (включая исходный порядок), при этом ведущая цифра не должна быть нулем.
Верните true, если и только если мы можем сделать это так, чтобы полученное число было степенью двойки.
Пример:
Input: n = 1
Output: true
class Solution {
func reorderedPowerOf2(_ N: Int) -> Bool {
let A = Array(String(N)).map { Int(String($0))! }
return permutations(A, 0)
}
private func isPowerOfTwo(_ A: [Int]) -> Bool {
if A[0] == 0 { return false }
var N = A.reduce(0) { $0 * 10 + $1 }
while N > 0 && (N & 1) == 0 { N >>= 1 }
return N == 1
}
private func permutations(_ A: [Int], _ start: Int) -> Bool {
var A = A
if start == A.count { return isPowerOfTwo(A) }
for i in start..<A.count {
A.swapAt(start, i)
if permutations(A, start + 1) { return true }
A.swapAt(start, i)
}
return false
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from easyoffer
Ура, друзья! Изиоффер переходит в публичное бета-тестирование!
🎉 Что нового:
🟢 Анализ IT собеседований на основе 4500+ реальных интервью
🟢 Вопросы из собеседований с вероятностью встречи
🟢 Видео-примеры ответов на вопросы от Senior, Middle, Junior грейдов
🟢 Пример лучшего ответа
🟢 Задачи из собеседований
🟢 Тестовые задания
🟢 Примеры собеседований
🟢 Фильтрация всего контента по грейдам, компаниям
🟢 Тренажер подготовки к собеседованию на основе интервальных повторений и флеш карточек
🟡 Тренажер "Реальное собеседование" с сценарием вопросов из реальных собеседований (скоро)
🟢 Автоотклики на HeadHunter
🟢 Закрытое сообщество easyoffer
💎 Акция в честь открытия для первых 500 покупателей:
🚀 Скидка 50% на PRO тариф на 1 год (15000₽ → 7500₽)
🔥 Акция уже стартовала! 👉 https://easyoffer.ru/pro
🎉 Что нового:
💎 Акция в честь открытия для первых 500 покупателей:
🚀 Скидка 50% на PRO тариф на 1 год (
🔥 Акция уже стартовала! 👉 https://easyoffer.ru/pro
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 524. Longest Word in Dictionary through Deleting
Сложность: medium
Даны строка s и массив строк dictionary. Верните самую длинную строку из dictionary, которую можно сформировать, удаляя некоторые символы из данной строки s. Если возможных результатов несколько, верните самое длинное слово с наименьшим лексикографическим порядком. Если возможного результата нет, верните пустую строку.
Пример:
👨💻 Алгоритм:
1⃣ Инициализируйте переменную для хранения самой длинной строки, соответствующей критериям. Пройдите по каждой строке x в неотсортированном массиве dictionary и проверьте, является ли x подпоследовательностью строки s.
2⃣ Если строка x является подпоследовательностью, сравните её с текущей самой длинной строкой по длине. Если длина x больше или равна длине текущей самой длинной строки и она меньше текущей строки в лексикографическом порядке (если равны по длине), обновите текущую самую длинную строку.
3⃣ После рассмотрения всех строк в dictionary, верните найденную строку. Если ни одна строка не подошла, верните пустую строку.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Даны строка s и массив строк dictionary. Верните самую длинную строку из dictionary, которую можно сформировать, удаляя некоторые символы из данной строки s. Если возможных результатов несколько, верните самое длинное слово с наименьшим лексикографическим порядком. Если возможного результата нет, верните пустую строку.
Пример:
Input: s = "abpcplea", dictionary = ["ale","apple","monkey","plea"]
Output: "apple"
class Solution {
func isSubsequence(_ x: String, _ y: String) -> Bool {
var j = x.startIndex
for i in y.indices where j < x.endIndex {
if x[j] == y[i] {
j = x.index(after: j)
}
}
return j == x.endIndex
}
func findLongestWord(_ s: String, _ d: [String]) -> String {
var maxStr = ""
for str in d {
if isSubsequence(str, s) {
if str.count > maxStr.count || (str.count == maxStr.count && str < maxStr) {
maxStr = str
}
}
}
return maxStr
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: №21. Merge Two Sorted Lists
Сложность: easy
Вам даны заголовки двух отсортированных связанных списков
Пример:
👨💻 Алгоритм:
1⃣ Если один из списков пуст, вернуть другой список.
2⃣ Сравнивать значения узлов
3⃣ Рекурсивно продолжать объединение, связывая меньший узел с результатом
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Вам даны заголовки двух отсортированных связанных списков
list1 и list2. Объедините два списка в один отсортированный список. Список должен быть составлен путем сращивания узлов первых двух списков. Возвращает заголовок объединенного связанного списка. Пример:
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
list1 и list2, выбирая меньший узел для объединенного списка. mergeTwoLists от оставшихся узлов. class Solution {
func mergeTwoLists(_ list1: ListNode?, _ list2: ListNode?) -> ListNode? {
guard let list1 = list1 else { return list2 }
guard let list2 = list2 else { return list1 }
if list1.val < list2.val {
list1.next = mergeTwoLists(list1.next, list2)
return list1
} else {
list2.next = mergeTwoLists(list1, list2.next)
return list2
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 950. Reveal Cards In Increasing Order
Сложность: medium
Вам дана колода целочисленных массивов. Имеется колода карт, в которой каждая карта имеет уникальное целое число. Целое число на i-й карте - deck[i]. Вы можете упорядочить колоду в любом порядке. Изначально все карты в одной колоде лежат лицевой стороной вниз (нераскрытыми). Вы будете выполнять следующие действия несколько раз, пока все карты не будут раскрыты: возьмите верхнюю карту колоды, раскройте ее и выньте из колоды. Если в колоде еще есть карты, положите следующую верхнюю карту колоды на дно колоды. Если еще есть нераскрытые карты, вернитесь к шагу 1. В противном случае остановитесь. Верните порядок колоды, при котором карты раскрываются в порядке возрастания. Обратите внимание, что первая запись в ответе считается верхом колоды.
Пример:
👨💻 Алгоритм:
1⃣ Создать индексы карт в порядке, в котором они будут раскрываться.
2⃣ Отсортировать колоду карт по возрастанию.
3⃣ Отсортировать колоду карт по возрастанию.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дана колода целочисленных массивов. Имеется колода карт, в которой каждая карта имеет уникальное целое число. Целое число на i-й карте - deck[i]. Вы можете упорядочить колоду в любом порядке. Изначально все карты в одной колоде лежат лицевой стороной вниз (нераскрытыми). Вы будете выполнять следующие действия несколько раз, пока все карты не будут раскрыты: возьмите верхнюю карту колоды, раскройте ее и выньте из колоды. Если в колоде еще есть карты, положите следующую верхнюю карту колоды на дно колоды. Если еще есть нераскрытые карты, вернитесь к шагу 1. В противном случае остановитесь. Верните порядок колоды, при котором карты раскрываются в порядке возрастания. Обратите внимание, что первая запись в ответе считается верхом колоды.
Пример:
Input: deck = [17,13,11,2,3,5,7]
Output: [2,13,3,11,5,17,7]
class Solution {
func deckRevealedIncreasing(_ deck: [Int]) -> [Int] {
var index = Array(deck.indices)
var result = [Int](repeating: 0, count: deck.count)
let sortedDeck = deck.sorted()
for card in sortedDeck {
result[index.removeFirst()] = card
if !index.isEmpty {
index.append(index.removeFirst())
}
}
return result
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 681. Next Closest Time
Сложность: medium
Пример:
👨💻 Алгоритм:
😎 Посмотреть решение
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано время, представленное в формате "ЧЧ:ММ". Сформируйте ближайшее следующее время, используя текущие цифры. Количество раз, которое можно использовать цифру, не ограничено.
Можно предположить, что заданная строка всегда корректна. Например, "01:34", "12:09" являются корректными. "1:34", "12:9" являются некорректными.
Пример:
Input: time = "19:34"
Output: "19:39"
Explanation: The next closest time choosing from digits 1, 9, 3, 4, is 19:39, which occurs 5 minutes later.
It is not 19:33, because this occurs 23 hours and 59 minutes later.
1⃣ Симулируйте ход часов, увеличивая время на одну минуту. Каждый раз, когда время увеличивается, если все цифры допустимы, верните текущее время.2⃣ Представьте время как целое число t в диапазоне 0 <= t < 24 * 60. Тогда часы равны t / 60, минуты равны t % 60.3⃣ Найдите каждую цифру часов и минут: часы / 10, часы % 10 и т.д.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 789. Escape The Ghosts
Сложность: medium
Вы играете в упрощенную игру PAC-MAN на бесконечной 2D-сетке. Вы начинаете в точке [0, 0], и у вас есть конечная точка target = [xtarget, ytarget], к которой вы пытаетесь добраться. На карте находятся несколько привидений, их начальные позиции заданы в виде двумерного массива ghosts, где ghosts[i] = [xi, yi] представляет начальную позицию i-го привидения. Все входные данные являются целочисленными координатами.
Каждый ход вы и все привидения можете независимо выбирать перемещение на 1 единицу в любом из четырех основных направлений: север, восток, юг или запад, или оставаться на месте. Все действия происходят одновременно.
Вы сможете сбежать, если и только если сможете достичь цели раньше, чем любое привидение достигнет вас. Если вы достигнете любой клетки (включая конечную точку) одновременно с привидением, это не считается побегом.
Верните true, если можно сбежать независимо от того, как движутся привидения, иначе верните false.
Пример:
👨💻 Алгоритм:
1⃣ Проверьте, что наше таксическое расстояние до цели меньше, чем расстояние от любого привидения до цели.
2⃣ Если это так, мы можем гарантированно добраться до цели раньше любого привидения.
3⃣ Если привидение может добраться до цели раньше нас или одновременно с нами, побег невозможен.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вы играете в упрощенную игру PAC-MAN на бесконечной 2D-сетке. Вы начинаете в точке [0, 0], и у вас есть конечная точка target = [xtarget, ytarget], к которой вы пытаетесь добраться. На карте находятся несколько привидений, их начальные позиции заданы в виде двумерного массива ghosts, где ghosts[i] = [xi, yi] представляет начальную позицию i-го привидения. Все входные данные являются целочисленными координатами.
Каждый ход вы и все привидения можете независимо выбирать перемещение на 1 единицу в любом из четырех основных направлений: север, восток, юг или запад, или оставаться на месте. Все действия происходят одновременно.
Вы сможете сбежать, если и только если сможете достичь цели раньше, чем любое привидение достигнет вас. Если вы достигнете любой клетки (включая конечную точку) одновременно с привидением, это не считается побегом.
Верните true, если можно сбежать независимо от того, как движутся привидения, иначе верните false.
Пример:
Input: ghosts = [[1,0],[0,3]], target = [0,1]
Output: true
Explanation: You can reach the destination (0, 1) after 1 turn, while the ghosts located at (1, 0) and (0, 3) cannot catch up with you.
class Solution {
func escapeGhosts(_ ghosts: [[Int]], _ target: [Int]) -> Bool {
func taxi(_ P: [Int], _ Q: [Int]) -> Int {
return abs(P[0] - Q[0]) + abs(P[1] - Q[1])
}
let playerDistance = taxi([0, 0], target)
return ghosts.allSatisfy { taxi($0, target) > playerDistance }
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 923. 3Sum With Multiplicity
Сложность: medium
Если задан целочисленный массив arr и целое число target, верните количество кортежей i, j, k, таких, что i < j < k и arr[i] + arr[j] + arr[k] == target. Поскольку ответ может быть очень большим, верните его по модулю 10^9 + 7.
Пример:
👨💻 Алгоритм:
1⃣ Отсортировать массив arr.
2⃣ Инициализировать счетчик для количества кортежей.
Пройти по массиву тремя указателями i, j, и k:
Для каждого i, установить j на i + 1, и k на конец массива.
Использовать двухуказательный метод для нахождения пар (j, k), таких что arr[i] + arr[j] + arr[k] == target.
3⃣ Вернуть результат по модулю 10^9 + 7.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Если задан целочисленный массив arr и целое число target, верните количество кортежей i, j, k, таких, что i < j < k и arr[i] + arr[j] + arr[k] == target. Поскольку ответ может быть очень большим, верните его по модулю 10^9 + 7.
Пример:
Input: arr = [1,1,2,2,3,3,4,4,5,5], target = 8
Output: 20
Пройти по массиву тремя указателями i, j, и k:
Для каждого i, установить j на i + 1, и k на конец массива.
Использовать двухуказательный метод для нахождения пар (j, k), таких что arr[i] + arr[j] + arr[k] == target.
class Solution {
func threeSumMulti(_ arr: [Int], _ target: Int) -> Int {
let MOD = 1_000_000_007
var count = 0
let arr = arr.sorted()
for i in 0..<arr.count {
var j = i + 1
var k = arr.count - 1
while j < k {
let sum = arr[i] + arr[j] + arr[k]
if sum == target {
if arr[j] == arr[k] {
count += (k - j + 1) * (k - j) / 2
break
} else {
var left = 1
var right = 1
while j + 1 < k && arr[j] == arr[j + 1] {
left += 1
j += 1
}
while k - 1 > j && arr[k] == arr[k - 1] {
right += 1
k -= 1
}
count += left * right
j += 1
k -= 1
}
} else if sum < target {
j += 1
} else {
k -= 1
}
}
}
return count % MOD
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1165. Single-Row Keyboard
Сложность: easy
Есть специальная клавиатура, на которой все клавиши расположены в один ряд.
Дана строка keyboard длиной 26, указывающая на раскладку клавиатуры (индексирована от 0 до 25). Изначально ваш палец находится на индексе 0. Чтобы напечатать символ, нужно переместить палец на индекс нужного символа. Время, затраченное на перемещение пальца с индекса i на индекс j, равно |i - j|.
Вам нужно напечатать строку word. Напишите функцию для расчета времени, необходимого для её набора одним пальцем.
Пример:
👨💻 Алгоритм:
1⃣ Клавиатура содержит уникальные строчные английские буквы, поэтому мы можем сопоставить её с массивом размера 26. Создадим массив размера 26, назовём его keyIndices. Сохраните индекс каждой буквы в этом массиве, проходя по строке keyboard. Инициализируйте переменную result значением 0, которая будет хранить сумму всех расстояний. Объявите переменную prev, которая будет хранить индекс предыдущей клавиши. Поскольку начальная позиция равна 0, инициализируйте её значением 0.
2⃣ Проходите по строке word буква за буквой. Для каждой буквы c добавьте ∣prev−indexOf(c)∣ к result. Обновите prev до индекса c.
3⃣ Повторите шаги 6 и 7 для всех букв. В конце прохода result будет содержать итоговое время, необходимое для набора слова.
😎 Решение
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Есть специальная клавиатура, на которой все клавиши расположены в один ряд.
Дана строка keyboard длиной 26, указывающая на раскладку клавиатуры (индексирована от 0 до 25). Изначально ваш палец находится на индексе 0. Чтобы напечатать символ, нужно переместить палец на индекс нужного символа. Время, затраченное на перемещение пальца с индекса i на индекс j, равно |i - j|.
Вам нужно напечатать строку word. Напишите функцию для расчета времени, необходимого для её набора одним пальцем.
Пример:
Input: keyboard = "abcdefghijklmnopqrstuvwxyz", word = "cba"
Output: 4
Explanation: The index moves from 0 to 2 to write 'c' then to 1 to write 'b' then to 0 again to write 'a'.
Total time = 2 + 1 + 1 = 4.
class Solution {
func calculateTime(_ keyboard: String, _ word: String) -> Int {
var keyIndices = Array(repeating: -1, count: 26)
for (i, c) in keyboard.enumerated() {
keyIndices[Int(c.asciiValue! - Character("a").asciiValue!)] = i
}
var prev = 0
var result = 0
for c in word {
let index = keyIndices[Int(c.asciiValue! - Character("a").asciiValue!)]
result += abs(prev - index)
prev = index
}
return result
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 276. Paint Fence
Сложность: medium
Вы красите забор из n столбцов, используя k различных цветов. Вы должны красить столбы, следуя этим правилам:
Каждый столб должен быть окрашен в один цвет.
Не может быть трех или более подряд идущих столбцов одного цвета.
Учитывая два целых числа n и k, верните количество способов покрасить забор.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация и определение вспомогательной функции:
Определить хеш-таблицу memo, где memo[i] представляет количество способов покрасить i столбцов.
Определить функцию totalWays, которая будет определять количество способов покрасить i столбцов.
2⃣ Реализация базы и проверка кэша:
В функции totalWays проверить базовые случаи: вернуть k, если i == 1, и вернуть k * k, если i == 2.
Проверить, рассчитан ли аргумент i и сохранен ли в memo. Если да, вернуть memo[i].
3⃣ Расчет с использованием рекуррентного соотношения:
В противном случае использовать рекуррентное соотношение для вычисления memo[i], сохранить результат в memo[i] и вернуть его.
Вызвать и вернуть totalWays(n).
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вы красите забор из n столбцов, используя k различных цветов. Вы должны красить столбы, следуя этим правилам:
Каждый столб должен быть окрашен в один цвет.
Не может быть трех или более подряд идущих столбцов одного цвета.
Учитывая два целых числа n и k, верните количество способов покрасить забор.
Пример:
Input: n = 3, k = 2
Output: 6
Explanation: All the possibilities are shown.
Note that painting all the posts red or all the posts green is invalid because there cannot be three posts in a row with the same color.
Определить хеш-таблицу memo, где memo[i] представляет количество способов покрасить i столбцов.
Определить функцию totalWays, которая будет определять количество способов покрасить i столбцов.
В функции totalWays проверить базовые случаи: вернуть k, если i == 1, и вернуть k * k, если i == 2.
Проверить, рассчитан ли аргумент i и сохранен ли в memo. Если да, вернуть memo[i].
В противном случае использовать рекуррентное соотношение для вычисления memo[i], сохранить результат в memo[i] и вернуть его.
Вызвать и вернуть totalWays(n).
class Solution {
func numWays(_ n: Int, _ k: Int) -> Int {
if n == 1 {
return k
}
var twoPostsBack = k
var onePostBack = k * k
for _ in 3...n {
let curr = (k - 1) * (onePostBack + twoPostsBack)
twoPostsBack = onePostBack
onePostBack = curr
}
return onePostBack
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 349. Intersection of Two Arrays
Сложность: easy
Даны два целочисленных массива nums1 и nums2. Верните массив их пересечения. Каждый элемент в результате должен быть уникальным, и вы можете вернуть результат в любом порядке.
Пример:
👨💻 Алгоритм:
1⃣ Создание множеств:
Преобразуйте оба массива nums1 и nums2 в множества для получения уникальных элементов.
2⃣ Нахождение пересечения:
Найдите пересечение двух множеств.
3⃣ Возврат результата:
Преобразуйте пересечение обратно в массив и верните его.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Даны два целочисленных массива nums1 и nums2. Верните массив их пересечения. Каждый элемент в результате должен быть уникальным, и вы можете вернуть результат в любом порядке.
Пример:
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2]
Преобразуйте оба массива nums1 и nums2 в множества для получения уникальных элементов.
Найдите пересечение двух множеств.
Преобразуйте пересечение обратно в массив и верните его.
class Solution {
func intersection(_ nums1: [Int], _ nums2: [Int]) -> [Int] {
let set1 = Set(nums1)
let set2 = Set(nums2)
return Array(set1.intersection(set2))
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 971. Flip Binary Tree To Match Preorder Traversal
Сложность: medium
Дано корневое дерево с n узлами, где каждому узлу уникально присвоено значение от 1 до n. Также дана последовательность из n значений voyage, которая является желаемым обходом дерева в порядке pre-order.
Любой узел в бинарном дереве можно перевернуть, поменяв местами его левое и правое поддеревья. Например, переворот узла 1 будет иметь следующий эффект:
Переверните минимальное количество узлов, чтобы обход дерева в порядке pre-order соответствовал voyage.
Верните список значений всех перевернутых узлов. Вы можете вернуть ответ в любом порядке. Если невозможно перевернуть узлы в дереве, чтобы сделать обход в порядке pre-order соответствующим voyage, верните список [-1].
Пример:
👨💻 Алгоритм:
1⃣ Выполните поиск в глубину. Если в каком-либо узле значение узла не соответствует значению в voyage, верните [-1].
2⃣ Иначе определите, когда нужно перевернуть: если следующее ожидаемое число в voyage (voyage[i]) отличается от следующего потомка.
3⃣ Переверните узел, добавьте его значение в список перевернутых узлов и продолжите обход дерева, пока весь порядок обхода pre-order не будет соответствовать voyage.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дано корневое дерево с n узлами, где каждому узлу уникально присвоено значение от 1 до n. Также дана последовательность из n значений voyage, которая является желаемым обходом дерева в порядке pre-order.
Любой узел в бинарном дереве можно перевернуть, поменяв местами его левое и правое поддеревья. Например, переворот узла 1 будет иметь следующий эффект:
Переверните минимальное количество узлов, чтобы обход дерева в порядке pre-order соответствовал voyage.
Верните список значений всех перевернутых узлов. Вы можете вернуть ответ в любом порядке. Если невозможно перевернуть узлы в дереве, чтобы сделать обход в порядке pre-order соответствующим voyage, верните список [-1].
Пример:
Input: root = [1,2], voyage = [2,1]
Output: [-1]
Explanation: It is impossible to flip the nodes such that the pre-order traversal matches voyage.
class Solution {
var flipped = [Int]()
var index = 0
var voyage: [Int] = []
func flipMatchVoyage(_ root: TreeNode?, _ voyage: [Int]) -> [Int] {
flipped = []
index = 0
self.voyage = voyage
dfs(root)
if !flipped.isEmpty && flipped[0] == -1 {
flipped = [-1]
}
return flipped
}
func dfs(_ node: TreeNode?) {
if let node = node {
if node.val != voyage[index] {
flipped = [-1]
return
}
index += 1
if index < voyage.count && node.left != nil && node.left!.val != voyage[index] {
flipped.append(node.val)
dfs(node.right)
dfs(node.left)
} else {
dfs(node.left)
dfs(node.right)
}
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 507. Perfect Number
Сложность: easy
Совершенное число — это положительное целое число, которое равно сумме своих положительных делителей, исключая само число. Делитель целого числа x — это целое число, которое может делить x нацело.
Дано целое число n, верните true, если n является совершенным числом, в противном случае верните false.
Пример:
👨💻 Алгоритм:
1⃣ Инициализация
Если число num меньше или равно 0, вернуть false. Инициализируйте переменную sum значением 0.
2⃣ Поиск делителей и вычисление суммы
Переберите числа от 1 до квадратного корня num. Если число является делителем num, добавьте его к sum. Если делитель не равен квадратному корню num, добавьте к sum также результат деления num на делитель.
3⃣ Проверка на совершенное число
Вычтите num из sum. Если результат равен num, вернуть true, иначе вернуть false.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: easy
Совершенное число — это положительное целое число, которое равно сумме своих положительных делителей, исключая само число. Делитель целого числа x — это целое число, которое может делить x нацело.
Дано целое число n, верните true, если n является совершенным числом, в противном случае верните false.
Пример:
Input: num = 28
Output: true
Explanation: 28 = 1 + 2 + 4 + 7 + 14
1, 2, 4, 7, and 14 are all divisors of 28.
Если число num меньше или равно 0, вернуть false. Инициализируйте переменную sum значением 0.
Переберите числа от 1 до квадратного корня num. Если число является делителем num, добавьте его к sum. Если делитель не равен квадратному корню num, добавьте к sum также результат деления num на делитель.
Вычтите num из sum. Если результат равен num, вернуть true, иначе вернуть false.
class Solution {
func checkPerfectNumber(_ num: Int) -> Bool {
if num <= 0 {
return false
}
var sum = 0
for i in 1...Int(sqrt(Double(num))) {
if num % i == 0 {
sum += i
if i * i != num {
sum += num / i
}
}
}
return sum - num == num
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Задача: 411. Minimum Unique Word Abbreviation
Сложность: hard
Строку можно сократить, заменив любое количество не смежных подстрок их длинами. Например, строка "substitution" может быть сокращена как (но не ограничиваясь этим):
"s10n" ("s ubstitutio n") "sub4u4" ("sub stit u tion") "12" ("substitution") "su3i1u2on" ("su bst i t u ti on") "substitution" (без замен подстрок) Обратите внимание, что "s55n" ("s ubsti tutio n") не является правильным сокращением "substitution", поскольку замененные подстроки являются смежными.
Длина аббревиатуры - это количество букв, которые не были заменены, плюс количество подстрок, которые были заменены. Например, аббревиатура "s10n" имеет длину 3 (2 буквы + 1 подстрока), а "su3i1u2on" - 9 (6 букв + 3 подстроки). Учитывая целевую строку target и массив строк dictionary, верните аббревиатуру target с наименьшей возможной длиной, которая не является аббревиатурой ни одной строки в словаре. Если существует несколько самых коротких аббревиатур, верните любую из них.
Пример:
👨💻 Алгоритм:
1⃣ Создайте множество всех аббревиатур из словаря, вычислив их все возможные аббревиатуры.
2⃣ Сгенерируйте все возможные аббревиатуры для строки target.
3⃣ Найдите самую короткую аббревиатуру для target, которая отсутствует в множестве аббревиатур словаря.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Строку можно сократить, заменив любое количество не смежных подстрок их длинами. Например, строка "substitution" может быть сокращена как (но не ограничиваясь этим):
"s10n" ("s ubstitutio n") "sub4u4" ("sub stit u tion") "12" ("substitution") "su3i1u2on" ("su bst i t u ti on") "substitution" (без замен подстрок) Обратите внимание, что "s55n" ("s ubsti tutio n") не является правильным сокращением "substitution", поскольку замененные подстроки являются смежными.
Длина аббревиатуры - это количество букв, которые не были заменены, плюс количество подстрок, которые были заменены. Например, аббревиатура "s10n" имеет длину 3 (2 буквы + 1 подстрока), а "su3i1u2on" - 9 (6 букв + 3 подстроки). Учитывая целевую строку target и массив строк dictionary, верните аббревиатуру target с наименьшей возможной длиной, которая не является аббревиатурой ни одной строки в словаре. Если существует несколько самых коротких аббревиатур, верните любую из них.
Пример:
Input: target = "apple", dictionary = ["blade"]
Output: "a4"
func generateAbbreviations(_ word: String) -> Set<String> {
var result = Set<String>()
generateAbbreviationsHelper(Array(word), "", 0, 0, &result)
return result
}
func generateAbbreviationsHelper(_ word: [Character], _ current: String, _ pos: Int, _ count: Int, _ result: inout Set<String>) {
if pos == word.count {
result.insert(current + (count > 0 ? String(count) : ""))
return
}
generateAbbreviationsHelper(word, current, pos + 1, count + 1, &result)
generateAbbreviationsHelper(word, current + (count > 0 ? String(count) : "") + String(word[pos]), pos + 1, 0, &result)
}
func minAbbreviation(_ target: String, _ dictionary: [String]) -> String {
let targetAbbrs = generateAbbreviations(target)
var dictAbbrs = Set<String>()
for word in dictionary {
dictAbbrs.formUnion(generateAbbreviations(word))
}
let validAbbrs = targetAbbrs.subtracting(dictAbbrs)
return validAbbrs.sorted(by: { $0.count < $1.count }).first!
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 25. Reverse Nodes in k-Group
Сложность: hard
Учитывая заголовок связанного списка, поменяйте местами узлы списка k за раз и верните измененный список.
k — целое положительное число, меньшее или равное длине связанного списка. Если количество узлов не кратно k, то пропущенные узлы в конечном итоге должны остаться такими, какие они есть.
Вы не можете изменять значения в узлах списка, можно изменять только сами узлы.
Пример:
👨💻 Алгоритм:
1⃣ Определяем длину списка, чтобы знать, сколько полных групп из k узлов можно перевернуть.
2⃣ Используем фиктивный узел (dummy) для удобного управления указателями.
3⃣ Переворачиваем группы по k узлов, изменяя связи в списке.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: hard
Учитывая заголовок связанного списка, поменяйте местами узлы списка k за раз и верните измененный список.
k — целое положительное число, меньшее или равное длине связанного списка. Если количество узлов не кратно k, то пропущенные узлы в конечном итоге должны остаться такими, какие они есть.
Вы не можете изменять значения в узлах списка, можно изменять только сами узлы.
Пример:
Input: head = [1,2,3,4,5], k = 3
Output: [3,2,1,4,5]
class ListNode {
var val: Int
var next: ListNode?
init(_ val: Int) {
self.val = val
self.next = nil
}
}
func reverseKGroup(_ head: ListNode?, _ k: Int) -> ListNode? {
if head == nil || k == 1 {
return head
}
let dummy = ListNode(0)
dummy.next = head
var current: ListNode? = dummy
var next: ListNode?
var prev: ListNode? = dummy
var count = 0
while current?.next != nil {
current = current?.next
count += 1
}
while count >= k {
current = prev?.next
next = current?.next
for _ in 1..<k {
current?.next = next?.next
next?.next = prev?.next
prev?.next = next
next = current?.next
}
prev = current
count -= k
}
return dummy.next
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1372. Longest ZigZag Path in a Binary Tree
Сложность: medium
Вам дан корень бинарного дерева.
Зигзагообразный путь для бинарного дерева определяется следующим образом:
Выберите любой узел в бинарном дереве и направление (вправо или влево).
Если текущее направление вправо, перейдите к правому дочернему узлу текущего узла; иначе перейдите к левому дочернему узлу.
Измените направление с вправо на влево или с влево на вправо.
Повторяйте второй и третий шаги, пока не сможете двигаться по дереву.
Длина зигзагообразного пути определяется как количество посещенных узлов минус 1 (один узел имеет длину 0).
Верните длину самого длинного зигзагообразного пути, содержащегося в этом дереве.
Пример:
👨💻 Алгоритм:
1⃣ Рекурсивная функция DFS:
Создайте рекурсивную функцию dfs, которая будет выполнять обход дерева и отслеживать текущую длину зигзагообразного пути и направление движения (влево или вправо).
2⃣ Обновление максимальной длины пути:
При каждом вызове рекурсивной функции обновляйте максимальную длину зигзагообразного пути, если текущая длина больше текущего максимума.
3⃣ Рекурсивный вызов для левого и правого дочерних узлов:
Рекурсивно вызывайте функцию dfs для левого и правого дочерних узлов с обновленными параметрами длины и направления.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Вам дан корень бинарного дерева.
Зигзагообразный путь для бинарного дерева определяется следующим образом:
Выберите любой узел в бинарном дереве и направление (вправо или влево).
Если текущее направление вправо, перейдите к правому дочернему узлу текущего узла; иначе перейдите к левому дочернему узлу.
Измените направление с вправо на влево или с влево на вправо.
Повторяйте второй и третий шаги, пока не сможете двигаться по дереву.
Длина зигзагообразного пути определяется как количество посещенных узлов минус 1 (один узел имеет длину 0).
Верните длину самого длинного зигзагообразного пути, содержащегося в этом дереве.
Пример:
Input: s = "rat"
Output: "art"
Explanation: The word "rat" becomes "art" after re-ordering it with the mentioned algorithm.
Создайте рекурсивную функцию dfs, которая будет выполнять обход дерева и отслеживать текущую длину зигзагообразного пути и направление движения (влево или вправо).
При каждом вызове рекурсивной функции обновляйте максимальную длину зигзагообразного пути, если текущая длина больше текущего максимума.
Рекурсивно вызывайте функцию dfs для левого и правого дочерних узлов с обновленными параметрами длины и направления.
class TreeNode {
var val: Int
var left: TreeNode?
var right: TreeNode?
init(_ val: Int) { self.val = val; self.left = nil; self.right = nil }
}
class Solution {
var maxLength = 0
func longestZigZag(_ root: TreeNode?) -> Int {
dfs(root, true, 0)
dfs(root, false, 0)
return maxLength
}
func dfs(_ node: TreeNode?, _ isLeft: Bool, _ length: Int) {
guard let node = node else { return }
maxLength = max(maxLength, length)
if isLeft {
dfs(node.left, false, length + 1)
dfs(node.right, true, 1)
} else {
dfs(node.right, true, length + 1)
dfs(node.left, false, 1)
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача: 1490. Clone N-ary Tree
Сложность: medium
Дан корень N-арного дерева, верните глубокую копию (клон) дерева.
Каждый узел в N-арном дереве содержит значение (val) типа int и список (List[Node]) его детей.
Сериализация входных данных N-арного дерева представлена в порядке обхода по уровням, каждая группа детей разделена значением null (см. примеры).
Пример:
👨💻 Алгоритм:
1⃣ Базовый случай:
Проверить, является ли входной узел null. Если да, вернуть null.
2⃣ Копирование узла:
Создать новый узел с таким же значением, как у входного узла.
3⃣ Рекурсивное клонирование детей:
Рекурсивно клонировать каждого ребёнка входного узла и добавить клонированных детей в список детей нового узла.
Вернуть клонированный узел.
😎 Решение:
Ставь 👍 и забирай 📚 Базу знаний
Сложность: medium
Дан корень N-арного дерева, верните глубокую копию (клон) дерева.
Каждый узел в N-арном дереве содержит значение (val) типа int и список (List[Node]) его детей.
class Node {
public int val;
public List<Node> children;
}Сериализация входных данных N-арного дерева представлена в порядке обхода по уровням, каждая группа детей разделена значением null (см. примеры).
Пример:
Input: root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
Output: [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
Проверить, является ли входной узел null. Если да, вернуть null.
Создать новый узел с таким же значением, как у входного узла.
Рекурсивно клонировать каждого ребёнка входного узла и добавить клонированных детей в список детей нового узла.
Вернуть клонированный узел.
class Node {
public var val: Int
public var children: [Node]
public init(_ val: Int) {
self.val = val
self.children = []
}
}
class Solution {
func cloneTree(_ root: Node?) -> Node? {
guard let root = root else {
return nil
}
let nodeCopy = Node(root.val)
for child in root.children {
nodeCopy.children.append(cloneTree(child)!)
}
return nodeCopy
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM