leetcode2两数相加 445两数相加II 剑指offer22链表中倒数第k个结点 19删除链表的倒数第 N 个结点

156 阅读3分钟

2两数相加

在这里插入图片描述

1.链表转list相加再创建一个新链表

空间复杂度O(n),时间复杂度O(n),需要遍历并储存全部的元素
①遍历两个链表,取出所有元素组成list1,list2
②对两个list求和:
(1)对齐两个list的长度,缺的元素用0补齐
(2)对应元素相加,大于10该结果减10,下一个元素进1,用try语句检测边界(末尾元素进位)
③对求和结果的list创建链表

class Solution:
    ##遍历链表,返回list####
    def travelList(self,L):
        l=[]
        while L:
            l.append(L.val)
            L=L.next
        return l
    ####创建新链表###
    def ceateList(self,L):
        head=ListNode()
        p=head
        for i in L:
            new=ListNode(i)
            p.next=new
            p=new
        return head.next
    ###不同长度list求和####
    def sumlist(self,L1,L2):
        s=[]
        len1,len2=len(L1),len(L2)
        l=max(len1,len2)
        L1.extend([0]*(l-len1))
        L2.extend([0]*(l-len2))
        for i in range(l):
            s.append(L1[i]+L2[i])
        return s

    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        list1,list2=self.travelList(l1),self.travelList(l2)
        r=self.sumlist(list1,list2)
        try:
            for i in range(len(r)):
                if r[i]>=10:
                    r[i]=r[i]-10
                    r[i+1]=r[i+1]+1
        except:
            r.append(1)
        return self.ceateList(r)

在这里插入图片描述

2.设置进位数,每次更新一个Node

class Solution(object):
    def addTwoNumbers(self, l1, l2):
        ###carry为进位数取0,1###
        carry=0
        head=ListNode()
        p=head
        ####l1,l2都指向None停止循环###
        while (l1 or l2):
        	#####指向none时用0补齐####
            x=l1.val if l1 else 0
            y=l2.val if l2 else 0
            s=carry+x+y
            #####进位######
            if s>=10:
                s-=10
                carry=1
            else:
                carry=0
            new=ListNode(s)
            ####给结果链表的新Node赋值####
            p.next=new
            p=new
            #####l1、l2指向下个Noede,加判定防止报错####
            if(l1!=None):l1=l1.next
            if(l2!=None):l2=l2.next
        ####处理边界,看最后一个节点是否需要进位####
        if carry==1:
            p.next=ListNode(1)
        return head.next

445.两数相加II

在这里插入图片描述

1.转list相加再转链表:

class Solution(object):
    def getlist(self,head):
        l=[]
        while head:
            l.append(head.val)
            head=head.next
        return l
    def createLinkedlist(self,list):
        head=ListNode()
        p=head
        for i in list:
            new=ListNode(val=i)
            p.next=new
            p=new
        return head.next
    def addTwoNumbers(self, l1, l2):
        l1,l2=self.getlist(l1),self.getlist(l2)
        len1,len2=len(l1),len(l2)
        maxlen=max(len1,len2)
        ####补零####
        l1[:]=[0]*(maxlen-len1)+l1
        l2[:]=[0]*(maxlen-len2)+l2
        ###求和####
        for i in range(maxlen):
            l1[i]=l1[i]+l2[i]
        ####进位####
        for i in range(-1,-maxlen,-1):
            if l1[i]>=10:
                l1[i]=l1[i]-10
                l1[i-1]=l1[i-1]+1
        ####处理边界,首个元素####
        if l1[0]>=10:
            l1[0]=l1[0]-10
            l1[:]=[1]+l1
        return self.createLinkedlist(l1)

在这里插入图片描述

2.倒序后两数相加

3.栈

将链表的节点一次压入栈中,然后再一次取出相加

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        s1,s2=[],[]
        ####压栈####
        while l1:
            s1.append(l1.val)
            l1=l1.next
        while l2:
            s2.append(l2.val)
            l2=l2.next
        carry=0
        new=None
        while s1 or s2:
            ####出栈求和####
            a=s1.pop() if s1 else 0
            b=s2.pop() if s2 else 0
            c=a+b+carry
            ####处理进位####
            val=c%10
            carry=c//10
            #####新建节点###
            new=ListNode(val,new)
        #####处理边界,考虑首位是否进1###
        if carry==1:
            new=ListNode(1,new)
        return new

在这里插入图片描述

剑指offer22 链表中倒数第k个结点

在这里插入图片描述
双指针,用dummy结点处理head=[]的边界

class Solution(object):
    def getKthFromEnd(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        dummy=ListNode(next=head)
        s,f=dummy,dummy
        for _ in range(k):
            f=f.next
        while f:
            s=s.next
            f=f.next
        return s

在这里插入图片描述

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

在这里插入图片描述

1.双指针

快指针f快慢指针sn+1步,两个指针同时移动,f.next=None时,s.next为倒数第n个Node,令s.next=s.next.next
时间复杂度O(n)遍历整个链表,空间复杂度O(1),只要储存两个指针

class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummy=ListNode(next=head)
        s,f=dummy,dummy.next
        for _ in range(n):
            f=f.next
        while f:
            s=s.next
            f=f.next
        s.next=s.next.next
        return dummy.next

2.链表转为list然后del删除,再转为链表

时间复杂度O(n),空间复杂度O(n)需要储存所有元素

class Solution(object):
    def initList(self,L):
        head=ListNode()
        p=head
        for i in L:
            new=ListNode(val=i)
            p.next=new
            p=new
        return head.next
    def travelList(self,L):
        l=[]
        while L:
            l.append(L.val)
            L=L.next
        return l
    def removeNthFromEnd(self, head, n):
        r=self.travelList(head)
        del r[-n]
        return self.initList(r)