# @return the intersected ListNode
    def getIntersectionNode(self, headA, headB):
        if not headA or not headB: return None
        pA,pB,tailA,tailB = headA,headB,None,None 
        while True:
            if not pA: pA = headB
            if not pB: pB = headA
            if not pA.next: tailA = pA
            if not pB.next: tailB = pB
            #The two links have different tails. So just return null;
            if tailA and tailB and tailA!=tailB: return None
            if pA == pB: return pA
            pA, pB = pA.next, pB.next        

if __name__=="__main__":
    l1 = LListUtil.buildList([2,3])
    l2 = LListUtil.buildList([4,5,6])
    l3 = LListUtil.buildList([8,9,10])
    l1.next.next = l3; l2.next.next.next = l3
    LListUtil.printList(l1); LListUtil.printList(l2);
    print (Solution().getIntersectionNode(l1,l2)).val

"""
Two pointer solution (O(n+m) running time, O(1) memory): (Standard solution) 
Maintain two pointers pA and pB initialized at the head of A and B, respectively. 
Then let them both traverse through the lists, one node at a time.
When pA reaches the end of a list, then redirect it to the head of B 
(yes, B, that's right.); similarly when pB reaches the end of a list, 
redirect it the head of A.
If at any point pA meets pB, then pA/pB is the intersection node.
"""
Ejemplo n.º 2
0
        curr, listLen = head, 0
        while curr:
            curr, listLen = curr.next, listLen + 1
        curr, prev, index = head, dumhead, 1
        prehead, preheadnext = dumhead, head
        while curr:
            if listLen - index < listLen % k: break
            nextN = curr.next
            curr.next = prev
            if index % k == 0:
                prehead.next = curr
                preheadnext.next = nextN
                prehead = preheadnext
                prev = prehead
                preheadnext = nextN
            else:
                prev = curr
            curr, index = nextN, index + 1
        return dumhead.next


if __name__ == "__main__":
    arr = range(1, 10)
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().reverseKGroup(head, 4))
"""
Simliar as problem 'Swap Nodes in Pairs'.
when index meet times of K (index%K==0), then reverse the list segement.
Notice, for the last few nodes (list_Length-index < list_Length%k) do nothing.
"""
Ejemplo n.º 3
0
path1.append(path2.dirname(path2.dirname(path2.abspath(__file__))))
import LListUtil


# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def deleteDuplicates(self, head):
        if not head or not head.next: return head
        curr = head
        while curr.next:
            if curr.next.val == curr.val:
                curr.next = curr.next.next
            else:
                curr = curr.next
        return head


if __name__ == "__main__":
    arr = [1, 1, 2, 3, 3]
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().deleteDuplicates(head))
Ejemplo n.º 4
0
        if not head: return head
        pivot = ListNode(0)
        pivot.next = head
        prev = None
        while pivot and pivot.val < x:
            prev = pivot
            pivot = pivot.next
        if pivot:
            curr = prev
            while pivot:
                if pivot.val < x:
                    temp = curr.next
                    prev.next = pivot.next
                    curr.next = pivot
                    curr = pivot
                    pivot.next = temp
                    pivot = prev
                prev = pivot
                pivot = pivot.next 
        return head

if __name__=="__main__":
    arr = [1,4,3,2,5,2]
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().partition(head,3))       

"""
Scan from left to right, if met a node(pivot node) value larger than X, 
then insert all small nodes found later into the left of pivot node.
"""
Ejemplo n.º 5
0
# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution:
    # @return a ListNode
    def removeNthFromEnd(self, head, n):
        if not head: return head
        dumhead = ListNode(0)
        dumhead.next = head
        head = prev = dumhead
        count = 0
        while head.next:
            head = head.next
            count += 1
            if count > n:
                prev = prev.next
        prev.next = prev.next.next
        return dumhead.next


if __name__ == "__main__":
    arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().removeNthFromEnd(head, 9))
Ejemplo n.º 6
0
    # @return a ListNode
    def mergeTwoLists(self, l1, l2):
        dumhead = ListNode(0)
        curr = dumhead
        while True:
            if not l1:
                curr.next = l2
                break
            if not l2:
                curr.next = l1
                break
            if l1.val < l2.val:
                curr.next = l1
                l1 = l1.next
            else:
                curr.next = l2
                l2 = l2.next
            curr = curr.next
        return dumhead.next

