2. 两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

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

示例:

1
2
3
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

链表ListNode结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.bd.leetcode.leetcode_2;

public class ListNode {
int val;
ListNode next;

ListNode(int x) {
val = x;
}

ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}

第一次实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.bd.leetcode.leetcode_2;

public class Solution {

private ListNode first;

public int getLength(ListNode l1) {
int count = 0;
while (l1 != null) {
l1 = l1.next;
count++;
}
return count;
}

public ListNode arr2ListNode(int[] arr) {
ListNode firstNode = null;

if (arr == null || arr.length == 0) {
return null;
}

for (int i = 0; i < arr.length; i++) {
if (firstNode == null) {
firstNode = new ListNode(arr[i]);
} else {
ListNode oldNode = firstNode;
firstNode = new ListNode(arr[i]);
firstNode.next = oldNode;
// ListNode oldNode = firstNode;
// firstNode = new ListNode(arr[i],oldNode);
}
}
return firstNode;
}

public ListNode reverse(ListNode a) {
ListNode pre = null;
ListNode cur = a;
ListNode tmp;

while (null != cur) {
tmp = cur.next; // 保存当前节点的下一个节点
cur.next = pre; // 把当前节点的下一个节点重置为上一个节点
pre = cur; //下次遍历时候需要使用的上一个节点
cur = tmp; //下次遍历时候需要的当前节点
}

return pre;
}

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int l1Len = getLength(l1);
int l2Len = getLength(l2);

int len = l1Len >= l2Len ? l1Len : l2Len;
int flag = 0;
int i = 0;

do {
int l1Value = l1 != null ? l1.val : 0;
int l2Value = l2 != null ? l2.val : 0;
int currVal = 0;
if (l1Value + l2Value + flag > 9) {
currVal = l1Value + l2Value + flag - 10;
flag = 1;
} else {
currVal = l1Value + l2Value + flag;
flag = 0;
}

if (first == null) {
first = new ListNode(currVal);
} else {
ListNode oldFirst = first;
first = new ListNode(currVal);
first.next = oldFirst;
}


l1 = l1 != null ? l1.next : null;
l2 = l2 != null ? l2.next : null;
i++;
} while (i < len || flag > 0);//flag>0说明有进位需要再次执行一边
return reverse(first);
}

public void walk(ListNode a) {
StringBuilder s = new StringBuilder();
while (a != null) {
s.append(a.val).append(" ");
a = a.next;
}
System.out.println(s.toString());

}

public static void main(String[] args) {
Solution s = new Solution();
ListNode a = s.arr2ListNode(new int[]{1});
ListNode b = s.arr2ListNode(new int[]{9, 9});
s.walk(a);
s.walk(b);
ListNode c = s.addTwoNumbers(a, b);
s.walk(c);
}
}

优化后代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int flag = 0;
ListNode root = new ListNode(0); //记录假head节点位置,真head为root.next
ListNode cursor = root;
while (l1 != null || l2 != null || flag > 0){
int l1Value = l1 != null ? l1.val : 0;
int l2Value = l2 != null ? l2.val : 0;
int currVal = 0;
if (l1Value + l2Value + flag > 9) {
currVal = l1Value + l2Value + flag - 10;
flag = 1;
} else {
currVal = l1Value + l2Value + flag;
flag = 0;
}

cursor.next = new ListNode(currVal);
cursor = cursor.next; // 指针后移


l1 = l1 != null ? l1.next : null;
l2 = l2 != null ? l2.next : null;
}
return root.next;
}