コード例 #1
0
def sum_lists_reverse(a: LinkedListNode, b: LinkedListNode) -> LinkedListNode:
    """Add two integers stored as a linked list.

    Each digit of the integer is a node, and the 1's place is the head node.

    Runtime: O(n)
    Memory: O(1)
    """
    carry = 0
    head = curr = None
    while a is not None or b is not None or carry == 1:
        x = 0 if a is None else a.data
        y = 0 if b is None else b.data
        if a is not None:
            a = a.next
        if b is not None:
            b = b.next

        digit = x + y + carry
        carry = digit // 10
        digit %= 10
        if head is None:
            head = LinkedListNode(digit)
            curr = head
        else:
            curr.next = LinkedListNode(digit)
            curr = curr.next
    return head
コード例 #2
0
def sum_lists_forward_stack(a: LinkedListNode,
                            b: LinkedListNode) -> LinkedListNode:
    """Add two integers stored as a linked list using a stack.

    Each digit of the integer is a node, and the 1's place is the tail.

    Runtime: O(n)
    Memory: O(n)
    """
    stack_a = []
    stack_b = []
    while a is not None:
        stack_a.append(a.data)
        a = a.next
    while b is not None:
        stack_b.append(b.data)
        b = b.next
    head = None
    carry = 0
    while len(stack_a) > 0 or len(stack_b) > 0 or carry == 1:
        x = stack_a.pop() if len(stack_a) > 0 else 0
        y = stack_b.pop() if len(stack_b) > 0 else 0
        digit = x + y + carry
        carry = digit // 10
        digit %= 10
        curr = LinkedListNode(digit)
        if head is None:
            head = curr
        else:
            curr.next = head
            head = curr
    return head
コード例 #3
0
def sum_lists_forward(a: LinkedListNode, b: LinkedListNode) -> LinkedListNode:
    """Add two integers stored as a linked list.

    Each digit of the integer is a node, and the 1's place is the tail.

    Runtime: O(n)
    Memory: O(1)
    """
    x = y = 0
    while a is not None:  # Could refactor to another function
        x += a.data
        if a.next is not None:
            x *= 10
        a = a.next
    while b is not None:
        y += b.data
        if b.next is not None:
            y *= 10
        b = b.next
    total = x + y
    head = None
    while total > 0:
        digit = total % 10
        total = total // 10
        curr = LinkedListNode(digit)
        if head is None:
            head = curr
        else:
            curr.next = head
            head = curr
    return head
コード例 #4
0
def partition(head: LinkedListNode, x: int) -> LinkedListNode:
    """Partition a singly linked list around a value x.

    All nodes less than x come before nodes greater than or equal to x.  The
    partition element x can appear anywhere in second grouping.

    Runtime: O(n)
    Memory: O(n)
    """
    new_head = left_tail = None
    right_curr = head
    right_prev = None
    while right_curr is not None:
        d = right_curr.data
        if d < x:
            if new_head is None:
                new_head = left_tail = LinkedListNode(d)
            else:
                left_tail.next = LinkedListNode(d)
                left_tail = left_tail.next

            if right_prev is None:  # i.e., haven't found anything >= x
                head = right_curr = right_curr.next
            else:
                right_prev.next = right_curr.next
                right_curr = right_curr.next
        else:
            right_prev = right_curr
            right_curr = right_curr.next
    left_tail.next = head
    return new_head
コード例 #5
0
def palindrome_reverse_list(head: LinkedListNode) -> bool:
    """Check if a linked list is a palindrome.

    Ignores punctuation, whitespace, and case.

    Runtime: O(n)
    Memory: O(n)
    """
    reverse_list = LinkedListNode(head.data)
    runner = head.next
    while runner is not None:
        new_node = LinkedListNode(runner.data)
        new_node.next = reverse_list
        reverse_list = new_node
        runner = runner.next

    while head is not None:
        h = chr(head.data)
        r = chr(reverse_list.data)
        if not h.isalpha():
            head = head.next
        elif not r.isalpha():
            reverse_list = reverse_list.next
        elif h.lower() != r.lower():
            return False
        else:
            head = head.next
            reverse_list = reverse_list.next
    return True
