【LeetCode】add-two-numbers

题目描述
  • You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
  • Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
  • Output: 7 -> 0 -> 8
  • 给出两个表示两个非负数的链表。这些数字以相反的顺序存储,每个节点都包含一个数字。两个数字相加并将其作为链表返回。
  • 首先我想说,我刚开始看到这个题目并没有搞清楚它想让我干什么。两条链表中个节点的数字进行相加,但是这些数字以相反的顺序存储是什么鬼。不过还好有输入输出样例,我才搞清楚这个题目的意思。即:每个节点对应的数字向加,若大于10,则要向下一个节点进位。(我想题目中数字以相反顺序存储的意思可能是:进位朝反方向进吧,因为我们通常的进位都是想高位进的)
解题思路
  • 我觉得这道题的解题思路是很清晰的,只要我们理清楚各种不同的情况,然后进行合并或者分别处理即可,主要有下面几种情况:
  • 首先,若两条链表任一条为空,则返回另一条链表,不用进行处理
  • 第二,若两条链表等长,则依次相加各节点的值,不过因为要考虑进位,所以实际相加结果还应该再加上前面节点的进位,所以相加的存储结果为实际相加结果做 %10 运算。进位则是实际相加结果做 /10 运算。
  • 第三,若两条链表不等长,则需要把剩下的链表节点链接到结果链表后面。注意:此时我们仍然要考虑进位
  • 关于进位,每相加一次都要考虑,若到最后一个节点进位非0,则需要新建一个节点来存储最后一个进位,此时才算是得到最终正确的结果
代码实现
  • 关于写代码,我们可以考虑在现成的链表上直接加或者是新建链表
  • 我用第一种方法写了一个可挫的代码,后来在网上看到大佬们的代码是在不好意思再贴出我的,总结大佬代码的特点,思路清晰,代码简洁。我们同样的思路但是我就不能将自己的思路整理的很清晰,导致代码写的一团糟
  • 大佬版代码实现:
    • 若有一条链表为空,则返回另一条
    • 用一个变量来存储存储到结果链表中的和 and 进位(我在考虑的时候是分别设置了变量,后来发现一个就够了,取得实际结果的和sum,sum%10得到存储结果,sum/10得到进位,因为进位也是要考虑的结果中的,所以下一轮操作直接在sum上累加和就可以了,所以设置两个变量是没必要的,当然如果你想让代码更显而易见,也可以使用)
    • 通过if判断语句来控制,若有空节点就不进行sum加和(我在写的时候是根据我上面分的情况写的,等长处理完后,对长的那条链表单独进行处理,后来发现也是没必要的)
    • 所以还是静观大佬代码,默默回去继续修炼吧,道阻且长
ListNode* addTwoNumbers(ListNode* l1,ListNode* l2)
{
    if(l1 == NULL)
        return l2;
    if(l2 == NULL)
        return l1;

    ListNode* head = new ListNode(0);
    ListNode* cur = head->next;
    int sum = 0;
    while(l1 != NULL || l2 != NULL || sum != 0)
    {
        if(l1 != NULL)
        {
            sum += l1->next;
            l1 = l1->next;
        }
        if(l2 != NULL)
        {
            sum += l2->next;
            l2 = l2->next;
        }

        //新建节点,存储相加结果,并将其插入到新链表中
        cur-next = new ListNode(sum%10);
        cur = cur->next;
        sum /= 10;
    }
    return head->next;
}
  • 也还是给大家贴一下我的代码吧,没有对比就没有伤害,我是在l1上进行操作的,我的分情况处理和我上面思路分析处的是一致的:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) 
{
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    ListNode* cur = l1;
    ListNode* prev = NULL;
    int carry = 0;
    while (cur != NULL && l2 != NULL)
    {
        prev = cur;
        int sum = cur->val + l2->val;
        cur->val = (sum + carry) % 10;
        carry = (sum + carry) / 10;
        cur = cur->next;
        l2 = l2->next;
    }
    //两条链表的相同部分已经相加完成
    //l1 == NULL 或 l2 == NULL;
    //将非空的那部分拼接在l1的后面,并且依次加carry直到最后一个节点
    if (cur == NULL)
    {
        prev->next = l2;
        cur = prev->next;
    }
    while (cur != NULL)
    {
        prev = cur;
        int sum = cur->val;
        cur->val = (sum + carry) % 10;
        carry = (sum + carry) / 10;
        cur = cur->next;
    }//cur == NULL;
    //carry/10!=0,说明进位大于10,则需要继续向前进位
    ListNode* tmp = new ListNode(carry);
    prev->next = tmp;
    return l1;
}

猜你喜欢

转载自blog.csdn.net/Aurora_pole/article/details/81475205