def generate_test_list2(): n1 = ListNode(1) n2 = ListNode(2) n1.next = n2 return n1
def reverseLinkedListII(head, m, n): if head == None: return None dummy = ListNode(0) dummy.next = head head = dummy # find premmNode and mNode for i in range(1, m): head = head.next prevmNode = head mNode = head.next # reverse link from m to n nNode = mNode nextnNode = nNode.next for i in range(m, n): temp = nextnNode.next nextnNode.next = nNode nNode = nextnNode nextnNode = temp # combine prevmNode.next = nNode mNode.next = nextnNode return dummy.next
def insertAtHead(self, item): ''' pre: an item to be inserted into list post: item is inserted into beginning of list ''' node = ListNode(item) if not self.length: # set the cursor to the head because it's the # first item inserted into the list self.head = node elif self.length == 1 and not self.tail: self.tail = self.head node.link = self.tail self.head = node else: node.link = self.head self.head = node # set the cursor to the head if it's not set yet if not self.cursor: self.cursor = self.head self.length += 1
def oddEvenList(self, head): """ :type head: ListNode :rtype: ListNode """ if not head: return dummy1, dummy2 = ListNode(0), ListNode(0) dummy1.next = head dummy2.next = head.next dummy3 = head.next count = 3 while head and dummy3 and dummy3.next and head.next: if head.next.next and not dummy3.next.next: head.next = head.next.next head = head.next break elif not head.next.next and dummy3.next.next: dummy3.next = dummy3.next.next dummy3 = dummy3.next break if count%2: head.next = head.next.next head = head.next else: dummy3.next = dummy3.next.next dummy3 = dummy3.next head.next = dummy2.next if dummy3: dummy3.next = None return dummy1.next
def rotateLSegment(l, m, n): dummyN = ListNode(0) dummyN.next = l l = dummyN rslt, i = l, 0 while i < m-1: l = l.next i += 1 t, i = None, 0 beg, end = l, l.next l = l.next while l and i <= n-m: h = l l = l.next h.next = t t = h i += 1 beg.next = t end.next = l return dummyN.next
def deleteDuplicates(self, head): """ :type head: ListNode :rtype: ListNode """ if not head: return head # a dummy node is must dummy = ListNode(0) dummy.next = head prev = dummy current = head while current: if current.next and current.val == current.next.val: # find duplciate, delete all while current.next and current.val == current.next.val: current = current.next # now current pointer is at last node of duplicated # delete duplicated nodes prev.next = current.next current = current.next # @note: prev stays the same else: prev = current current = current.next return dummy.next # return could be a empty list, if input list with all duplicates
def revKGroup_r(h, k): count = 0 dummy = ListNode(-1) dummy.next = h n = dummy head = dummy while head: tail = head.next n = tail while n and count < k: n = n.next count += 1 if count < k and not n: break count = 0 stopN = n head.next = revK_r(tail, stopN) tail.next = stopN head = tail return dummy.next
def test3(): n1 = ListNode(1) n2 = ListNode(2) n1.next = n2 ListNode.print_ll(reorderList(n1))
def test3(): n1 = ListNode(1) n2 = ListNode(2) n2.next = n1 h = n2 rslt = mergeSort(h) ListNode.print_ll(rslt)
def generate_test_list3(): n1 = ListNode(1) n2 = ListNode(2) n3 = ListNode(3) n1.next = n2 n2.next = n3 return n1
def addNumbers(h1, h2): l1, l2 = getLeng(h1), getLeng(h2) needToAdd1 = addNumRecur(h1, h2, l1 >= l2, abs(l1-l2)) if needToAdd1: newN = ListNode(1) newN.next = (h1 if l1>=l2 else h2) return newN else: return (h1 if l1>=l2 else h2)
def test2(): n1a = ListNode(1) n1b = ListNode(1) n1c = ListNode(1) n1a.next = n1b n1b.next = n1c rslt = removeElement(n1a, 1) print(ListNode.print_ll(rslt))
def test_quicksort_list(self): A = ListNode.makeList([5, 4, 3, 2, 1, 6, 10, 7, 8, 9]) quicksort_list(A, None) A.show() A = ListNode.makeList([2, 1, 2, 4, 5, 9, 8]) quicksort_list(A, None) A.show() A = ListNode.makeList([10]) quicksort_list(A, None) A.show()
def removeElement(n, val): dummyN = ListNode(-1) dummyN.next = n h = dummyN while h: if h.next and h.next.val == val: h.next = h.next.next else: h = h.next return dummyN.next
def test004(self): print "test 004" n0 = ListNode(0) n0.next = n0 r = Solution().detectCycle(n0) print " expect:\t", True print " output:\t", r print
def test_hasCycle(self): s = LeetSolution() self.assertFalse(s.hasCycle(None)) A = ListNode.makeList([1]) self.assertFalse(s.hasCycle(A)) A.next = A self.assertTrue(s.hasCycle(A)) A = ListNode.makeList([1, 2, 3, 4, 5]) self.assertFalse(s.hasCycle(A)) A = ListNode.makeList([1, 2, 3, 4, 5]) A.tail.next = A.next.next self.assertTrue(s.hasCycle(A))
def test_removeNthFromEnd(self): s = LeetSolution() head = ListNode.makeList([1, 2, 3, 4, 5]) s.removeNthFromEnd(head, 2).show() head = ListNode.makeList([1, 2]) s.removeNthFromEnd(head, 1).show() head = ListNode.makeList([1]) print(s.removeNthFromEnd(head, 1)) head = ListNode.makeList([1, 2]) s.removeNthFromEnd(head, 2).show() head = ListNode.makeList([1, 2, 3]) s.removeNthFromEnd(head, 3).show()
def removeLinkedListElements(head, val): if head == None or val == None: return head dummy = ListNode(0) dummy.next = head head = dummy while head.next != None: if head.next.val == val: head.next = head.next.next else: head = head.next return dummy.next
def test004(self): print "test 004" n0 = ListNode(0) n0.next = n0 hasCycle = Solution().hasCycle(n0) print " expect:\t", True print " output:\t", hasCycle print
def test2(): n1 = ListNode(1) n1a = ListNode(1) n1b = ListNode(1) n2 = ListNode(2) n3 = ListNode(3) n1.next = n1a n1a.next = n1b n1b.next = n2 n2.next = n3 ListNode.print_ll(removeDupComp(n1))
def test3(): n1 = ListNode(1) n1a = ListNode(1) n1b = ListNode(1) n2a = ListNode(2) n2b = ListNode(2) n1.next = n1a n1a.next = n1b n1b.next = n2a n2a.next = n2b ListNode.print_ll(removeDupComp(n1))
def nthtoLastNodeinList(head, n): if head is None or n is None: return None dummy = ListNode(0) dummy.next = head fast = head slow = head for i in range(n): fast = fast.next while fast is not None: fast =fast.next slow = slow.next return slow
def test_detectCycle(self): s = LeetSolution() self.assertEqual(None, s.detectCycle(None)) A = ListNode.makeList([1]) self.assertEqual(None, s.detectCycle(A)) A = ListNode.makeList([1, 2, 3, 4, 5]) self.assertEqual(None, s.detectCycle(A)) A = ListNode.makeList([1]) A.next = A self.assertEqual(1, s.detectCycle(A).val) A = ListNode.makeList([1, 2, 3, 4, 5]) A.tail.next = A.next.next self.assertEqual(3, s.detectCycle(A).val)
def test1(): n0 = ListNode(0) n1 = ListNode(1) n2 = ListNode(2) n3 = ListNode(3) n4 = ListNode(4) n0.next = n1 n1.next = n2 n2.next = n3 n3.next = n4 ListNode.print_ll(reorderList(n0))
def removeDuplicatesfromUnsortedList(head): if head == None: return None dummy = ListNode(0) dummy.next = head head = dummy s = set() while head.next != None: if head.next.val in s: head.next = head.next.next else: s.add(head.next.val) head = head.next return dummy.next
def partition(self, head, x): """ :type head: ListNode :type x: int :rtype: ListNode """ if not head: return head # maintain the tail of sub-list with (nodes <= target) tail = ListNode(0) tail.next = head dummy = tail # record it currentPrev = tail current = head # two operation: 1. cut smaller node; 2. insert to sublist while current: ''' @note:@memorize: 下面的反人类解法我也给自己跪了,找到比x小的,插入。 一直维护小于x的sublist的tail,被main里的测试fail 其实,维护大于等于x的sublit的head,要更加简单,符合人类思维。。。 ''' if current.val < x: # update tail pointer, but do nothing # 1. cut currentPrev.next = current.next currentForNextLoop = current.next # record it first # 2. insert tmp = tail.next tail.next = current current.next = tmp tail = current # update smaller-node-list tail current = currentForNextLoop # for next loop # @note: here, no update for currentPrev, still the same one else: currentPrev = current current = current.next return dummy.next
def removeNthNodefromEndofList(head, n): if head == None and not n: return head dummy = ListNode(0) dummy.next = head slow = dummy fast = dummy for i in range(n): fast = fast.next while fast.next != None: slow = slow.next fast = fast.next slow.next = slow.next.next return dummy.next
def reverseBetween(self, head, m, n): """ :type head: ListNode :type m: int :type n: int :rtype: ListNode """ """ Given: 1->2->3->4->5->NULL, m = 2 and n = 4, return: 1->4->3->2->5->NULL. """ # also need to check list-length >= m,n if not head or m > n: return head dummy = ListNode(0) dummy.next = head prev = dummy current = head count = 1 while count < m: prev = current current = current.next count += 1 # now current is at m-th node # @note:@memorize: m-node will always be tail of this local-reversed list # 1,3,2,4,5 => 1,4,3,2,5 localTail = current while count < n: # @note:@memorize: note the times of operation, 1-time less # cache 2 ends, especially current.next, since it will be overwritten currenthead = prev.next futureHead = localTail.next # do the swap prev.next = futureHead localTail.next = futureHead.next futureHead.next = currenthead count += 1 return dummy.next
def deleteDuplicates(self, head): if not head: return head dummy_head = ListNode(head.val - 1) dummy_head.next = head pre = dummy_head while pre: cur = pre.next if cur and cur.next and cur.val == cur.next.val: while cur and cur.next and cur.val == cur.next.val: cur = cur.next pre.next = cur.next cur = pre.next else: pre = cur return dummy_head.next
def reverseList(self, head): if not head: return head dummy = ListNode(0) while head: tmpDummyNext = dummy.next tmpHeadNext = head.next # @note: should record head.next first: i.e., cut out head node dummy.next = head head.next = tmpDummyNext head = tmpHeadNext # @memorize: stupid, head.next is modified above already! return dummy.next
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: x = l1 y = l2 e = 0 root = ListNode(-1) tail = root while x != None or y != None: xv = x.val if x != None else 0 yv = y.val if y != None else 0 res = xv + yv + e r = res % 10 e = res // 10 rl = ListNode(r) tail.next = rl tail = rl x = x.next if x != None else None y = y.next if y != None else None if e != 0: tail.next = ListNode(1) return root.next
def deleteDuplicates(self, head): # write your code here if head is None: return head prehead = ListNode(head.val - 1) prehead.next = head node = prehead while node.next and node.next.next: if node.next.val == node.next.next.val: v = node.next.val tnode = node.next while tnode: if tnode.val == v: tnode = tnode.next else: break node.next = tnode else: node = node.next return prehead.next
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: add_one = False sum_node = ListNode(0) savehead = sum_node while l1 or l2 or add_one: sum_node.next = ListNode(0) sum_node = sum_node.next if l1: sum_node.val += l1.val l1 = l1.next if l2: sum_node.val += l2.val l2 = l2.next if add_one: sum_node.val += 1 add_one = False if sum_node.val >= 10: sum_node.val -= 10 add_one = True return savehead.next
def addTwoNumbersHelper(l1, l2): l1_p, l2_p = l1, l2 carry, dummy_result = 0, ListNode(-1) tail = dummy_result while l1_p or l2_p or carry: l1_val = 0 if not l1_p else l1_p.val l2_val = 0 if not l2_p else l2_p.val cur_sum = l1_val + l2_val + carry tail.next = ListNode(cur_sum % 10) tail = tail.next carry = cur_sum / 10 if l1_p: l1_p = l1_p.next if l2_p: l2_p = l2_p.next return dummy_result.next
def merge_two_sorted_lists(l1, l2): dummy_head = tail = ListNode() while l1 and l2: if l1.data > l2.data: tail.next, l2 = l2, l2.next else: tail.next, l1 = l1, l1.next tail = tail.next tail.next = l1 or l2 return dummy_head.next
def partition(self, head: ListNode, x: int) -> ListNode: if not head: return None list_left = ListNode(201) list_right = ListNode(201) sentinel_left = list_left sentinel_right = list_right while head: if head.val < x: list_left.next = ListNode(head.val) list_left = list_left.next else: list_right.next = ListNode(head.val) list_right = list_right.next head = head.next list_left.next = sentinel_right.next return sentinel_left.next
def remove_kth_last(L, k): dummy_head = ListNode(0, L) first = dummy_head.next for _ in range(k): first = first.next second = dummy_head while first: first, second = first.next, second.next second.next = second.next.next return dummy_head.next
def removeElements(self, head, val): """ 算法:dummy节点 思路: 设置dummy节点,head节点向后遍历,如果找到==val的head就删除,否则的话指针向后挪 复杂度分析: 时间:ON 空间:O1 """ dummy = ListNode(0) dummy.next = head pre = dummy while head: if head.val == val: pre.next = head.next head = pre.next else: head = head.next pre = pre.next return dummy.next
def swapPairs0(self, head): """ do as they say 按照人家的要求来 """ if head == None or head.next == None: return head dummy = ListNode(0) p = dummy dummy.next = head while p and p.next and p.next.next: first = p.next second = p.next.next third = p.next.next.next p.next = second second.next = first first.next = third p = first return dummy.next
def mergeKLists_bruteforce(self, lists): """ 算法:"暴力"求解 遍历链表,将所有元素添加进一个list,对list排序后构建成链表的形式 复杂度分析: 时间:Onlogn,转为list要On,排序Onlogn,转成链表On,共Onlogn 空间:On,sort的空间+最后新建后返回的On长度的链表 """ nodes = [] for i in range(len(lists)): head = lists[i] while head != None: nodes.append(head.val) head = head.next nodes.sort() dummy = ListNode(0) p = dummy for x in nodes: p.next = ListNode(x) p = p.next return dummy.next
def even_odd_merge_original(L): if not L: return L even_head = even_tail = ListNode(0, None) odd_head = odd_tail = ListNode(0, None) curr = L while curr: if curr.data % 2 == 0: even_tail.next = curr even_tail = curr else: odd_tail.next = curr odd_tail = curr curr = curr.next even_tail.next = odd_head odd_tail.next = None return even_head.next
def addTwoNumbers(n1, n2, co): if n1 is None and n2 is None: if co == 0: return None return ListNode(co) n1_val = 0 n2_val = 0 if n1 is not None: n1_val = n1.val if n2 is not None: n2_val = n2.val s = n1_val + n2_val + co new_n = ListNode(s % 10) n1_next = None if n1 is None else n1.next n2_next = None if n2 is None else n2.next new_n.next = addTwoNumbers(n1_next, n2_next, s / 10) return new_n
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: if m == n: return head dummy = ListNode(-1) dummy.next = head pre, cur = None, dummy for _ in range(m): pre, cur = cur, cur.next pos = pre pre, cur = cur, cur.next for _ in range(m, n): cur.next, pre, cur = pre, cur, cur.next pos.next.next = cur pos.next = pre return dummy.next
def removeDupComp(head): """ Got this first try. 96.2% - 39.0% performance """ if not head: return None dummy = ListNode(head.val - 1) dummy.next = head i, j = dummy, dummy.next while j: if i.next == j: j = j.next elif i.next.val == j.val: while j and i.next.val == j.val: j = j.next i.next = j else: i = i.next j = j.next return dummy.next
def mergeTwoLists(self, l1, l2): cur = dummy = ListNode(0) while l1 and l2: if l1.val <= l2.val: cur.next = l1 l1 = l1.next else: cur.next = l2 l2 = l2.next cur = cur.next cur.next = l1 or l2 return dummy.next
def deleteDuplicates(self, head: ListNode) -> ListNode: sentinel = ListNode(101, head) pred = sentinel while head: if head.next and head.val == head.next.val: while head.next and head.val == head.next.val: head = head.next pred.next = head.next else: pred = head head = head.next return sentinel.next
def partition_(self, head, x): """ 算法:与上述方法相似,不同的是这里每次创建新的节点,这样最后就不用q.next = None了,但是这样会增大空间复杂度 时间:ON,遍历原链表需要On 空间:ON,两个辅助链表需要ON+ON,故总ON """ left = ListNode(0) p = left right = ListNode(0) q = right while head != None: if head.val < x: p.next = ListNode(head.val) p = p.next else: q.next = ListNode(head.val) q = q.next head = head.next p.next = right.next return left.next
def reorderList(self, head: ListNode) -> None: """ Do not return anything, modify head in-place instead. """ dummy = ListNode(0) dummy.next = head fast = slow = dummy while fast and fast.next: slow = slow.next fast = fast.next.next ReverseHead = self.__reverse(slow.next) slow.next = None ptr1 = head ptr2 = ReverseHead while ptr1 and ptr2: tmp1 = ptr1.next tmp2 = ptr2.next ptr1.next = ptr2 ptr2.next = tmp1 ptr1 = tmp1 ptr2 = tmp2
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: if head is None or n < 0: return None dummy_head = ListNode(-1) dummy_head.next = head node1 = dummy_head node2 = dummy_head for i in range(n): node1 = node1.next if node1 is None: return None while node1.next is not None: node1 = node1.next node2 = node2.next node2.next = node2.next.next return dummy_head.next
def main(): node7 = ListNode('7', None) node6 = ListNode('6', node7) node5 = ListNode('5', node6) node4 = ListNode('4', node5) node3 = ListNode('3', node4) node2 = ListNode('2', node3) node1 = ListNode('1', node2) node0 = ListNode('0', node1) newhead = reverse_single_linked_list(node0) while newhead: print(newhead.val) newhead = newhead.next
def insert( self, index, data ): #runs in O(n) time. #we are inserting the data at the index you assign to. newNode = ListNode(data, None, None) itrNode = self.__start counter = 1 while ( counter < index ): # we are going to loop based on where we want to insert the new node itrNode = self.__start.getNext() # this iteraters through each node counter = counter + 1 # we are keeping track of whwere the index is in the linked list. if (index == 0): self.push_front(data) elif (index > self.__length): self.push_back(data) else: #A in the code will be itrNode #B in the code will be itrNode.getPrevious(); A = itrNode B = itrNode.getPrevious() newNode.setPrevious(B) newNode.setNext(A) B.setNext(newNode) A.setPrevious(newNode)
def sortList2(self, head): """ Disscussion QuickSort 算法:快排 思路: 快排的链表写法,要注意一些dummy节点的运用,以及记录pre和post等 复杂度分析: 时间:NLOGN 空间:01,不考虑递归栈的话 """ def partition(start, end): node = start.next.next pivotPrev = start.next pivotPrev.next = end pivotPost = pivotPrev while node != end: temp = node.next if node.val > pivotPrev.val: node.next = pivotPost.next pivotPost.next = node elif node.val < pivotPrev.val: node.next = start.next start.next = node else: node.next = pivotPost.next pivotPost.next = node pivotPost = pivotPost.next node = temp return [pivotPrev, pivotPost] def quicksort(start, end): if start.next != end: prev, post = partition(start, end) quicksort(start, prev) quicksort(post, end) newHead = ListNode(0) newHead.next = head quicksort(newHead, None) return newHead.next
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: if l1 is None: return l2 if l2 is None: return l1 newhead = ListNode(-1, None) returnhead = newhead while l1 and l2: if l1.val < l2.val: newhead.next = l1 l1 = l1.next else: newhead.next = l2 l2 = l2.next newhead = newhead.next if l1: newhead.next = l1 if l2: newhead.next = l2 return returnhead.next
def swapPairs(self, head): """ My Method 算法:倒插 思路: 本题思路比较直观,就是新建一个dummy,然后给原链表也建一个头节点,每两个结点倒插 到新的dummy后,如果出现落单的那直接在尾部插入其即可,说明一定是最后一个结点了, 9=2*4+1,8=2*4 要注意的是每次倒插完之后要将p.next 置None,断掉尾部节点与原链表之间的关系 复杂度分析: 时间:ON,遍历一遍链表 空间:O1,常数级 """ if head == None or head.next == None: return head dummy = ListNode(0) p = dummy dummy_head = ListNode(0) dummy_head.next = head while dummy_head.next != None: if dummy_head.next.next != None: p.next = dummy_head.next.next tmp = dummy_head.next dummy_head.next = dummy_head.next.next.next p = p.next p.next = tmp else: p.next = dummy_head.next dummy_head.next = None p = p.next p.next = None return dummy.next
def deleteDuplicates3(self, head: ListNode) -> ListNode: dummy = ListNode(-1) pre, cur = dummy, head while cur: if cur.next and cur.next.val == cur.val: while cur.next and cur.val == cur.next.val: cur = cur.next else: pre.next = cur pre = pre.next cur = cur.next pre.next = None return dummy.next
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: sentinel = ListNode() head = sentinel while l1 and l2: if l1.val > l2.val: head.next = l2 l2 = l2.next else: head.next = l1 l1 = l1.next head = head.next head.next = l1 or l2 return sentinel.next
def removeNthFromEnd(head: ListNode, n: int) -> ListNode: first = head while n: n -= 1 first = first.next result = ListNode(0, head) second = result while first: first = first.next second = second.next second.next = second.next.next return result.next
def merge(self, l1, l2): dummy = ListNode(-1) curr = dummy while l1 and l2: if l1.val < l2.val: curr.next = l1 l1 = l1.next else: curr.next = l2 l2 = l2.next curr = curr.next curr.next = l1 if l1 else l2 return dummy.next
def reverse_between(self, head, m, n): dummy = ListNode(-1, head) pre_m = self.find_k_th(dummy, m - 1) m_th = pre_m.next n_th = self.find_k_th(dummy, n) post_n = n_th.next n_th.next = None self.reverse(m_th) pre_m.next = n_th m_th.next = post_n return dummy.next