if __name__=="__main__":
    arr1 = LListUtil.randomArr(10,5)
    arr2 = LListUtil.randomArr(10,5)
    arr1.sort(); arr2.sort()
    l1 = LListUtil.buildList(arr1)
    l2 = LListUtil.buildList(arr2)
    LListUtil.printList(l1)
    LListUtil.printList(l2)
    sol = Solution()
    LListUtil.printList(sol.mergeTwoLists(l1,l2))     
Ejemplo n.º 7
0
class Solution:
    # @return a ListNode
    def addTwoNumbers(self, l1, l2):
        dumhead = ListNode(0)
        carry = 0
        head = dumhead
        while carry or l1 or l2:
            node = ListNode(carry)
            if l1:
                node.val += l1.val
                l1 = l1.next
            if l2:
                node.val += l2.val
                l2 = l2.next
            carry = node.val / 10
            node.val %= 10
            head.next = node
            head = head.next
        return dumhead.next


if __name__ == "__main__":
    arr1 = LListUtil.randomArr(10, 5)
    arr2 = LListUtil.randomArr(10, 5)
    l1 = LListUtil.buildList(arr1)
    l2 = LListUtil.buildList(arr2)
    LListUtil.printList(l1)
    LListUtil.printList(l2)
    LListUtil.printList(Solution().addTwoNumbers(l1, l2))
Ejemplo n.º 8
0
        if not head: return head
        pivot = ListNode(0)
        pivot.next = head
        prev = None
        while pivot and pivot.val < x:
            prev = pivot
            pivot = pivot.next
        if pivot:
            curr = prev
            while pivot:
                if pivot.val < x:
                    temp = curr.next
                    prev.next = pivot.next
                    curr.next = pivot
                    curr = pivot
                    pivot.next = temp
                    pivot = prev
                prev = pivot
                pivot = pivot.next
        return head


if __name__ == "__main__":
    arr = [1, 4, 3, 2, 5, 2]
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().partition(head, 3))
"""
Scan from left to right, if met a node(pivot node) value larger than X, 
then insert all small nodes found later into the left of pivot node.
"""
Ejemplo n.º 9
0
import LListUtil
# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # @param head, a ListNode
    # @return a ListNode
    def deleteDuplicatesII(self, head):
        if not head or not head.next: return head
        dumhead = ListNode(0)
        dumhead.next = head
        prev = dumhead
        while prev.next:
            curr = prev.next
            while curr.next and curr.val==curr.next.val:
                curr = curr.next
            if curr != prev.next:
                prev.next = curr.next
            else:
                prev = prev.next
        return dumhead.next

if __name__=="__main__":
    arr = [1,2,3,3,4,4,5] # [1,1,1,2,3]
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().deleteDuplicatesII(head))     
Ejemplo n.º 10
0
        dumhead.next = head
        curr, listLen = head, 0
        while curr: curr, listLen = curr.next, listLen+1
        curr, prev, index = head, dumhead, 1
        prehead, preheadnext = dumhead, head
        while curr:
            if listLen-index < listLen%k: break
            nextN = curr.next
            curr.next = prev
            if index%k == 0:
                prehead.next = curr
                preheadnext.next = nextN
                prehead = preheadnext
                prev = prehead
                preheadnext = nextN
            else:
                prev = curr
            curr, index = nextN, index+1   
        return dumhead.next

if __name__=="__main__":
    arr = range(1,10)
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().reverseKGroup(head,4))

"""
Simliar as problem 'Swap Nodes in Pairs'.
when index meet times of K (index%K==0), then reverse the list segement.
Notice, for the last few nodes (list_Length-index < list_Length%k) do nothing.
"""
Ejemplo n.º 11
0
        # now slow is the mid point and do reverse
        fast = slow.next
        while fast.next:
            temp = slow.next
            slow.next = fast.next
            fast.next = fast.next.next
            slow.next.next = temp
        # insert reverse part
        fast = head
        while slow != fast and slow.next:
            temp = fast.next
            fast.next = slow.next
            slow.next = slow.next.next
            fast.next.next = temp
            fast = fast.next.next


