[LeetCode] Add Two Numbers
2016-11-15 01:13
211 查看
关于LeetCode更多详细的代码,请参考https://github.com/Crazykev/Leetcode
You are given two linked lists representing two non-negative numbers. 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.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
思路1
将链表表示的数字转换成一个数字,再将它们相加,再转化为逆序链表。这样的算法时间复杂度是O(max(m,n)),要循环三遍来解析整数以及表示成链表。但是考虑到题目中没有说该非负数的大小是在int(即使是long)的表示范围,我们可能需要一个方法来表示一个不限长度的长整形,进行大数字求和,而大数字求和的常规思路便是模拟纸上手工两数字求和,所以将链表转换为数字毫无意义。这样的推理让我们很容易想到思路2。
思路2
直接对链表进行大数字模拟纸上求和,从头到尾同时遍历两个链表的元素,对它们进行求和,对10进行取模操作,获得余数和进位,将余数填入结果链表的对应元素中。继续对下一组元素求和(需要加上进位)。
golang代码
这里可以进行一个小优化,取模操作也是一个比较耗时的操作,我们尽量用加减法或者位操作代替,考虑我们相加的是两个小于10的正数,结果必然位于区间[0,19],所以我们可以通过判断和的范围来对余数和进位的值进行简单计算得出。相加代码(
优化后执行时间从32ms降到28ms。
You are given two linked lists representing two non-negative numbers. 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.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
分析
也是比较常规的题型,两个链表分别表示两个整数(非负),每个链表元素表示整数的一个位,逆序表示(例如2->4->3表示342)。现在求两个这样的链表表示数的和,同样用逆序链表表示。题目很直观,我们也可以很直观地去思考题目解决方案,有两种。思路1
将链表表示的数字转换成一个数字,再将它们相加,再转化为逆序链表。这样的算法时间复杂度是O(max(m,n)),要循环三遍来解析整数以及表示成链表。但是考虑到题目中没有说该非负数的大小是在int(即使是long)的表示范围,我们可能需要一个方法来表示一个不限长度的长整形,进行大数字求和,而大数字求和的常规思路便是模拟纸上手工两数字求和,所以将链表转换为数字毫无意义。这样的推理让我们很容易想到思路2。
思路2
直接对链表进行大数字模拟纸上求和,从头到尾同时遍历两个链表的元素,对它们进行求和,对10进行取模操作,获得余数和进位,将余数填入结果链表的对应元素中。继续对下一组元素求和(需要加上进位)。
golang代码
golang代码
思路1
无思路2
func newNode(val int) *ListNode { return &ListNode{ Val: val, } } func add(val1, val2, carry int) (int, int) { res := val1 + val2 + carry return res % 10, res / 10 } func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode { p1 := l1 p2 := l2 carry := 0 sum := 0 var resList, curList *ListNode if p1 == nil { return l2 } if p2 == nil { return l1 } for p1 != nil && p2 != nil { sum, carry = add(p1.Val, p2.Val, carry) if resList == nil { resList = newNode(sum) curList = resList } else { curList.Next = newNode(sum) curList = curList.Next } p1 = p1.Next p2 = p2.Next } for p1 != nil { sum, carry = add(p1.Val, 0, carry) curList.Next = newNode(sum) curList = curList.Next p1 = p1.Next } for p2 != nil { sum, carry = add(p2.Val, 0, carry) curList.Next = newNode(sum) curList = curList.Next p2 = p2.Next } if carry != 0 { curList.Next = newNode(carry) } return resList }
这里可以进行一个小优化,取模操作也是一个比较耗时的操作,我们尽量用加减法或者位操作代替,考虑我们相加的是两个小于10的正数,结果必然位于区间[0,19],所以我们可以通过判断和的范围来对余数和进位的值进行简单计算得出。相加代码(
add函数)可以优化如下:
func add(val1, val2, carry int) (int, int) { res := val1 + val2 + carry if res >= 10 { return res - 10, 1 } return res, 0 }
优化后执行时间从32ms降到28ms。
相关文章推荐
- LeetCode Add Two Numbers
- [LeetCode]Add Two Numbers
- LeetCode # Add Two Numbers #
- [LeetCode]2.Add Two Numbers
- [LeetCode - 模拟加法] 2. Add Two Numbers
- leetcode 2 : Add two numbers
- C实现 LeetCode->Add Two Numbers
- leetcode: add two numbers , hash search solution, java. O(n)
- LeetCode4: Add Two Numbers
- Leetcode-2 Add Two Numbers
- LeetCode | Add Two Numbers
- leetcode-Add Two Numbers-2
- Add Two Numbers---LeetCode
- leetcode Add Two Numbers
- LeetCode java实现Add Two Numbers
- LeetCode002 Add Two Numbers
- Add Two Numbers -- LeetCode
- [leetcode][2]add two numbers
- LeetCode: 2. Add Two Numbers
- [LeetCode]Add Two Numbers