c++实现两数相加

题目:

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

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

示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

实现思路:

  1. 首先创建一个新的ListNode,用来存储相加后的结果。同时创建三个指针p1、p2、p3,分别指向两个输入链表和新链表的头节点。

  2. 对于链表中每个节点的相加操作,使用while循环实现,其中只要两个链表都不为空,就进行循环。每次循环中,将当前节点对应的值相加,并加上前一个节点相加的进位值carry。

  3. 如果相加的结果小于10,则直接将结果存入新链表中,并将p3指向下一个节点。否则,将相加结果减去10,进位值carry加1,然后将结果存入新链表中,并将p3指向下一个节点。

  4. 当其中一个链表为空时,继续循环处理另一个链表中的节点,直到整个链表都被处理完。

  5. 如果两个链表都为空,并且还有进位值carry,则创建一个新节点存储进位值,并将该节点添加到新链表的末尾。

  6. 最后返回新链表的头节点的下一个节点,因为新链表的头节点是用来初始化的,不存储任何有效的值。

总之,这段代码实现了两个链表的相加操作,采用了简单的逐位相加的思路,逐步计算每一位的进位和结果,并将结果存入一个新的链表中。

// 链表节点的定义
struct ListNode {
    int val;  // 节点的值
    ListNode *next;  // 指向下一个节点的指针
    // 三个构造函数,用于初始化节点
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* ans=new ListNode(0);  // 创建一个新链表,用于存储结果
        ListNode* p1=l1;  // 指针 p1 指向链表 l1 的头结点
        ListNode* p2=l2;  // 指针 p2 指向链表 l2 的头结点
        ListNode* p3=ans;  // 指针 p3 指向链表 ans 的头结点
        int sum,carry=0;  // sum 用于存储两个节点的值的和,carry 用于存储进位
        // 对两个链表同时进行遍历
        while(p1&&p2){
            sum=p1->val+p2->val+carry;  // 计算节点值的和
            p1=p1->next;  // 将指针 p1 向后移动一个节点
            p2=p2->next;  // 将指针 p2 向后移动一个节点
            carry=0;  // 将进位清零
            if(sum<10){  // 如果节点值的和小于 10
                ListNode* tem=new ListNode(sum);  // 创建一个新节点
                p3->next=tem;  // 将新节点插入到 ans 链表的末尾
                p3=p3->next;  // 将指针 p3 向后移动一个节点
            }
            else {  // 如果节点值的和大于等于 10
                ListNode* tem=new ListNode(sum-10);  // 创建一个新节点,节点值为 sum-10
                carry++;  // 进位加 1
                p3->next=tem;  // 将新节点插入到 ans 链表的末尾
                p3=p3->next;  // 将指针 p3 向后移动一个节点
            }
        }
        // 如果链表 l1 还有剩余节点,继续遍历 l1
        while(p1!=NULL){
            ListNode* tem;
            if(p1->val+carry<10){  // 如果节点值加上进位小于 10
                tem=new ListNode(p1->val+carry);  // 创建一个新节点,节点值为 p1->val+carry
                carry=0;  // 将进位清零
            }
            else{  // 如果节点值加上进位大于等于 10
                tem=new ListNode(p1->val+carry-10);  // 创建一个新节点,节点值为 p1->val+carry-10
                carry=1;  // 进位加 1
            }
            p3->next=tem;  // 将新节点插入到 ans 链表的末尾
            p3=p3->next;  // 将指针 p3 向后移动一个节点
            p1=p1->next;  // 将指针 p1 向后移动一个节点
        }
        // 如果链表 l2 还有剩余节点,继续遍历 l2
        while(p2!=NULL){
            ListNode* tem;
            if(p2->val+carry<10){  // 如果节点值加上进位小于 10
                tem=new ListNode(p2->val+carry);  // 创建一个新节点,节点值为 p2->val+carry
                carry=0;  // 将进位清零
            }
            else {  // 如果节点值加上进位大于等于 10
                tem=new ListNode(p2->val+carry-10);  // 创建一个新节点,节点值为 p2->val+carry-10
                carry=1;  // 进位加 1
            }   
            p3->next=tem;  // 将新节点插入到 ans 链表的末尾
            p3=p3->next;  // 将指针 p3 向后移动一个节点
            p2=p2->next;  // 将指针 p2 向后移动一个节点
        }
        // 如果有进位,还需要在 ans 链表的末尾添加一个节点
        if(p1==NULL&&p2==NULL&&carry==1){
            ListNode* tem=new ListNode(1);  // 创建一个新节点,节点值为 1
            p3->next=tem;  // 将新节点插入到 ans 链表的末尾
            p3=p3->next;  // 将指针 p3 向后移动一个节点
        }
        return ans->next;  // 返回 ans 链表的第二个节点,因为第一个节点的值为 0
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值