if __name__ == "__main__":
    arr = list(range(1, 10))
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    Solution().reorderList(head)
    LListUtil.printList(head)
'''
So the algorithm implemented below can be summarized as:
Step 1  Find the middle pointer of the linked list (you can use the slow/fast pointers)
Step 2  Reverse the second part of the linked list (from middle->next to the end)
Step 3  Do the reordering. (inset every element in the second part in between the 
elements in the first part)
'''
Ejemplo n.º 12
0
        alen,blen = getsize(headA),getsize(headB) 
        if alen > blen:
            while alen > blen:
                headA = headA.next; alen -= 1 
        else:
            while blen > alen:
                headB = headB.next; blen -= 1
        while headA:
            if headA == headB: return headA
            headA, headB = headA.next, headB.next 
        return None       

        

if __name__=="__main__":
    l1 = LListUtil.buildList([2,3])
    l2 = LListUtil.buildList([4,5,6])
    l3 = LListUtil.buildList([8,9,10])
    l1.next.next = l3; l2.next.next.next = l3 
    LListUtil.printList(l1); LListUtil.printList(l2); 
    print (Solution().getIntersectionNode(l1,l2)).val

"""
Get both list length, then start to traverse from the shorter length.
e.g.
     a1 -> a2
     |       \
     |         c1 -> c2 -> c3
     |       /            
b1 ->|b2 -> b3
     v
    # @return a ListNode
    def reverseBetween(self, head, m, n):
        for i in range(n-m):
            index1 = n - i
            index2 = m + i
            if index2 >= index1: return head
            first, second = head, head
            while index1-1>0: first,index1 = first.next,index1-1
            while index2-1>0: second,index2 = second.next,index2-1
            first.val, second.val = second.val, first.val
        return head

if __name__=="__main__":
    arr = list(range(1,10))
    sol = Solution()
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(sol.reverseBetween(head,1,8))

"""
This is easy way which reverses just value of nodes.
(1) the stop condition is the middle of the reversed sublist (m+n)/2
(2) for each element in the sublist, the swapping element is the next 
(n-m-(i-m)*2) element.
    e.g.
    1-2-3-4-5-6-7-8-9-10-null
      |             |
     m=2           n=9
    for 2, just get the next (n-m) element.

    1-9-3-4-5-6-7-8-2-10-null
        second = dumhead
        count = 0
        while count < n - 1 and first.next:
            first = first.next
            count += 1
            if count > n - m:
                second = second.next
        if not first.next: return None
        temp1 = first.next.next
        curr = second.next
        prev = None
        while curr != temp1:
            temp2 = curr.next
            curr.next = prev
            prev = curr
            curr = temp2
        second.next = prev
        if curr:
            while prev.next:
                prev = prev.next
            prev.next = curr
        return dumhead.next


