def test_case1(self): nums = [1, 2, 3, 4, 5] m = 2 n = 4 answer = [1, 4, 3, 2, 5] result = self.sol.reverseBetween(ListNode.parseArray2List(nums), m, n) self.assertEqual(answer, ListNode.parseList2Array(result))
def swapPairs(self, head): #45ms, 83% """ :type head: ListNode :rtype: ListNode """ if head is None or head.next is None: return head dummy = ListNode(0) dummy.next = head zero = dummy one = head two = head.next while one and two: three = two.next # one.val, two.val = two.val, one.val # 32ms, 98%, if use the swap value way # zero = two # one = three # two = one.next if one else None zero.next = two one.next = three two.next = one zero = one one = one.next two = one.next if one else None return dummy.next
def test_case1(self): nums = [0, 1] nodes = ListNode.parseArray2List(nums) #node at index 0 (node.val = 0) answer = [1] result = self.sol.deleteNode(nodes) self.assertEqual(answer, ListNode.parseList2Array(nodes))
def test_case1(self): nums = [1,2,3,4,5] m =2 n = 4 answer = [1,4,3,2,5] result = self.sol.reverseBetween(ListNode.parseArray2List(nums),m, n) self.assertEqual(answer, ListNode.parseList2Array(result))
def test_case2(self): head = ListNode(0) head.next = None n = 1 answer = None result = self.sol.removeNthFromEnd(head, n) self.assertEqual(answer, result)
def partition1(self, head, x): #55ms, 45% """ :type head: ListNode :type x: int :rtype: ListNode """ if not head: return None dummy = ListNode(-1) dummy.next = head left = ListNode(-1) ltail = left right = ListNode(-1) rtail = right tmp = head while tmp: if tmp.val<x: ltail.next = tmp ltail = ltail.next else: rtail.next = tmp rtail = rtail.next tmp = tmp.next if left.next: # need to check if left part is None, otherwise wrong for case2 dummy.next = left.next ltail.next = right.next else: dummy.next = right.next rtail.next = None return dummy.next
def test_case1(self): l1 = [2, 4, 3] l2 = [5, 6, 4] answer = [7, 0, 8] result = self.sol.addTwoNumbers(ListNode.parseArray2List(l1), ListNode.parseArray2List(l2)) self.assertEqual(answer, ListNode.parseList2Array(result))
def addTwoNumbers(self, l1, l2): #119ms, 95% """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ if l1 is None: return l2 if l2 is None: return l1 dummy = ListNode(0) head = dummy carry = 0 while l1 and l2: tmp = l1.val + l2.val + carry carry = tmp / 10 digit = tmp % 10 head.next = ListNode(digit) head = head.next l1 = l1.next l2 = l2.next if l2: l1 = l2 if l1: while l1: tmp = l1.val + carry carry = tmp / 10 digit = tmp % 10 head.next = ListNode(digit) head = head.next l1 = l1.next if carry: # don't forget this one, otherwise wrong for case3 head.next = ListNode(1) return dummy.next
def reverseKGroup( self, head, k ): # 85ms, 37%, pay attention to link details, trial and error process """ :type head: ListNode :type k: int :rtype: ListNode """ if not head: return None if k == 1: return head dummy = ListNode(-1) dummy.next = head p = dummy done_tail = dummy cnt = 0 while True: while cnt < k: p = p.next if p: cnt += 1 else: break if cnt < k or not p: return dummy.next next_head = p.next new_done = done_tail.next done_tail.next = self.reverse_link(done_tail.next, next_head) done_tail = new_done p = next_head if not p: return dummy.next cnt = 1 return dummy.next
def deleteDuplicates(self, head): """ :type head: ListNode :rtype: ListNode """ if head is None or head.next is None: return head dummy = ListNode(-1) dummy.next = head ############################################################### # like remove duplicate from array, pre is the last valid one # # and pre.next == cur means the left-side OK one # ############################################################### pre = dummy cur = head while cur.next is not None: if cur.val != cur.next.val: # right-side ok if pre.next == cur: # if left-side ok, add one to result pre = pre.next else: pre.next = cur.next # left-side not ok, new start cur = cur.next if pre.next == cur: # cur is the last one, add it to result pre = pre.next pre.next = None return dummy.next
def deleteDuplicates(self, head): #58ms, 65% """ :type head: ListNode :rtype: ListNode """ if not head: return None dummy = ListNode(0) dummy.next = head good = dummy first = head faster = head.next while first: if faster is None or first.val != faster.val: good.next = first good = good.next first = faster if faster: faster = faster.next else: while faster and faster.val == first.val: faster = faster.next first = faster faster = first.next if first else None good.next = None # need to add ending to good, otherwise wrong for case 2 return dummy.next
def reverseKGroup(self, head, k): # 85ms, 37%, pay attention to link details, trial and error process """ :type head: ListNode :type k: int :rtype: ListNode """ if not head: return None if k==1: return head dummy = ListNode(-1) dummy.next = head p = dummy done_tail = dummy cnt = 0 while True: while cnt < k: p = p.next if p: cnt+=1 else: break if cnt < k or not p: return dummy.next next_head = p.next new_done = done_tail.next done_tail.next = self.reverse_link(done_tail.next,next_head) done_tail = new_done p = next_head if not p: return dummy.next cnt = 1 return dummy.next
def test_case2(self): l1 = [2] l2 = [8, 6, 4] answer = [0, 7, 4] result = self.sol.addTwoNumbers(ListNode.parseArray2List(l1), ListNode.parseArray2List(l2)) self.assertEqual(answer, ListNode.parseList2Array(result))
def deleteDuplicates(self, head): #58ms, 65% """ :type head: ListNode :rtype: ListNode """ if not head: return None dummy = ListNode(0) dummy.next = head good = dummy first = head faster = head.next while first: if faster is None or first.val != faster.val: good.next = first good = good.next first = faster if faster: faster = faster.next else: while faster and faster.val == first.val: faster = faster.next first = faster faster = first.next if first else None good.next = None # need to add ending to good, otherwise wrong for case 2 return dummy.next
def swapPairs(self, head): #45ms, 83% """ :type head: ListNode :rtype: ListNode """ if head is None or head.next is None: return head dummy = ListNode(0) dummy.next = head zero = dummy one = head two = head.next while one and two: three = two.next # one.val, two.val = two.val, one.val # 32ms, 98%, if use the swap value way # zero = two # one = three # two = one.next if one else None zero.next = two one.next = three two.next = one zero = one one = one.next two = one.next if one else None return dummy.next
def test_case3(self): # ====> l1 = [5] l2 = [5] answer = [0, 1] result = self.sol.addTwoNumbers(ListNode.parseArray2List(l1), ListNode.parseArray2List(l2)) self.assertEqual(answer, ListNode.parseList2Array(result))
def test_case2(self): head = ListNode(0) head.next = None n = 1 answer = None result = self.sol.removeNthFromEnd(head, n) self.assertEqual(answer, result)
def rotateRight(self, head, k): """ :type head: ListNode :type k: int :rtype: ListNode """ if head is None or head.next is None: return head cur = head L = 1 while cur.next is not None: cur = cur.next L += 1 cur.next = head # previous is NULL size = L - k % L dummy = ListNode(-1) dummy.next = head for i in range(size): dummy = dummy.next ret = dummy.next dummy.next = None return ret
def test_case3(self): head = ListNode(0) n1 = ListNode(1) head.next = n1 n = 2 answer = n1 result = self.sol.removeNthFromEnd(head, n) self.assertEqual(answer, result)
def removeNthFromEnd2(self, head, n): # slower 72ms dummy=ListNode(0); dummy.next=head p1=p2=dummy for i in range(n): p1=p1.next while p1.next: p1=p1.next; p2=p2.next p2.next=p2.next.next return dummy.next
def test_case4(self): head = ListNode(0) n1 = ListNode(1) head.next = n1 n = 1 answer = head result = self.sol.removeNthFromEnd(head, n) self.assertEqual(None, result.next)
def test_case4(self): head = ListNode(0) n1 = ListNode(1) head.next = n1 n = 1 answer = head result = self.sol.removeNthFromEnd(head, n) self.assertEqual(None, result.next)
def test_case3(self): head = ListNode(0) n1 = ListNode(1) head.next = n1 n = 2 answer = n1 result = self.sol.removeNthFromEnd(head, n) self.assertEqual(answer, result)
def removeNthFromEnd2(self, head, n): # slower 72ms dummy = ListNode(0) dummy.next = head p1 = p2 = dummy for i in range(n): p1 = p1.next while p1.next: p1 = p1.next p2 = p2.next p2.next = p2.next.next return dummy.next
def reverse_link(self, head, tail): dummy = ListNode(-1) dummy.next = head p = head.next while p!=tail: new_next = p.next head.next = new_next p.next = dummy.next dummy.next = p p = new_next return dummy.next
def reverse_link(self, head, tail): dummy = ListNode(-1) dummy.next = head p = head.next while p != tail: new_next = p.next head.next = new_next p.next = dummy.next dummy.next = p p = new_next return dummy.next
def reverse_list(self, head): if not head: return dummy = ListNode(-1) dummy.next = head fast, slow = head.next, head while fast: tmp = fast.next fast.next = slow slow = fast fast = tmp dummy.next.next = None return slow
def reverse_list_wrong(self, head): dummy = ListNode(-1) dummy.next = head fast = head.next mid = head slow = None while fast: mid.next = slow mid = fast slow = mid fast = fast.next # set new tail to None, when only one head node, won't go into fast loop dummy.next.next = None return mid
def reverseBetween_ref(self, head, m, n): if head == None or head.next == None: return head dummy = ListNode(0); dummy.next = head head1 = dummy for i in range(m - 1): head1 = head1.next p = head1.next for i in range(n - m): tmp = head1.next head1.next = p.next p.next = p.next.next head1.next.next = tmp return dummy.next
def deleteDuplicates_ref(self, head): #69ms, 35% if head == None or head.next == None: return head dummy = ListNode(0); dummy.next = head p = dummy tmp = dummy.next while p.next: while tmp.next and tmp.next.val == p.next.val: tmp = tmp.next if tmp == p.next: p = p.next tmp = p.next else: p.next = tmp.next return dummy.next
def reverseBetween_ref(self, head, m, n): if head == None or head.next == None: return head dummy = ListNode(0) dummy.next = head head1 = dummy for i in range(m - 1): head1 = head1.next p = head1.next for i in range(n - m): tmp = head1.next head1.next = p.next p.next = p.next.next head1.next.next = tmp return dummy.next
def reverseList_itera(self, head): # iterative way , 49ms, 67% """ remember to do it in on pass!!! :type head: ListNode :rtype: ListNode """ if head is None: return head dummy = ListNode(0) while head: tmp = head head = head.next tmp.next = dummy.next dummy.next = tmp return dummy.next
def deleteDuplicates_ref(self, head): #69ms, 35% if head == None or head.next == None: return head dummy = ListNode(0) dummy.next = head p = dummy tmp = dummy.next while p.next: while tmp.next and tmp.next.val == p.next.val: tmp = tmp.next if tmp == p.next: p = p.next tmp = p.next else: p.next = tmp.next return dummy.next
def reverseList_itera(self, head): # iterative way , 49ms, 67% """ remember to do it in on pass!!! :type head: ListNode :rtype: ListNode """ if head is None: return head dummy = ListNode(0) while head: tmp = head head = head.next tmp.next = dummy.next dummy.next = tmp return dummy.next
def test_case04(self): nums = [0,1,2] k = 3 from util.list_node import ListNode head = ListNode.parseArray2List(nums) #answer = [head, head.next, head.next.next, head.next.next.next, None] result = self.sol.splitListToParts(head, k) pass
def test_case04(self): nums = [0, 1, 2] k = 3 from util.list_node import ListNode head = ListNode.parseArray2List(nums) #answer = [head, head.next, head.next.next, head.next.next.next, None] result = self.sol.splitListToParts(head, k) pass
def partition_ref2(self, head, x): #39ms, 90% # write your code here if head is None: return head aHead, bHead = ListNode(0), ListNode(0) aTail, bTail = aHead, bHead while head is not None: if head.val < x: aTail.next = head aTail = aTail.next else: bTail.next = head bTail = bTail.next head = head.next bTail.next = None aTail.next = bHead.next return aHead.next
def splitListToParts(self, root, k): """ :type root: ListNode :type k: int :rtype: List[ListNode] """ if not root: return [ [] for _ in range(k)] list_len = self.find_len(root) short_len = list_len / k long_cnt = list_len % k #long_len = short_len + list_len % k long_len = short_len + 1 dummy = ListNode(-1) dummy.next = root res = [] curr = dummy tmp = dummy.next for i in range(long_cnt): res.append(tmp) curr = tmp for j in range(long_len-1): curr = curr.next tmp = curr.next curr.next = None # tmp = curr.next if curr else None dummy = ListNode(-1) dummy.next = tmp curr = dummy for i in range(k - long_cnt): if not short_len: res.append(None) continue res.append(tmp) curr = tmp for j in range(short_len-1): if not curr: return res curr = curr.next if curr: tmp = curr.next curr.next = None else: tmp = None return res
def partition1(self, head, x): #55ms, 45% """ :type head: ListNode :type x: int :rtype: ListNode """ if not head: return None dummy = ListNode(-1) dummy.next = head left = ListNode(-1) ltail = left right = ListNode(-1) rtail = right tmp = head while tmp: if tmp.val < x: ltail.next = tmp ltail = ltail.next else: rtail.next = tmp rtail = rtail.next tmp = tmp.next if left.next: # need to check if left part is None, otherwise wrong for case2 dummy.next = left.next ltail.next = right.next else: dummy.next = right.next rtail.next = None return dummy.next
def reverseKGroup(self, head, k): # Write your code here if not head or k < 2: return head dummy = ListNode(-1) dummy.next = head start = head preHead = dummy while True: head, tail, postTail = self.get_k_nodes(start, k) if not tail: break head, tail = self.reverse_node_list(head, tail) preHead.next = head tail.next = postTail start = postTail preHead = tail return dummy.next
def test_case1(self): nums = [1, 2, 3, 4, 5] #answer = [3,1,4,None,2, None,5] # -- array way answer = [3, 2, 5, 1, None, 4] # -- list way result = self.sol.sortedListToBST(ListNode.parseArray2List(nums)) self.assertEqual( True, TreeNode.compare_tree(result, TreeNode.generate_bt_from_list(answer)))
def swapPairs(self, head): """ :type head: ListNode :rtype: ListNode """ if head is None or head.next is None: return head dummy = ListNode(-1) dummy.next = head tmp = head for i in range(2): cur = head head = head.next cur.next = dummy.next dummy.next = cur tmp.next = self.swapPairs(head) return dummy.next
def removeNthFromEnd(self, head, n): """ :type head: ListNode :type n: int :rtype: ListNode """ dummy = ListNode(-1) dummy.next = head fast = dummy slow = dummy for i in range(n): fast = fast.next while fast.next is not None: fast = fast.next slow = slow.next slow.next = slow.next.next return dummy.next
def reverseKGroup(self, head, k): # Write your code here if not head or k < 2: return head dummy = ListNode(-1) dummy.next = head start = head preHead = dummy while True: head, tail, postTail = self.get_k_nodes(start, k) if not tail: break head, tail = self.reverse_node_list(head, tail) preHead.next = head tail.next = postTail start = postTail preHead = tail return dummy.next
def mergeKListsMinQueue(self, lists): """ :type lists: List[ListNode] :rtype: ListNode """ pq = [] for i in lists: if i is not None: heapq.heappush(pq, (i.val, i)) dummy = ListNode(-1) tmp = dummy while len(pq) > 0: val, cur = heapq.heappop(pq) dummy.next = cur dummy = dummy.next if cur.next is not None: heapq.heappush(pq, (cur.next.val, cur.next)) return tmp.next
def addTwoNumbers_ref(self, l1, l2): # code simpler, but runs slower, around 75%-50% head = ListNode(0) l = head carry = 0 while l1 or l2 or carry: sum, carry = carry, 0 if l1: sum += l1.val l1 = l1.next if l2: sum += l2.val l2 = l2.next if sum > 9: carry = 1 sum -= 10 l.next = ListNode(sum) l = l.next return head.next
def partition_ref(self, head, x): #45ms, 71% head1 = ListNode(0) head2 = ListNode(0) Tmp = head phead1 = head1 phead2 = head2 while Tmp: if Tmp.val < x: phead1.next = Tmp Tmp = Tmp.next phead1 = phead1.next phead1.next = None else: phead2.next = Tmp Tmp = Tmp.next phead2 = phead2.next phead2.next = None phead1.next = head2.next head = head1.next return head
def removeNthFromEnd(self, head, n): """ :type head: ListNode :type n: int :rtype: ListNode """ if not head: # AC by OJ, but just add this for case1 return None dummy = ListNode(-1) dummy.next = head p1 = head for i in range(n - 1): p1 = p1.next p2 = dummy while p1.next: p1 = p1.next p2 = p2.next target = p2.next p2.next = target.next return dummy.next
def removeNthFromEnd(self, head, n): """ :type head: ListNode :type n: int :rtype: ListNode """ if not head: # AC by OJ, but just add this for case1 return None dummy = ListNode(-1) dummy.next = head p1 = head for i in range(n - 1): p1 = p1.next p2 = dummy while p1.next: p1 = p1.next p2 = p2.next target = p2.next p2.next = target.next return dummy.next
def mergeTwoLists(self, l1, l2): """ :type l1: ListNode :type l2: ListNode :rtype: ListNode """ dummy = ListNode(-1) tmp = dummy while l1 and l2: if l1.val < l2.val: dummy.next = l1 l1 = l1.next else: dummy.next = l2 l2 = l2.next dummy = dummy.next if l1: dummy.next = l1 if l2: dummy.next = l2 return tmp.next
def mergeKLists_ref(self, lists): #139ms, 67% """ 解题思路:归并k个已经排好序的链表。使用堆这一数据结构,首先将每条链表的头节点进入堆中,然后将最小的弹出,并将最小的节点这条链表的 下一个节点入堆,依次类推,最终形成的链表就是归并好的链表。 :param lists: :return: """ heap = [] for node in lists: if node: heap.append((node.val, node)) heapq.heapify(heap) head = ListNode(0) curr = head while heap: pop = heapq.heappop(heap) curr.next = ListNode(pop[0]) curr = curr.next if pop[1].next: heapq.heappush(heap, (pop[1].next.val, pop[1].next)) return head.next
def partition(self, head, x): """ :type head: ListNode :type x: int :rtype: ListNode """ small = ListNode(-1) tmpS = small big = ListNode(-1) tmpB = big if head is None or head.next is None: return head while head is not None: if head.val < x: small.next = head small = small.next else: big.next = head big = big.next head = head.next big.next = None small.next = tmpB.next return tmpS.next
def reverseList_recursive_slower( self, head ): # recursive way , 108ms, 1.36% -- 59ms, 40%, iter is still better """ remember to do it in on pass!!! :type head: ListNode :rtype: ListNode """ if head is None: return None dummy = ListNode(-1) self.reverse_list_recur(head, dummy) return dummy.next
def reorderList_ref(self, head): #202ms, 31% """ :type head: ListNode :rtype: void Do not return anything, modify head in-place instead. """ if head == None or head.next == None or head.next.next == None: return # break linked list into two equal length slow = fast = head # 快慢指针技巧 while fast and fast.next: # 需要熟练掌握 slow = slow.next # 链表操作中常用 fast = fast.next.next head1 = head head2 = slow.next slow.next = None # reverse linked list head2 dummy = ListNode(0); dummy.next = head2 # 翻转前加一个头结点 p = head2.next; head2.next = None # 将p指向的节点一个一个插入到dummy后面 while p: # 就完成了链表的翻转 tmp = p; p = p.next # 运行时注意去掉中文注释 tmp.next = dummy.next dummy.next = tmp head2 = dummy.next # merge two linked list head1 and head2 p1 = head1; p2 = head2 while p2: tmp1 = p1.next; tmp2 = p2.next p1.next = p2; p2.next = tmp1 p1 = tmp1; p2 = tmp2
def reverseBetween1(self, head, m, n): #45ms, 49% """ Pay a lot of attention to the links!!! and how to reserve and connect them. Easy to think about it, lots of details that may go wrong when implementation. :type head: ListNode :type m: int :type n: int :rtype: ListNode """ if head is None: return None if m==n: return head dummy = ListNode(-1) dummy.next = head p = dummy cnt = 0 while cnt<m-1 and p: cnt+=1 p=p.next reverse_head = p p=p.next cnt+=1 revers_tail = p p = p.next cnt += 1 while m <=cnt<=n and p: next = p.next p.next = reverse_head.next reverse_head.next = p p = next cnt += 1 if cnt > n: revers_tail.next = next return dummy.next
def reverseKGroup(self, head, k): """ :type head: ListNode :type k: int :rtype: ListNode """ if k == 1: return head tmp = head for i in range(k): if tmp is None: return head tmp = tmp.next dummy = ListNode(-1) dummy.next = head tmp = head for i in range(k): cur = head head = head.next cur.next = dummy.next dummy.next = cur tmp.next = self.reverseKGroup(head, k) return dummy.next
def test_case1(self): nums = [1,2,3,4,5] #answer = [3,1,4,None,2, None,5] # -- array way answer = [3,2,5,1, None,4] # -- list way result = self.sol.sortedListToBST(ListNode.parseArray2List(nums)) self.assertEqual(True, TreeNode.compare_tree(result,TreeNode.generate_bt_from_list(answer)))
def test_case1(self): nums = ListNode.parseArray2List([1,2,3,4,5,6,7]) answer = TreeNode.generate_bt_from_list([4,2,6,1,3,5,7]) result = self.sol.sortedListToBST(nums) self.assertTrue(TreeNode.compare_tree(answer, result))
def test_case1(self): nums = [1,2,3,4] answer = [1,4,2,3] root = ListNode.parseArray2List(nums) self.sol.reorderList(root) self.assertEqual(answer, ListNode.parseList2Array(root))