每天一道LeetCode-02(两数相加)

65 阅读2分钟

题目:两数之和

给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之外,这两个数都不会以0开头。

示例 1:

image.png

输入: 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]

分析

我们可以考虑直接对位相加,如果值大于等于10,则将进位标识符设为1,对当前相加结果取余,计算下一个节点时,只需要加上进位值即可。

代码

struct ListNode* addTwoNumbers(struct ListNode* l1,struct ListNode* l2){
    struct ListNode *head = NULL, *tail = NULL, *p;
    int carrage = 0; //进位标识符
    //当l1,l2都指向空时不能跳出循环,因为可能还需要进位,例如 5 + 5
    //第二轮循环l1、l2都指向null,但是还需要进一位
    while(l1 || l2 || carrage){
        //假设可能出现l1有三个节点,而l2只有两个节点,为了实现对位相加
        //我们可以判断l2当前是否指向为NULL,当指针指向NULL,即让该位的数字为0,例如:
        // l1: 3 -> 5 ->1
        // l2: 4 -> 2(->0)
        int n1 = l1 ? l1->val:0;
        int n2 = l2 ? l2->val:0;
        int sum = n1 + n2 + carrage;
        carrage = 0;
        if(sum >= 10){
            sum = sum % 10;
            carrage = 1;
        }
        //p节点用来存储新加的
        p = malloc(sizeof(struct ListNode));
        p -> val = sum;
        p -> next = NULL;
        //第一次进入循环
        if(!head){ 
            head = tail = p;
        }else{
            tail -> next = p;
            tail = p;
        }
        
        if(l1){
            l1 = l1 -> next;
        }
        if(l2){
            l2 = l2 -> next;
        }
    }
    return head;
}