leetcode打卡9:题号2——两数相加

题目:

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

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

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

示例:

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

理解:

1.这道题似乎没有什么优化的算法,就是一些细节需要注意
2.其实思路大家都是有的,就是每次取一节点进行相加,设置一个进位标志位,依次相加即可。但是在细节上还需要把握一下
3.第一个就是当两个链表长度不同时,例如l1链表已经遍历完了,但是l2链表还没有遍历完,那么就需要将l2的后面继续放到新的链表中,其中还是需要注意是否最高位是否还有进位
4.第二个就是当链表长度相同时,哪怕已经加完了,最后还是要判断一下最高位是否有进位,否则会导致输出错误
3.对于进位的标志设置,我就走了不少弯路,我设置的是一个布尔值来判断是否有进位,看了答案之后我发现进位标志直接设置0或者1就行,就可以直接相加,无需判断。
4.对于两个链表不同长的问题,我也走了弯路,我的思想是走完了一个链表之后,把没走完的链表后面直接放进去,考虑进位就可以了,但是实际上可以不用这么做。我们完全可以直接遍历最长的链表为标准,当短链表为空的时候,我们就把加的值设置为0就可以了
5.对于标志位,根本不需要判断加起来的值是否大于9,无论是否大于9,只要除以10,就可以得到0或者1,这是如何求标志位
6.对于进位数,也不用判断是否大于9,进行模10,无论是否大于9,都进行模10,进行存储即可

自己的算法(未优化):

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if(l1 == null && l2 == null)  {
            return null;
        }else if(l1 == null){
            return l2;
        }else if(l2 == null){
            return l1;
        }else{
            ListNode listHead = new ListNode(0); //虚拟头结点
            ListNode head = listHead;
            boolean ifAdd = false;  //是否进位
            while(l1 != null && l2 != null){
                ListNode temp = new ListNode(0);
                int sum = l1.val + l2.val;
                if(ifAdd == true){ //是否低位有进位
                    sum = sum + 1;
                    ifAdd = false;
                }
                if(sum > 9){
                    ifAdd = true;
                    sum = sum % 10;
                }
                temp.val = sum;
                head.next = temp;

                head = temp;
                l1 = l1.next;
                l2 = l2.next;
            }
            if(l1 == null && l2 != null){ //链表不同长
                while(l2 != null){
                    ListNode temp = new ListNode(0);
                    int value = l2.val;
                    if(ifAdd == true){
                        value = value  + 1;
                        ifAdd = false;
                    }
                    if(value > 9){
                        value = value % 10;
                        ifAdd = true;
                    }
                    temp.val = value;

                    head.next = temp;
                    head = temp;
                    l2 = l2.next;
                }

            }else if(l1 != null && l2 == null){
                while(l1 != null){
                    ListNode temp = new ListNode(0);
                    int value = l1.val;
                    if(ifAdd == true){
                        value = value + 1;
                        ifAdd = false;
                    }
                    if(value > 9){
                        value = value % 10;
                        ifAdd = true;
                    }
                    temp.val = value;

                    head.next = temp;
                    head = temp;
                    l1 = l1.next;
                }

            }

            if(ifAdd == true){//链表同长但是最高位有进位!
                ListNode temp = new ListNode(1);
                head.next = temp;

            }

            return listHead.next;
        }


    }

简便算法:

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; //如果链表为空就设置为0
        int y = (q != null) ? q.val : 0;
        int sum = carry + x + y;
        carry = sum / 10; //无论有没有进位都求出进位数
        curr.next = new ListNode(sum % 10); //无论有没有进位都模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;
}

总结:

其实就是在代码的高效性上,我没有做到最优!以后对于这方面的东西要努力进步。

你可能感兴趣的:(Leetcode)