Go语言:LeetCode-两数相加

题目:给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字0之外,这两个数都不回以0开头。
示例
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

分析:

  1. 由于是用链表存储的整数,所以所表示的整数有可能会超过 int64 所能表示的整数范围,因此不能够直接把链表所表示的整数取出来相加,然后在存回链表。这就涉及到大整数相加的问题。
  2. 这种加法是逆序相加,设计大整数相加的时候要注意加法的方式。应该是从左边往右加,还需要考虑进位。
  3. 利用go语言中的切片来存储链表所表示的整数,然后,对两个切片进行特殊的加法。具体细节如下代码所示。
//getNumFromList函数:给定一个链表的表头,返回这个链表所表示的逆序整数
func getNumFromList(l *ListNode) []int {
	var num []int
	for {
		if l == nil {
			break
		}
		num = append(num, l.Val)
		l = l.Next
	}
	return num
}
/*Special_Add函数:这个特殊的加法,特殊在:
1.它的输入是两个整数切片,对这两个整数切片进行相加
2.它是逆序相加,也就是两个切片从左边加到右边为止
*/
func Special_Add(num1 []int, num2 []int) []int {
	var i, j int
	var jinwei int   //加法要考虑进位
	var res []int
	for {
		if i < len(num1) && j < len(num2) {
		    //存储两数相加的余数作为结果,商作为进位
			res = append(res, (num1[i]+num2[j]+jinwei)%10) 
			jinwei = (num1[i] + num2[j] + jinwei) / 10
			i++
			j++
		} else {
			break
		}
	}
	//以下两种情况是考虑到两个整数切片的长度不一样所进行的特殊处理。
	//如:999+11、11+9999这种情况
tag1:
	if i == len(num1) && j != len(num2) {
		res = append(res, (num2[j]+jinwei)%10)
		jinwei = (num2[j] + jinwei) / 10
		j++
		goto tag1
	}
tag2:
	if i != len(num1) && j == len(num2) {
		res = append(res, (num1[i]+jinwei)%10)
		jinwei = (num1[i] + jinwei) / 10
		i++
		goto tag2
	}
	//下面是判断两个切片整数加完后,是否还存在进位,如88+22这种情况
	if i == len(num1) && j == len(num2) && jinwei != 0 {
		res = append(res, jinwei)
	}
	return res
}

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
	//取出第一个链表所表示的逆序整数,存储在切片num1中
	num1 := getNumFromList(l1)  
	//取出第二个链表所表示的逆序整数,存储在切片num2中
	num2 := getNumFromList(l2)
	//对两个整数切片进行逆序相加,得到的结果存储在切片res中
	res := Special_Add(num1, num2)
	var i int
	//将res中所表示的逆序整数用链表存储
	var head, p, tail *ListNode
	head = new(ListNode) //新建节点
	head.Next = nil
	p = head
	tail = head
	//不断迭代,把结果存回链表中
	for i = 0; i < len(res); i++ {
		tail = new(ListNode)
		tail.Val = res[i]
		tail.Next = nil
		p.Next = tail
		p = p.Next
	}
	return head.Next
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值