2.计算2数之和

力扣题目链接: leetcode.cn/problems/ad...

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

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

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

示例 1:

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

示例 2:

java 复制代码
输入: l1 = [0], l2 = [0]
输出: [0]

示例 3:

java 复制代码
输入: 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
  • 题目数据保证列表表示的数字不含前导零

提示:

  • 链表结构如下:
java 复制代码
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; }
}

解法:模拟

java 复制代码
class Solution3 {

    public static void main(String[] args) {

        ListNode listNode = new ListNode(7);
        listNode.next = new ListNode(8);
        listNode.next.next = new ListNode(9);

        ListNode listNode2 = new ListNode(3);
        listNode2.next = new ListNode(2);

        ListNode result = addTwoNumbers(listNode, listNode2);
    }

    public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //要返回的链表
        ListNode result = null;
        //链表头部指针
        ListNode head = null;
        //进位数,2个个位数相加最大为18,所以进位数最大为1
        int carry = 0;
        //当链表中的某1个不为空 执行计算逻辑
        while (l1 != null || l2 != null) {
            //赋值,默认值为0
            //只有链表没有对齐,比如某个链表的节点个数为3,某个节点个数为2,此时补位默认值就是0
            int x = l1 == null ? 0 : l1.val;
            int y = l2 == null ? 0 : l2.val;
            //计算两数之和
            int sum = x + y + carry;
            //计算和的十位数
            carry = sum / 10;
            //计算和的个位数
            int mod = sum % 10;
            //判断结果链表是否为空
            if (result == null) {
                //为空就构造链表
                result = new ListNode(mod);
                //将链表的头结点赋值给head
                head = result;
            } else {
                //头结点的next指针指向新节点
                head.next = new ListNode(mod);
                //将头节点的后置节点赋值给head 供下一轮循环使用
                head = head.next;
            }
            //准备下一轮的数据
            if (l1 != null) {
                l1 = l1.next;
            }
            if (l2 != null) {
                l2 = l2.next;
            }
        }
        //如果还有进位数没处理,做处理
        if (carry == 1) {
            head.next = new ListNode(carry);
        }
        return result;
    }
}

精髓在于链表的构建:

java 复制代码
//要返回的链表
ListNode result = null;
//链表头部指针
ListNode head = null;
//伪代码
while(true){
 if (result == null) {
        //为空就构造链表
        result = new ListNode(mod);
        //将链表的头结点赋值给head
        head = result;
    } else {
        //头结点的next指针指向新节点
        head.next = new ListNode(mod);
        //将头节点的后置节点赋值给head 供下一轮循环使用
        head = head.next;
    }
}

复杂度分析

时间复杂度:O(max⁡(m,n)),其中 m 和 n 分别为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要O(1)的时间。

空间复杂度:O(1)。注意返回值不计入空间复杂度。

我的错误解法,由于不能用BigDecimal导致数字比较大提交失败,原来限制不能使用BigDecimal,好坑!

java 复制代码
class Solution {

    public static void main(String[] args) {
        ListNode listNode = new ListNode(7);
        listNode.next = new ListNode(8);
        listNode.next.next = new ListNode(9);

        ListNode listNode2 = new ListNode(3);
        listNode2.next = new ListNode(2);

        ListNode result = addTwoNumbers(listNode, listNode2);
    }

    public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //转换为数字342
        BigDecimal v1 = transferToNumber(l1);
        //转换为数字465
        BigDecimal v2 = transferToNumber(l2);
        //计算342+465 = 807
        BigDecimal sum = v1.add(v2);
        //将807反转为708
        String[] split = sum.toString().split("");
        LinkedList<String> list = new LinkedList<>();
        for (String s : split) {
            list.addFirst(s);
        }
        //遍历708 转换为链表结构
        ListNode result = null;
        ListNode head = null;
        for (int i = 0; i <= list.size() - 1; i++) {
            if (result == null) {
                result = new ListNode(Integer.parseInt(list.get(i)));
                head = result;
                continue;
            }
            head.next = new ListNode(Integer.parseInt(list.get(i)));
            head = head.next;
        }
        return result;
    }
    private static BigDecimal transferToNumber(ListNode l1) {
        LinkedList<Integer> list = new LinkedList<>();
        list.addFirst(l1.val);
        while (l1.next != null) {
            list.addFirst(l1.next.val);
            l1.next = l1.next.next;
        }
        String v = "";
        for (Integer val : list) {
            v += val;
        }
        return new BigDecimal(v);
    }
}
相关推荐
ID_180079054735 小时前
小红书笔记详情API接口基础解析:数据结构与调用方式
数据结构·数据库·笔记
千金裘换酒10 小时前
LeetCode 移动零元素 快慢指针
算法·leetcode·职场和发展
wm104310 小时前
机器学习第二讲 KNN算法
人工智能·算法·机器学习
NAGNIP10 小时前
一文搞懂机器学习线性代数基础知识!
算法
NAGNIP10 小时前
机器学习入门概述一览
算法
奋进的芋圆11 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端
iuu_star11 小时前
C语言数据结构-顺序查找、折半查找
c语言·数据结构·算法
Yzzz-F11 小时前
P1558 色板游戏 [线段树 + 二进制状态压缩 + 懒标记区间重置]
算法
计算机程序设计小李同学11 小时前
个人数据管理系统
java·vue.js·spring boot·后端·web安全
漫随流水11 小时前
leetcode算法(515.在每个树行中找最大值)
数据结构·算法·leetcode·二叉树