from leetcode import test def reverse_words(s: str) -> str: words = [] for word in s.split(" "): reversed_word = "".join(ch for ch in reversed(word)) words.append(reversed_word) return " ".join(words) # noinspection SpellCheckingInspection test( reverse_words, [ ("Let's take LeetCode contest", "s'teL ekat edoCteeL tsetnoc"), ], )
result += 1 return mid = start + length // 2 merge(start, mid) merge(mid, end) buf = nums[start:end] i, j = 0, mid - start for k in range(start, end): lhs = buf[i] if i < length // 2 else float("inf") rhs = buf[j] if j < length else float("inf") if lhs <= rhs: nums[k] = lhs i += 1 else: nums[k] = rhs j += 1 result += length // 2 - i merge(0, len(nums)) return result test( reverse_pairs, [ ([7, 5, 6, 4], 5), ], )
from leetcode import TreeNode, test, new_tree def count_nodes(root: TreeNode) -> int: if root is None: return 0 queue, result = deque((root, )), 0 while True: length = len(queue) result += length if queue[0].left is None: return result for _ in range(length): node = queue.popleft() if node.left: queue.append(node.left) if node.right: queue.append(node.right) test( count_nodes, [ (new_tree(1, 2, 3, 4, 5, 6), 6), (None, 0), (new_tree(1), 1), ], )
return ord(ch) - ord("0") def int2char(ch: int): return chr(ch + ord("0")) result = [] carry = False for lc, rc in itertools.zip_longest(map(char2int, reversed(left)), map(char2int, reversed(right)), fillvalue=0): digit = lc + rc if carry: digit += 1 if digit > 9: carry = True digit -= 10 else: carry = False result.append(digit) if carry: result.append(1) return "".join(int2char(digit) for digit in reversed(result)) test( add_strings, [("0", "0", "0"), ("10", "90", "100"), ("9999", "2", "10001"), ("408", "5", "413")], )
for i, word in enumerate(words): for j in range(len(word) + 1): tmp1 = word[:j] tmp2 = word[j:] if ( tmp1[::-1] in word_dict and word_dict[tmp1[::-1]] != i and tmp2 == tmp2[::-1] ): res.append([i, word_dict[tmp1[::-1]]]) if ( j > 0 and tmp2[::-1] in word_dict and word_dict[tmp2[::-1]] != i and tmp1 == tmp1[::-1] ): res.append([word_dict[tmp2[::-1]], i]) return res # noinspection SpellCheckingInspection test( palindrome_pairs_1, [ (["abcd", "dcba", "lls", "s", "sssll"], [[0, 1], [1, 0], [3, 2], [2, 4]]), (["bat", "tab", "cat"], [[0, 1], [1, 0]]), ], map_func=lambda l: (l.sort(), l), )
from collections import defaultdict from heapq import heappush, heapreplace from typing import List, Tuple from leetcode import test, sorted_list def top_k_frequent(nums: List[int], k: int) -> List[int]: counter = defaultdict(lambda: 0) for num in nums: counter[num] += 1 heap: List[Tuple[int, int]] = [] for num, count in counter.items(): if len(heap) < k: heappush(heap, (count, num)) elif heap[0][0] < count: heapreplace(heap, (count, num)) return [t[1] for t in heap] test( top_k_frequent, [ ([1, 1, 1, 2, 2, 3], 2, [1, 2]), ([1], 1, [1]), ], map_func=sorted_list, )
result.append(list(stack)) elif current < target and i < n: for j in range(i, n): candidate = candidates[j] if candidate <= target - current: stack.append(candidate) backtrack(j, current + candidate) stack.pop() else: break backtrack(0, 0) return result def sll(li): for i in li: i.sort() li.sort() return li test( combination_sum, [ ([2, 3, 6, 7], 7, [[7], [2, 2, 3]]), ([2, 3, 5], 8, [[2, 2, 2, 2], [2, 3, 3], [3, 5]]), ], map_func=sll, )
from leetcode import test, sorted_list def combinations(k: int, n: int) -> List[List[int]]: result, stack = [], [] def backtrace(ki: int, ni: int, current: int) -> None: nonlocal result, stack if ni == 0 and ki == 0: result.append(list(stack)) if current > 9 or current > ni or ni > 45: return stack.append(current) backtrace(ki - 1, ni - current, current + 1) stack.pop() backtrace(ki, ni, current + 1) backtrace(k, n, 1) return result test( combinations, [ (3, 7, [[1, 2, 4]]), (3, 9, [[1, 2, 6], [1, 3, 5], [2, 3, 4]]), ], map_func=sorted_list, )
first_char = word[0] for i, row in enumerate(board): for j, char in enumerate(row): if char == first_char and dfs(i, j, word[1:]): return True return False # noinspection SpellCheckingInspection test( exist, [ ( [["A", "B", "C", "E"], ["S", "F", "C", "S"], ["A", "D", "E", "E"]], "ABCCED", True, ), ( [["A", "B", "C", "E"], ["S", "F", "C", "S"], ["A", "D", "E", "E"]], "SEE", True, ), ( [["A", "B", "C", "E"], ["S", "F", "C", "S"], ["A", "D", "E", "E"]], "ABCB", False, ), ], )
from typing import List from leetcode import test def reverse_string(s: List[str]) -> None: l = len(s) for i in range(l // 2): s[i], s[l - i - 1] = s[l - i - 1], s[i] test( reverse_string, [ (["h", "e", "l", "l", "o"], ["o", "l", "l", "e", "h"]), (["H", "a", "n", "n", "a", "h"], ["h", "a", "n", "n", "a", "H"]), (["a", "b"], ["b", "a"]), ], actual_func=lambda t, _: t[0], )
from leetcode import TreeNode, test, new_tree def min_depth(root: TreeNode) -> int: if not root: return 0 def inner(node: TreeNode) -> int: if node.left and node.right: return min(inner(node.left), inner(node.right)) + 1 if node.left: return inner(node.left) + 1 if node.right: return inner(node.right) + 1 return 1 return inner(root) test( min_depth, [ (new_tree(3, 9, 20, None, None, 15, 7), 2), (new_tree(1, 2), 2), ], )
from typing import List from leetcode import test def max_profit(prices: List[int]) -> int: rest, hold, sold = 0, float("-inf"), 0 for price in prices: old_sold = sold sold = hold + price hold = max(hold, rest - price) rest = max(rest, old_sold) return max(rest, sold) test( max_profit, [ ([1, 2, 3, 0, 2], 3), ], )
new_color: int) -> List[List[int]]: m, n = len(image), len(image[0]) origin_color = image[src_x][src_y] if origin_color == new_color: return image queue: Deque[Tuple[int, int]] = deque() queue.append((src_x, src_y)) while queue: x, y = queue.popleft() image[x][y] = new_color if x > 0 and image[x - 1][y] == origin_color: queue.append((x - 1, y)) if x < m - 1 and image[x + 1][y] == origin_color: queue.append((x + 1, y)) if y > 0 and image[x][y - 1] == origin_color: queue.append((x, y - 1)) if y < n - 1 and image[x][y + 1] == origin_color: queue.append((x, y + 1)) return image test( flood_fill, [ ([[1, 1, 1], [1, 1, 0], [1, 0, 1]], 1, 1, 2, [[2, 2, 2], [2, 2, 0], [2, 0, 1]]), ], )
from leetcode import TreeNode, test, new_tree def sum_of_left_leaves(root: TreeNode) -> int: def helper(node: TreeNode, is_left: bool) -> int: if node: if node.left or node.right: return helper(node.left, True) + helper(node.right, False) elif is_left: return node.val return 0 return helper(root, False) test( sum_of_left_leaves, [ (new_tree(3, 9, 20, None, None, 15, 7), 24), ], )
from typing import List from leetcode import test def diving_board(shorter: int, longer: int, k: int) -> List[int]: if k == 0: return [] if shorter == longer: return [shorter * k] diff = longer - shorter acc = shorter * k result = [acc] for _ in range(k): acc += diff result.append(acc) return result test( diving_board, [ (1, 2, 3, [3, 4, 5, 6]), (1, 1, 0, []), (1, 1, 2, [2]), ], )
from leetcode import TreeNode, test, new_tree def convert_bst(root: TreeNode) -> TreeNode: acc = 0 def reversed_inorder(node: TreeNode) -> None: nonlocal acc if node: reversed_inorder(node.right) acc = node.val = acc + node.val reversed_inorder(node.left) reversed_inorder(root) return root test( convert_bst, [ (new_tree(5, 2, 13), new_tree(18, 20, 13)), ], )
elif segment[0] == "2": return segment[1] < "5" or segment[ 1] == "5" and segment[2] < "6" else: return False def dfs(s: str, dots: int) -> None: nonlocal segments, results if dots: for idx in range(1, min(3, len(src) - dots) + 1): segment = s[:idx] if is_valid_segment(segment): segments.append(segment) dfs(s[idx:], dots - 1) segments.pop() else: if is_valid_segment(s): segments.append(s) results.append(".".join(segments)) segments.pop() dfs(src, 3) return results test( restore_ip_address, [("25525511135", ["255.255.11.135", "255.255.111.35"])], map_func=lambda l: (l.sort(), l), )
from typing import List from leetcode import TreeNode, new_tree, test def inorder_traversal(root: TreeNode) -> List[int]: stack, result = [], [] def push_node(node: TreeNode) -> None: while node: stack.append(node) node = node.left push_node(root) while stack: p = stack.pop() result.append(p.val) push_node(p.right) return result test( inorder_traversal, [ (new_tree(1, None, 2, 3), [1, 3, 2]), ], )
test( solve_sudoku, [ ( [ ["5", "3", ".", ".", "7", ".", ".", ".", "."], ["6", ".", ".", "1", "9", "5", ".", ".", "."], [".", "9", "8", ".", ".", ".", ".", "6", "."], ["8", ".", ".", ".", "6", ".", ".", ".", "3"], ["4", ".", ".", "8", ".", "3", ".", ".", "1"], ["7", ".", ".", ".", "2", ".", ".", ".", "6"], [".", "6", ".", ".", ".", ".", "2", "8", "."], [".", ".", ".", "4", "1", "9", ".", ".", "5"], [".", ".", ".", ".", "8", ".", ".", "7", "9"], ], [ ["5", "3", "4", "6", "7", "8", "9", "1", "2"], ["6", "7", "2", "1", "9", "5", "3", "4", "8"], ["1", "9", "8", "3", "4", "2", "5", "6", "7"], ["8", "5", "9", "7", "6", "1", "4", "2", "3"], ["4", "2", "6", "8", "5", "3", "7", "9", "1"], ["7", "1", "3", "9", "2", "4", "8", "5", "6"], ["9", "6", "1", "5", "3", "7", "2", "8", "4"], ["2", "8", "7", "4", "1", "9", "6", "3", "5"], ["3", "4", "5", "2", "8", "6", "1", "7", "9"], ], ), ], actual_func=lambda t, _: t[0], )
import bisect from typing import List from leetcode import test def min_subarray_len(nums: List[int], target: int) -> int: prefix_sums = [] result = float("Infinity") prefix_sum = 0 for i, num in enumerate(nums): prefix_sum += num prefix_sums.append(prefix_sum) diff = prefix_sum - target if diff >= 0: j = bisect.bisect_right(prefix_sums, diff) result = min(result, i - j + 1) return 0 if result == float("Infinity") else result test(min_subarray_len, [([2, 3, 1, 2, 4, 3], 7, 2), ([], 100, 0)])
from leetcode import test def is_valid(s: str) -> bool: stack = [] for ch in s: if ch in ("(", "[", "{"): stack.append(ch) elif not stack: return False elif (stack[-1], ch) in (("(", ")"), ("[", "]"), ("{", "}")): stack.pop() else: return False return not stack test( is_valid, [ ("", True), ("()", True), ("()[]{}", True), ("(]", False), ("([)]", False), ("{[()]}", True), ("]", False), ], )
nonlocal head if start > end: return None middle = (start + end) // 2 left = build_bst(start, middle - 1) root = TreeNode(head.val) root.left = left head = head.next root.right = build_bst(middle + 1, end) return root return build_bst(0, length - 1) def list_length(list_head: Optional[ListNode]) -> int: node, length = list_head, 0 while node: length += 1 node = node.next return length test( sorted_list_to_bst, [ (new_list(-10, 3, 0, 5, 9), None), (new_list(), None), ], equals_func=lambda root, _: is_valid_avl(root), )
if head is None or head.next is None or head.next.next is None: return head flag = True even_head = head.next odds = head evens = even_head ptr = even_head.next while ptr is not None: if flag: odds.next = ptr odds = ptr else: evens.next = ptr evens = ptr ptr = ptr.next flag = not flag odds.next = even_head evens.next = None return head test( odd_even_list, [ (new_list(1, 2, 3, 4, 5), new_list(1, 3, 5, 2, 4)), (new_list(2, 1, 3, 5, 6, 4, 7), new_list(2, 3, 6, 7, 1, 5, 4)), ], )
from typing import List from leetcode import test def find_length(a: List[int], b: List[int]) -> int: dp = [0] * (len(b) + 1) result = 0 for i in range(1, len(a) + 1): for j in range(len(b), 0, -1): if a[i - 1] == b[j - 1]: dp[j] = dp[j - 1] + 1 else: dp[j] = 0 result = max(result, dp[j]) return result test(find_length, [([1, 2, 3, 2, 1], [3, 2, 1, 4, 7], 3)])
self.queens.pop() self.columns[c] = False self.diagonals[self.diagonal(r, c)] = False self.rev_diagonals[self.rev_diagonal(r, c)] = False def add_result(self) -> None: result = [["."] * self.n for _ in range(self.n)] for r, c in self.queens: result[r][c] = "Q" self.results.append(["".join(row) for row in result]) # noinspection PyMethodMayBeStatic def diagonal(self, r: int, c: int) -> int: return r + c def rev_diagonal(self, r: int, c: int) -> int: if r >= c: return r - c else: return c - r + self.n - 1 test( solve_n_queens, [ (4, [[".Q..", "...Q", "Q...", "..Q."], ["..Q.", "Q...", "...Q", ".Q.."]]), ], map_func=sorted_list, )
from leetcode import TreeNode, test, new_tree def is_balanced(root: TreeNode) -> bool: if not root: return True if not (is_balanced(root.left) and is_balanced(root.right)): return False left_height = root.left.val if root.left else 0 right_height = root.right.val if root.right else 0 root.val = max(left_height, right_height) + 1 return -1 <= left_height - right_height <= 1 test( is_balanced, [ (new_tree(3, 9, 20, None, None, 15, 7), True), (new_tree(1, 2, 2, 3, 3, None, None, 4, 4), False), ], )
from leetcode import test def repeated_substring_pattern(s: str) -> bool: return len(s) >= 2 and s in (s * 2)[1:-1] # noinspection SpellCheckingInspection test( repeated_substring_pattern, [ ("abab", True), ("aba", False), ("abcabcabcabc", True), ], )
def zigzag_level_order(root: TreeNode) -> List[List[int]]: if not root: return [] level = [root] result = [] reverse = False while level: values = [node.val for node in level] if reverse: values.reverse() reverse = not reverse result.append(values) tmp = [] for node in level: if node.left: tmp.append(node.left) if node.right: tmp.append(node.right) level = tmp return result test( zigzag_level_order, [(new_tree(3, 9, 20, None, None, 15, 7), [[3], [20, 9], [15, 7]])], )
from leetcode import TreeNode, test, new_tree, inorder_traverse def insert_into_bst(root: TreeNode, val: int) -> TreeNode: node, prev, is_left = root, None, False while node: prev = node if val < node.val: node, is_left = node.left, True else: node, is_left = node.right, False new_node = TreeNode(val) if prev is None: return new_node if is_left: prev.left = new_node else: prev.right = new_node return root test( insert_into_bst, [(new_tree(4, 2, 7, 1, 3), 5, [1, 2, 3, 4, 5, 7]), (new_tree(), 1, [1])], equals_func=lambda actual, expect: inorder_traverse(actual) == expect, )
dp[0][0] = True for j in range(1, p_len + 1): dp[0][j] = p[j - 1] == "*" and dp[0][j - 1] for i in range(1, s_len + 1): for j in range(1, p_len + 1): if p[j - 1] == "?" or p[j - 1] == s[i - 1]: dp[i][j] = dp[i - 1][j - 1] elif p[j - 1] == "*" and (dp[i - 1][j] or dp[i][j - 1]): dp[i][j] = True return dp[s_len][p_len] # noinspection SpellCheckingInspection test( match, [ ("", "", True), ("", "a", False), ("", "*", True), ("a", "", False), ("aa", "a", False), ("aa", "*", True), ("cb", "?a", False), ("abceb", "*a*b", True), ("acdcb", "a*c?b", False), ("ho", "ho**", True), ], )