コード例 #6
0
def sum_lists_forward_recursive(a: LinkedListNode,
                                b: LinkedListNode) -> LinkedListNode:
    """Add two integers stored as a linked list using recursion.

    Each digit of the integer is a node, and the 1's place is the tail.

    Runtime: O(n)
    Memory: O(n)
    """
    curr_a, curr_b = a, b
    len_a = len_b = 0
    while curr_a is not None:
        len_a += 1
        curr_a = curr_a.next
    while curr_b is not None:
        len_b += 1
        curr_b = curr_b.next
    if len_a > len_b:
        b = pad_zeroes(b, len_a - len_b)
    elif len_b > len_a:
        a = pad_zeroes(a, len_b - len_a)
    head, carry = sum_lists_forward_recursive_helper(a, b)
    if carry > 0:
        curr = LinkedListNode(1)
        curr.next = head
        head = curr
    return head
 def setUp(self):
     self.node_a = LinkedListNode(ord('a'))
     self.node_c = LinkedListNode(ord('c'))
     self.node_f = LinkedListNode(ord('f'))
     self.node_t = LinkedListNode(ord('t'))
     self.node_c.next = self.node_a
     self.node_f.next = self.node_a
     self.node_a.next = self.node_t
 def setUp(self):
     self.head_a = LinkedListNode(ord('a'))
     for i in range(5):
         self.head_a.append_to_tail(ord('b') + i)
     self.head_b = LinkedListNode(1)
     self.head_b.append_to_tail(5)
     self.head_b.append_to_tail(9)
     self.head_b.append_to_tail(12)
コード例 #9
0
    def append(self, key, value):
        new_node = LinkedListNode(key, value)

        self.tail.prev.next = new_node
        new_node.prev = self.tail.prev
        new_node.next = self.tail
        self.tail.prev = new_node

        return new_node
コード例 #10
0
 def convert_to_reverse_linked_list(number: int) -> LinkedListNode:
     head = None
     while number > 0:
         digit = number % 10
         if head is None:
             head = LinkedListNode(digit)
         else:
             head.append_to_tail(digit)
         number //= 10
     return head
コード例 #11
0
 def add_to_front(self, value):
     """
     O(1)
     """
     temp_node = self.head
     self.head = LinkedListNode(value)
     self.head.set_next_node(temp_node)
     self.length += 1
     if self.length == 1:
         self.tail = self.head
コード例 #12
0
	def append(self, data):
		node = LinkedListNode(data)

		if self.head == None:
			self.head = node
		else:
			node.next_node = self.tail

		self.tail = node

		self.list.append(node)
def delete_middle_node(node: LinkedListNode) -> None:
    """Delete a node from anywhere in the middle of a singly linked list.

    Runtime: O(n)
    Memory: O(1)
    """
    while node.next.next is not None:
        node.data = node.next.data
        node = node.next
    node.data = node.next.data
    node.next = None
コード例 #14
0
 def convert_to_forward_linked_list(number: int) -> LinkedListNode:
     # https://stackoverflow.com/questions/2189800/length-of-an-integer-in-python
     n = 1 if number == 0 else int(log10(number)) + 1
     head = None
     while n > 0:
         n -= 1
         digit = number // 10**n % 10
         if head is None:
             head = LinkedListNode(digit)
         else:
             head.append_to_tail(digit)
     return head
コード例 #15
0
 def enqueue(self, value):
     newNode = LinkedListNode(value)
     
     if (len(self) == 0):
         self.first = newNode
         self.last = newNode
     else:
         self.last.next = newNode
         newNode.prev = self.last
         self.last = newNode
     
     self.size += 1
class TestQ02_02ReturnKthToLast(unittest.TestCase):
    def setUp(self):
        self.head = LinkedListNode(20)
        for i in range(19, -1, -1):
            self.head.append_to_tail(i)

    def test_return_kth_to_last(self):
        self.assertEqual(return_kth_to_last(self.head, 5), 5)
        self.assertEqual(return_kth_to_last(self.head, 15), 15)

    def test_return_kth_to_last_recursive(self):
        self.assertEqual(return_kth_to_last_recursive(self.head, 5), 5)
        self.assertEqual(return_kth_to_last_recursive(self.head, 15), 15)
コード例 #17
0
 def convert_str_to_linked_list(s: str) -> LinkedListNode:
     if s is None or len(s) == 0:
         return None
     head = curr = None
     for i in range(len(s)):
         ch = ord(s[i])
         if head is None:
             head = LinkedListNode(ch)
             curr = head
         else:
             curr.next = LinkedListNode(ch)
             curr = curr.next
     return head
