• 两个数字相加


    两个数字相加

    题干

    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

    如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

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

    示例:

    输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)

    输出:7 -> 0 -> 8

    原因:342 + 465 = 807

    解题代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     struct ListNode *next;
     * };
     */
    
    struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
      /*
        思路:
        1.同时遍历两个链表,直到两个链表都为空为止
        2.考虑进位的问题
        何时进位
        两个节点之和+上一位的进位>9进位
        原位变为(两个数之和+上一位的进位)%10,进位变为两个数之和+上一位的进位)/10
        考虑边界情况:
        1.只有在一个链表遍历指针不为空的情况下,才指向下一个
        2.最末位进位,所以当进位为1的时候不能结束循环
      */
        struct ListNode* t1=l1;//遍历指针,不改变原来的链表
        struct ListNode* t2=l2;
        struct ListNode* h3=(struct ListNode*)malloc(sizeof(struct ListNode));//头结点
        struct ListNode* pNew=NULL;//指向新申请的节点
        struct ListNode* pTail=h3;//指向链表的末尾
        int sum=0;
        h3->val=0;
        h3->next=NULL;//初始化头结点
        int carry=0;//向前一位的进位
        while(t1||t2||carry)
        {
            pNew=(struct ListNode*)malloc(sizeof(struct ListNode));//申请新的节点
            pNew->val=0;
            pNew->next=NULL;//申请新的节点,初始化该节点
            int sum=0;//对应项的和
            if(t1!=NULL)//只有在遍历指针不空的情况下才加上其值
            {
                sum+=t1->val;
            }
            if(t2!=NULL)
            {
                sum+=t2->val;
            }
            sum+=carry;
            if(sum>=10)
            {
                sum=sum%10;//取模
                carry=1;//进位
            }
            else
            {
                carry=0;//取消进位
            }
            pNew->val=sum;
            //将新的节点插入结果链表
            pTail->next=pNew;//插入最新链表的末尾
            pTail=pNew;//移动到尾节点
            //向下遍历链表
            if(t1!=NULL)//不空才指向下一个节点
            {
                t1=t1->next;
            }
            if(t2!=NULL)
            {
                t2=t2->next;
            }
            
        }
        struct ListNode* temp2=h3->next;
        free(h3);//释放空的头结点
        return temp2;//返回链表
    }

    画图分析

    思路分析

    整体上来说,如图所示一共有两个链表,其头结点分别是l1和l2。每一个链表的节点顺序是从头结点对应数字的低位,而尾节点对应数字的高位。我们的目的是将将两个链表按位相加,考虑进位的情况,最终得到一个新的链表,这个链表各个位对应两个链表对应数字相加的结果的各位结果。

    如图,l1从高位到低位是1984,而l2从高位到低位是52。两个数字相加结果为2036,正好对应l3从高位到低位的2036.

    然后我们分析一下过程,我们从低位到高位开始算,carry是进位。

    * 0.初始进位为0,carray=0

    * 4+2+carry=4+2+0=6 没有进位 carry=0;

    * 8+5+carry=8+5+0=13 进了一位 carry=1; 值为 13%10=3

    * 9+0+carry=9+0+1=10 进了一位 carry=1; 值为10%10=0

    * 1+0+carry=1+0+1=2 进位为0

    代码分析

    1.为了尽可能简单,我们将创建一个新的链表来保存最终的结果,最后返回这个链表的头指针

    2.在整个过程中不改变传入的两个链表

    3.我们需要同时遍历两个链表

    • 何时结束?两个条件缺一不可
    • 两个链表都空的时候
    • 进位为0的时候

    4.每次都要申请一个新的节点

    • 新的节点的值怎么算?如果对应两个节点的值+进位的值>9就取余数,否则就是两个节点的值+进位的值
    • 进位怎么考虑?如果对应两个节点的值+进位的值>9进位为1,否则进位为0
    •  还要考虑一个问题,如果某个链表的遍历指针指向空了怎么办?只有在遍历指针不指向空才加数值

    5.插入新的链表,采用尾插法,这样才能对应顺序。

    6.遍历指针后移,只有在遍历指针不为空的情况下才进行

  • 相关阅读:
    Linux服务器安全审计工具与流程完全指南
    谈谈站桩
    Django Push 的一些资料
    Angularjs $http服务的两个request安全问题
    Ubuntu本地uwsgi配Django问题的解决
    Angularjs Post传值后台收不到的原因
    Flex实现双轴条状图
    时间序列学习笔记
    Nuget公布Dll
    【小游戏】有意思的小游戏集合
  • 原文地址:https://www.cnblogs.com/mengxiaoleng/p/11374094.html
Copyright © 2020-2023  润新知