if __name__ == "__main__":
    arr = list(range(1, 10))
    sol = Solution()
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(sol.reverseBetween(head, 1, 8))
Ejemplo n.º 15
0
"""
from sys import path as path1; from os import path as path2
path1.append(path2.dirname(path2.dirname(path2.abspath(__file__))))
import LListUtil
# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # @param head, a ListNode
    # @return a boolean
    def hasCycle(self, head):
        if not head: return False
        fast = head
        slow = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if slow == fast:
                return True
        return False 

if __name__=="__main__":
    import random
    arr = list(range(10))
    sol = Solution()
    head = LListUtil.buildList(arr)
    print sol.hasCycle(head)     
Ejemplo n.º 16
0
            head = head.next
        print


def buildList(arr):
    head = ListNode(0)
    curr = head
    for i in arr:
        curr.next = ListNode(i)
        curr = curr.next

    return head.next


if __name__ == "__main__":
    arr = list(range(1, 10))
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().swapTwoLinkedList(head, 8, 9))
    LListUtil.printList(Solution().swapTwoLinkedList2(head, 1, 9))
'''
swap two nodes in linked list scheme::
nide1->node2->node3->nide4
first swap node1.next with node2.next 
node1.next = node2.next
node2.next = node2
second swap node2.next with node3.next
node2.next = node4
node3.next = node2
'''
Ejemplo n.º 17
0
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # @param head, a ListNod
    # @return a ListNode
    def reverseLinkedList(self, head): 
        if not head: return None
        dumhead = ListNode(0)
        dumhead.next = head
        prev = dumhead
        curr = prev.next
        while curr.next:
            temp = prev.next
            prev.next = curr.next
            curr.next = curr.next.next
            prev.next.next = temp
        return dumhead.next

if __name__=="__main__":
    arr = list(range(1,10))
    sol = Solution()
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(sol.reverseLinkedList(head))
"""
Alternative way, fixed prev and curr val, 
and move curr to the end
"""
Ejemplo n.º 18
0
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # @param head, a ListNode
    # @param k, an integer
    # @return a ListNode
    def rotateRight(self, head, k):
        if not head or k==0: return head
        curr, listLen = head, 1
        while curr.next: curr, listLen = curr.next, listLen+1
        k = listLen - k % listLen
        if k == listLen: return head
        curr.next, index = head, 0
        while index < k: curr, index = curr.next, index+1
        head = curr.next
        curr.next = None    
        return head

if __name__=="__main__":
    arr = list(xrange(1,6))
    head = LListUtil.buildList(arr)
    k = 2
    LListUtil.printList(head)
    LListUtil.printList(Solution().rotateRight(head,k))

"""
First, get the length of the list, then make last node.next point to head.
Second, iterate from head until length-k%length, then break the node. 
"""
Ejemplo n.º 19
0
        self.next = None

class Solution:
    # @return a ListNode
    def addTwoNumbers(self, l1, l2):
        dumhead = ListNode(0)
        carry = 0
        head = dumhead
        while carry or l1 or l2:
            node = ListNode(carry)
            if l1:
                node.val += l1.val
                l1 = l1.next
            if l2:
                node.val += l2.val
                l2 = l2.next
            carry = node.val / 10
            node.val %= 10
            head.next = node
            head = head.next
        return dumhead.next 

if __name__=="__main__":
    arr1 = LListUtil.randomArr(10,5)
    arr2 = LListUtil.randomArr(10,5)
    l1 = LListUtil.buildList(arr1)
    l2 = LListUtil.buildList(arr2)
    LListUtil.printList(l1)
    LListUtil.printList(l2)
    LListUtil.printList(Solution().addTwoNumbers(l1,l2))
Ejemplo n.º 20
0
    # Time Limit Exceeded
    def mergeKLists(self, lists):
        if len(lists) == 0: return None
        head = ListNode(0)
        head.next = lists[0]
        for l2 in lists[1:]:
            l1 = head
            while l2:
                if not l1.next:
                    l1.next = l2
                    break
                if l1.next.val < l2.val:
                    l1 = l1.next
                else:
                    temp = l1.next
                    l1.next = l2
                    l2 = l2.next
                    l1.next.next = temp
                    l1 = l1.next
        return head.next

if __name__=="__main__":
    l1 = sorted(LListUtil.randomArr(100,5))
    l2 = sorted(LListUtil.randomArr(100,5))
    l3 = sorted(LListUtil.randomArr(100,5))
    l4 = sorted(LListUtil.randomArr(100,5))
    l5 = sorted(LListUtil.randomArr(100,5))
    lists = [LListUtil.buildList(l1),LListUtil.buildList(l2),LListUtil.buildList(l3),LListUtil.buildList(l4),LListUtil.buildList(l5)]
    LListUtil.printLists(lists)
    LListUtil.printList(Solution().mergeKLists(lists))    
Ejemplo n.º 21
0
        curr = ListNode(0)
        curr.next = head
        head = curr
        while True:
            if not curr.next: break
            if not curr.next.next: break
            p1 = curr.next
            p2 = p1.next
            p1.next = p2.next
            p2.next = p1
            curr.next = p2
            curr = p1
        return head.next


if __name__ == "__main__":
    arr = list(range(1, 10))
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().swapPairs(head))
'''
swap two nodes in linked list scheme::
nide1->node2->node3->nide4
first swap node1.next with node2.next 
node1.next = node2.next
node2.next = node2
second swap node2.next with node3.next
node2.next = node4
node3.next = node2
'''
Ejemplo n.º 22
0
        curr = ListNode(0)
        curr.next = head
        head = curr
        while True:
            if not curr.next: break
            if not curr.next.next: break
            p1 = curr.next
            p2 = p1.next
            p1.next = p2.next
            p2.next = p1
            curr.next = p2
            curr = p1
        return head.next           

if __name__=="__main__":
    arr = list(range(1,10))
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().swapPairs(head))
    
'''
swap two nodes in linked list scheme::
nide1->node2->node3->nide4
first swap node1.next with node2.next 
node1.next = node2.next
node2.next = node2
second swap node2.next with node3.next
node2.next = node4
node3.next = node2
'''
Ejemplo n.º 23
0
        # now slow is the mid point and do reverse
        fast = slow.next
        while fast.next:
            temp = slow.next
            slow.next = fast.next
            fast.next = fast.next.next
            slow.next.next = temp 
        # insert reverse part
        fast = head
        while slow != fast and slow.next:
            temp = fast.next
            fast.next = slow.next
            slow.next = slow.next.next
            fast.next.next = temp
            fast = fast.next.next              

if __name__=="__main__":
    arr = list(range(1,10))
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    Solution().reorderList(head)
    LListUtil.printList(head)

'''
So the algorithm implemented below can be summarized as:
Step 1  Find the middle pointer of the linked list (you can use the slow/fast pointers)
Step 2  Reverse the second part of the linked list (from middle->next to the end)
Step 3  Do the reordering. (inset every element in the second part in between the 
elements in the first part)
'''    
Ejemplo n.º 24
0
            if slow == fast:
                flag = True
                break
        if not flag: return None
        fast = head
        while fast != slow:
            fast = fast.next
            slow = slow.next
        return fast


if __name__ == "__main__":
    import random
    arr = list(range(10))
    sol = Solution()
    head = LListUtil.buildList(arr)
    print sol.detectCycle(head)
"""
Firstly let us assume the slow pointer (S) and fast pointer (F) 
start at the same place in a n node circle. S run t steps while F 
can run 2t steps, we want to know what is t (where they meet) , then
just solve:  t mod n = 2t mod n,  we know when t = n, they meet, that 
is the start of the circle.

