力扣第二题,单链表两数相加,附完整代码和全注释

61 阅读3分钟

题目描述:

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

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

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

解题思路:

这是一道链表题,重点在对于链表的操作。难点在于操作链表过程中两数相加时进位的操作。

如下是依据官方思路操作的代码。 完整代码如下,包含注释:

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {

        /*  结合题意可知,解题过程中只需用到单链表  */

        //创建两个节点head和tail,都设置为null,head是存放结果的链表的首元节点
        //tail用来表示最后一个节点,当在链表尾部添加节点时需要用到tail
        //当链表中只有一个节点时,head=tail;
        ListNode head=null, tail=null;

        //因为(l1.val+l2.val)的值有可能大于9,所以需要有一个变量存放进位值
        int carry=0;    //carry用来存放进位值

        //循环的条件是l1和l2至少有一个不为null
        while (l1!=null || l2!=null){

            //使用三目运算符使代码更加简洁
            //当 l1不为null时,n1的值就是l1.val,否则n1的值是0
            int num1 = (l1!=null) ? l1.val : 0;
            //n2同理
            int num2 = (l2!=null) ? l2.val : 0;

            //sum存放对应节点的值,注意要加上进位值
            int sum = num1+num2+carry;

            //head==null时表示此时链表为空(无节点)
            if (head==null){
                //向链表中添加第一个节点
                //当链表中只有一个节点时,head=tail;
                head = tail = new ListNode(sum%10);
            }else {
                //链表中已存在节点时,新建(new)节点,并让 tail指向新建的节点,此时链表的最后一个节点是新建的这一个节点
                tail.next = new ListNode(sum % 10);
                tail = tail.next;
            }
            carry = sum / 10;
            //如果l1还有后继节点,就进行后移操作,遍历下一个节点,l2同理
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        //当遍历完两个链表后,最后需要判断进位值中是否还有数据,如果有,要再向链表中添加一个节点,存放进位值
        if (carry > 0) {
            tail.next = new ListNode(carry);
        }
        return head;
    }
}

下面是笔者自己进行解题时缩写代码,过于繁琐,当时的思路是先创建了一个工具类,用工具类遍历单链表,分别得到单链表的长度,然后依据单链表的长度进行操作。
完整代码如下:

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int leng1, leng2;
        //leng是节点数
        leng1 = Util.leng(l1);
        leng2 = Util.leng(l2);
        //确保l1中放的是较长的数
        if (leng2>leng1){
            //交换l1,l2
            ListNode temp = l1;
            l1 = l2;
            l2 = temp;
            //交换leng1,leng2
            int leng3 = leng1;
            leng1 = leng2;
            leng2 = leng3;
        }
        ListNode res = new ListNode(0,null);//res不变
        ListNode l3 = res;//l3用来遍历
        for (int i=1;i<=leng1;i++){
            if (i<=leng2){
                if ((l1.val+l2.val + l3.val)<=9){
                    l3.val = l1.val + l2.val + l3.val;
                    l1 = l1.next;
                    l2 = l2.next;
                    ListNode l4 = new ListNode();//l4是下一个节点
                    l4.val=0;
                    l3.next = l4;
                    l3 = l4;
                }
                else if ((l1.val+l2.val+l3.val)>9){
                    l3.val = l1.val + l2.val - 10 + l3.val;
                    l1 = l1.next;
                    l2 = l2.next;
                    ListNode l4 = new ListNode();//l4是下一个节点
                    l4.val=1;
                    l3.next = l4;
                    if (i==leng1&&l4.val==0){
                        l3.next=null;
                    }
                    l3 = l4;
                }
            }
            else if (i>leng2&&l1.val + l3.val<=9){
                l3.val = l1.val + l3.val;
                l1 = l1.next;
                ListNode l4 = new ListNode();//l4是下一个节点
                l4.val = 0;
                l3.next = l4;
                if (i==leng1&&l4.val==0){
                    l3.next=null;
                }
                l3 = l4;
            }
            else if (i>leng2&&l1.val + l3.val>9){
                l3.val = l1.val + l3.val - 10;
                l1 = l1.next;
                ListNode l4 = new ListNode();//l4是下一个节点
                l4.val = 1;
                l3.next = l4;
                l3 = l4;
            }
        }
        ListNode stemp = null;
        ListNode temp2 = res;//借助temp2检查链表的尾部是否有多余0,并将其去除
        while (temp2.next!=null){
            stemp = temp2;
            temp2 = temp2.next;
        }
        if (temp2.val==0){
            stemp.next = null;
        }
        return res;
    }
}
class Util{
    public static int leng(ListNode listNode){
        int l=0;
        ListNode temp = listNode;
        while (temp.next!=null){
            temp = temp.next;
            l++;
        }
        return l+1;
    }
}