LeetCode刷题(链表)

链表基础

链表结构的定义

# 链节点类
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

# 链表类
class LinkedList:
    def __init__(self):
        self.head = None
        
	# 根据 data 初始化一个新链表 O(n)
    def create(self, data):
        self.head = ListNode(0)
        cur = self.head
        for i in range(len(data)):
            node = ListNode(data[i])
            cur.next = node
            cur = cur.next
	
    
    # 获取链表长度 O(n)
    def length(self):
        count = 0
        cur = self.head
        while cur:
            count += 1
            cur = cur.next 
        return count
    
    # 查找元素 O(n)
    def find(self, val):
        cur = self.head
        while cur:
            if val == cur.val:
                return cur
            cur = cur.next

        return None
    
    # 链表头部删除元素
	def removeFront(self):
        if self.head:
            self.head = self.head.next
            
	# 链表尾部删除元素
    def removeRear(self):
        if not self.head.next:
            return 'Error'

        cur = self.head
        while cur.next.next:
            cur = cur.next
        cur.next = None
        
	# 链表中间删除元素
    def removeInside(self, index):
        count = 0
        cur = self.head

        while cur.next and count < index - 1:
            count += 1
            cur = cur.next

        if not cur:
            return 'Error'

        del_node = cur.next
        cur.next = del_node.next	       

83.删除排序链表中的重复元素

  • 题目

    给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表
    
  • 分析:

    对链表进行循环,然后省略掉对每个结点中的重复结点,
    即:将head赋值给cur
    当cur.next存在时,
    将cur 赋值给 temp 判断temp.next的值与temp的值是否相等,
    如果相等,则跳过,即temp= temp.next
    直至temp.next的值 != temp的值
    将temp.next 赋值给cur
    然后cur后移一位
    
  • 代码

    class Solution:
        class ListNode():
            def __init__(self, val=0, next=None):
                self.val = val
                self.next = next
    
    
        def deleteDuplicates(self, head: ListNode) -> ListNode:
            cur = head
            while cur:
                temp = cur
                while temp.next and temp.next.val == temp.val:
                    temp = temp.next
                cur.next = temp.next
                cur = cur.next
            return head
    

82.删除排序链表中的重复元素II

  • 题目

    给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表
    
  • 分析:

    需要删除所有重复的元素,
    即设置一个头结点,将所有符合的结点添加入头结点,
    当指针cur的下个元素与下下个元素存在时:
        如果这两个元素的值相同,则用temp保存cur的下一个元素,然后用temp进行遍历,跳过所有重复元素(判断条件为 temp and temp.next and temp.val == temp.next.val)
        然后将temp.next(与前一个元素不同)赋值给cur.next,然后继续进行遍历
    如果指针cur的下个元素与下下个元素不存在时
        将cur右移一位,继续遍历
    
  • 代码

    class Solution:
        class ListNode:
            def __init__(self, val=0, next=None):
                self.val = val
                self.next = next
    
        def deleteDuplicates(self, head: ListNode) -> ListNode:
            head_li = self.ListNode(0, head)  # 将头指针加入到head中,避免第一个元素重复
            cur = head_li
            while cur.next and cur.next.next:
                if cur.next.val == cur.next.next.val:
                    temp = cur.next
                    while temp and temp.next and temp.next.val == temp.val:  # 跳过重复元素
                        temp = temp.next
                    cur.next = temp.next    # 继续进行判断cur.next与cur.next.next是否相同,temp.next是这个循环的结点值的下一个
                else:
                    cur = cur.next
            return head_li.next
    

206.反转链表

  • 题目

    给你单链表的头节点 head ,请你反转链表,并返回反转后的链表
    
  • 分析:

    循环链表,对每个结点进行头插操作,防止对当前指针进行改动,则再进行改动之前需要将移动至下一位
    
  • 代码

    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            # 循环链表,对每个结点进行头插操作
            head_res = ListNode(0)
            cur = head
            while cur:
                temp = cur
                cur = cur.next
                temp.next = head_res.next
                head_res.next = temp
            return head_res.next
    

