问题描述
这个是字节跳动面试题。
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
- 如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
示例
输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 8 -> 0 -> 7
思路
读到数组里,然后从后往前相加就行了。效率最高(方法一)
用栈,因为是倒序的嘛,栈是个自然而然的思想。(方法二)
方法一
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
//
//class TreeNode {
// int val;
// TreeNode left;
// TreeNode right;
// TreeNode(int x) { val = x; }
//}
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int countL1 = 0,countL2 = 0;
ListNode tmp = l1;
while(tmp != null){
countL1++;
tmp = tmp.next;
}
tmp = l2;
while(tmp != null){
countL2++;
tmp = tmp.next;
}
tmp = l1; int i = 0;
int[] L1 = new int[countL1];
int[] L2 = new int[countL2];
while(tmp != null){
L1[i++] = tmp.val;
tmp = tmp.next;
}
tmp = l2; i = 0;
while(tmp != null){
L2[i++] = tmp.val;
tmp = tmp.next;
}
if(L1.length < L2.length){
int[] t = L1;
L1 = L2;
L2 = t;
}
int remains = 0;
/*数组相加*/
int index1,index2;
for(index1 = L1.length-1, index2 = L2.length-1; index1 > -1 && index2 > -1; index1--,index2--){
int curSum = L1[index1]+L2[index2]+remains;
remains = curSum/10;
L1[index1] = curSum%10;
}
for(int j = index1; j > -1; j--){
int curSum = L1[j] + remains;
remains = curSum/10;
L1[j] = curSum%10;
if(remains == 0) break;
}
ListNode res = new ListNode(-1);
ListNode cur = res;
if(remains != 0){
cur.next = new ListNode(1);
cur = cur.next;
}
for(i = 0; i < L1.length; i++){
cur.next = new ListNode(L1[i]);
cur = cur.next;
}
return res.next;
}
}
嗯。。有点丑,重构一下。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int countL1 = getLength(l1),countL2 = getLength(l2);
int[] L1 = getArr(l1,countL1), L2 = getArr(l2,countL2);
if(L1.length < L2.length){
int[] t = L1;
L1 = L2;
L2 = t;
}
int remains = getRemainsAndMergeArr(L1,L2);
/*数组相加*/
ListNode res = new ListNode(-1);
ListNode cur = res;
if(remains != 0){
cur.next = new ListNode(1);
cur = cur.next;
}
for(int i = 0; i < L1.length; i++){
cur.next = new ListNode(L1[i]);
cur = cur.next;
}
return res.next;
}
private int getLength(ListNode l){
int res = 0;
while(l != null){
res++;
l = l.next;
}
return res;
}
private int[] getArr(ListNode l, int length){
int[] res = new int[length];
int i = 0;
while(l != null){
res[i++] = l.val;
l = l.next;
}
return res;
}
private int getRemainsAndMergeArr(int[] arr1, int[] arr2){
int index1 = arr1.length-1, index2 = arr2.length-1;
int remains = 0;
for(index1 = arr1.length-1, index2 = arr2.length-1; index1 > -1 && index2 > -1; index1--,index2--){
int curSum = arr1[index1]+arr2[index2]+remains;
remains = curSum/10;
arr1[index1] = curSum%10;
}
for(int j = index1; j > -1; j--){
int curSum = arr1[j] + remains;
remains = curSum/10;
arr1[j] = curSum%10;
if(remains == 0) break;
}
return remains;
}
}
方法二
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
while(l1 != null){
stack1.add(l1.val);
l1 = l1.next;
}
while(l2 != null){
stack2.add(l2.val);
l2 = l2.next;
}
ListNode res = new ListNode(-1);
int remains = 0;
while(!stack1.isEmpty() && !stack2.isEmpty()){
int val = stack1.pop() + stack2.pop() + remains;
remains = val/10;
ListNode tmp = new ListNode(val%10);
tmp.next = res.next;
res.next = tmp;
}
if(!stack1.isEmpty()) handle(stack1,res,remains);
else handle(stack2,res,remains);
return res.next;
}
private void handle(Stack<Integer> stack, ListNode res, int remains){
while(!stack.isEmpty()){
int val = stack.pop() + remains;
remains = val/10;
ListNode tmp = new ListNode(val%10);
tmp.next = res.next;
res.next = tmp;
}
if(remains == 1){
ListNode tmp = new ListNode(1);
tmp.next = res.next;
res.next = tmp;
}
}
}