LeetCode 2 - 两数之和 - 解题思路记录 - GoLang

570 阅读4分钟

今天下午分享了一篇21题的链表操作,未了巩固一下自己的知识,在晚上的时候再刷了一题,也与链表相关的题目。

老规矩,先看题目

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Exmaple

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

我在没看清题目的情况下,妄自开始做题。结果很悲催,就是怎么做都做不出来,后来查了一下答案,发现我压根就看错题目了 !!!(大家千万别跟我一样,不然面试的时候就完蛋)

我是怎么理解错的呢, 题目中需要将3个数字相加,我脑海里浮现了2个百位数相加!
然后我直接开始按照小学加法的算法,对2个百位数进行计算(未考虑他已经反转好了),进位
然后我的进位则再需要一次单链表翻转,才能够完成任务,原本以为终于完成了,然而一提交Wrong Answer

好吧, 承认自己太粗心大意了, 但并非没收获, 当一看到正确答案的时候,灵光一闪直接懂了其中原理。

废话不少说,我们直接来看题目吧,就如例子所说, 有2个链表,里面各自有各自的数字,你要做的就是将其结果创建一个新的链表连起来, 要注意的是 进位的问题,

这道题目难点就在于其进位的问题, 我们先上代码

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
 var result *ListNode = new(ListNode)
 var head *ListNode
 head = result
 carry := 0
 for l1 != nil || l2 !=nil {
  d1:=0
  d2:=0
  if l1 == nil{ //防止该节点为null
   d1 = 0
  }else{
   d1 = l1.Val
  }
  if l2 == nil{ //防止该节点为null
   d2 = 0
  }else{
   d2 = l2.Val
  }

  sum := d1 + d2 + carry
  if sum >= 10 {
   carry = 1
  }else {
   carry = 0
  }
  var tmp *ListNode = new(ListNode)
  tmp.Val = sum % 10
  head.Next = tmp
  head = head.Next

  if l1 != nil{
   l1 = l1.Next
  }
  if l2 != nil {
   l2 = l2.Next
  }
 }
 if carry == 1{
  var tmp *ListNode = new(ListNode)
  tmp.Val = 1
  head.Next = tmp
 }
 return result.Next
}

老规矩,咱们还是顺序来, 头3行代码跟我上一篇(合并有序列表)的介绍一样, 这里不详细说明,只是一图带过就好, 需要详细的去参考我上一篇文章

head 就是 result本身, 为的是返回的时候,要返回链表的头部回去
然后我们定义了

carry := 0

初始化进位标识符为0

if l1 == nil{ //防止该节点为null
	d1 = 0
}else{
	d1 = l1.Val
}
if l2 == nil{ //防止该节点为null
	d2 = 0
}else{
	d2 = l2.Val
}

防止节点为nil的时候造成错误

d1:=0
d2:=0
sum := d1 + d2 + carry

这三句主要是将两数与进位符号相加, 就跟我们做的加法题一样
5 + 5 必须进位1

if sum >= 10 {
	carry = 1
}else {
	carry = 0
}

这个If主要是判断需不需要进位

var tmp *ListNode = new(ListNode)
tmp.Val = sum % 10
head.Next = tmp
head = head.Next

来重头戏了, sum%10就是取个位的数字, 如果不懂的可以往前翻我第12题,罗马数字的解题思路

取得数值的个位,创建一个节点,并把head.next指向这个节点,这里咱们画个图解释

每一次的相加,都会创建出一个Temp的节点,并把head.Next指向他,再把head指向Temp(相当于往后移了一位),我们再来看个完整版本

每次循环后,再把题目给予的链表往后移一位

if l1 != nil{
 l1 = l1.Next
}
if l2 != nil {
 l2 = l2.Next
}

到这里我们就解释完了9成的代码了,剩下最后一块

if carry == 1{
 var tmp *ListNode = new(ListNode)
 tmp.Val = 1
 head.Next = tmp
}

这里零散的多了一块 carry ==1 的例子是什么意思?
我们画个图,你就懂了

没错, 就是当链表长度是1的时候, 要进位,但l1 和 l2 的next确是空的情况下,我们也要对进位的Carry 1进行链表操作

到这里就完结散花了, 继续加油

其他相关题目连接

LeetCode 5 - 回文串 - 解题思路记录 - GoLang

LeetCode 15 - 3数之和 - 解题思路记录 - GoLang

LeetCode 12 - 罗马数字 - 解题思路记录 - GoLang