leetcode第二题:两数相加

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 }

这样可以省去一些重复的判断,从提交结果来看,也的确是有明显的效果的。

猜你喜欢

转载自www.cnblogs.com/pyexile/p/11484060.html