高频算法面试题(二十二)- 两数相加II

「这是我参与11月更文挑战的第 11 天,活动详情查看:2021最后一次更文挑战

刷算法题,从来不是为了记题,而是练习把实际的问题抽象成具体的数据结构或算法模型,然后利用对应的数据结构或算法模型来进行解题。个人觉得,带着这种思维刷题,不仅能解决面试问题,也能更多的学会在日常工作中思考,如何将实际的场景抽象成相应的算法模型,从而提高代码的质量和性能

链表中的两数相加

题目来源LeetCode-445. 两数相加 II

题目描述

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

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

示例

示例 1

image.png

1
2
css复制代码输入:l1 = [7,2,4,3], l2 = [5,6,4]
输出:[7,8,0,7]

示例 2

1
2
css复制代码输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[8,0,7]

示例 3

1
2
css复制代码输入:l1 = [0], l2 = [0]
输出:[0]

提示:

  • 链表的长度范围为 [1, 100]
  • 0 <= node.val <= 9
  • 输入数据保证链表代表的数字无前导 0

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

解题

思路

这个题在前边已经做过类似的,就是大数相加。思路差不多,这个稍微不一样的地方就是,它的高位存在了链表的前边,低位在后边。因为是单向链表,我们不能说让指针指向尾部,然后往前遍历来进行求和

因为这跟我们求和是反着来的,很容易就想到用栈这种数据结构。先分别遍历这两个链表,然后将链表的元素分别压入各自的栈中,然后逐个从栈中弹出元素进行求和(求和过程很简单,注意进位就行了),将每次的计算结果创建一个结点,按照尾插法插入到新的链表尾部即可

代码

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
go复制代码//栈实现
func AddTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
if l1 == nil {
return l2
}
if l2 == nil {
return l1
}
stack1 := []int{}
stack2 := []int{}
//head1, head2 := l1, l2
for l1 != nil {
stack1 = append(stack1, l1.Val)
l1 = l1.Next
}
for l2 != nil {
stack2 = append(stack2, l2.Val)
l2 = l2.Next
}

//头插法创建新的链表
var newHead *ListNode
carry := 0
for len(stack1) > 0 || len(stack2) > 0 || carry != 0{
v1, v2 := 0, 0
if len(stack1) > 0 {
v1 = stack1[len(stack1)-1]
stack1 = stack1[:len(stack1)-1]
}
if len(stack2) > 0 {
v2 = stack2[len(stack2)-1]
stack2 = stack2[:len(stack2)-1]
}
sum := v1 + v2 +carry
carry = sum/10
sum = sum % 10
node := ListNode{sum, nil}
node.Next = newHead
newHead = &node
}
return newHead
}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%