示例#1
0
from typing import NamedTuple


def check_balanced(root: BinaryTreeNode) -> bool:
    class Result(NamedTuple):
        is_balanced: bool
        height: int

    def helper(node: BinaryTreeNode, height: int) -> Result:
        if node is None:
            return Result(True, height)
        l: Result = helper(node.left, height + 1)
        r: Result = helper(node.right, height + 1)

        if not l.is_balanced or not r.is_balanced:
            return Result(False, max(l.height, r.height))

        if abs(l.height - r.height) > 1:
            return Result(False, max(l.height, r.height))

        return Result(True, max(l.height, r.height))

    return helper(root, 0).is_balanced


Solution(check_balanced, [
    Test([parse_tree('1(2(2,),3(1,))')], True, None),
    Test([parse_tree('1(2(2,3),3)')], True, None),
    Test([parse_tree('1(2(2,3(1,2)),3)')], False, None),
    Test([parse_tree('1(2(1(2,),),3(1(2,),))')], False, None),
])
示例#2
0
            cur = head
        else:
            cur.next = SinglyNode(data)
            cur = cur.next
        num = num // base

    return head


def sum_linked_list(a: SinglyNode, b: SinglyNode) -> SinglyNode:
    total = linked_list_to_num(a) + linked_list_to_num(b)
    return num_to_linked_list(total)


Solution(sum_linked_list, [
    Test([parse('1>2>3').head, parse('4>5>6').head],
         parse('5>7>9').head, None)
])


def add_lists(a: SinglyNode, b: SinglyNode, carry=0) -> SinglyNode:
    result = carry

    if a is None and b is None:
        if result != 0:
            return SinglyNode(carry)
        return None

    elif a is not None and b is not None:
        result += a.data + b.data

    elif a is not None:
示例#3
0
def create_bst(sorted_list: List[int]) -> BinaryTreeNode:
    def helper(start: int, end: int) -> BinaryTreeNode:
        if start > end:
            return None
        
        mid = (start + end)//2
        node = BinaryTreeNode(sorted_list[mid])
        node.left = helper(start, mid-1)
        node.right = helper(mid+1, end)
        return node
    
    return helper(0, len(sorted_list) - 1)




Solution(
    create_bst,
    [
        Test(
            [
                [1, 2, 3, 4, 5]
            ],
            parse_tree('3(1(,2),4(,5))'),
            None
        )

    ]

)
示例#4
0
from algo_problems.utils.linked_list import SinglyNode, parse
from algo_problems.utils.testing import Solution, Test


def delete_middle(node: SinglyNode):
    while node.next is not None:
        node.data = node.next.data

        if node.next.next is None:
            node.next = None
            break

        node = node.next


t1 = parse('1>2>3>4>5')
Solution(delete_middle, [Test([t1.k_th(2)], parse('1>2>4>5'), t1)])
示例#5
0
from algo_problems.utils.testing import Solution, Test


def is_unique_chars(string: str) -> bool:
    if len(string) > 128:
        return False

    seen_table = [False] * 128

    for l in string:
        index = ord(l)
        if seen_table[index]:
            return False
        else:
            seen_table[index] = True

    return True


Solution(is_unique_chars, [Test(['ab'], True), Test(['aba'], False)])
示例#6
0
    count_all_spaces = 0
    for c in char_list:
        if c == ' ':
            count_all_spaces += 1

    # Space is normally 1 character while %20 is 3
    # 2 additional characters per space
    count_spaces = count_all_spaces // 3
    offset = count_spaces * 2
    # Reverse for loop to take advantage of buffer at end
    # and not overwriting anything when moving
    for i in range((true_length - 1) - offset, 0, -1):
        c = char_list[i]
        if c != ' ':
            char_list[i + offset] = c
        else:
            char_list[i + offset] = '0'
            char_list[i + offset - 1] = '2'
            char_list[i + offset - 2] = '%'
            # For the buffer we have 'lost'
            offset -= 2
            if offset == 0:
                return char_list

    # For testing
    return char_list


Solution(urlify, [
    Test([list('Mr John Smith    '), 17], list('Mr%20John%20Smith')),
])
示例#7
0
from algo_problems.utils.testing import Test, Solution


def is_rotation(s1: str, s2: str) -> bool:
    if len(s1) != len(s2):
        return False

    xyxy = s1 + s1

    return (s2 in xyxy)


Solution(is_rotation, [
    Test(['waterbottle', 'erbottlewat'], True),
    Test(['waterbottles', 'ewatserbottle'], False)
])
示例#8
0
from algo_problems.utils.testing import Solution, Test

# NOTE: Can only use one additional stack


def sort_stack(s: list):
    temp_stack = []
    while len(s) != 0:
        temp = s.pop()
        while len(temp_stack) != 0 and temp_stack[-1] > temp:
            s.append(temp_stack.pop())
        temp_stack.append(temp)

    while len(temp_stack) != 0:
        s.append(temp_stack.pop())


s1 = [2, 3, 1, 5]
Solution(sort_stack, [Test([s1], [5, 3, 2, 1], s1)])
示例#9
0
from typing import List
from algo_problems.utils.testing import Test, Solution


def rotate(m: List[List[int]]) -> List[List[int]]:
    n = len(m)
    for layer in range(int(n / 2)):
        first = layer
        last = n - (1 + layer)

        for i in range(first, last):
            offset = i - first
            top = m[first][i]
            m[first][i] = m[last - offset][first]  # Left -> Top
            m[last - offset][first] = m[last][last - offset]  # Bottom -> Left
            m[last][last - offset] = m[i][last]  # Right -> Bottom
            m[i][last] = top  # Top -> Right

    return m


