zoukankan      html  css  js  c++  java
  • 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 }

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

  • 相关阅读:
    功能类控件
    关系类控件-明细表
    WPF MenuItem 四种角色分析
    自定义的 ListBoxItem 自适应ListBox的宽度
    由DataGridTextColumn不能获取到父级DataContext引发的思考
    GDI+中发生一般性错误的解决办法(转帖)
    WPF中RadioButton绑定数据的正确方法
    C# 使用XML序列化对象(二)
    C# 使用XML序列化对象(一)
    WPF中RadioButton的分组
  • 原文地址:https://www.cnblogs.com/pyexile/p/11484060.html
Copyright © 2011-2022 走看看