迭代需要三个指针,pre,cur,nxt,分别按顺序指向三个节点
三个指针的初始化:pre指向空节点,cur指向头结点head,nxt指向head.next
因为head.next可能不存在,nxt在循环中定义,这样如果head为空就不会进入循环
迭代过程
class Solution: def reverseList(self, head: ListNode) -> ListNode: curr,pre = head,None while curr: nxt = curr.next pre = curr curr.next = pre cur = nxt return pre
先模拟出这个过程:使用1->2->3->4->5模拟作为例子
先初始化出:curr
表示当前指针指向的对象为head
;res
代表结果指针,初始化为None
。while循环进行res,curr赋值情况如下表:
class Solution: def reverseList(self, head: ListNode) -> ListNode: curr,res = head,None while curr: res,res.next,curr = curr,res,curr.next return res
次数 | res = curr: res | res.next=res : res | curr = curr.next: curr |
---|---|---|---|
1 | 1->2->3->4->5 | 1->None | 2->3->4->5 |
2 | 2->3->4->5 | 2->1->None | 3->4->5 |
3 | 3->4->5 | 3->2->1->None | 4->5 |
4 | 4->5 | 4->3->2->1->None | 5 |
5 | 5 | 5->4->3->2->1->None | None |
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: if l1 is None: return l2 if l2 is None: return l1 if l1.val < l2.val: l1.next = self.mergeTwoLists(l1.next,l2) return l1 else: l2.next = self.mergeTwoLists(l1,l2.next) return l2
解决有序链表的一般解决思路,使用python的特性,先定义一个哨兵结点res,然后在遍历过程中维护一个pre指针,在循环迭代的过程中找到每一次的需求。
class Solution: def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: if l1 is None: return l2 if l2 is None: return l1 res = ListNode(0) # 首先预定义一个栈 pre = ListNode(0) while l1 and l2: if l1.val > l2.val: pre.next = l2 l2 = l2.next else: pre.next = l1 l1 = l1.next pre = pre.next pre.next = l1 if l1 else l2 return res.next
将链表的值复制到数组中后使用双指针法进行求解
class Solution: def isPalindrome(self, head: ListNode) -> bool: vals = [] current_node = head while current_node is not None: vals.append(current_node.val) current_node = current_node.next return vals == vals[::-1]
时间复杂度O(n),空间复杂度O(n), 其中链表转化为数组的时间复杂度为O(n),空间复杂度也为O(n)。双指针数组对比时间复杂度为O(n),空间复杂度也为O(n)。因此总的来看时间复杂度为O(n),算法复杂度为O(n)。
。。。
使用双指针的方法:快指针用来判断前后是否相等,慢指针用来将不相等的值按顺序存储。
class Solution: def removeDuplicates(self, nums: List[int]) -> int: # 使用双指针的方法进行求解 if not nums: return 0 j = 0 for i in range(1,len(nums)): if nums[i-1] != nums[i]: j +=1 nums[j] = nums[i] return j+1
class Solution: def deleteDuplicates(self, head: ListNode) -> ListNode: curr = head if not head: return head while curr.next: if curr.val == curr.next.val: curr.next = curr.next.next else: curr = curr.next return head
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def rotateRight(self, head: ListNode, k: int) -> ListNode: if not head or not head.next: return head curr = head n = 0 while curr: n+=1 curr = curr.next k = k % n if k == 0: return head p = head for i in range(n-k-1): p = p.next nxt = p.next p.next = None new_nxt = nxt
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def mergeInBetween(self, list1: ListNode, a: int, b: int, list2: ListNode) -> ListNode: curr = list1 for i in range(b+1): if i < a-1: curr = curr.next elif i == a-1: nxt = curr.next curr.next = list2 else: nxt = nxt.next while curr.next: curr = curr.next curr.next = nxt return list1
假设链表的总长度为n,我们可以先得出k个升序链表的总长度,然后使用一个列表Docker存储当前K个链表的当前头节点的值,如果当前的链表为空,那么令其值为10**5(该值大于题目所规定的链表的最大值)。然后循环查找Docker中的最小值,并将其链接结果链表中。时间复杂度:O(KN), 空间复杂度O(K)
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def mergeKLists(self, lists: List[ListNode]) -> ListNode: res = ListNode(0) curr = res count = 0 # 查看所有链表的总长度count for item in lists: while item: count+= 1 item = item.next if count == 0: return None docker = [] for lst in lists: if lst is not None: docker.append(lst.val) else: docker.append(10**5) # 10**5代表无法取到的最大值 while count > 0: # 遍历count次将链表组合到res链表中 count -= 1 curr_min = min(docker) for i in range(len(docker)): if docker[i] == curr_min: tmp = docker[i] curr.next = lists[i] curr = curr.next if lists[i].next: docker[i] = lists[i].next.val lists[i] = lists[i].next else: docker[i] = 10**5 break return res.next