LeetCode 两数相加算法题解 All In One
LeetCode 两数相加算法题解 All In One
js / ts 实现两数相加
两数相加原理 图解
字符串相加 / 大数相加
// 字符串相加 / 大数相加
const addStrings = function(num1: string, num2: string): string {
let res = '';
let temp = 0;
const arr1 = num1.split('');
const arr2 = num2.split('');
while (arr1.length || arr2.length || temp) {
// `~~` double bitwise not 双非位运算, 字符串转换成整数
temp += ~~arr1.pop() + ~~arr2.pop();
// 字符串相加,要注意先后顺序
res = (temp % 10) + res;
// 进位
temp = temp > 9 ? 1 : 0;
}
// console.log('res =', res, typeof res);
return res === "0" ? res : res.replace(/^0+/, '');
}
~~
double bitwise not 双非位运算, 字符串转换成整数
正数向下
取整 & 负数向上
取整
let s = `3`;
// '3'
~s;
// -4
~~s;
// 3
+s;
// 3
链表相加
// 链表相加
function addTwoNumbers(l1: ListNode | null, l2: ListNode | null): ListNode | null {
let head;
let tail;
let carry = 0;
while (l1 || l2) {
const n1 = l1?.val ?? 0;
const n2 = l2?.val ?? 0;
// const n1 = l1?.val || 0;
// const n2 = l2?.val || 0;
// const n1 = l1 ? l1.val : 0;
// const n2 = l2 ? l2.val : 0;
// 进位 carry
const sum = n1 + n2 + carry;
// 取余
let node = new ListNode(sum % 10);
if (!head) {
// head = tail = new ListNode(sum % 10);
// tail = new ListNode(sum % 10);
tail = node;
head = tail;
} else {
// 迭代链表
// tail.next = new ListNode(sum % 10);
tail.next = node;
tail = tail.next;
}
carry = sum > 9 ? 1 : 0;
// carry = Math.floor(sum / 10);
if (l1) {
l1 = l1.next;
}
if (l2) {
l2 = l2.next;
}
}
// 最后一个进位
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
};
2. 两数相加
// 2. Add Two Numbers
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2022-09-08
* @modified
*
* @description 2. 两数相加
* @description 2. Add Two Numbers
* @difficulty Medium
* @ime_complexity O(n)
* @space_complexity O(n)
* @augments
* @example
* @link https://leetcode.com/problems/add-two-numbers/
* @link https://leetcode-cn.com/problems/add-two-numbers/
* @solutions
*
* @best_solutions
*
*/
// export {};
const log = console.log;
// 2. 链表相加 🚀
function addTwoNumbers(l1: ListNode | null, l2: ListNode | null): ListNode | null {
let head;
let tail;
let carry = 0;
while (l1 || l2) {
const n1 = l1?.val ?? 0;
const n2 = l2?.val ?? 0;
// const n1 = l1?.val || 0;
// const n2 = l2?.val || 0;
// const n1 = l1 ? l1.val : 0;
// const n2 = l2 ? l2.val : 0;
const sum = n1 + n2 + carry;
if (!head) {
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = Math.floor(sum / 10);
if (l1) {
l1 = l1.next;
}
if (l2) {
l2 = l2.next;
}
}
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
};
// 2. Add Two Numbers
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2022-09-08
* @modified
*
* @description 2. 两数相加
* @description 2. Add Two Numbers
* @difficulty Medium
* @ime_complexity O(n)
* @space_complexity O(n)
* @augments
* @example
* @link https://leetcode.com/problems/add-two-numbers/
* @link https://leetcode-cn.com/problems/add-two-numbers/
* @solutions
*
* @best_solutions
*
*/
// export {};
const log = console.log;
// // 节点
// function ListNode(val, next) {
// this.val = 0 || val;
// this.next = null || next;
// }
// // 链表
// function LinkedList(value) {
// const node = new ListNode(value, ``);
// let head;
// if(!head) {
// head = node;
// } else {
// let current = head;
// while(current.next) {
// current = current.next;
// }
// current.next = node;
// }
// };
// function sumString(a1, a2) {
// const s1 = a1.reverse();
// const s2 = a2.reverse();
// let result = [];
// let upNum = 0;
// if(s1.length > s2.length) {
// result = s1;
// for (let i = 0; i < s1.length; i++) {
// let a = s1[s1.length - i - 1];
// let b = s2[s2.length - i - 1] || 0;
// result[s1.length - i - 1] = (a + b + upNum) % 10;
// if((a + b + upNum) >= 10) {
// upNum = 1;
// } else {
// upNum = 0;
// }
// }
// } else {
// result = s2;
// for (let i = 0; i < s2.length; i++) {
// let a = s2[s2.length - i - 1];
// let b = s1[s1.length - i - 1] || 0;
// result[s2.length - i - 1] = (a + b + upNum) % 10;
// if((a + b + upNum) >= 10) {
// upNum = 1;
// } else {
// upNum = 0;
// }
// }
// }
// if(upNum) {
// result.unshift(upNum);
// }
// // return result.reverse();
// return result;
// }
// singly-linked list
class ListNode {
val: number
next: ListNode | null
constructor(val?: number, next?: ListNode | null) {
this.val = (val===undefined ? 0 : val)
this.next = (next===undefined ? null : next)
}
// add
// remove
}
// 链表生成
const linkedListGenerator = (arr) => {
let head;
for (const item of arr) {
const node = new ListNode(item);
if(!head) {
head = node;
} else {
let temp = head;
// 关键:迭代 next
while(temp.next) {
temp = temp.next;
}
temp.next = node;
}
}
return head;
}
// 字符串相加 / 大数相加
const addStrings = function(num1, num2) {
let res = '';
let temp = 0;
const arr1 = num1.split('');
const arr2 = num2.split('');
while (arr1.length || arr2.length || temp) {
// ~~ ??? bitwise not 双非位运算
temp += ~~arr1.pop() + ~~arr2.pop();
// 字符串相加,要注意先后顺序
res = (temp % 10) + res;
// 进位
temp = temp > 9 ? 1 : 0;
}
// console.log('res =', res, typeof res);
return res === "0" ? res : res.replace(/^0+/, '');
}
function addTwoNumbers(l1: ListNode | null, l2: ListNode | null): ListNode | null {
// 1. 暴力法
// 遍历链表,获取原始正数,求和
// 然后,逆序的生成一个新的链表
let nums1: number[] = [];
let nums2: number[] = [];
while(l1?.val || l1?.val === 0) {
nums1.push(l1.val);
l1 = l1.next;
}
while(l2?.val || l2?.val === 0) {
nums2.push(l2.val);
l2 = l2.next;
}
let num1 = nums1.reverse().join('');
let num2 = nums2.reverse().join('');
// console.log(`num1 =`, num1)
// console.log(`num2 =`, num2)
// let sum = parseInt(num1) + parseInt(num2);
let sum = addStrings(num1, num2);
// let arr = [...`${sum}`.split('')].map(Number);
let arr = [...`${sum}`.split('')].map(Number).reverse();
// [8, 0, 7]
// console.log(`arr =`, arr)
return linkedListGenerator(arr);
};
// 测试用例 test cases
const testCases = [
{
inputs: [[2,4,3], [5,6,4]],
result: [7,0,8],
desc: 'value equal to [7,0,8]',
},
{
inputs: [[0],[0]],
result: [0],
desc: 'value equal to [0]',
},
{
inputs: [[9,9,9,9,9,9,9],[9,9,9,9]],
result: [8,9,9,9,0,0,0,1],
desc: 'value equal to [8,9,9,9,0,0,0,1]',
},
{
inputs: [[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[5,6,4]],
result: [6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
desc: 'value equal to [6,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]',
},
];
for (const [i, testCase] of testCases.entries()) {
const [first, second] = testCase.inputs;
const l1 = linkedListGenerator(first);
const l2 = linkedListGenerator(second);
const testResult = linkedListGenerator(testCase.result);
const result = addTwoNumbers(l1, l2);
log(`test case i result: `, JSON.stringify(result) === JSON.stringify(testResult) ? `✅ passed` : `❌ failed`, JSON.stringify(result));
// log(`test case i result: `, JSON.stringify(result) === JSON.stringify(testResult) ? `✅ passed` : `❌ failed`, result);
// log(`test case i result: `, result === testCase.result ? `passed ✅` : `failed ❌`, result);
// log(`test case i =`, testCase);
}
// npx ts-node ./002\ add-two-numbers.ts
/*
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1].join('')
'1000000000000000000000000000001'
[5,6,4].join('')
'564'
[5,6,4].reverse().join('')
'465'
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1].reverse().join('')
'1000000000000000000000000000001'
parseInt('1000000000000000000000000000001');
1e+30
parseInt('1000000000000000000000000000001') + parseInt('465')
1e+30
sum = parseInt('1000000000000000000000000000001') + parseInt('465');
1e+30
`${sum}`.split('');
(5) ['1', 'e', '+', '3', '0']
科学计数法 ??? 字符串相加 ??? 进位
*/
https://leetcode.com/problems/add-two-numbers/
https://leetcode.cn/problems/add-two-numbers/
LeetCode 题解 / LeetCode Solutions
https://www.youtube.com/results?search_query=+Leetcode+2
https://www.youtube.com/playlist?list=PLamwFu9yMruCBtS2tHUD77oI_Wsce-syE
YouTube & LeetCode 力扣官方算法题解视频列表
https://github.com/xgqfrms/leetcode/issues/14
https://www.youtube.com/channel/UCftIXZeipv4MTVwmfFphtYw/videos
https://github.com/neetcode-gh/leetcode/blob/main/javascript/2-Add-Two-Numbers.js
https://github.com/neetcode-gh/leetcode/blob/main/typescript/2-Add-Two-Numbers.ts
类似问题
LeetCode 445. Add Two Numbers II / 两数相加 II
https://leetcode.com/problems/add-two-numbers-ii/
LeetCode 415. Add Strings / 字符串相加 (大数相加)
https://leetcode.com/problems/add-strings/
LeetCode 43. Multiply Strings / 字符串相乘
https://leetcode.com/problems/multiply-strings/
refs
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16671318.html
未经授权禁止转载,违者必究!