コード例 #1
0
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"),
    ],
)
コード例 #2
0
            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),
    ],
)
コード例 #3
0
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),
    ],
)
コード例 #4
0
ファイル: add_strings.py プロジェクト: CNife/leetcode
        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")],
)
コード例 #5
0
    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),
)
コード例 #6
0
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,
)
コード例 #7
0
ファイル: combination_sum.py プロジェクト: CNife/leetcode
            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,
)
コード例 #8
0
ファイル: combination_sum_3.py プロジェクト: CNife/leetcode
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,
)
コード例 #9
0
ファイル: word_search.py プロジェクト: CNife/leetcode
    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,
        ),
    ],
)
コード例 #10
0
ファイル: reverse_string.py プロジェクト: CNife/leetcode
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],
)
コード例 #11
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),
    ],
)
コード例 #12
0
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),
    ],
)
コード例 #13
0
               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]]),
    ],
)
コード例 #14
0
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),
    ],
)
コード例 #15
0
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]),
    ],
)
コード例 #16
0
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)),
    ],
)
コード例 #17
0
            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),
)
コード例 #18
0
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]),
    ],
)
コード例 #19
0
ファイル: sudoku_solver.py プロジェクト: CNife/leetcode
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],
)
コード例 #20
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)])
コード例 #21
0
ファイル: valid_parentheses.py プロジェクト: CNife/leetcode
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),
    ],
)
コード例 #22
0
        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),
)
コード例 #23
0
    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)),
    ],
)
コード例 #24
0
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)])
コード例 #25
0
ファイル: n_queens.py プロジェクト: CNife/leetcode
        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,
)
コード例 #26
0
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),
    ],
)
コード例 #27
0
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),
    ],
)
コード例 #28
0
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]])],
)
コード例 #29
0
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,
)
コード例 #30
0
    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),
    ],
)