题目: 两数相加

来自智得网
跳转至: 导航、​ 搜索


两数相加

难度:中等

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

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

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

示例 1:

<img alt="" src="addtwonumber1.jpeg" />

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100]
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零


分析

两数相加中两个输入都是以链表形式表示的。

链表存储的形式可以方便的转为十进制的整形,因为链表中每个结点代表某个位上的值,再乘以其位数就可以还原是整形,例如文中的[2, 4, 3]表示的是2+4*10+3*102,也就是342。

该题先转换为数字在进行计算在数字较小的时候没有问题,但是因为整形的表示范围的问题,如题中所示的100位的数字会出现溢出情况,所以不能转为整型之后计算。

双指针

直接使用链接计算,使用两个指针分别指向链表头部,将指针指向的两个数字相加,将数字的和存入结果链表,如果数字超过10,则将和的个位数存入链表,同时使用一个辅助的整形作为进位的存储,如果和超过10,则将进位存为1,后续操作的时候除了计算两个指针指向的数字之外,还需要加上进位。

两个指针依此右移一位,重复上述过程,如果其中一个链表已经为空,则第一次将另一个链表的结点加上进位进行计算即可。

题解

package 两数相加.双指针;

class LinkNode{
    private int value;
    private LinkNode next;

    public static LinkNode getInstance(int[] nums){
        LinkNode dummyHeader = new LinkNode(0);
        LinkNode current = dummyHeader;
        for(int num : nums){
            LinkNode nextNode = new LinkNode(num);
            current.next = nextNode;
            current = nextNode;
        }

        return dummyHeader;
    }

    public LinkNode(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public LinkNode getNext() {
        return next;
    }

    public void setNext(LinkNode next) {
        this.next = next;
    }
}

public class Solution {

    public static LinkNode solute(int[] nums1, int[] nums2) {
        LinkNode numLink1 = LinkNode.getInstance(nums1);
        LinkNode numLink2 = LinkNode.getInstance(nums1);

        boolean hasNext1 = true;
        boolean hasNext2 = true;
        int carry = 0;
        LinkNode header = null;
        LinkNode currentNode = null;
        while (true) {
            LinkNode numLinkNode1;
            LinkNode numLinkNode2;
            int firstNum = 0;
            int secondNum = 0;

            if (hasNext1) {
                numLinkNode1 = numLink1.getNext();
                if (numLinkNode1 == null) {
                    hasNext1 = false;
                } else {
                    firstNum = numLinkNode1.getValue();
                }
            }
            if (hasNext2) {
                numLinkNode2 = numLink2.getNext();
                if (numLinkNode2 == null) {
                    hasNext2 = false;
                } else {
                    secondNum = numLinkNode2.getValue();
                }
            }

            if (!hasNext1 && !hasNext2) {
                break;
            }

            int plus = firstNum + secondNum + carry;
            carry = plus / 10;
            int digit = plus % 10;

            LinkNode linkNode = new LinkNode(digit);
            if (currentNode == null) {
                header = linkNode;
                currentNode = linkNode;
            } else {
                currentNode.setNext(linkNode);
                currentNode = linkNode;
            }
        }
        return header;
    }
}