コード例 #18
0
def sum_lists_forward_recursive_helper(
        a: LinkedListNode, b: LinkedListNode) -> (LinkedListNode, int):
    if a.next is None and b.next is None:
        digit = a.data + b.data
        carry = digit // 10
        digit %= 10
        curr = LinkedListNode(digit)
        return curr, carry
    next_node, carry = sum_lists_forward_recursive_helper(a.next, b.next)
    digit = a.data + b.data + carry
    carry = digit // 10
    digit %= 10
    curr = LinkedListNode(digit)
    curr.next = next_node
    return curr, carry
コード例 #19
0
class TestQ02_04Partition(unittest.TestCase):
    def setUp(self):
        self.head = LinkedListNode(3)
        elements = [5, 8, 5, 10, 2, 1]
        for e in elements:
            self.head.append_to_tail(e)

    def test_partition(self):
        partition_element = 5
        curr = partition(self.head, partition_element)
        count = 0
        while curr.data < partition_element:
            count += 1
            curr = curr.next
        while curr is not None:
            count += 1
            self.assertGreaterEqual(curr.data, partition_element)
            curr = curr.next
        self.assertEqual(count, 7)
コード例 #20
0
    def test_loop_detection(self):
        loop_list = LinkedList(None)
        for value in self.loop_values:
            loop_list.append_to_tail(value)
        loop_list.head = loop_list.head.next

        node = LinkedListNode('C')
        current = loop_list.head
        while current.value != 'B':
            current = current.next
        node.next = current.next.next
        current.next = node

        while current.next is not None:
            current = current.next
        current.next = node

        self.assertEqual(self.expected, loop_detection(loop_list))
        self.assertEqual(self.expected, loop_detection_no_extra_space(loop_list))
コード例 #21
0
 def add_to_back(self, value):
     """
     O(1)
     """
     node = LinkedListNode(value)
     if self.is_empty():
         self.head = node
     else:
         self.tail.set_next_node(node)
     self.tail = node
     self.length += 1
class TestQ02_01RemoveDups(unittest.TestCase):
    def setUp(self):
        self.head = LinkedListNode(0)
        for i in range(20):
            self.head.append_to_tail(i % 5)

    def test_remove_dups(self):
        remove_dups(self.head)
        self.assertEqual(self.count_nodes(), 5)

    def test_remove_dups_no_buffer(self):
        remove_dups_no_buffer(self.head)
        self.assertEqual(self.count_nodes(), 5)

    def count_nodes(self) -> int:
        curr = self.head
        count = 0
        while curr is not None:
            count += 1
            curr = curr.next
        return count
class TestQ02_03DeleteMiddleNode(unittest.TestCase):
    def setUp(self):
        self.head_a = LinkedListNode(ord('a'))
        for i in range(5):
            self.head_a.append_to_tail(ord('b') + i)
        self.head_b = LinkedListNode(1)
        self.head_b.append_to_tail(5)
        self.head_b.append_to_tail(9)
        self.head_b.append_to_tail(12)

    def test_delete_middle_node(self):
        curr = self.head_a
        while curr.data != ord('c'):
            curr = curr.next
        delete_middle_node(curr)
        self.assertEqual(self.convert_linked_list_to_string(), 'abdef')

        curr = self.head_b
        while curr.data != 9:
            curr = curr.next
        delete_middle_node(curr)
        curr = self.head_b
        self.assertEqual(curr.data, 1)
        curr = curr.next
        self.assertEqual(curr.data, 5)
        curr = curr.next
        self.assertEqual(curr.data, 12)

    def convert_linked_list_to_string(self) -> str:
        curr = self.head_a
        letters = []
        while curr is not None:
            letters.append(chr(curr.data))
            curr = curr.next
        return ''.join(letters)
コード例 #24
0
def remove_dups(n: LinkedListNode) -> None:
    """Remove duplicates from an unsorted singly linked list.

    Runtime: O(n)
    Memory: O(n)
    """
    uniques = {n.data}
    while n is not None and n.next is not None:
        if n.next.data in uniques:
            n.next = n.next.next
        else:
            uniques.add(n.next.data)
            n = n.next
コード例 #25
0
 def setUp(self):
     self.node_a = LinkedListNode(ord('a'))
     self.node_b = LinkedListNode(ord('b'))
     self.node_c = LinkedListNode(ord('c'))
     self.node_d = LinkedListNode(ord('d'))
     self.node_e = LinkedListNode(ord('e'))
     self.node_f = LinkedListNode(ord('f'))
     self.node_g = LinkedListNode(ord('g'))
     self.node_h = LinkedListNode(ord('h'))
     self.node_i = LinkedListNode(ord('i'))
     self.node_a.next = self.node_b
     self.node_b.next = self.node_c
     self.node_c.next = self.node_d
     self.node_d.next = self.node_e
     self.node_e.next = self.node_f
     self.node_f.next = self.node_g
     self.node_g.next = self.node_h
     self.node_h.next = self.node_i
     self.node_i.next = self.node_d
