算法-链表

两数相加 LeetCode-2

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

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

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

示例:

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

code:

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
/**
* Definition for a singly-linked list.
* class ListNode {
* public $val = 0;
* public $next = null;
* function __construct($val) { $this->val = $val; }
* }
*/
class Solution {

/**
* @param ListNode $l1
* @param ListNode $l2
* @return ListNode
*/
function addTwoNumbers($l1, $l2) {
$t = $l1;
$k = 0;

do {
$val = $t->val + $l2->val + $k;
$t->val = $val % 10;
$k = $val >= 10 ? 1 : 0;

if (!$t->next && !$l2->next && $k) {
$t->next = new ListNode(1);
break;
}
if($t->next && !$l2->next) {
$l2->next = new ListNode(0);
}
if($l2->next && !$t->next) {
$t->next = new ListNode(0);
}
$t = $t->next;
$l2 = $l2->next;
} while ($t);

return $l1;
}
}

两数相加II LeetCode-445

给你两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

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

进阶:

如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。

示例:

1
2
输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 8 -> 0 -> 7
1
2
3
4
5
6
7
class ListNode {
public $val = 0;
public $next = null;
function __construct($val) {
$this->val = $val;
}
}

解法1:栈

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
class Solution {
/**
* 对于逆序处理,用栈处理
* @param ListNode $l1
* @param ListNode $l2
* @return ListNode
*/
function addTwoNumbersII($l1, $l2) {
if ($l1 === null) {
return $l2;
}
if ($l2 === null) {
return $l1;
}
// 初始化栈
$stack1 = new SplStack();
$stack2 = new SplStack();
// 入栈
while ($l1 !== null) {
$stack1->push($l1->val);
$l1 = $l1->next;
}
while ($l2 !== null) {
$stack2->push($l2->val);
$l2 = $l2->next;
}

$k = 0;
$head = null;
while (!$stack1->isEmpty() || !$stack2->isEmpty() || $k > 0) {
$sum = $k;
$sum += $stack1->isEmpty() ? 0 : $stack1->pop();
$sum += $stack2->isEmpty() ? 0 : $stack2->pop();
$node = new ListNode($sum % 10);
$node->next = $head;
$head = $node;
$k = floor($sum / 10);
}
return $head;
}
}

解法2:翻转链表

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
class Solution {
/**
* @param ListNode $l1
* @param ListNode $l2
* @return ListNode
*/
function addTwoNumbersII($l1, $l2) {
// 翻转链表
$list_rev = function ($listNode) {
$prev = null;
$cur = $listNode;
while ($cur) {
$next = $cur->next;
// 新链表从后往前生成
$cur->next = $prev;
$prev = $cur;

$cur = $next;
}
return $prev;
};
$l1 = $list_rev($l1);
$l2 = $list_rev($l2);
$res = null;
$add = false;
while ($l1 || $l2 || $add) {
$sum = $add ? 1 : 0;
if ($l1) {
$sum += $l1->val;
$l1 = $l1->next;
}
if ($l2) {
$sum += $l2->val;
$l2 = $l2->next;
}
if ($sum >= 10) {
$sum -= 10;
$add = true;
} else {
$add = false;
}
// 返回链表也是从后往前生成
$node = new ListNode($sum);
$node->next = $res;
$res = $node;
}
return $res;
}
}