问题描述:https://leetcode.com/problems/add-two-numbers/

思路1:基本加法规则

根据小学学的基本加法规则。。。。。我们需要将两个数以最低位为基准对齐,然后逐个加,需要进位的给进位就行了。。。。恰好这个链表是逆序的!!!已经为我们对齐了。用两个指针分别指向两个链表头,开始同步往后移动,边移动边计算结果,直到两个指针都到了尽头/没有进位。时间复杂度是O(max(m, n)),空间复杂度和时间复杂度一样。js代码如下:

// Runtime: 116 ms
var addTwoNumbers = function(l1, l2) {
let dummy = { next: null }, // 结果链表的head指针
tail = dummy, // tail总是指向dummy的末尾元素,以便在链表尾插入新元素
flag = false, // flag标示是否需要进位
sum; let init = () => { // 初始化,因为保证非空,所以首位总是存在的(可能为0)
sum = l1.val + l2.val;
tail.next = new ListNode(sum % 10);
// 为下一位的计算做准备
flag = sum >= 10;
l1 = l1.next;
l2 = l2.next;
// 保持tail性质不变
tail = tail.next;
}; let work = () => {
let v1, v2;
while (l1 || l2 || flag) {
// 统一化处理,不用判断谁空谁不空
v1 = l1 ? l1.val : 0;
v2 = l2 ? l2.val : 0;
sum = v1 + v2 + (flag ? 1 : 0);
tail.next = new ListNode(sum % 10);
// 为下一位的计算做准备
flag = sum >= 10;
l1 = l1 ? l1.next : null;
l2 = l2 ? l2.next : null;
// 保持tail性质不变
tail = tail.next;
}
}; init();
work(); return dummy.next;
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode *l3 = malloc(sizeof(struct ListNode));
struct ListNode *tail = l3; int sum = l1->val + l2->val;
tail->val = sum % ;
int flag = sum >= ;
l1 = l1->next;
l2 = l2->next; int v1, v2;
while (l1 || l2 || flag) {
v1 = l1 ? l1->val : ;
v2 = l2 ? l2->val : ;
sum = v1 + v2 + (flag ? : ); tail->next = malloc(sizeof(struct ListNode));
tail = tail->next;
tail->val = sum % ; flag = sum >= ;
l1 = l1 ? l1->next : NULL;
l2 = l2 ? l2->next : NULL;
} tail->next = NULL; // 这句话是必要的!否则提交后会有运行时错误。
return l3;
}

C语言版本

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode ans = new ListNode(0), tail = ans;
boolean flag = false; // 当前位是否需要进位
// 保持一个循环不变式:
// ans的前面n位为l1与l2前n位相加的正确结果
// l1与l2要么为空要么指向当前/即将计算位 // 初始化
int sum = l1.val + l2.val + (flag ? 1 : 0);
tail.val = sum % 10; flag = sum >= 10;
l1 = l1.next;
l2 = l2.next; // 保持
int v1, v2; // l1.val与l2.val不能再直接用,可能为空
while (flag || l1 != null || l2 != null) {
if (l1 == null) {
v1 = 0;
} else {
v1 = l1.val;
l1 = l1.next;
} if (l2 == null) {
v2 = 0;
} else {
v2 = l2.val;
l2 = l2.next;
} sum = v1 + v2 + (flag ? 1 : 0);
tail.next = new ListNode(sum % 10); flag = sum >= 10;
tail = tail.next;
} // 终止 return ans;
}
}

Java版本

思路2:移花接木法。。。

基本上和思路1没区别,并不能改善时间复杂度的渐进性,只是省了点空间。js代码:

// 不创建新链表,直接把结果存到l1上,并对多出来的部分做"嫁接"处理
// Runtime: 112 ms, faster than 99.52% of JavaScript online submissions for Add Two Numbers.
var addTwoNumbers2 = function(l1, l2) {
let dummy = { next: l1 }, // 结果链表的head指针
tail = dummy, // tail总是指向l1的前继元素(也就是dummy的尾元素),以便在链尾插入链表/新元素
flag = false, // flag标示下一位的计算是否需要进位
sum; let init = () => { // 初始化,因为保证非空,所以首位总是存在的
sum = l1.val + l2.val;
l1.val = sum % 10;
// 为下一位的计算做准备
flag = sum >= 10;
l1 = l1.next;
l2 = l2.next;
// 保持tail性质不变
tail = tail.next;
}; let status1 = () => { // 处理等长的那部分
while (l1 && l2) {
sum = l1.val + l2.val + (flag ? 1 : 0);
l1.val = sum % 10;
// 为下一位的计算做准备
flag = sum >= 10;
l1 = l1.next;
l2 = l2.next;
// 保持tail性质不变
tail = tail.next;
}
}; let status2 = () => { // 处理多出来的部分
// 如果l2更长,直接移植到l1
if (l2) {
l1 = tail.next = l2;
}
// 处理进位
while (l1 && flag) {
sum = l1.val + 1;
l1.val = sum % 10;
// 为下一位的计算做准备
flag = sum >= 10;
l1 = l1.next;
// 保持tail性质不变
tail = tail.next;
}
if (flag) {
tail.next = new ListNode(1);
}
}; init();
status1();
status2(); return dummy.next;
};