コード例 #26
0
def sum_lists_reverse_recursive(a: LinkedListNode,
                                b: LinkedListNode,
                                carry: int = 0) -> LinkedListNode:
    """Add two integers stored as a linked list without intermediate conversion.

    Each digit of the integer is a node, and the 1's place is the head node.

    Runtime: O(n)
    Memory: O(n)
    """
    if a is None and b is None:
        return None
    x = 0 if a is None else a.data
    y = 0 if b is None else b.data
    digit = x + y + carry
    carry = digit // 10
    digit %= 10
    head = LinkedListNode(digit)
    if a is not None:
        a = a.next
    if b is not None:
        b = b.next
    head.next = sum_lists_reverse_recursive(a, b, carry)
    return head
コード例 #27
0
ファイル: is_palindrome.py プロジェクト: hkhaisty/Practice
def is_palindrome(linked_list):
    reverse_list = LinkedList(None)
    current = linked_list.head
    while current is not None:
        head = reverse_list.head
        reverse_list.head = LinkedListNode(current.value)
        reverse_list.head.next = head
        current = current.next

    while reverse_list.head.value is not None:
        if reverse_list.head.value != linked_list.head.value:
            return False
        reverse_list.head = reverse_list.head.next
        linked_list.head = linked_list.head.next

    return True
コード例 #28
0
 def append_to_tail(self, node_value):
     current = self.head
     while current.next is not None:
         current = current.next
     current.next = LinkedListNode(node_value)
コード例 #29
0
 def __init__(self, value):
     self.head = LinkedListNode(value)
コード例 #30
0
def pad_zeroes(node: LinkedListNode, n: int) -> LinkedListNode:
    for _ in range(n):
        new_node = LinkedListNode(0)
        new_node.next = node
        node = new_node
    return node
コード例 #31
0
class LinkedList(object):
    def __init__(self):
        self.head = None
        self.tail = None
        self.length = 0

    def is_empty(self):
        return self.length == 0

    def add_to_front(self, value):
        """
        O(1)
        """
        temp_node = self.head
        self.head = LinkedListNode(value)
        self.head.set_next_node(temp_node)
        self.length += 1
        if self.length == 1:
            self.tail = self.head

    def add_to_back(self, value):
        """
        O(1)
        """
        node = LinkedListNode(value)
        if self.is_empty():
            self.head = node
        else:
            self.tail.set_next_node(node)
        self.tail = node
        self.length += 1

    def add(self, value):
        """
        O(1)
        """
        self.add_to_back(value)

    def remove_front(self):
        if not self.is_empty():
            self.head = self.head.get_next_node()
            self.length -= 1
            if self.length == 0:
                self.tail = None

    def remove_back(self):
        """
        O(n)
        """
        if not self.is_empty():
            if self.length == 1:
                self.tail = None
                self.head = None
            else:
                current = self.head
                while current.get_next_node() is not self.tail:
                    current = current.get_next_node()
                current.next_node = None
                self.tail = current
            self.length -= 1

    def remove(self, item):
        """
        O(n)
        :param item:
        :return:
        """
        if not self.is_empty():
            previous = None
            current_node = self.head
            while current_node is not None:
                if current_node.get_value() == item:
                    if previous is not None:
                        previous.set_next_node(current_node.get_next_node())
                        if current_node.get_next_node() is None:
                            self.tail = previous
                    else:
                        self.remove_front()
                    self.length -= 1
                    return True
                previous = current_node
                current_node = current_node.get_next_node()
        return False

    def clear(self):
        """
        O(1)
        :return:
        """
        self.head = None
        self.tail = None
        self.length = 0

    def enumerate(self):
        """
        O(n)
        :return:
        """
        current_node = self.head
        while current_node != None:
            yield current_node
            current_node = current_node.get_next_node()

    def __str__(self):
        """
         O(n)
        """
        if not self.is_empty():
            buffer_array = []
            for node in self.enumerate():
                buffer_array.append(str(node))
                buffer_array.append(str('=>'))
            buffer_array.append('None')
            return ''.join(buffer_array)
        else:
            return 'This Linked List is empty!'
 def setUp(self):
     self.head = LinkedListNode(20)
     for i in range(19, -1, -1):
         self.head.append_to_tail(i)