fa
Feedback
Swift | LeetCode

Swift | LeetCode

رفتن به کانال در Telegram
1 365
مشترکین
اطلاعاتی وجود ندارد24 ساعت
-17 روز
-1330 روز

در حال بارگیری داده...

جذب مشترکین
ژوئن '26
ژوئن '26
+1
در 0 کانال‌ها
مه '26
+4
در 0 کانال‌ها
Get PRO
آوریل '26
+6
در 0 کانال‌ها
Get PRO
مارس '26
+4
در 0 کانال‌ها
Get PRO
فوریه '26
+9
در 0 کانال‌ها
Get PRO
ژانویه '26
+17
در 0 کانال‌ها
Get PRO
دسامبر '25
+12
در 0 کانال‌ها
Get PRO
نوامبر '25
+54
در 0 کانال‌ها
Get PRO
اکتبر '25
+30
در 0 کانال‌ها
Get PRO
سپتامبر '25
+32
در 0 کانال‌ها
Get PRO
اوت '25
+37
در 0 کانال‌ها
Get PRO
ژوئیه '25
+34
در 1 کانال‌ها
Get PRO
ژوئن '25
+30
در 0 کانال‌ها
Get PRO
مه '25
+33
در 0 کانال‌ها
Get PRO
آوریل '25
+68
در 0 کانال‌ها
Get PRO
مارس '25
+143
در 2 کانال‌ها
Get PRO
فوریه '25
+113
در 1 کانال‌ها
Get PRO
ژانویه '25
+113
در 53 کانال‌ها
Get PRO
دسامبر '24
+50
در 0 کانال‌ها
Get PRO
نوامبر '24
+55
در 0 کانال‌ها
Get PRO
اکتبر '24
+143
در 12 کانال‌ها
Get PRO
سپتامبر '24
+459
در 331 کانال‌ها
Get PRO
اوت '24
+87
در 0 کانال‌ها
Get PRO
ژوئیه '24
+325
در 219 کانال‌ها
Get PRO
ژوئن '24
+261
در 232 کانال‌ها
تاریخ
رشد مشترکین
اشارات
کانال‌ها
04 ژوئن0
03 ژوئن0
02 ژوئن+1
01 ژوئن0
پست‌های کانال
Задача: 1318. Minimum Flips to Make a OR b Equal to c Сложность: medium Даны три положительных числа a, b и c. Верните минимальное количество переворотов, необходимых в некоторых битах a и b, чтобы сделать (a OR b == c) (побитовая операция OR). Операция переворота состоит из изменения любого отдельного бита с 1 на 0 или с 0 на 1 в их двоичном представлении. Пример:
Input: a = 2, b = 6, c = 5
Output: 3
Explanation: After flips a = 1 , b = 4 , c = 5 such that (a OR b == c)
👨‍💻 Алгоритм: 1⃣Инициализируйте переменную answer как 0, которая будет использоваться для отслеживания минимального количества необходимых переворотов. 2⃣Итеративно обрабатывайте каждый бит двоичного представления чисел a, b и c одновременно: Если (c & 1) == 0, обновите answer как answer += (a & 1) + (b & 1). Если (c & 1) == 1, и если оба значения a & 1 и b & 1 равны 0, увеличьте answer на 1. 3⃣Сдвигайте все числа вправо с помощью a >>= 1, b >>= 1, c >>= 1. Если все числа равны 0, верните answer, в противном случае, повторите шаги 2 и 3. 😎 Решение
class Solution {
    func minFlips(_ a: Int, _ b: Int, _ c: Int) -> Int {
        var a = a, b = b, c = c
        var answer = 0
        while a != 0 || b != 0 || c != 0 {
            if (c & 1) == 1 {
                if (a & 1) == 0 && (b & 1) == 0 {
                    answer += 1
                }
            } else {
                answer += (a & 1) + (b & 1)
            }
            a >>= 1
            b >>= 1
            c >>= 1
        }
        return answer
    }
}
Ставь 👍 и забирай 📚 Базу знаний