Solution(rotate, [
    Test([[[1, 2, 3], [4, 5, 6], [7, 8, 9]]], [
        [7, 4, 1],
        [8, 5, 2],
        [9, 6, 3],
    ])
])
示例#10
0
    return True

test_table =   [
        Test(
            [parse('1>2>3>5>3>2>1').head],
            True,
            None
        ),
                Test(
            [parse('1>2>3>3>2>1').head],
            True,
            None
        )
    ]
Solution(
    is_palindrome,
    test_table
)    

class Result:
    def __init__(self, node: SinglyNode = None, match: bool = False):
        self.node = node
        self.match = match


def is_palindrome_rec(head: SinglyNode) -> bool:
    mid = get_length(head)

    def helper(node: SinglyNode, length: int) -> Result:
        # node is None is the case when you are given an empty list
        if node is None or length <= 0:
            return Result(node, True)
示例#11
0
    return helper(v, w, {})


def has_path2(g: UndirectedGraph, v: int, w: int) -> bool:
    q = Queue()
    seen: Dict[i, bool] = {}

    q.enqueue(v)
    while not q.is_empty():
        u = q.dequeue()

        if u in seen:
            pass
        else:
            if u == w:
                return True
            for vertex in g.adj(u):
                q.enqueue(vertex)

    return False


g1 = build_simple_graph(7, [(1, 2), (2, 6), (2, 5), (4, 5), (3, 1), (3, 6)])
Solution(has_path,
         [Test([g1, 1, 3], False, None),
          Test([g1, 3, 5], True, None)])

Solution(has_path2,
         [Test([g1, 1, 3], False, None),
          Test([g1, 3, 5], True, None)])
示例#12
0
            return p1
        p2 = p2.next
        p1 = p1.next


def kth_last_rec(head: SinglyNode, k: int) -> Any:
    class IntWrapper:
        def __init__(self, val: int = 0):
            self.val = val

    def helper(helper_head: SinglyNode, k: int, w: IntWrapper) -> SinglyNode:
        if helper_head is None:
            return None

        node = helper(helper_head.next, k, w)
        w.val += 1

        if w.val == k:
            return helper_head

        return node

    return helper(head, k, IntWrapper(val=0))


Solution(kth_last_rec, [
    Test([parse('1>2>3>4').head, 2], SinglyNode(3)),
    Test([parse('1>2>3>4').head, 1], SinglyNode(4)),
    Test([parse('1').head, 1], SinglyNode(1))
])
示例#13
0
from algo_problems.utils.testing import Solution, Test


def check_permutation(a: str, b: str) -> bool:
    freq_table = [0] * 128
    if len(a) != len(b):
        return False

    for l in a:
        val = ord(l)
        freq_table[val] += 1

    for l in b:
        val = ord(l)
        freq_table[val] -= 1
        if freq_table[val] == -1:
            return False

    return True


Solution(check_permutation, [
    Test(['aba', 'ab'], False),
    Test(['same', 'mase'], True),
    Test(['diff', 'diph'], False)
])
示例#14
0
Solution(
    zero_matrix,
    [
        Test(
            [
                [
                    [1, 2, 3],
                    [1, 2, 0]
                ]

            ],
            [
                [1, 2, 0],
                [0, 0, 0]
            ]
        ),
        Test(
            [
                [
                    [0, 2, 3],
                    [1, 2, 0]
                ]

            ],
            [
                [0, 0, 0],
                [0, 0, 0]
            ]
        )
    ]
)
示例#15
0
    tail.next = None
    return head_to_linked_list(head)


# t1 = parse('3>5>8>5>10>2>1')
# Solution(
#     partition,
#     [
#         Test(
#             [t1.head, 5],
#             parse('3>2>1>5>10>5>8'),
#             t1
#         )
#     ]
# )

# t1 = parse('3>5>8>5>10>2>1')
# Solution(
#     partition2,
#     [
#         Test(
#             [t1.head, 5],
#             parse('1>2>3>10>5>8>5'),
#             t1
#         )
#     ]
# )

t1 = parse('3>5>8>5>10>2>1')
Solution(partition3, [Test([t1.head, 5], parse('1>2>3>5>8>5>10'), None)])
示例#16
0
    
    while True:
        if slow == fast:
            return True
        elif fast is None or fast.next is None:
            return False
        
        slow = slow.next
        fast = fast.next.next
    
# Circular list
x = SinglyNode(2)
x.next = SinglyNode(1)
x.next.next = SinglyNode(3)
x.next.next.next = x

Solution(
    is_circlular,
    [
        Test(
            [x],
            True,
            None
        ),
        Test(
            [parse('1>2>3>1>2>4').head],
            False,
            None
        )
    ]
)
示例#17
0
        while j < len(s):
            if s[i] == s[j]:
                count += 1
                j += 1
            else:
                new_s += s[i] + str(count)
                i = j
                break

        if j >= len(s):
            if j > len(s):
                return s

            new_s += s[i] + str(count)
            break

    if len(new_s) >= len(s):
        return s

    return new_s


Solution(compress_string, [
    Test(['aaabb'], 'a3b2'),
    Test(['aaabbba'], 'a3b3a1'),
    Test(['a'], 'a'),
    Test([''], ''),
    Test(['aba'], 'aba'),
    Test(['aaaaa'], 'a5'),
])
示例#18
0
        node = node.next

    return head


def remove_dups_no_buffer(head: SinglyNode) -> SinglyNode:
    current = head

    if head is None:
        return head

    while current is not None:
        runner = current

        while runner.next is not None:
            if runner.next.data == current.data:
                runner.next = runner.next.next
            else:
                runner = runner.next

        current = current.next
    return head


Solution(remove_dups_no_buffer, [
    Test([parse('1>1').head],
         parse('1').head),
    Test([parse('1>2>3>2').head],
         parse('1>2>3').head)
])