前言
今天无意间看到LeetCode的一道“两数相加”的算法题,第一次接触链表ListNode,ListNode结构如下:
public class ListNode {
        int val;
        ListNode next;
        ListNode() {
        }
        ListNode(int val) {
            this.val = val;
        }
        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }算法题目
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:

输入: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
- 题目数据保证列表表示的数字不含前导零
解题思路
使用迭代的方法来实现链表的相加。从两个链表的头节点开始,依次将对应位置的数字相加,并保留进位。在遍历完两个链表的所有节点之后,如果还存在进位,就需要在结果链表中追加一个节点来存储进位。
第一版代码
/**
     * 两数相加
     */
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        StringBuilder s = new StringBuilder();
        while (l1 != null) {
            s.append(l1.val);
            l1 = l1.next;
        }
        StringBuilder s1 = new StringBuilder();
        for (int i = s.toString().length(); i > 0; i--) {
            s1.append(s.toString().charAt(i - 1));
        }
        long x1 = Long.parseLong(s1.toString());
        s = new StringBuilder();
        while (l2 != null) {
            s.append(l2.val);
            l2 = l2.next;
        }
        s1 = new StringBuilder();
        for (int i = s.toString().length(); i > 0; i--) {
            s1.append(s.toString().charAt(i - 1));
        }
        long x2 = Long.parseLong(s1.toString());
        long sum = x1 + x2;
        //结果倒序
        s1 = new StringBuilder();
        for (int i = String.valueOf(sum).length(); i > 0; i--) {
            s1.append(String.valueOf(sum).charAt(i - 1));
        }
        //返回链表
        ListNode listNode = new ListNode(Integer.parseInt(s1.substring(0, 1)));
        ListNode p = listNode;//声明一个变量在移动过程中充当节点
        for (int i = 1; i < s1.toString().length(); i++) {
            p.next = new ListNode(Integer.parseInt(s1.substring(i, i + 1)));    //创建链表的下一个节点,并赋值
            p = p.next;    //将指针的位置指向当前节点
        }
        return listNode;
    }注意:万万没有想到,在LeetCode通过测试,但是提交的时候,却被一个长链表被给卡主了,查看了错误,发现是超出了long的长度,不能用传统的方法来解决,只能通过每一位数的相加,然后进位进行循环计算和进位处理。
经过思考和优化,最后优化代码如下,顺利提交LeetCode通过所有的测试用例。
最终实现代码
/**
     * 两数相加
     */
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode ln = l1;
        ListNode lx = l2;
        StringBuilder res = new StringBuilder();
        int val = 0;
        while (ln != null || lx != null) {
            int x = (ln != null) ? ln.val : 0;
            int y = (lx != null) ? lx.val : 0;
            int sum = x + y + val;
            if (sum >= 10) {
                //大于10
                res.append(sum % 10);
                //下一次运算+N
                val = sum / 10;
            } else {
                //小于10
                res.append(sum);
                //清空进位
                val = 0;
            }
            //下一个
            ln = ln != null ? ln.next : null;
            lx = lx != null ? lx.next : null;
        }
        if (val > 0) {
            //结果有进位
            res.append(val);
        }
        //返回链表
        ListNode listNode = new ListNode(Integer.parseInt(res.substring(0, 1)));
        ListNode p = listNode;//声明一个变量在移动过程中充当节点
        for (int i = 1; i < res.toString().length(); i++) {
            p.next = new ListNode(Integer.parseInt(res.substring(i, i + 1)));//创建链表的下一个节点,并赋值
            p = p.next;    //将指针的位置指向当前节点
        }
        return listNode;
    }📚学习永无止境,每天进步一点点,向知识的海洋更深处探索。



















