链表专题训练

1、合并两个有序链表

  递归:判断两个节点值大小并递归下一次,递归出口为当节点为空时

  

class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        if not list1:
            return list2
        if not list2:
            return list1
        if list1.val<list2.val:
            list1.next=self.mergeTwoLists(list1.next,list2)
            return list1
        if list1.val>list2.val:
            list2.next=self.mergeTwoLists(list2.next,list1)
            return list2
    

 

2、两数相加

class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        pre=ListNode(0)
        cur=pre
        a=0
        while l1!=None or l2!=None:
            x=l1.val if l1 else 0
            y=l2.val if l2 else 0
            s=x+y+a 
            a=1 if s>9 else 0
            s=s%10
            cur.next=ListNode(s)
            cur=cur.next
            l1=l1.next if l1 else None
            l2=l2.next if l2 else None
        if a:
            cur.next=ListNode(a)
        return pre.next

 

3、回文链表

  关i键:有两种解法,第一种创建一个数组复制链表的值然后判断数组是否回文,此种方法消耗O(n)空间;第二种解法用快慢指针,慢指针一次走一步,快指针一次走两步,这样当快指针走到空的的时候慢指针刚好在中间位置

class Solution:
    #方法一
    def isPalindrome(self, head: ListNode) -> bool:
        r=[]
        h=head
        while h!=None:
            r.append(h.val)
            h=h.next
        if r==r[::-1]:
            return True
        return False
    
    
     #方法二:快慢指针
    def isPalindrome(self, head: ListNode) -> bool:
        slow=head
        fast=head
        half_head=self.half(slow,fast)
        rev_half=self.reverse(half_head)
        h=head
        while h!=None and rev_half!=None:
            if h.val!=rev_half.val:
                return False
            h=h.next
            rev_half=rev_half.next
        return True
        
        
    def half(self,slow,fast):
        try:
            while slow.next!=None and fast.next.next!=None:
                slow=slow.next
                fast=fast.next.next
        except:
            pass
        return slow
    
    def reverse(self,half_head):
        h=half_head
        p=None
        while h!=None:
            t=h.next
            h.next=p
            p=h
            h=t
        return p
    
    

 

4、相交链表

  关键:找交点这种题多涉及循环判断,两个链表存在距离差,距离差在前半部分,后半部分长度相等,则两个链表同时遍历时短距离链表先走到链尾,可以使他再次指向长链表链头,当长链表走到链尾时使他指向短链表链头,这样就可以消除距离差,当两链表节点相同时即找到了交点

  

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        p1=headA
        p2=headB
        while p1!=p2:    #因为不管是不是None都要循环,所以循环条件是两者是否相等而不是是否为空
            p1=p1.next if p1 else headB    #一行判断可以提升效率
            p2=p2.next if p2 else headA
        return p1

 

5、排序链表

  关键:取值—>排序—>赋值

class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head:
            return None
        r=[]
        h=head
        while h!=None:
            r.append(h.val)
            h=h.next
        h2=head
        for i in sorted(r):
            h2.val=i 
            h2=h2.next
        return head

        

 

6、环形链表

  关键:遍历链表,判断当前链表是否被遍历过

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        r=set()
        h=head
        while h!=None:
            if h in r:
                return h
            r.add(h)
            h=h.next
        return None

 

7、二叉树展开为链表

消耗时间和空间

class Solution:
    def __init__(self):
        self.r=[]
    def flatten(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        if root==None:
            return
        self.r.append(root.val)
        self.flatten(root.left)
        self.flatten(root.right)
        for i in self.r[1:]:
            root.left=None
            root.right=TreeNode(i)
            root=root.right

 

8、删除链表倒数第n个结点

  关键:设置头节点的细节很重要啊!当需要返回当前链表时一般给当前链表设置一个pre节点的next指向当前head,然后处理完后返回pre.next

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        l=0
        h=head
        while h!=None:
            l+=1
            h=h.next
        pre=ListNode(0,head)
        h2=pre
        for i in range(1,l-n+1):    #索引和题目描述一致,从1开始
            h2=h2.next
        h2.next=h2.next.next
        return pre.next

 

posted @ 2022-07-23 19:44  肥余  阅读(71)  评论(0)    收藏  举报