For our problem, we can consider the time when S enter the loop for 
the 1st time, which we assume k step from the head. At this time, 
the F is already in k step ahead in the loop. When will they meet next time? 
Still solve the function:    
t mod n = (k + 2t) mod n
Finally, when t = (n-k), S and F will meet, 
this is k steps before the start of the loop.
Ejemplo n.º 25
0

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution:
    # @param head, a ListNod
    # @return a ListNode
    def reverseLinkedList(self, head):
        if not head: return None
        curr = head
        prev = None
        while curr:
            temp = curr.next
            curr.next = prev
            prev = curr
            curr = temp
        return prev


if __name__ == "__main__":
    arr = list(range(1, 10))
    sol = Solution()
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(sol.reverseLinkedList(head))
    # @param head, a ListNode
    # @return a ListNode
    def insertionSortList(self, head):
        if head is None: return None
        pivot = ListNode(0)
        pivot.next = head
        head = pivot
        while pivot.next:
            curr = head
            flag = False
            while curr != pivot:
                if curr.next.val > pivot.next.val:
                    temp = pivot.next
                    pivot.next = pivot.next.next
                    temp.next = curr.next
                    curr.next = temp
                    flag = True
                    break
                else:
                    curr = curr.next
            if not flag:
                pivot = pivot.next 
	return head.next        

if __name__=="__main__":
    arr = LListUtil.randomArr(20,10)
    sol = Solution()
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(sol.insertionSortList(head))     
Ejemplo n.º 27
0
path1.append(path2.dirname(path2.dirname(path2.abspath(__file__))))
import LListUtil

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # @return a ListNode
    def removeNthFromEnd(self, head, n):
        if not head: return head
        dumhead = ListNode(0)
        dumhead.next = head
        head = prev = dumhead
        count = 0
        while head.next:
            head = head.next
            count += 1
            if count > n:
                prev = prev.next
        prev.next = prev.next.next
        return dumhead.next

if __name__=="__main__":
    arr = [1,2,3,4,5,6,7,8,9]
    head = LListUtil.buildList(arr)
    LListUtil.printList(head)
    LListUtil.printList(Solution().removeNthFromEnd(head,9))