leetcode2 两数相加

本文介绍了一种使用链表表示非负整数并进行加法运算的方法。通过逆序存储数字,实现了链表相加的功能,并提供了C++和Java两种语言的实现方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题目:

给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

思路:

逆序为我们提供了便利,进位的处理

踩的坑:

必须用malloc/new,因为在子函数结束栈会回收。必须在堆中实现。。。

否则:double free or corruption (out): 0x00000000011abe70 ***

因为运行的时候一直释放Tmp结构体

还踩了一个坑:

member access within misaligned address 0x000000000031 for type 'struct ListNode', which requires 8 byte alignment

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* l3=(ListNode *)malloc(sizeof(ListNode));
        l3->val=0;
        l3->next=NULL;
        ListNode* tmpl3=l3;
        ListNode* tmp;
        int i=0;
        for(ListNode* p=l1;p!=NULL;p=p->next)
            i++;
        
        int j=0;
        for(ListNode* p=l2;p!=NULL;p=p->next)
            j++;
        
        int a=0;
        int flag=0;//flag for carry(进位)
        int min,max;
        if(i>j){
            max=i;
            min=j;
        } else{
            max=j;
            min=i;
        }
        for(;a<min;a++){
            tmp=(ListNode *)malloc(sizeof(ListNode));            
            tmp->next=NULL;
            tmp->val=flag;
            flag=0;
            tmp->val+=l1->val+l2->val;
            if(tmp->val>=10)
            {   flag=1;
                tmp->val-=10;
            }
            tmpl3->next=tmp;

            tmpl3=tmpl3->next;
            l1=l1->next;
            l2=l2->next;
        }
        ListNode* tmp_p;
        if(i>j)
            tmp_p=l1;
        else
            tmp_p=l2;
        for(;a<max;a++){ 
            tmp=(ListNode *)malloc(sizeof(ListNode));
            tmp->next=NULL;
            tmp->val=flag;
            flag=0;                
                if(tmp_p!=NULL){
                    tmp->val+=tmp_p->val;
                    if(tmp->val>=10)
                    {   flag=1;
                        tmp->val-=10;
                    }
                    tmpl3->next=tmp;
                    tmpl3=tmpl3->next;
                    tmp_p=tmp_p->next;
                } 
        }
        if(flag)
        {
            tmp=(ListNode *)malloc(sizeof(ListNode));
            tmp->next=NULL;
            tmp->val=flag;
            flag=0;
            tmpl3->next=tmp;
        }
        return l3->next;       
    }
};

通过就花了1个多小时。。。

还是再看看复杂度,l1是M,l2是N,我的算法复杂度是O(M+N)

但是代码明显可以优化。看着这个代码就垃圾。。。

看了看答案

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0);
    ListNode p = l1, q = l2, curr = dummyHead;
    int carry = 0;
    while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        int sum = carry + x + y;
        carry = sum / 10;
        curr.next = new ListNode(sum % 10);
        curr = curr.next;
        if (p != null) p = p.next;
        if (q != null) q = q.next;
    }
    if (carry > 0) {
        curr.next = new ListNode(carry);
    }
    return dummyHead.next;
}

我的 JAVA

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode tmp = dummy;
        int rest = 0;
        while(l1 != null || l2 != null || rest != 0){
            int val1 = l1 == null ? 0 : l1.val;
            int val2 = l2 == null ? 0 : l2.val;
            int nextRest = (val1 + val2 + rest) / 10;
            tmp.next = new ListNode(val1+ val2 + rest - 10*nextRest);

            tmp = tmp.next;
            if(l1 != null) l1 = l1.next;
            if(l2 != null) l2 = l2.next;
            rest = nextRest;
        }
        return dummy.next;
    }
}

虽然是java,但是也能看懂,明显能看出来代码能力的巨大差距。。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* head=new ListNode(0);
        ListNode* tmp=head;
        int carry=0;
        while(l1!=NULL||l2!=NULL)
        {
            int l1_val=(l1!=NULL)?l1->val:0;
            int l2_val=(l2!=NULL)?l2->val:0;
            int sum=l1_val+l2_val+carry;
            carry=sum/10;
            tmp->next=new ListNode(sum%10);
            tmp=tmp->next;
            if(l1!=NULL)
                l1=l1->next;
            if(l2!=NULL)
                l2=l2->next;
            
        }
        if(carry>0)
            tmp->next=new ListNode(carry);
         return head->next;
   
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值