1. 题目(题目链接:https://leetcode-cn.com/problems/add-two-numbers)
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
2.解题(Java)
一开始我以为可以随便写,就直接用链表LinkedList做了,自己在本地测试也可以的,但是就是通不过。所以应该还是要严格按照规范来吧。如下图,当你选择了语言之后,就会有一些提示。
(1) 思路
因为是用链表,所以首先要知道几点:获取节点的值(l2.val),获取下一个节点(其实是获取到下一个节点的地址,l2.next)。其实示例中的原因有点误导人,你大可不必看。你只要知道,其实就是遍历两个链表,然后将遍历到的两个值相加,如果相加超过10,那么就要向前进1,然后将该次相加的结果(其实是还要加上上一次的进位的值)追加到我们要返回的新链表后。简单的加法而已。
现在主要是要明白,新链表每一次的添加的值有那几部分:其实是三个部分(即l1.val + l2.val + 上一次相加的进位,如果上一回相加超过10,那么进位就是1,否则就是0)。
(2) 代码
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */ 9 10 class Solution { 11 public ListNode addTwoNumbers(ListNode l1, ListNode l2){ 12 ListNode newLink = new ListNode(0); // 创建新的链表 13 ListNode link = newLink; 14 int carry = 0; // 默认进位位0 15 while (l1 != null || l2 != null) { 16 int x = l1 != null ? l1.val : 0; 17 int y = l2 != null ? l2.val : 0; 18 int num = x + y + carry; 19 carry = num / 10; 20 link.next = new ListNode(num % 10); 21 link = link.next; 22 if (l1 != null) l1 = l1.next ; 23 if (l2 != null) l2 = l2.next; 24 } 25 if (carry > 0) { 26 link.next = new ListNode(up); 27 } 28 return newLink.next; 29 } 30 }
可能有人会有疑问,为什么12行已经创建了一个新的链表,13行又创建一个指向同一个内存地址的引用。
因为我们最终是要返回这个新链表的头结点,题目中的这个链表是单链表,单链表的遍历只能从头开始,但是我们每次操作会使指向链表的引用(指针)向后移动,最终这个引用指向的就是最后一个节点,如果不把链表的初始地址记下,那么这个链表就没有意义了。
来看一个图
图中变量跟代码中的保持一致的。可以看到,我们每次操作之后,link就会往后移动一位,最终link会指向最后一个节点,但是你返回这个link没有用,必须返回newLink才行。但是我的代码中为什么最后返回的是newLink.next呢?因为我们创建链表的时候是new LiskNode(0);这表示该链表的第一个节点中的val为0,真正由我们相加的有用的值是从第二个节点开始的,所以最后我们返回的是newLink.next。
其实为了更方便,还可以将代码改一下
1 class Solution { 2 public ListNode addTwoNumbers(ListNode l1, ListNode l2){ 3 ListNode newLink = new ListNode(0); 4 ListNode link = newLink; 5 int carry = 0; 6 while (l1 != null || l2 != null) { 7 int x = 0; 8 int y = 0; 9 if (l1 != null) { 10 x = l1.val; 11 l1 = l1.next; 12 } 13 if (l2 != null) { 14 y = l2.val; 15 l2 = l2.next; 16 } 17 int num = x + y + up; 18 carry = num / 10; 19 link.next = new ListNode(num % 10); 20 link = link.next; 21 } 22 if (carry > 0) { 23 link.next = new ListNode(up); 24 } 25 return newLink.next; 26 } 27 }
这样可以省去一些重复的判断,从提交结果来看,也的确是有明显的效果的。
原文地址:https://www.cnblogs.com/pyexile/p/11484060.html