92.反转链表II

  • 题目

    给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表
    
  • 分析:

    如果left与left相等,则没有进行反转直接返回,
    先将cur移动到要反转链表的前一个结点,并保存到left_node
    将cur(不包括)后right-left+1的结点进行反转存入一个新的链表reverse中
    然后保存cur为right_node这时cur指向所有反转结点的后一个结点
    然后将left_node与reverse拼接,然后遍历head,找到最后一个结点,拼接right_node
    然后返回头结点
    
  • 代码

    # Definition for singly-linked list.
    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    
    
    class Solution:
        def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
            if left == right:
                return head
            reverse = ListNode(0)
            head = ListNode(0, head)
            count = 0
            # 进入到反转的链表的前一个结点
            cur = head
            while cur and count < left - 1:
                count += 1
                cur = cur.next
            # 这里cur为进行反转的链表的前一个结点
            left_node = cur
            count = 0
            cur = cur.next
            while cur and count < right - left + 1:
                temp = cur
                cur = cur.next
                temp.next = reverse.next
                reverse.next = temp
                count += 1
            right_node = cur
            left_node.next = reverse.next
            cur = head
            while cur.next:
                cur = cur.next
            cur.next = right_node
            return head.next
    

链表排序

链表排序简介

  • 适合链表排序的算法:冒泡排序选择排序插入排序归并排序快速排序计数排序桶排序基数排序

  • 不适合链表的排序算法:希尔排序

    • 希尔排序中经常涉及到对序列中第 i + gap 的元素进行操作,其中 gap 是希尔排序中当前的步长。而链表不支持随机访问的特性,导致这种操作不适合链表,因而希尔排序算法不适合进行链表排序
  • 可以用链表排序的但不建议用的排序算法堆排序

    • 堆排序所使用的最大堆 / 最小堆结构本质上是一棵完全二叉树。而完全二叉树适合采用顺序存储结构(数组)。因为数组存储的完全二叉树可以很方便的通过下标序号来确定父亲节点和孩子节点,并且可以极大限度的节省存储空间。

      而链表用在存储完全二叉树的时候,因为不支持随机访问的特性,导致其寻找子节点和父亲节点会比较耗时,如果增加指向父亲节点的变量,又会浪费大量存储空间。所以堆排序算法不适合进行链表排序。

      如果一定要对链表进行堆排序,则可以使用额外的数组空间表示堆结构。然后将链表中各个节点的值依次添加入堆结构中,对数组进行堆排序。排序后,再按照堆中元素顺序,依次建立链表节点,构建新的链表并返回新链表头节点

  • 链表冒泡

    1. 使用三个指针,一个node_i、node_j和tail,node_i用于控制外层循环次数,node_j用于控制内层循环,tail指向链表尾部,即None,node_i,node_j指向头结点

    2. 比较链表中相邻两个元素,如果node_j.val>node_j.next.val,则值进行交换,否则值不进行交换,右移node_j指针,直到node_j==tail时停止

    3. 一次循环之后,将taile移动到node_j的位置,则node_j就是链表中值最大的结点

    4. 右移node_i,并将node_j置于头结点位置,重复2、3步骤

    5. 直到node_i移动到链表末尾停止,排序结束

    6. 返回头结点,head

      代码:

      def bubbleSort(head):
          node_i=head
          tail=None
          while node_i:
              node_j = head
              while node_j and node_j.next != tail:
                  if node_j.val == node.next.val:
                      node_j.val,node_j.next,val = node_j.next.val,node_j.val
                  node_j = node_j.next
              taile = node_j
          	node_i = node_i.next
           return head
                  
      
  • 链表选择排序

    1. 使用两个指针 node_inode_jnode_i 既可以用于控制外循环次数,又可以作为当前未排序链表的第一个链节点位置

    2. 使用 min_node 记录当前未排序链表中值最小的链节点

    3. 每一趟排序开始时,先令 min_node = node_i

    4. 然后依次比较未排序链表中 node_j.valmin_node.val 的值大小。如果 node_j.val < min_node.val,则更新 min_nodenode_j

    5. 这一趟排序结束时,未排序链表中最小值节点为 min_node,如果 node_i != min_node,则将 node_imin_node 值进行交换。如果 node_i == min_node,则不用交换

    6. 排序结束后,继续向右移动 node_i,重复上述步骤,在剩余未排序链表中寻找最小的链节点,并与 node_i 进行比较和交换,直到 node_i == None 或者 node_i.next == None 时,停止排序

    7. 返回链表的头节点 head

      代码:

      def selectSort(head):
          node_i = head
          while node_i:
              min_node = node_i
              node_j = node_i
              while node_j:
                 	if node_j.val <min_node.val:
                      min_node.val = node_j.val
                  node_j = node_j,next
              if node_i.val !=min_node.val:
                  node_i.val,min_node.val = min_node.val,node_i.val
              node_i= node_i.next
          return head
      
  • 链表插入排序

    1. 先使用哑节点 dummy_head 构造一个指向 head 的指针,使得可以从 head 开始遍历。

    2. 维护 sorted_list 为链表的已排序部分的最后一个节点,初始时,sorted_list = head

    3. 维护 prev 为插入元素位置的前一个节点,维护 cur 为待插入元素。初始时,prev = headcur = head.next

    4. 比较 sorted_listcur 的节点值。

      • 如果 sorted_list.val <= cur.val,说明 cur 应该插入到 sorted_list 之后,则将 sorted_list 后移一位。
      • 如果 sorted_list.val > cur.val,说明 cur 应该插入到 headsorted_list 之间。则使用 prevhead 开始遍历,直到找到插入 cur 的位置的前一个节点位置。然后将 cur 插入。
    5. cur = sorted_list.next,此时 cur 为下一个待插入元素。

    6. 重复 4、5 步骤,直到 cur 遍历结束为空。返回 dummy_head 的下一个节点。

      代码

      def insertSort(head):
          if not head and not head.next:
              return head
         	dummy_head=ListNode(-1,head)
          sort_head = head
          cur = head.next
          sorted_list = head
          while cur:
              if sorted_list.val <=cur.val:
                  sorted_list = sorted_list.next
              else:
                  prev = dummy_head
                  while prev.next.val <=cur.head:
                      prev = prev.next
                  sort_list.next = cur.next
                  cur.next = prev.next
                  prev.next = cur
              cur = sorted_list.next
          return dummy_head.next
      
  • 链表归并排序

    1. 分割环节:找到链表中心链节点,从中心节点将链表断开,并递归进行分割。

      • 使用快慢指针 fast = head.nextslow = head,让 fast 每次移动 2 步,slow 移动 1 步,移动到链表末尾,从而找到链表中心链节点,即 slow
      • 从中心位置将链表从中心位置分为左右两个链表 left_headright_head,并从中心位置将其断开,即 slow.next = None
      • 对左右两个链表分别进行递归分割,直到每个链表中只包含一个链节点。
    2. 归并环节:将递归后的链表进行两两归并,完成一遍后每个子链表长度加倍。重复进行归并操作,直到得到完整的链表。

      • 使用哑节点 dummy_head 构造一个头节点,并使用 cur 指向 dummy_head 用于遍历。
      • 比较两个链表头节点 leftright 的值大小。将较小的头节点加入到合并后的链表中。并向后移动该链表的头节点指针。
      • 然后重复上一步操作,直到两个链表中出现链表为空的情况。
      • 将剩余链表插入到合并中的链表中。
      • 将哑节点 dummy_dead 的下一个链节点 dummy_head.next 作为合并后的头节点返回

      代码

      def merge(left,right):
          dummy_head = ListNode(-1)
          cur = dummy_head
          while left and right:
              if left.val <= right.val:
                  cur.next = left
                  left= left.next
              else:
                  cur.next = right
                  right = right.next
              cur = cur.next
          if left:
              cur.next = left
          elif right:
              cur.next = right
          return dummy_head.next
      
      def mergesort(head):
          if not head and not head.next:
              return head
          slow,fast = head,head.next
          while fast and fast.next:# 在中间进行切割
              slow = slow.next
              fast = fast.next.next
          left_head,right_head = head,slow.next
          slow.next = None  # 断开左右链表
          return merge(mergesort(left_head),merge(right_head)
      
  • 链表快速排序

    1. 从链表中找到一个基准值 pivot,这里以头节点为基准值。

    2. 然后通过快慢指针 node_inode_j 在链表中移动,使得 node_i 之前的节点值都小于基准值,node_i 之后的节点值都大于基准值。从而把数组拆分为左右两个部分。

    3. 再对左右两个部分分别重复第二步,直到各个部分只有一个节点,则排序结束。

      代码:

      def partition(left,right):
          # 区间左闭右开,如果只有一个元素则直接返回第一个结点
          if left==right or left.next ==right:
              return left
          # 选择基准结点
          pivot = left.val
          node_i,node_j = left,left.next
          while node_j !=right:
              if node_j.val < pivot:
                  node_i = node_i.next
                  node_i.val,node_j.val = node_j.val,node_i.val
              node_j = node_j.next
          node_i.val,left.val = left.val,node_i.val
          return node_i
      
      def quick_sort(left,right):
          if left==right or left.next ==right:
              return left
          pi = partition(left,right)
          quicksort(left,pi)
          quicksort(pi.next,right)
          return left
      
  • 链表计数排序

    1. 使用 cur 指针遍历一遍链表。找出链表中最大值 list_max 和最小值 list_min

    2. 使用数组 counts 存储节点出现次数。

    3. 再次使用 cur 指针遍历一遍链表。将链表中每个值为 cur.val 的节点出现次数,存入数组对应第 cur.val - list_min 项中。

    4. 反向填充目标链表:

      • 建立一个哑节点 dummy_head,作为链表的头节点。使用 cur 指针指向 dummy_head
      • 从小到大遍历一遍数组 counts。对于每个 counts[i] != 0 的元素建立一个链节点,值为 i + list_min,将其插入到 cur.next 上。并向右移动 cur。同时 counts[i] -= 1。直到 counts[i] == 0 后继续向后遍历数组 counts
    5. 将哑节点 dummy_dead 的下一个链节点 dummy_head.next 作为新链表的头节点返回。

      代码

      def countSort(head):
          if not head:
              return head
          
          # 找出最大值与最小值
          list_min,list_max = float("inf"),float("-inf")
          cur = head
          while cur:
              if cur.val < list_min:
                  list_min = cur.val
              if cur.val > list_max:
                  list_max = cur.val
          	cur=cur.next
          
          size = list_max -list_min +1
          counts = [0]*size
          
          cur = head
          while cur:
              count[cur.val-list_min] +=1
              cur = cur.next
          dummy_head = ListNode(-1)
          cur = dummy_head
          for i in range(size):
              while count[i]:
                  cur.next = ListNode(i+list_min)
                  cur = cur.next
                  count[i] -=1
         	return dummy_head.next
      
  • 链表桶排序

    1. 使用 cur 指针遍历一遍链表。找出链表中最大值 list_max 和最小值 list_min

    2. 通过 (最大值 - 最小值) / 每个桶的大小 计算出桶的个数,即 bucket_count = (list_max - list_min) // bucket_size + 1 个桶。

    3. 定义二维数组 buckets 为桶,外层数组大小为 bucket_count 个。

    4. 使用 cur 指针再次遍历一遍链表,将每个元素装入对应的桶中。

    5. 对每个桶内的元素单独排序(使用插入、归并、快排等算法)。

    6. 最后按照顺序将桶内的元素拼成新的链表,并返回。

      代码

      def insertionSort(self, arr):
          for i in range(1, len(arr)):
              temp = arr[i]
              j = i
              while j > 0 and arr[j - 1] > temp:
                  arr[j] = arr[j - 1]
                  j -= 1
              arr[j] = temp
              
          return arr
      
      def bucketSort(self, head: ListNode, bucket_size=5):
          if not head:
              return head
          
          # 找出链表中最大值 list_max 和最小值 list_min
          list_min, list_max = float('inf'), float('-inf')
          cur = head
          while cur:
              if cur.val < list_min:
                  list_min = cur.val
              if cur.val > list_max:
                  list_max = cur.val
              cur = cur.next
              
          # 计算桶的个数,并定义桶
          bucket_count = (list_max - list_min) // bucket_size + 1
          buckets = [[] for _ in range(bucket_count)]
          
          # 将链表节点值依次添加到对应桶中
          cur = head
          while cur:
              buckets[(cur.val - list_min) // bucket_size].append(cur.val)
              cur = cur.next
          
          dummy_head = ListNode(-1)
          cur = dummy_head
          for bucket in buckets:
              # 对桶中元素单独排序
              self.sortLinkedList(bucket)
              for num in bucket:
                  cur.next = ListNode(num)
                  cur = cur.next
          
          return dummy_head.next
      
  • 链表基数排序

    1. 使用 cur 指针遍历链表,获取节点值位数最长的位数 size

    2. 从个位到高位遍历位数。因为 0 ~ 9 共有 10 位数字,所以建立 10 个桶。

    3. 以每个节点对应位数上的数字为索引,将节点值放入到对应桶中。

    4. 建立一个哑节点 dummy_head,作为链表的头节点。使用 cur 指针指向 dummy_head

    5. 将桶中元素依次取出,并根据元素值建立链表节点,并插入到新的链表后面。从而生成新的链表。

    6. 之后依次以十位,百位,…,直到最大值元素的最高位处值为索引,放入到对应桶中,并生成新的链表,最终完成排序。

    7. 将哑节点 dummy_dead 的下一个链节点 dummy_head.next 作为新链表的头节点返回。

      代码

      def radixSort(self, head: ListNode):       
          # 计算位数最长的位数
          size = 0
          cur = head
          while cur:
              val_len = len(str(cur.val))
              if val_len > size:
                  size = val_len
              cur = cur.next
          
          # 从个位到高位遍历位数
          for i in range(size):
              buckets = [[] for _ in range(10)]
              cur = head
              while cur:
                  # 以每个节点对应位数上的数字为索引,将节点值放入到对应桶中
                  buckets[cur.val // (10 ** i) % 10].append(cur.val)
                  cur = cur.next
              
              # 生成新的链表
              dummy_head = ListNode(-1)
              cur = dummy_head
              for bucket in buckets:
                  for num in bucket:
                      cur.next = ListNode(num)
                      cur = cur.next
              head = dummy_head.next
              
          return head
      

148.排序链表

  • 题目

    •   给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表
      
  • 分析:

    •   可采用链表排序中任何一种算法
      
  • 代码

    •   class Solution:
            def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
                return self.quicksort(head,None)
        
            def quicksort(self,left,right):
                if left == right or left.next == right:
                    return left
                pi = self.potition(left,right)
                self.quicksort(left,pi)
                self.quicksort(pi.next,right)
                return left
        
            def potition(self,left,right):
                if left==right or left.next == right:
                    return left
                pivot = left.val
                node_i,node_j = left,left.next
                while node_j !=right:
                    if node_j.val < pivot:
                        node_i = node_i.next
                        node_i.val,node_j.val = node_j.val,node_i.val
                    node_j = node_j.next
                left.val,node_i.val = node_i.val,left.val
                return node_i
      

21.合并两个有序链表

  • 题目

    •   将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
      
  • 分析

    •   直接采用双指针,比较两个链表表中的值,然后在新链表中拼接
      
  • 代码

    •   class Solution:
            def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
                cur1 = list1
                cur2 = list2
                head = ListNode()
                cur = head
                while cur1 is not None and cur2 is not None:
                    if cur1.val <= cur2.val:
                        cur.next =cur1
                        cur = cur.next
                        cur1 = cur1.next
                    else:
                        cur.next = cur2
                        cur = cur.next
                        cur2 = cur2.next
                if cur1 is None:
                    cur.next = cur2
                else:
                    cur.next = cur1
                return head.next
      

24.合并K个升序链表

  • 题目

    •   给你一个链表数组,每个链表都已经按升序排列。
        
        请你将所有链表合并到一个升序链表中,返回合并后的链表
      
  • 分析

    •   使用优先级队列,将每一个链表的头结点存入优先级队列中,然后选取队列中最小的值,然后在那拿出结点的链表,该链表后移一位,然后再存入优先级队列,直到链表为空
      
  •   class Solution:
          def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
              from queue import PriorityQueue
      
              pq = PriorityQueue()
              head = ListNode(0)
              cur = head
              for i in range(len(lists)):
                  if lists[i] is not None:
                      pq.put((lists[i].val,i))
              while not pq.empty():
                  idx = pq.get()[1]
                  li = lists[idx]
                  cur.next = li
                  cur = cur.next
                  lists[idx] = lists[idx].next
                  if lists[idx] is not None:
                      pq.put((lists[idx].val,idx))
              return head.next
    

链表双指针

起点不一致的快慢指针

起点不一致的快慢指针:指的是两个指针从同一侧开始遍历链表,但是两个指针的起点不一样。 快指针 fast 比慢指针 slow 先走 n 步,直到快指针移动到链表尾端时为止

  • 求解步骤

    • 使用两个指针 slowfastslowfast 都指向链表的头节点,即:slow = headfast = head
    • 先将快指针向右移动 n 步。然后再同时向右移动快、慢指针。
    • 等到快指针移动到链表尾部(即 fast == None)时跳出循环体
  • 代码模板

    •   slow = head
        fast = head
        
        while n:
            fast = fast.next
            n -= 1
        while fast:
            fast = fast.next
            slow = slow.next
      
  • 适用范围:

    • 起点不一致的快慢指针主要用于找到链表中倒数第 k 个节点、删除链表倒数第 N 个节点等

19.删除链表的倒数第N个结点

  • 题目:

    •   给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点
      
  • 分析:

    •   使用起点不一样的快慢指针,先将快指针走n步,然后快慢指针一起移动,当快指针达到末尾是,慢指针刚好指向倒数第n个结点的前一个结点
      
  • 代码:

    •   class Solution:
            def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
                head = ListNode(0,head)
                fast,slow = head,head
                while n:
                    fast=fast.next
                    n-=1
                while fast.next:
                    fast = fast.next
                    slow = slow.next
                slow.next = slow.next.next
                return head.next
      

步长不一样的快慢指针

步长不一致的慢指针:指的是两个指针从同一侧开始遍历链表,两个指针的起点一样,但是步长不一致。例如,慢指针 slow 每次走 1 步,快指针 fast 每次走两步。直到快指针移动到链表尾端时为止

  • 求解步骤

    • 使用两个指针 slowfastslowfast 都指向链表的头节点。
    • 在循环体中将快、慢指针同时向右移动,但是快、慢指针的移动步长不一致。比如将慢指针每次移动 1 步,即 slow = slow.next。快指针每次移动 2 步,即 fast = fast.next.next
    • 等到快指针移动到链表尾部(即 fast == None)时跳出循环体
  • 代码模板

    •   fast = head
        slow = head
        
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
      
  • 使用范围

    • 步长不一致的快慢指针适合寻找链表的中点、判断和检测链表是否有环、找到两个链表的交点等问题。

876.链表的中间结点

  • 题目

    •   给定一个头结点为 head 的非空单链表,返回链表的中间结点。
        
        如果有两个中间结点,则返回第二个中间结点
      
  • 分析

    •   slow移动一步,fast移动两步,当fast与fast.next不存在时,slow即中间结点
      
  • 代码:

    •   class Solution:
            def middleNode(self, head: ListNode) -> ListNode:
                if not head:
                    return head
                slow = head
                fast = head
                while fast and fast.next:
                    slow = slow.next
                    fast = fast.next.next
                return slow
      

分离双指针

分离双指针:两个指针分别属于不同的链表,两个指针分别在两个链表中移动

  • 求解步骤

    • 使用两个指针 left_1left_2left_1 指向第一个链表头节点,即:left_1 = list1left_2 指向第二个链表头节点,即:left_2 = list2
    • 当满足一定条件时,两个指针同时右移,即 left_1 = left_1.nextleft_2 = left_2.next
    • 当满足另外一定条件时,将 left_1 指针右移,即 left_1 = left_1.next
    • 当满足其他一定条件时,将 left_2 指针右移,即 left_2 = left_2.next
    • 当其中一个链表遍历完时或者满足其他特殊条件时跳出循环体
  • 代码模板

    •   left_1 = list1
        left_2 = list2
        
        while left_1 and left_2:
            if 一定条件 1:
                left_1 = left_1.next
                left_2 = left_2.next
            elif 一定条件 2:
                left_1 = left_1.next
            elif 一定条件 3:
                left_2 = left_2.next
      

21.合并两个有序链表

  • 题目

    •   将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
      
  • 分析

    •   直接采用双指针,比较两个链表表中的值,然后在新链表中拼接
      
  • 代码

    •   class Solution:
            def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
                cur1 = list1
                cur2 = list2
                head = ListNode()
                cur = head
                while cur1 is not None and cur2 is not None:
                    if cur1.val <= cur2.val:
                        cur.next =cur1
                        cur = cur.next
                        cur1 = cur1.next
                    else:
                        cur.next = cur2
                        cur = cur.next
                        cur2 = cur2.next
                if cur1 is None:
                    cur.next = cur2
                else:
                    cur.next = cur1
                return head.next
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值