Esempio n. 1
0
def add_linked_lists(ll1: LinkedList, ll2: LinkedList) -> LinkedList:
    sum_linked_list = LinkedList()
    pos1, pos2 = ll1.head, ll2.head
    carry, curr_position_sum = 0, 0
    # generating the sum of the linked lists
    while pos1 or pos2:
        if pos1 == None:
            curr_position_sum = pos2.val + carry
            if curr_position_sum >= 10:
                carry, curr_position_sum = 1, curr_position_sum - 10
            else:
                carry = 0
        elif pos2 == None:
            curr_position_sum = pos1.val + carry
            if curr_position_sum >= 10:
                carry, curr_position_sum = 1, curr_position_sum - 10
            else:
                carry = 0
        else:
            curr_position_sum = pos2.val + pos1.val + carry
            if curr_position_sum >= 10:
                carry, curr_position_sum = 1, curr_position_sum - 10
            else:
                carry = 0
        sum_linked_list.add(curr_position_sum)
        # moving to the next value
        if pos1:
            pos1 = pos1.next
        if pos2:
            pos2 = pos2.next
    if carry == 1:
        sum_linked_list.add(1)
    return sum_linked_list
def merge_sorted_linked_list(list_of_LL: List[LinkedList]) -> LinkedList:
    k = len(list_of_LL)
    position_arr = [LL.head for LL in list_of_LL]
    sorted_ll = LinkedList()
    while any(position_arr):
        # finding the node with minimum value
        minimum = maxsize
        for i in range(k):
            if position_arr[i] is not None:
                if position_arr[i].val < minimum:
                    minimum = position_arr[i].val
                    position = i
        # generating new node
        if sorted_ll.head is None:
            sorted_ll.add(position_arr[position].val)
            curr_position = sorted_ll.head
        else:
            curr_position.next = Node(position_arr[position].val)
            curr_position = curr_position.next
        sorted_ll.length += 1
        position_arr[position] = position_arr[position].next
    # resetting rear
    sorted_ll.rear = curr_position
    return sorted_ll
            cumulative_sum_map[cumulative].next = node.next
        cumulative_sum_map[cumulative] = node
        node = node.next
    # resetting the linked list (removing dummy head and setting rear)
    linked_list.head = linked_list.head.next
    node = linked_list.head
    while node:
        linked_list.rear = node
        node = node.next
    return linked_list


if __name__ == "__main__":
    linked_list = LinkedList()
    for elem in [3, 4, -7, 5, -6, 6]:
        linked_list.add(elem)
    print(delete_zero_sum(linked_list))

    linked_list = LinkedList()
    for elem in [7, 4, -4, -7, 5, -6, 6]:
        linked_list.add(elem)
    print(delete_zero_sum(linked_list))

    linked_list = LinkedList()
    for elem in [7, 4, -4, -7, 5, -6, 6, 10]:
        linked_list.add(elem)
    print(delete_zero_sum(linked_list))
"""
SPECS:

TIME COMPLEXITY: O(n)
Esempio n. 4
0

def swap_nodes(ll: LinkedList) -> Node:
    node1 = ll.head
    node2 = ll.head.next
    while True:
        try:
            node1.val, node2.val = node2.val, node1.val
            node1, node2 = node1.next.next, node2.next.next
        except:
            break
    return ll.head


if __name__ == "__main__":
    LL = LinkedList()

    LL.add(1)
    LL.add(2)
    LL.add(3)
    LL.add(4)

    print(LL)
    print(swap_nodes(LL))
"""
SPECS:

TIME COMPLEXITY: O(n)
SPACE COMPLEXITY: O(1)
"""
def rearrange(ll: LinkedList) -> None:
    nodes_count = len(ll)
    nodes = [int(node) for node in ll]
    nodes.sort()

    for i in range(2, nodes_count, 2):
        nodes[i], nodes[i - 1] = nodes[i - 1], nodes[i]

    curr = ll.head
    for i in range(nodes_count):
        curr.val = nodes[i]
        curr = curr.next


if __name__ == "__main__":
    LL = LinkedList()

    for i in range(1, 6):
        LL.add(i)

    print(LL)
    rearrange(LL)
    print(LL)
"""
SPECS:

