445. Add Two Numbers II

题目

You are given two non-empty linked lists representing two non-negative integers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.

Example:

Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7

我的解法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    
    int mark;
    
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int length1 = getLength(l1);
        int length2 = getLength(l2);
        int dis = Math.abs(length1 - length2);
        ListNode r1 = (length1 >= length2) ? l1 : l2;
        //将较长链表变成和短链表一样长
        while(dis != 0){
            r1 = r1.next;
            dis --;
        }
        ListNode r2 = (length1 < length2) ? l1 : l2;
        //先add()递归将两等长链表相加,再add2()将之前相加结果与较长的链表前面突出部分相加
        ListNode r = add2((length1 >= length2) ? l1 : l2, add(r1, r2), Math.abs(length1 - length2));
        
        if(mark == 1){
            ListNode res = new ListNode(1);
            res.next = r;
            return res;
        }else
            return r;
        
    }
    
    
    //链表深度
    public int getLength(ListNode l){
        if(l == null)
            return 0;
        return 1 + getLength(l.next);
    }
    //递归相加两等长链表
    public ListNode add(ListNode r1, ListNode r2){
        if(r1 == null || r2 == null){
            mark = 0;
            return null;
        }
        ListNode next = add(r1.next, r2.next);
        int sum = r1.val + r2.val + mark;
        if(sum >= 10){
            mark = 1;
            sum = sum - 10;
        }else
            mark = 0;
        ListNode l = new ListNode(sum);
        l.next = next;
        return l;
    }
    //较长链表l与之前相加的结果r相加,生成最后结果
    public ListNode add2(ListNode l, ListNode r, int dis){
        if(dis == 0){
            return r;
        }
        ListNode next = add2(l.next, r, dis - 1);
        int sum = l.val + mark;
        if(sum >= 10){
            mark = 1;
            sum = sum - 10;
        }else
            mark = 0;
        ListNode ln = new ListNode(sum);
        ln.next = next;
        return ln;
    }
    
}

利用堆栈的解法:倒序生成链表—方法1

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //数据入栈
        Stack<Integer> s1 = new Stack<>();
        Stack<Integer> s2 = new Stack<>();
        getStack(s1, l1);
        getStack(s2, l2);
        //进位符
        int mark = 0;
        //上一次生成的节点,作为本节点的next
        ListNode next = null;
        while(!s1.isEmpty() || !s2.isEmpty()){
            int n1 = s1.isEmpty() ? 0 : s1.pop();
            int n2 = s2.isEmpty() ? 0 : s2.pop();
            int sum = n1 + n2 + mark;
            mark = sum / 10;
            // 生成当前节点,接着保存下来作为下一次的next
            ListNode l = new ListNode(sum % 10);
            l.next = next;
            next = l;
        }
        if(mark == 1){
            ListNode l = new ListNode(1);
            l.next = next;
            next = l;
        }
        return next;  
    }
    
    public void getStack(Stack s, ListNode l){
        while(l != null){
            s.push(l.val);
            l = l.next;
        }
    }
    
}

利用堆栈的解法:倒序生成链表—方法2

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //数据入栈
        Stack<Integer> s1 = new Stack<>();
        Stack<Integer> s2 = new Stack<>();
        getStack(s1, l1);
        getStack(s2, l2);
        //进位节点
        ListNode mark = new ListNode(0);
        while(!s1.isEmpty() || !s2.isEmpty()){
            int n1 = s1.isEmpty() ? 0 : s1.pop();
            int n2 = s2.isEmpty() ? 0 : s2.pop();
            int sum = mark.val + n1 + n2;
            mark.val = (sum % 10);
            // 新进位节点,就节点插到其后
            ListNode l = new ListNode(sum / 10);
            l.next = mark;
            mark = l;
        }
        
        return (mark.val == 1) ? mark : mark.next;  
    }
    
    public void getStack(Stack s, ListNode l){
        while(l != null){
            s.push(l.val);
            l = l.next;
        }
    }
    
}
算法分析:利用堆栈来做,思路更清晰、明了。堆栈法一需要进位符变量,将保存的上一次生成节点插入本次节点中,再保存本次节点;堆栈法二不需要进位符变量,更新之前进位符节点的值,再将其插入本次新生成的进位符节点后,再保存此进位符节点。推荐方法二





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值