LeetCode #002# Add Two Numbers(js描述)
问题描述: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描述)的更多相关文章
- 【JAVA、C++】LeetCode 002 Add Two Numbers
You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...
- [Leetcode] 002. Add Two Numbers
https://leetcode.com/problems/add-two-numbers/ public class Solution { public ListNode addTwoNumbers ...
- LeetCode:1. Add Two Numbers
题目: LeetCode:1. Add Two Numbers 描述: Given an array of integers, return indices of the two numbers su ...
- LeetCode(2) || Add Two Numbers && Longest Substring Without Repeating Characters
LeetCode(2) || Add Two Numbers && Longest Substring Without Repeating Characters 题记 刷LeetCod ...
- [LeetCode] 445. Add Two Numbers II 两个数字相加之二
You are given two linked lists representing two non-negative numbers. The most significant digit com ...
- [Leetcode Week15] Add Two Numbers
Add Two Numbers 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/add-two-numbers/description/ Descrip ...
- LeetCode 面试:Add Two Numbers
1 题目 You are given two linked lists representing two non-negative numbers. The digits are stored in ...
- [LeetCode] 2. Add Two Numbers 两个数字相加 java语言实现 C++语言实现
[LeetCode] Add Two Numbers 两个数字相加 You are given two non-empty linked lists representing two non-ne ...
- [LeetCode] 2. Add Two Numbers 两个数字相加
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
随机推荐
- HTML自动跳转
本文首发于 http://youngzy.com/ 关于页面的自动跳转,以前知道有JavaScript的方法,直接设置window.location 或者在setTimeout 函数里进行设置. 现在 ...
- CXF Spring开发WebService,基于SOAP和REST方式
版本CXF2.6.9 添加的包文件 这个版本的不可在Tomcat7上运行,会出错. 配置文件 applicationContext.xml <?xml version="1.0&quo ...
- react使用apollo简单的获取列表
react yarn add apollo-boost apollo-client react-apollo apollo-cache-inmemory apollo-link-http graphq ...
- Oracle 创建表 Create Table...
一.创建表 主键约束primary key 约束条件,唯一且非空,一个表中只能有一个主键:有多个字段联合作为主键时,合在一起唯一标识记录,叫做联合主键. 外键约束 foreign key 受另外一张表 ...
- javascript的数组之from()
Array.from()方法从一个类似数组或可迭代对象中创建一个新的数组实例. const arr = [1, 2, 3]; Array.from(arr); //[1, 2, 3] Array.fr ...
- JavaScript基础知识(数据类型)
数据类型 布尔:true/fasle console.log(typeof true);// "boolean" Number : true -->1 false --> ...
- intput/output 文件的复制练习
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStrea ...
- [No0000186]治愈系课程教材 第一课
一部分:时态 时态有时间和特点组成 时间:现在.过去.将来 特点:一般.完成.进行.完成进行 所以时态总共有12种(加上过去将来的时间又多出4种时态,总共16种) 一般现在时 一般过去时 一般将来时 ...
- pytorch-MNIST数据模型测试
用pytorch搭建一个DNN网络,主要目的是熟悉pytorch的使用 """ test Function """ import torch ...
- Linux中找到占用cpu最高的线程
在工作中,经常会碰到CPU占用100%的情况,那如何找到是那个线程占用了cpu呢? 1. top命令,找到cpu占用最高的进程 2. 查看该进程的线程, top -p <pid> 3. ...