思路很直接,就是每两个节点的值求和,然后串接到新的链表上。需要注意的是
- 一个链表比另一个链表长,要处理较长的链表的剩余部分
- 一直要考虑进位的值
下面是我的实现,其中用了一个常见的技巧——虚拟头节点。通过它可以使循环中的逻辑更直接、更纯粹。
代码已提交通过。
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
if l1 == nil {
return l2
}
if l2 == nil {
return l1
}
// l1 != nil && l2 != nil
var (
dummy ListNode // 用于存储结果的新链表的虚拟头节点,用于简化代码逻辑
curr = &dummy // 新链表的尾节点
r int // 进位
n1 = l1
n2 = l2
)
for n1 != nil && n2 != nil { // 两个链表等长部分相加
sum := n1.Val + n2.Val + r // 求和,要加上r
node := &ListNode{Val: sum%10} // 创建新节点,sum的个位做Val
curr.Next = node // 串接到新链表尾部
curr = node // 更新新链表尾节点
r = sum/10 // 更新r
// 迭代
n1 = n1.Next
n2 = n2.Next
}
for n1 != nil { // l1较长,处理l1剩余部分
sum := n1.Val + r
node := &ListNode{Val: sum%10}
curr.Next = node
curr = node
r = sum/10
n1 = n1.Next
}
for n2 != nil { // l2较长,处理l2剩余部分
sum := n2.Val + r
node := &ListNode{Val: sum%10}
curr.Next = node
curr = node
r = sum/10
n2 = n2.Next
}
if r != 0 { // 最后进位不为0的情况
node := &ListNode{Val: r}
curr.Next = node
}
return dummy.Next
}