给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。

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

示例:

输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出: 7 -> 8 -> 0 -> 7
结点类如下

public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}

答案:

public ListNode addTwoNumbers(ListNode list1, ListNode list2) {
     Stack<Integer> s1 = new Stack<>();
     Stack<Integer> s2 = new Stack<>();
     while (list1 != null) {
         s1.push(list1.val);
         list1 = list1.next;
     }
     while (list2 != null) {
         s2.push(list2.val);
        list2 = list2.next;
    }
    int sum = 0;
    ListNode head = new ListNode(0);
    while (!s1.empty() || !s2.empty()) {
        if (!s1.empty())
            sum += s1.pop();
        if (!s2.empty())
            sum += s2.pop();
        head.val = sum % 10;
        ListNode node = new ListNode(sum / 10);
        node.next = head;
        head = node;
        sum /= 10;
    }
    return head.val == 0 ? head.next : head;
}

解析:

思路其实很简单,就是分别把两个链表的结点先存放到两个栈中,因为链表的最高位是在链表的最开始的位置,所以存放到栈中之后,栈底是高位,栈顶是个位(也是低位),然后两个栈中的元素再相加,因为栈是先进后出的,最先出来的肯定是个位(也是低位),最后出来的肯定是高位,也就是这两个数是从个位开始相加,这也符合加法的运算规律。

1,代码中第19行我们只保存相加的个位数,因为链表的每个结点只能保存一位数,如果有进位就会在下一步进行保存。

2,第20行在保留进位的值。其中第20到22行涉及到链表的插入,这个使用的是头插法,在链表节点的头部插入,比较简单,如果看不懂的,还可以看下前面刚讲的352,数据结构-2,链表。

3,代码第25行先判断链表相加之后的最高位是否有进位,如果有就直接返回,如果没有就返回头结点head的下一个结点即可。

代码比较简单,我们就以上面的例子来画一个图加深一下理解,

java相加的api java两数相加_数据结构


java相加的api java两数相加_数据结构_02


java相加的api java两数相加_数据结构_03


java相加的api java两数相加_链表_04


java相加的api java两数相加_结点_05


我们还可以改成递归的方式来解决

public ListNode addTwoNumbers(ListNode list1, ListNode list2) {
     int size1 = getLength(list1);
     int size2 = getLength(list2);
     ListNode head = new ListNode(1);
     head.next = size1 < size2 ? helper(list2, list1, size2 - size1) : helper(list1, list2, size1 - size2);
     if (head.next.val > 9) {
         head.next.val = head.next.val % 10;
         return head;
     }
    return head.next;
}

//这里链表list1的长度是大于等于list2的长度的
public ListNode helper(ListNode list1, ListNode list2, int offset) {
    if (list1 == null)
        return null;
    ListNode result = offset == 0 ? new ListNode(list1.val + list2.val) : new ListNode(list1.val);
    ListNode post = offset == 0 ? helper(list1.next, list2.next, 0) : helper(list1.next, list2, offset - 1);
    if (post != null && post.val > 9) {
        result.val += 1;
        post.val = post.val % 10;
    }
    result.next = post;
    return result;
}

public int getLength(ListNode list) {
    int count = 0;
    while (list != null) {
        list = list.next;
        count++;
    }
    return count;
}