TIME COMPLEXITY: O(n)
SPACE COMPLEXITY: O(n)
"""
        if sorted_ll.head is None:
            sorted_ll.add(position_arr[position].val)
            curr_position = sorted_ll.head
        else:
            curr_position.next = Node(position_arr[position].val)
            curr_position = curr_position.next
        sorted_ll.length += 1
        position_arr[position] = position_arr[position].next
    # resetting rear
    sorted_ll.rear = curr_position
    return sorted_ll


if __name__ == "__main__":
    LL1 = LinkedList()
    LL1.add(2)
    LL1.add(25)
    LL1.add(70)

    LL2 = LinkedList()
    LL2.add(5)
    LL2.add(8)
    LL2.add(14)
    LL2.add(15)
    LL2.add(21)
    LL2.add(48)

    LL3 = LinkedList()
    LL3.add(0)
    LL3.add(90)
            pos = len1 - len2
            for _ in range(pos):
                pos1 = pos1.next
        # checking for intersecting node
        for _ in range(smaller_len):
            if pos1 is pos2:
                return pos1
            pos1 = pos1.next
            pos2 = pos2.next
    # no intersection
    return None


if __name__ == "__main__":
    ll1 = LinkedList()
    ll1.add(5)
    ll1.add(6)
    ll1.add(7)
    ll1.add(8)

    ll2 = LinkedList()
    ll2.add(1)
    ll2.add(2)
    ll2.add(3)
    ll2.add(4)

    ll3 = LinkedList()
    ll3.add(9)
    ll3.rear.next = ll1.head.next.next
    ll3.rear = ll3.rear.next.next
    ll3.length = 3
Esempio n. 8
0
def create_linked_list(val: int) -> LinkedList:
    LL = LinkedList()
    while val > 0:
        LL.add(val % 10)
        val = val // 10
    return LL
Esempio n. 9
0
def sort(ll: LinkedList) -> LinkedList:
    ll.head = merge_sort(ll, ll.head)
    # reseting rear
    curr = ll.head
    while curr.next:
        curr = curr.next
    ll.rear = curr
    return ll


if __name__ == "__main__":
    LL = LinkedList()

    for val in [6, 3, 7, 5, 30, 2, 50]:
        LL.add(val)

    print(LL)
    sort(LL)
    print(LL)
    print()

    LL = LinkedList()

    for val in [4, 1, -3, 99]:
        LL.add(val)

    print(LL)
    sort(LL)
    print(LL)
"""
Esempio n. 10
0
    length = len(ll)
    if length in (0, 1):
        return ll

    for _ in range(length):
        pos1, pos2 = randint(0, length - 1), randint(0, length - 1)
        node1, node2 = ll.head, ll.head
        for _ in range(pos1):
            node1 = node1.next
        for _ in range(pos2):
            node2 = node2.next
        node1.val, node2.val = node2.val, node1.val
    return ll


if __name__ == "__main__":
    ll = LinkedList()

    for i in range(1, 6):
        ll.add(i)

    print(ll)
    shuffle(ll)
    print(ll)
"""
SPECS:

TIME COMPLEXITY: O(n ^ 2)
SPACE COMPLEXITY: O(1)
"""
        pos2 = pos2.next
    # creating the cloned linked list from the generated nodes
    cloned_LL = LinkedList()
    cloned_LL.head = clone_head
    cloned_LL.length = ll.length
    cloned_LL.rear = pos2
    return cloned_LL


# adding the random pointer to Node class
setattr(Node, "random_ptr", None)

if __name__ == "__main__":
    LL = LinkedList()

    LL.add(1)
    LL.add(2)
    LL.add(3)
    LL.add(4)

    rand_join(LL, 0, 2)
    rand_join(LL, 2, 0)
    rand_join(LL, 1, 3)

    print("Original List:", LL)

    LL_clone = clone(LL)

    print("Cloned List:", LL_clone)

    # adding different elements to show that the clone is a deep copy
Esempio n. 12
0
    # ptr_k is k nodes away from the end
    while ptr_end is not None:
        ptr_end = ptr_end.next
        ptr_k = ptr_k.next
    # removing the required element
    temp = ptr_k.next
    ptr_k.next = temp.next
    temp.next = None
    ll.length -= 1
    del temp


if __name__ == "__main__":
    ll1 = LinkedList()
    for i in range(1, 10):
        ll1.add(i)
    print(ll1)
    delete_kth_last_node(ll1, 5)
    print(ll1)

    ll2 = LinkedList()
    for i in range(1, 4):
        ll2.add(i)
    print(ll2)
    delete_kth_last_node(ll2, 3)
    print(ll2)
"""
SPECS:

TIME COMPLEXITY: O(n)
SPACE COMPLEXITY: O(1)
    ll.rear = ll.head
    ptr_prev, ptr_curr, ptr_next = None, ll.head, ll.head.next
    # reversing the flow
    while ptr_curr is not None:
        ptr_curr.next = ptr_prev
        ptr_prev, ptr_curr = ptr_curr, ptr_next
        if ptr_next is None:
            break
        ptr_next = ptr_next.next
    ll.head = ptr_prev


if __name__ == "__main__":
    ll = LinkedList()
    for num in range(1, 6):
        ll.add(num)
    print(ll)
    reverse_inplace(ll)
    print(ll)

    ll = LinkedList()
    for num in range(1, 3):
        ll.add(num)
    print(ll)
    reverse_inplace(ll)
    print(ll)

    ll = LinkedList()
    for num in range(1, 2):
        ll.add(num)
    print(ll)
Esempio n. 14
0

def pivot_linked_list(ll: LinkedList, k: int) -> None:
    ptr1, ptr2 = ll.head, ll.head
    length = len(ll)
    k = k % length
    for _ in range(length):
        if ptr2.val < k:
            ptr1.val, ptr2.val = ptr2.val, ptr1.val
            ptr1 = ptr1.next
        ptr2 = ptr2.next


if __name__ == "__main__":
    LL = LinkedList()
    LL.add(5)
    LL.add(1)
    LL.add(8)
    LL.add(0)
    LL.add(3)

    print(LL)

    pivot_linked_list(LL, 3)

    print(LL)
"""
SPECS:

TIME COMPLEXITY: O(n)
SPACE COMPLEXITY: O(1)
def rotate_linked_list(ll: LinkedList, k: int = 0) -> None:
    k = k % ll.length

    for _ in range(k):
        temp = ll.head
        ll.head = ll.head.next
        temp.next = None
        ll.rear.next = temp
        ll.rear = ll.rear.next


if __name__ == "__main__":
    LL = LinkedList()
    for num in [7, 7, 3, 5]:
        LL.add(num)

    print(LL)
    rotate_linked_list(LL, 2)
    print(LL)
    print()

    LL = LinkedList()
    for num in [1, 2, 3, 4, 5]:
        LL.add(num)

    print(LL)
    rotate_linked_list(LL, 3)
    print(LL)
"""
SPECS: