算法通关村第二关白银挑战——链表相加问题

单链表加1

法一:链表反转

我的思路:

因为在链表反转的题目中,以下就想到了链表反转

难点:

1.最后一个数如果为9,要进行拆分,这个特殊情况没有考虑到,拆分后的两个数排列也需要仔细考虑,因为还要反转链表。然后是拆分后会多出来一个,我第一次忘记直接跳出去了,拆分的前面那个数也加了一,悲伤

2.进位符号要记得每次清零啊

def plusOne(self,head):
    def reverist(head):
        if not head or not head.next:
            return head
        cur = head.next
        head.next = None
        while cur:
            next = cur.next
            cur.next = head
            head = cur
            cur = next
        return head

    head = reverist(head)
    ans = 0
    cur = head
    cur.val = cur.val + 1
    while cur:
        if ans == 1:
            cur.val = cur.val + 1
            ans=0
        if cur.val >= 10:
            if cur.next==None:
                next=ListNode(cur.val%10)
                cur.val=cur.val/10
                cur.next=next
                break
            else:
                ans = 1
                cur.val = cur.val % 10
        cur = cur.next
    head = reverist(head)
    return head

 法2:栈

改进了的栈算法,比前面用链表长度好,不用考虑取值

def plusOne(self,head):
    s = []
    p1 = head
    while p1:
        s.append(p1.val)
        p1 = p1.next

    ans = 1
    dummy_head = ListNode(0)
    while s or ans:
        adder = s.pop() if s else 0
        sum = adder + ans
        ans = 1 if sum >= 10 else 0
        sum = sum - 10 if sum >= 10 else sum
        cur = ListNode(sum)
        cur.next = dummy_head.next
        dummy_head.next = cur
    return dummy_head.next

特殊——找9

思路:找到最右边的不是9的数字,这是进位终止的地方

注意:必须设置虚拟结点为0,这样才可以把特殊情况也解决

def plusOne(self,head):
    ans=ListNode(0)
    ans.next=head
    not_nine=ans

    while head:
        if head.val!=9
            not_nine=head
        head=head.next

    not_nine.val+=1
    not_nine=not_nine.next

    while not_nine:
        not_nine.val=0
        not_nine=not_nine.next

    return ans if ans.val else ans.next

两数相加

方法1:反转

我的想法:三次反转

思考:如何不用其他指针成功合并两个链表

#改进:如何让代码更简洁
def addTwoNumbers(self, l1, l2):
    def reverist(head):
        if not head.next:
            return head
        cur = head.next
        head.next = None
        while cur:
            next = cur.next
            cur.next = head
            head = cur
            cur = next
        return head

    l1 = reverist(l1)
    l2 = reverist(l2)

    prehead = ListNode(0)
    p = prehead
    n1, n2 = l1, l2
    # 思考:不用其他指针就实现两个链表的合并
    while n1 and n2:
        s = n1.val + n2.val
        cur = ListNode(s)
        p.next = cur
        p = p.next
        n1 = n1.next
        n2 = n2.next

    p.next = n1 if n1 else n2
    p = prehead.next
    ans = 0
    right = p
    while right:
        if ans == 1:
            right.val += 1
            ans = 0
        if right.val >= 10:
            ans = 1
            right.val = right.val % 10
        right = right.next

    p = reverist(p)
    prehead.next = p
    if ans == 1:
        prehead.val += 1
    return prehead if ans else prehead.next

老师的方法

区别在于我是加完再进位,老师是边加边进位

重点:如何持续创建新节点
ans.next=ListNode(0,None)
ans=ans.next
class ReverseList:
    def reverseList(self,head):
        prev=None
        curr=head
        while curr:
            nextTemp=curr.next
            curr.next=prev
            prev=curr
            curr=nextTemp
        return prev

    def addTwoNumbersI(self, l1, l2):
        ans=ListNode(0,None)
        DUMMT_HEAD,rea=ans,0
        p1,p2=l1,l2

        while p1!=None or p2!=None or res==1:
            #创建新next节点
            ans.next=ListNode(0,None)
            ans=ans.next

            if p1!=None and p2!=None:
                sums=p1.val+p2.val
                if sums+res<10:
                    ans.val=sums+res
                    res=0
                else:
                    ans.val=sums+res-10
                    res=1
                p1,p2=p1.next,p2.next

            elif p1==None and p2!=None:
                sums=p2.val
                if sums + res < 10:
                    ans.val = sums + res
                    res = 0
                else:
                    ans.val = sums + res - 10
                    res = 1
                p2=p2.next

            elif p2==None and p1!=None:
                sums=p1.val
                if sums + res < 10:
                    ans.val = sums + res
                    res = 0
                else:
                    ans.val = sums + res - 10
                    res = 1
                p1=p1.next

            else:
                ans.val=res
                res=0
        return DUMMY_HEAD.next

    #调用入口
    def addTwoNumbers(self,l1,l2):
        return self.reverseList(self.addTwoNumbersI(self.reverseList(l1),self.reverseList(l2)))

方法二:栈

栈弹出用pop()

class AddTwoNumbers:
    def addTwoNumbers(self,l1,l2):
        s1=[]
        s2=[]
        p1,p2=l1,l2
        while p1:
            s1.append(p1.val)
            p1=p1.next
        while p2:
            s2.append(p2.val)
            p2=p2.next

        ans=0
        dummy_head=ListNode(0)
        while s1 or s2 or ans:
            adder1=s1.pop() if s1 else 0
            adder2=s2.pop() if s2 else 0
            sum=adder1+adder2+ans
            ans=1 if sum>=10 else 0
            sum=sum-10 if sum>=10 else sum
            cur=ListNode(sum)
            cur.next=dummy_head.next
            dummy_head.next=cur
        return dummy_head.next
    

拓展——关于链表的减法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值