2
Задача: 252. Meeting Rooms Сложность: easy Дан массив интервалов времени встреч, где intervals[i] = [starti, endi]. Определите, может ли человек посетить все встречи. Пример: Input: intervals = [[0,30],[5,10],[15,20]] Output: false 👨‍💻 Алгоритм: 1⃣Создайте функцию для проверки перекрытия двух интервалов: Возвращайте true, если начало одного интервала находится внутри другого интервала. 2⃣Проверьте каждый интервал с каждым другим интервалом: Если найдено перекрытие, верните false. 3⃣Если все интервалы проверены и перекрытий не найдено, верните true. 😎 Решение: class Solution { func overlap(_ interval1: [Int], _ interval2: [Int]) -> Bool { return (interval1[0] >= interval2[0] && interval1[0] < interval2[1]) || (interval2[0] >= interval1[0] && interval2[0] < interval1[1]) } func canAttendMeetings(_ intervals: [[Int]]) -> Bool { for i in 0..<intervals.count { for j in i + 1..<intervals.count { if overlap(intervals[i], intervals[j]) { return false } } } return true } } Ставь 👍 и забирай 📚 Базу знаний
77
3
Задача: 719. Find K-th Smallest Pair Distance Сложность: hard Расстояние между парой целых чисел a и b определяется как абсолютная разность между a и b. Учитывая целочисленный массив nums и целое число k, верните k-е наименьшее расстояние среди всех пар nums[i] и nums[j], где 0 <= i < j < nums.length. Пример: Input: nums = [1,3,1], k = 1 Output: 0 👨‍💻 Алгоритм: 1⃣Отсортируйте массив nums. 2⃣Определите минимальное и максимальное возможные расстояния. 3⃣Используйте бинарный поиск, чтобы найти k-е наименьшее расстояние, проверяя количество пар с расстоянием меньше или равно текущему среднему значению. 😎 Решение: func smallestDistancePair(_ nums: [Int], _ k: Int) -> Int { let nums = nums.sorted() func countPairs(_ mid: Int) -> Int { var count = 0, j = 0 for i in 0..<nums.count { while j < nums.count && nums[j] - nums[i] <= mid { j += 1 } count += j - i - 1 } return count } var left = 0, right = nums.last! - nums.first! while left < right { let mid = (left + right) / 2 if countPairs(mid) < k { left = mid + 1 } else { right = mid } } return left } Ставь 👍 и забирай 📚 Базу знаний
94
4
Задача: 1182. Shortest Distance to Target Color Сложность: medium Дан массив colors, содержащий три цвета: 1, 2 и 3. Также даны несколько запросов. Каждый запрос состоит из двух целых чисел i и c. Верните наименьшее расстояние между заданным индексом i и целевым цветом c. Если решения нет, верните -1. Пример: Input: colors = [1,1,2,1,3,2,2,3,3], queries = [[1,3],[2,2],[6,1]] Output: [3,0,3] Explanation: The nearest 3 from index 1 is at index 4 (3 steps away). The nearest 2 from index 2 is at index 2 itself (0 steps away). The nearest 1 from index 6 is at index 3 (3 steps away). 👨‍💻 Алгоритм: 1⃣Инициализируйте хэш-таблицу для отображения каждого цвета в список индексов. Итерируйте по массиву colors и добавляйте каждый индекс в соответствующий список хэш-таблицы. 2⃣Для каждого запроса, содержащего i и c, если c не является одним из ключей в хэш-таблице, то colors не содержит c, поэтому верните -1. Иначе, найдите позицию i в соответствующем списке индексов indexList для поддержания упорядоченного порядка. 3⃣Если i меньше всех элементов в indexList, то i - indexList[0] является кратчайшим расстоянием. Если i больше всех элементов в indexList, то indexList[indexList.size() - 1] - i является кратчайшим расстоянием. Иначе, ближайшее появление c к i либо на индексе вставки, либо перед ним, поэтому рассчитайте расстояние от i до каждого из них и верните наименьшее. 😎 Решение class Solution { func shortestDistanceColor(_ colors: [Int], _ queries: [[Int]]) -> [Int] { var queryResults = [Int]() var hashmap = [Int: [Int]]() for i in 0..<colors.count { hashmap[colors[i], default: [Int]()].append(i) } for query in queries { let target = query[0] let color = query[1] guard let indexList = hashmap[color] else { queryResults.append(-1) continue } let insert = indexList.binarySearch(target) if insert < 0 { let insertPos = -(insert + 1) if insertPos == 0 { queryResults.append(indexList[insertPos] - target) } else if insertPos == indexList.count { queryResults.append(target - indexList[insertPos - 1]) } else { let leftNearest = target - indexList[insertPos - 1] let rightNearest = indexList[insertPos] - target queryResults.append(min(leftNearest, rightNearest)) } } else { queryResults.append(0) } } return queryResults } } extension Array where Element: Comparable { func binarySearch(_ value: Element) -> Int { var left = 0 var right = self.count - 1 while left <= right { let mid = (left + right) / 2 if self[mid] == value { return mid } else if self[mid] < value { left = mid + 1 } else { right = mid - 1 } } return -(left + 1) } } Ставь 👍 и забирай 📚 Базу знаний
88
5
Главный навык на ближайшие годы — ВАЙБ-КОДИНГ ИИ уже пишет код, чинит баги, генерирует тесты, документацию и помогает запуска
Главный навык на ближайшие годы — ВАЙБ-КОДИНГ ИИ уже пишет код, чинит баги, генерирует тесты, документацию и помогает запускать продукты быстрее, чем это делали классические команды разработки. И это уже не "будущее когда-нибудь", а реальность, которая меняет рынок уже сегодня И те, кто научится вайбкодить сейчас, будут увереннее конкурировать на рынке и зарабатывать больше тех, кто по-прежнему делает всё вручную. Стартовать с нуля поможет канал Вайб-кодинг. Там ребята круглосуточно мониторят более 320 российских и зарубежных источников и публикуют только главное: релизы, инструменты, гайды, курсы и практические кейсы. Подписывайтесь, нас уже 30 тысяч: @vibecoding_tg
0
6
Задача: 968. Binary Tree Cameras Сложность: hard Вам дан корень бинарного дерева. Мы устанавливаем камеры на узлы дерева, где каждая камера на узле может наблюдать за своим родителем, собой и своими непосредственными детьми. Верните минимальное количество камер, необходимых для наблюдения за всеми узлами дерева. Пример: Input: root = [0,0,null,0,null,0,null,null,0] Output: 2 Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement. 👨‍💻 Алгоритм: 1⃣Рекурсивное решение (solve): Для каждого узла определите три состояния: - [State 0] Строгое поддерево: все узлы ниже этого узла покрыты, но не сам узел. - [State 1] Нормальное поддерево: все узлы ниже и включая этот узел покрыты, но на этом узле нет камеры. - [State 2] Установленная камера: все узлы ниже и включая этот узел покрыты, и на этом узле установлена камера. Рассчитайте эти состояния для левого и правого поддеревьев. 2⃣Рассчёт состояний: Чтобы покрыть строгое поддерево, дети этого узла должны находиться в состоянии 1. Чтобы покрыть нормальное поддерево без установки камеры на этом узле, дети этого узла должны находиться в состояниях 1 или 2, и по крайней мере один из этих детей должен быть в состоянии 2. Чтобы покрыть поддерево при установке камеры на этом узле, дети могут находиться в любом состоянии. 3⃣Минимальное количество камер: Запустите функцию solve на корневом узле и верните минимальное значение между состояниями 1 и 2. 😎 Решение: class Solution { func minCameraCover(_ root: TreeNode?) -> Int { let ans = solve(root) return min(ans[1], ans[2]) } func solve(_ node: TreeNode?) -> [Int] { if node == nil { return [0, 0, 99999] } let L = solve(node?.left) let R = solve(node?.right) let mL12 = min(L[1], L[2]) let mR12 = min(R[1], R[2]) let d0 = L[1] + R[1] let d1 = min(L[2] + mR12, R[2] + mL12) let d2 = 1 + min(L[0], mL12) + min(R[0], mR12) return [d0, d1, d2] } } Ставь 👍 и забирай 📚 Базу знаний
0
7
Задача: 1134. Armstrong Number Сложность: easy Дано целое число n, верните true, если и только если оно является числом Армстронга. k-значное число n является числом Армстронга, если сумма k-й степени каждой его цифры равна n. Пример: Input: n = 153 Output: true Explanation: 153 is a 3-digit number, and 153 = 1^3 + 5^3 + 3^3. 👨‍💻 Алгоритм: 1⃣Получите количество цифр в n, преобразовав его в строку и найдя длину. 2⃣Создайте функцию getSumOfKthPowerOfDigits(n, k), которая возвращает сумму k-й степени каждой цифры числа n. Инициализируйте переменную result для хранения результата. Пока n не равно 0, добавляйте k-ю степень последней цифры n к result и удаляйте последнюю цифру. 3⃣Верните true, если результат равен исходному числу n. 😎 Решение: class Solution { func getSumOfKthPowerOfDigits(_ n: Int, _ k: Int) -> Int { var result = 0 var number = n while number != 0 { let digit = number % 10 result += Int(pow(Double(digit), Double(k))) number /= 10 } return result } func isArmstrong(_ n: Int) -> Bool { let length = String(n).count return getSumOfKthPowerOfDigits(n, length) == n } } Ставь 👍 и забирай 📚 Базу знаний
0
8
Задача: 1056. Confusing Number Сложность: easy Запутанное число - это число, которое при повороте на 180 градусов становится другим числом, каждая цифра которого действительна. Мы можем повернуть цифры числа на 180 градусов, чтобы получить новые цифры. Когда 0, 1, 6, 8 и 9 поворачиваются на 180 градусов, они становятся 0, 1, 9, 8 и 6 соответственно. При повороте на 180 градусов 2, 3, 4, 5 и 7 становятся недействительными. Обратите внимание, что после поворота числа мы можем игнорировать ведущие нули. Например, после поворота 8000 мы получим 0008, которое считается просто 8. Если задано целое число n, верните true, если это запутанное число, или false в противном случае. Пример: Input: n = 6 Output: true 👨‍💻 Алгоритм: 1⃣Преобразуй число в строку для удобства работы с его цифрами. Используй словарь для хранения соответствий цифр при повороте на 180 градусов. 2⃣Пройди по цифрам числа, проверяя, что все цифры действительны и заменяя их на соответствующие при повороте. 3⃣Проверь, что перевернутая строка отличается от исходной. 😎 Решение: func isConfusingNumber(_ n: Int) -> Bool { let rotationMap: [Character: Character] = ["0": "0", "1": "1", "6": "9", "8": "8", "9": "6"] let nStr = String(n) var rotatedStr = "" for char in nStr { guard let rotatedChar = rotationMap[char] else { return false } rotatedStr = String(rotatedChar) + rotatedStr } return rotatedStr != nStr } Ставь 👍 и забирай 📚 Базу знаний
0
9
Задача: 290. Word Pattern Сложность: easy Дан шаблон и строка s, необходимо определить, следует ли строка s этому шаблону. Здесь "следует" означает полное соответствие, такое что существует биекция между буквой в шаблоне и непустым словом в строке s. Пример: Input: pattern = "abba", s = "dog cat cat dog" Output: true 👨‍💻 Алгоритм: 1⃣Разделение строки на слова: Разделите строку s на отдельные слова. Если количество слов не равно длине шаблона, возвращаем false. 2⃣Создание отображений: Создайте два словаря: один для отображения букв шаблона на слова, другой для слов на буквы шаблона. 3⃣Проверка биекции: Пройдите по каждому символу шаблона и соответствующему слову. Если символ уже в словаре и не соответствует текущему слову или слово уже в словаре и не соответствует текущему символу, возвращаем false. Иначе добавляем символ и слово в словари и продолжаем проверку. Если все проверки пройдены, возвращаем true. 😎 Решение: class Solution { func wordPattern(_ pattern: String, _ s: String) -> Bool { var mapChar = [Character: String]() var mapWord = [String: Character]() let words = s.split(separator: " ") if words.count != pattern.count { return false } for (i, word) in words.enumerated() { let c = pattern[pattern.index(pattern.startIndex, offsetBy: i)] let w = String(word) if mapChar[c] == nil { if mapWord[w] != nil { return false } else { mapChar[c] = w mapWord[w] = c } } else { if mapChar[c] != w { return false } } } return true } } Ставь 👍 и забирай 📚 Базу знаний
0
10
Задача: 940. Distinct Subsequences II Сложность: hard Поскольку ответ может быть очень большим, верните его по модулю 10^9 + 7. Подпоследовательность строки - это новая строка, которая образуется из исходной строки путем удаления некоторых (можно ни одного) символов без нарушения взаимного расположения оставшихся символов. (Например, "ace" является подпоследовательностью "abcde", а "aec" - нет. Пример: Input: s = "abc" Output: 7 👨‍💻 Алгоритм: 1⃣Определить матрицу DP, где dp[i][j] будет хранить количество подпоследовательностей строки s с длиной i, оканчивающихся символом j. 2⃣Инициализировать матрицу DP нулями. Пройти по каждому символу строки: Если символ еще не был встречен, все подпоследовательности до текущего символа + текущий символ. Если символ уже был встречен, учет всех подпоследовательностей, включающих текущий символ, с учетом предыдущих вхождений. 3⃣Вернуть сумму всех значений в DP по модулю 10^9 + 7. 😎 Решение: class Solution { func countSubsequences(_ s: String) -> Int { let MOD = 1000000007 var dp = [Int](repeating: 0, count: 26) for c in s { let index = Int(c.asciiValue! - Character("a").asciiValue!) dp[index] = (dp.reduce(0, +) + 1) % MOD } return dp.reduce(0, +) % MOD } } Ставь 👍 и забирай 📚 Базу знаний
0
11
Задача: 73. Set Matrix Zeroes Сложность: medium Дана матрица размером m×n, состоящая из целых чисел. Если элемент матрицы равен 0, установите в 0 все элементы его строки и столбца. Необходимо выполнить это действие на месте, не используя дополнительное пространство для другой матрицы. Пример: Input: matrix = [[1,1,1],[1,0,1],[1,1,1]] Output: [[1,0,1],[0,0,0],[1,0,1]] 👨‍💻 Алгоритм: 1⃣Мы перебираем матрицу и отмечаем первую ячейку строки i и первую ячейку столбца j, если условие в приведенном выше псевдокоде выполняется, т.е. если cell[i][j] == 0. 2⃣Первая ячейка строки и столбца для первой строки и первого столбца совпадают, т.е. cell[0][0]. Поэтому мы используем дополнительную переменную, чтобы узнать, был ли отмечен первый столбец, а cell[0][0] используется для того же для первой строки. 3⃣Теперь мы перебираем исходную матрицу, начиная со второй строки и второго столбца, т.е. с matrix[1][1]. Для каждой ячейки мы проверяем, были ли ранее отмечены строка r или столбец c, проверяя соответствующую первую ячейку строки или первую ячейку столбца. Если любая из них была отмечена, мы устанавливаем значение в ячейке на 0. Обратите внимание, что первая строка и первый столбец служат как row_set и column_set, которые мы использовали в первом подходе. Затем мы проверяем, равна ли cell[0][0] нулю, если это так, мы отмечаем первую строку как ноль. И, наконец, если первый столбец был отмечен, мы делаем все записи в нем нулевыми. 😎 Решение: func setZeroes(_ matrix: inout [[Int]]) { var isCol = false let R = matrix.count let C = matrix[0].count for i in 0..<R { if matrix[i][0] == 0 { isCol = true } for j in 1..<C { if matrix[i][j] == 0 { matrix[0][j] = 0 matrix[i][0] = 0 } } } for i in 1..<R { for j in 1..<C { if matrix[i][0] == 0 || matrix[0][j] == 0 { matrix[i][j] = 0 } } } if matrix[0][0] == 0 { for j in 0..<C { matrix[0][j] = 0 } } if isCol { for i in 0..<R { matrix[i][0] = 0 } } } Ставь 👍 и забирай 📚 Базу знаний
0
12
Задача: 294. Flip Game II Сложность: medium Вы играете в игру Flip со своим другом. Вам дана строка currentState, которая содержит только символы '+' и '-'. Вы и ваш друг по очереди переворачиваете две последовательные "++" в "--". Игра заканчивается, когда игрок больше не может сделать ход, и, следовательно, другой игрок становится победителем. Верните true, если начальный игрок может гарантировать победу, и false в противном случае. Пример: Input: currentState = "++++" Output: true Explanation: The starting player can guarantee a win by flipping the middle "++" to become "+--+". 👨‍💻 Алгоритм: 1⃣Генерация всех возможных следующих ходов: Для текущего состояния currentState, создайте все возможные новые состояния, заменяя каждую пару "++" на "--". 2⃣Рекурсивная проверка выигрыша: Для каждого нового состояния вызовите функцию рекурсивно, чтобы проверить, может ли противник проиграть в этом новом состоянии. Если противник не может сделать ход, верните true, так как начальный игрок гарантирует победу. 3⃣Проверка всех возможных ходов: Если для всех возможных ходов начальный игрок не может гарантировать победу, верните false. Иначе, если есть хотя бы один ход, при котором противник проигрывает, верните true. 😎 Решение: class Solution { func canWin(_ currentState: String) -> Bool { var stateArray = Array(currentState) for i in 0..<(stateArray.count - 1) { if stateArray[i] == "+" && stateArray[i + 1] == "+" { stateArray[i] = "-" stateArray[i + 1] = "-" let newState = String(stateArray) if !canWin(newState) { stateArray[i] = "+" stateArray[i + 1] = "+" return true } stateArray[i] = "+" stateArray[i + 1] = "+" } } return false } } Ставь 👍 и забирай 📚 Базу знаний
0
13
Задача: 1357. Apply Discount Every n Orders Сложность: medium В супермаркете, который посещает множество покупателей, товары представлены двумя параллельными массивами целых чисел products и prices, где i-й товар имеет идентификатор products[i] и цену prices[i]. Когда покупатель оплачивает товар, его счет представлен двумя параллельными массивами целых чисел product и amount, где j-й приобретенный товар имеет идентификатор product[j], а amount[j] - количество купленного товара. Их промежуточный итог рассчитывается как сумма каждого amount[j] * (цена j-го товара). Супермаркет решил провести распродажу. Каждому n-му покупателю, оплачивающему свои покупки, будет предоставлена скидка в процентах. Сумма скидки задается параметром discount, и покупатель получит скидку в discount процентов от своего промежуточного итога. Формально, если их промежуточный итог составляет bill, то они фактически заплатят bill * ((100 - discount) / 100). Реализуйте класс Cashier: Cashier(int n, int discount, int[] products, int[] prices): инициализирует объект с параметрами n, discount, а также массивами товаров и их цен. double getBill(int[] product, int[] amount): возвращает итоговую сумму счета с примененной скидкой (если применима). Ответы, отличающиеся от фактического значения не более чем на 10^-5, будут приняты. Пример: Input ["Cashier","getBill","getBill","getBill","getBill","getBill","getBill","getBill"] [[3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]],[[1,2],[1,2]],[[3,7],[10,10]],[[1,2,3,4,5,6,7],[1,1,1,1,1,1,1]],[[4],[10]],[[7,3],[10,10]],[[7,5,3,1,6,4,2],[10,10,10,9,9,9,7]],[[2,3,5],[5,3,2]]] Output [null,500.0,4000.0,800.0,4000.0,4000.0,7350.0,2500.0] 👨‍💻 Алгоритм: 1⃣Инициализация объекта: Создайте класс Cashier с конструктором, который принимает параметры n, discount, products и prices. В конструкторе инициализируйте необходимые переменные и создайте словарь для сопоставления идентификаторов продуктов с их ценами. 2⃣Обработка каждого счета: Создайте метод getBill, который принимает массивы product и amount. Вычислите промежуточный итог счета, умножая количество каждого продукта на его цену и суммируя результаты. Увеличьте счетчик клиентов. Если клиент является n-м по счету, примените скидку к промежуточному итогу. 3⃣Верните итоговую сумму счета. 😎 Решение: class Cashier { private let n: Int private let discount: Int private var productsPrices: [Int: Int] private var customerCount: Int init(_ n: Int, _ discount: Int, _ products: [Int], _ prices: [Int]) { self.n = n self.discount = discount self.customerCount = 0 self.productsPrices = Dictionary(uniqueKeysWithValues: zip(products, prices)) } func getBill(_ product: [Int], _ amount: [Int]) -> Double { customerCount += 1 var bill = 0.0 for (index, prod) in product.enumerated() { bill += Double(productsPrices[prod]! * amount[index]) } if customerCount % n == 0 { bill *= Double(100 - discount) / 100.0 } return bill } } Ставь 👍 и забирай 📚 Базу знаний
0
14
Задача: 128. Longest Consecutive Sequence Сложность: Medium Дан несортированный массив целых чисел nums. Верните длину самой длинной последовательности последовательных элементов. Необходимо написать алгоритм, который работает за время O(n). Пример: Input: nums = [100,4,200,1,3,2] Output: 4 Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. 👨‍💻 Алгоритм: 1⃣Проверка базового случая: Перед началом работы проверяем базовый случай с пустым массивом. Самая длинная последовательность в пустом массиве, очевидно, равна 0, поэтому мы можем просто вернуть это значение. 2⃣Обработка чисел в массиве: Для всех других случаев мы сортируем массив nums и рассматриваем каждое число, начиная со второго (поскольку нам нужно сравнивать каждое число с предыдущим). Если текущее число и предыдущее равны, то текущая последовательность не удлиняется и не прерывается, поэтому мы просто переходим к следующему числу. Если числа не равны, то нужно проверить, удлиняет ли текущее число последовательность (т.е. nums[i] == nums[i-1] + 1). Если удлиняет, то мы увеличиваем наш текущий счёт и продолжаем. 3⃣Завершение обработки и возврат результата: В противном случае последовательность прерывается, и мы записываем нашу текущую последовательность и сбрасываем её до 1 (чтобы включить число, которое прервало последовательность). Возможно, что последний элемент массива nums является частью самой длинной последовательности, поэтому мы возвращаем максимум из текущей последовательности и самой длинной. 😎 Решение: func longestConsecutive(_ nums: [Int]) -> Int { var longestStreak = 0 let numSet = Set(nums) for num in numSet { if !numSet.contains(num - 1) { var currentNum = num var currentStreak = 1 while numSet.contains(currentNum + 1) { currentNum += 1 currentStreak += 1 } longestStreak = max(longestStreak, currentStreak) } } return longestStreak } Ставь 👍 и забирай 📚 Базу знаний
0
15
Задача: 684. Redundant Connection Сложность: medium В этой задаче дерево — это неориентированный граф, который является связным и не содержит циклов. Вам дан граф, который изначально был деревом с n узлами, пронумерованными от 1 до n, и к которому добавили одно дополнительное ребро. Добавленное ребро соединяет две разные вершины, выбранные из 1 до n, и это ребро не существовало ранее. Граф представлен массивом edges длины n, где edges[i] = [ai, bi] указывает на то, что существует ребро между узлами ai и bi в графе. Верните ребро, которое можно удалить, чтобы результирующий граф стал деревом из n узлов. Если существует несколько ответов, верните тот, который встречается последним в исходных данных. Пример: Input: edges = [[1,2],[1,3],[2,3]] Output: [2,3] 👨‍💻 Алгоритм: 1⃣Для каждого ребра (u, v) создайте представление графа с использованием списка смежности. Это позволит легко выполнять обход в глубину (DFS) для проверки соединений между узлами. 2⃣Выполняйте обход в глубину для каждого ребра, временно удаляя его из графа. Проверьте, можно ли соединить узлы u и v с помощью обхода в глубину. Если узлы остаются соединенными, значит, это ребро является дублирующимся. 3⃣Верните дублирующееся ребро, которое встречается последним в исходных данных. Это обеспечит корректность решения, даже если существует несколько ответов. 😎 Решение: class Solution { var seen = Set<Int>() let MAX_EDGE_VAL = 1000 func findRedundantConnection(_ edges: [[Int]]) -> [Int] { var graph = Array(repeating: [Int](), count: MAX_EDGE_VAL + 1) for edge in edges { seen.removeAll() if !graph[edge[0]].isEmpty && !graph[edge[1]].isEmpty && dfs(graph, edge[0], edge[1]) { return edge } graph[edge[0]].append(edge[1]) graph[edge[1]].append(edge[0]) } return [] } func dfs(_ graph: [[Int]], _ source: Int, _ target: Int) -> Bool { if !seen.contains(source) { seen.insert(source) if source == target { return true } for nei in graph[source] { if dfs(graph, nei, target) { return true } } } return false } } Ставь 👍 и забирай 📚 Базу знаний
0
16
Задача: 263. Ugly Number Сложность: easy Уродливое число — это положительное целое число, простые множители которого ограничены числами 2, 3 и 5. Дано целое число n, верните true, если n является уродливым числом. Пример: Input: n = 6 Output: true Explanation: 6 = 2 × 3 👨‍💻 Алгоритм: 1⃣Если данное целое число n неположительное, верните false, так как неположительное число не может быть уродливым. 2⃣Определите функцию keepDividingWhenDivisible, которая принимает два аргумента: делимое и делитель. Эта функция будет делить делимое на делитель до тех пор, пока оно делится без остатка. Функция возвращает измененное делимое. Последовательно примените эту функцию к n с делителями 2, 3 и 5. 3⃣Если после всех делений n равно 1, верните true, иначе верните false. 😎 Решение: class Solution { func isUgly(_ n: Int) -> Bool { if n <= 0 { return false } var n = n for factor in [2, 3, 5] { n = keepDividingWhenDivisible(n, factor) } return n == 1 } private func keepDividingWhenDivisible(_ dividend: Int, _ divisor: Int) -> Int { var dividend = dividend while dividend % divisor == 0 { dividend /= divisor } return dividend } } Ставь 👍 и забирай 📚 Базу знаний
0
17
Задача: 931. Minimum Falling Path Sum Сложность: medium Если задан массив целых чисел n x n, верните минимальную сумму любого падающего пути через матрицу. Падающий путь начинается с любого элемента в первой строке и выбирает элемент в следующей строке, который находится либо прямо под ним, либо по диагонали слева/справа. В частности, следующим элементом из позиции (row, col) будет (row + 1, col - 1), (row + 1, col) или (row + 1, col + 1). Пример: Input: matrix = [[2,1,3],[6,5,4],[7,8,9]] Output: 13 👨‍💻 Алгоритм: 1⃣Использовать динамическое программирование для хранения минимальных сумм падающих путей для каждой позиции. 2⃣Инициализировать dp массив копией первой строки исходной матрицы. Пройти по каждой строке, обновляя dp массив на основе значений из предыдущей строки. 3⃣Вернуть минимальное значение в последней строке dp массива. 😎 Решение: class Solution { func minFallingPathSum(_ matrix: [[Int]]) -> Int { let n = matrix.count var dp = matrix[0] for i in 1..<n { var newDp = [Int](repeating: 0, count: n) for j in 0..<n { newDp[j] = matrix[i][j] + min(dp[j], dp[j-1] ?? Int.max, dp[j+1] ?? Int.max) } dp = newDp } return dp.min()! } } Ставь 👍 и забирай 📚 Базу знаний
0
18
Задача: 844. Backspace String Compare Сложность: easy Даны две строки s и t, верните true, если они равны после ввода в пустые текстовые редакторы. Символ '#' означает клавишу backspace. Обратите внимание, что после нажатия backspace на пустом тексте, текст останется пустым. Пример: Input: s = "ab#c", t = "ad#c" Output: true Explanation: Both s and t become "ac". 👨‍💻 Алгоритм: 1⃣Пройдите по строкам s и t с конца, учитывая символы '#' как backspace и пропуская соответствующие символы. 2⃣Сравнивайте текущие символы из обеих строк, пропуская символы, которые должны быть удалены. 3⃣Если все соответствующие символы совпадают и строки эквивалентны после всех backspace операций, верните true; в противном случае верните false. 😎 Решение: class Solution { func backspaceCompare(_ S: String, _ T: String) -> Bool { var i = S.count - 1, j = T.count - 1 var skipS = 0, skipT = 0 let sArray = Array(S), tArray = Array(T) while i >= 0 || j >= 0 { while i >= 0 { if sArray[i] == "#" { skipS += 1 i -= 1 } else if skipS > 0 { skipS -= 1 i -= 1 } else { break } } while j >= 0 { if tArray[j] == "#" { skipT += 1 j -= 1 } else if skipT > 0 { skipT -= 1 j -= 1 } else { break } } if i >= 0 && j >= 0 && sArray[i] != tArray[j] { return false } if (i >= 0) != (j >= 0) { return false } i -= 1 j -= 1 } return true } } Ставь 👍 и забирай 📚 Базу знаний
0
19
Задача: 438. Find All Anagrams in a String Сложность: medium Даны две строки s и p, вернуть массив всех начальных индексов анаграмм строки p в строке s. Ответ можно вернуть в любом порядке. Анаграмма - это слово или фраза, образованные перестановкой букв другого слова или фразы, обычно с использованием всех исходных букв ровно один раз. Пример: Input: s = "cbaebabacd", p = "abc" Output: [0,6] Explanation: The substring with start index = 0 is "cba", which is an anagram of "abc". The substring with start index = 6 is "bac", which is an anagram of "abc". 👨‍💻 Алгоритм: 1⃣Построить эталонный счетчик pCount для строки p. 2⃣Передвигать скользящее окно по строке s: Пересчитывать счетчик скользящего окна sCount на каждом шаге, добавляя одну букву справа и удаляя одну букву слева. 3⃣Если sCount == pCount, обновить выходной список. Вернуть выходной список. 😎 Решение: class Solution { func findAnagrams(_ s: String, _ p: String) -> [Int] { let ns = s.count, np = p.count if ns < np { return [] } var pCount = [Character: Int]() var sCount = [Character: Int]() for ch in p { pCount[ch, default: 0] += 1 } var output = [Int]() let sArray = Array(s) for i in 0..<ns { let ch = sArray[i] sCount[ch, default: 0] += 1 if i >= np { let leftChar = sArray[i - np] if sCount[leftChar] == 1 { sCount.removeValue(forKey: leftChar) } else { sCount[leftChar]! -= 1 } } if pCount == sCount { output.append(i - np + 1) } } return output } } Ставь 👍 и забирай 📚 Базу знаний
0
20
Задача: 677. Map Sum Pairs Сложность: medium Создайте карту, которая позволяет выполнять следующие действия: Отображает строковый ключ на заданное значение. Возвращает сумму значений, у которых ключ имеет префикс, равный заданной строке. Реализуйте класс MapSum: MapSum() Инициализирует объект MapSum. void insert(String key, int val) Вставляет пару ключ-значение в карту. Если ключ уже существовал, исходная пара ключ-значение будет заменена на новую. int sum(string prefix) Возвращает сумму всех значений пар, у которых ключ начинается с данного префикса. Пример: Input ["MapSum", "insert", "sum", "insert", "sum"] [[], ["apple", 3], ["ap"], ["app", 2], ["ap"]] Output [null, null, 3, null, 5] Explanation MapSum mapSum = new MapSum(); mapSum.insert("apple", 3); mapSum.sum("ap"); // return 3 (apple = 3) mapSum.insert("app", 2); mapSum.sum("ap"); // return 5 (apple + app = 3 + 2 = 5) 👨‍💻 Алгоритм: 1⃣Для каждого ключа в карте проверить, начинается ли этот ключ с данного префикса. 2⃣Если ключ начинается с префикса, добавить его значение к ответу. 3⃣Вернуть полученную сумму как результат. 😎 Решение: class MapSum { private var mapData: [String: Int] init() { self.mapData = [:] } func insert(_ key: String, _ val: Int) { mapData[key] = val } func sum(_ prefix: String) -> Int { var ans = 0 for (key, val) in mapData { if key.hasPrefix(prefix) { ans += val } } return ans } } Ставь 👍 и забирай 📚 Базу знаний
0