LeetCode #002# Add Two Numbers(js描述)的更多相关文章

  1. 【JAVA、C++】LeetCode 002 Add Two Numbers

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  2. [Leetcode] 002. Add Two Numbers

    https://leetcode.com/problems/add-two-numbers/ public class Solution { public ListNode addTwoNumbers ...

  3. LeetCode:1. Add Two Numbers

    题目: LeetCode:1. Add Two Numbers 描述: Given an array of integers, return indices of the two numbers su ...

  4. LeetCode(2) || Add Two Numbers && Longest Substring Without Repeating Characters

    LeetCode(2) || Add Two Numbers && Longest Substring Without Repeating Characters 题记 刷LeetCod ...

  5. [LeetCode] 445. Add Two Numbers II 两个数字相加之二

    You are given two linked lists representing two non-negative numbers. The most significant digit com ...

  6. [Leetcode Week15] Add Two Numbers

    Add Two Numbers 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/add-two-numbers/description/ Descrip ...

  7. LeetCode 面试:Add Two Numbers

    1 题目 You are given two linked lists representing two non-negative numbers. The digits are stored in ...

  8. [LeetCode] 2. Add Two Numbers 两个数字相加 java语言实现 C++语言实现

    [LeetCode] Add Two Numbers 两个数字相加   You are given two non-empty linked lists representing two non-ne ...

  9. [LeetCode] 2. Add Two Numbers 两个数字相加

    You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...

随机推荐

  1. 一个简易的netty udp服务端

    netty号称java高性能网络库,为人帮忙中,研究了下,写了一个demo.反复调试,更改,局域网两个客户端同时for循环发10000个20字节的数据包,入库mysql,居然没丢. 思路,netty的 ...

  2. [VS SVN] VS的SVN插件AnkhSvn

    VS的SVN插件AnkhSvn   修改VS配置  将解决方案或项目加入SVN管理

  3. Spark连接MongoDB之Scala

    MongoDB Connector for Spark Spark Connector Scala Guide spark-shell --jars "mongo-spark-connect ...

  4. Lucene入门学习

    技术原理: 开发环境: lucene包:分词包,核心包,高亮显示(highlight和memory),查询包.(下载请到官网去查看,如若下载其他版本,请看我的上篇文档,在luke里面) 原文文档: 入 ...

  5. chrome 调试进入 paused in debugger 状态解决办法

    今天调试代码的时候总是一刷新就进入 debugger 状态,总是需要按几次 F8 才能进到页面,我那个暴脾气啊,几次后终于是忍不住了,然后再网上找到了解决办法.就如一位网友所说,“Oh God! I ...

  6. Oracle课程档案,第二天

    salary:工资 order by:排序 desc:降序 hire:雇佣 单行函数 一周有七天 一月不一定只有30天 trunc:截取 dual:空表 last:最后 month:月份 round: ...

  7. 性能优化-YAHOO军规

    1.尽可能减少http请求数量 2.使用CDN 3.添加Expire/Cache-Control头 4.启用Gzip压缩 5.将css放在页面最上 6.将script放在页面最下 7.避免在CSS中使 ...

  8. ssm项目中KindEditor的图片上传插件,浏览器兼容性问题

    解决办法: 原因:使用@ResponseBody注解返回java对象,在浏览器中是Content-Type:application/json;charset=UTF-8 我们需要返回字符串(Strin ...

  9. 常用邮箱的 IMAP/POP3/SMTP 设置

    通过网上查找的资料和自己的总结完成了下面的文章,看完之后相信大家对这三种协议会有更深入的理解.如有错误的地方望指正. POP3 POP3是Post Office Protocol 3的简称,即邮局协议 ...

  10. Gym 101194L / UVALive 7908 - World Cup - [三进制状压暴力枚举][2016 EC-Final Problem L]

    题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...