两数相加(二)--链表
给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储一位数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
你可以假设除了0之外,这两个数都不会以0开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
解法一
思路:
- 标签: 链表
- 将两个链表看成是相同长度的进行遍历,如果一个链表较短则在前面补0,比如987 + 23 = 987 + 023 = 1010
- 每一位计算的同时需要考虑上一位的进位问题,而当前位计算结束后同样需要更新进位值
- 如果两个链表全部遍历完毕后,进位值为1 ,则在新链表最前方添加节点1
- 小技巧: 对于链表问题,返回结果为头节点时,通常需要先初始化一个预先指针pre,该指针的下一个节点指向真正的头节点head . 使用预先指针的目的在于链表初始化时无可用节点值,而且链表构造过程需要指针的移动,进而会导致头指针丢失,无法返回结果
下面我们一一图解上面过程:
(1)初始化pre指针,并让cur也指向都指向头节点head,以及进位carry初始化为0
(2)利用上面思路l1.value + l2.value + carry,并对10取余,取整
(3)利用7+3 = 10 ,carry = 1, sum = 0,并且平移节点l1,l2,cur
(4)经过l1.value + l2.value + carry = 11,carry = sum/10 = 1,进位值为1,余值为sum % 10 = 1
(5)计算之后,开始平移l1,l2,cur
(6) 经过l1.value + l2.value + carry = 11,carry = sum/10 = 1,进位值为1,余值为sum % 10 = 0(实际存入链表)
(7)计算之后平移l1,l2,cur,没有位数的,补0
(8)链表遍历结束,进位为1,添加节点,并去除头节点
(9)去除头节点0之后,也就是结果为0101,逆转过来为1010,满足要求.
下面整个代码:
public class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode pre = new ListNode(0); ListNode cur = pre; int carry = 0; while(l1 != null || l2 != null) { int x = l1 == null ? 0 : l1.val; int y = l2 == null ? 0 : l2.val; int sum = x + y + carry; carry = sum / 10; sum = sum % 10; cur.next = new ListNode(sum); cur = cur.next; if(l1 != null) l1 = l1.next; if(l2 != null) l2 = l2.next; } if(carry == 1) { cur.next = new ListNode(carry); } return pre.next; } }
解法二
抛弃解法一的思想:
- 新建节点的class,包括该节点的值以及指向下一个节点的指针
- 新建链表result,用于输出结果
- 此不需要进位值标志carry,而是如果total > 10,让l1.value加1(或者l2.value加1),然后循环遍历即可
首先我们新建节点的class,如下:
public class ListNode { public var val: Int public var next: ListNode? public init(_ val: Int) { self.val = val self.next = nil } }
下面是核心代码,已在leetcode上成功运行.
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? { var result: ListNode? = nil if l1 == nil && l2 == nil { return result } var s1 = l1 var s2 = l2 var total = (s1?.val ?? 0) + (s2?.val ?? 0) if total < 10 { s1 = s1?.next } else { total = total % 10 s1 = s1?.next ?? ListNode.init(0) s1!.val = s1!.val + 1 } result = ListNode.init(total) s2 = s2?.next result!.next = addTwoNumbers(s1, s2) return result }
以上就是别致的两数之和,关于自己解决此类方法的思想和代码,希望对大家有所帮助!!!