HuanL资料

本文主要介绍HuanL资料 方法和在新技术下所面对的“挑战”,方便大家深入理解HuanL资料 过程。本文也将分享HuanL资料 所遇到的问题和应对策略,怎么解决怎么做的问题。
通过深入本文可以理解代码原理,进行代码文档的下载,也可以查看相应 Demo 部署效果。

两数相加

题目:

HuanL

我的解法:

  /**
    * @Description TODO
    * @Param [l1, l2]
    * @return arrays.addTwoNumbers.ListNode
    * @date 2020/7/14 17:21
    * @author huanl
    *
    * 思路:先把他全部拿出来,拿出来的时候用字符串的append函数连接起来,后面再用reverse去反转.在把他们相加的到的
    * 数转换为StringBuilder类型,然后反转,然后在把他变成ListNode类型.
    *
    * 问题: 为什么要全部拿出来? 我们正常时候做加法,不就是从低位做起,然后有进位就记录一下,下一次添加上.现在链表他给我们就是已经弄好了的低位,
    * 直接从低位开始相加就好了.
    *       直接一个一个取然后加的话怎么判断他本身到底有没有值? 噢,直接判断这个节点是不是为null
    *       加到最后可能最后一次的进位记录为一,怎么处理?   再在后面多加一个节点,将这个一记录上去.
    */
     public  ListNode addTwoNumber(ListNode l1, ListNode l2) {
         
         //用StringBuilder取出l1和l2里面所有的
         StringBuilder num1 = new StringBuilder();
         StringBuilder num2 = new StringBuilder();
         num1.append(l1.val);
         num2.append(l2.val);
         while (l1.next != null) {
             num1.append(l1.next.val);
             l1 = l1.next;
        }
         while (l2.next != null) {
             num2.append(l2.next.val);
             l2 = l2.next;
        }
         //反转为正常的顺序
         num1 = num1.reverse();
         num2 = num2.reverse();
 
         //将两个字符串相加 (因为直接一次的话会超出int或者long的长度) 其实最好就是将他们逆转过来,这样才符合我们日常的加法
         int[] nums = new int[(Math.max(num1.length(), num2.length())) + 1];
         for (int i = 1; i <= (Math.max(num1.length(), num2.length())); i++) {
             if (i>num1.length()){
                 nums[nums.length-i] = Integer.parseInt(String.valueOf(num2.charAt(num2.length()-i)));
            }else if(i>num2.length()){
                 nums[nums.length-i] = Integer.parseInt(String.valueOf(num1.charAt(num1.length()-i)));
            }else {
                 nums[nums.length-i] = Integer.parseInt(String.valueOf(num1.charAt(num1.length()-i))) + Integer.parseInt(String.valueOf(num2.charAt(num2.length()-i)));
            }
 
        }
 
         //处理进位信息
         for (int i = nums.length - 1; i > 0; i--) {
             nums[i-1] = nums[i-1] + nums[i] / 10;
             nums[i] = nums[i] % 10;
        }
 
         //因为两数相加可能会多一位,也就是第一位可能为1,可能为0,这里就先不处理第一位,直接从第二位开始处理
         StringBuilder num = new StringBuilder();
         for (int i = 1; i < nums.length ; i++) {
             num.append(nums[i]);
        }
         //处理第一位,如果为一,则直接插入最前面
         if (nums[0] != 0) {
             num.insert(0,nums[0]);
        }
         num = num.reverse();
 
         //将字符串类型的转化为ListNode类型
         ListNode ret = new ListNode(num.charAt(0) - 48);
 
         ListNode jilu = ret;
 
         for (int i = 1; i < num.length(); i++) {
             jilu.next = new ListNode(num.charAt(i) - 48);
             jilu = jilu.next;
    }
         return ret;
 
        }

问题:

  1. 为什么要先全部取出来? 有什么好处? 还是不能直接一个一个操作?

  2. 正是因为想要全部取出来,然后StringBuilder类型拼接快,然后StringBuilder又有一个反转函数,所以去用了StringBuilder,然后反转之后,本来想要用Integer.parseInt()转化为int然后相加,但是发现这个太容易直接超出范围,所以不得不直接用StringBuilder类型的直接相加,并且还用了反转之后的来相加,这就导致了相加函数复杂,并且相加之后,还需要处理进位信息,处理有没有多了一位的信息.

  3. 总结:

     1. 第一步的思路就问题,导致后续麻烦不断的到来,那为什么我会想取直接把他全部取出来呢?  
          没有取过多的考虑全部取出来有什么麻烦,就是简单就直接去取出来
     2. 能够去写出不定长字符串的加法,这个值得鼓励.

优解:

      /**
          * @Description TODO
          * @Param [l1, l2]
          * @return arrays.addTwoNumbers.ListNode
          * @date 2020/7/14 17:08
          * @author huanl
          */
     public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
         ListNode dummyHead = new ListNode(0);
         ListNode p = l1, q = l2, curr = dummyHead;
         int carry = 0;
         while (p != null || q != null) {
             int x = (p != null) ? p.val : 0;
             int y = (q != null) ? q.val : 0;
             int sum = carry + x + y;
             carry = sum / 10;
             curr.next = new ListNode(sum % 10);
             curr = curr.next;
             if (p != null) p = p.next;
             if (q != null) q = q.next;
        }
         if (carry > 0) {
             curr.next = new ListNode(carry);
        }
         return dummyHead.next;
    }

优点:

 1. 一个一个取,取出来直接进行操作,该进位的直接将进位符标志为1.
  为什么要一个一个取?
  因为他给我们的就是符合加法计算规律的,也就是先从低位算起,有进位加到高位,并且链表取值的方向也正好是从低位到高位,各种条件都非常适合直接加.
 2. 注意细节:
  a. 先建造一个头节点,这个头节点里面的值不和任何有关,那为什么要建一个这样的头节点呢? 因为没有这个头节点,第一次加法的时候就没有链表去操作,那么就势必需要把第一次提出来先做,这样就感觉有点不统一了.
  b. 用另外一个指针去操作,因为你需要返回这个链表,那么这个链表的头指针你必须保存一个,不然你就找不到这个指针了.
  c. 注意判断此时值到底取val还是0,判断条件是什么? 直接判断这个节点是不是空节点,因为我们操作的就是此节点,不是next节点.
  d. 注意可能最后一次加法时,进位为一,那么则需要在给他最后再加上一个节点,例如999+1就可能得到4位,这样就需要多加一个节点.

经验

  1. 先想一下怎么做,然后确定觉得这样做可以之后,把详细的思路写一遍,想一想为什么每一步需要这样做?和实际的相符吗?

  2. 不定长字符串的加法,每位保存一个值的算法.

HuanL资料部分资料来自网络,侵权毕设源码联系删除

区块链毕设网(www.qklbishe.com)全网最靠谱的原创区块链毕设代做网站
部分资料来自网络,侵权联系删除!
资源收费仅为搬运整理打赏费用,用户自愿支付 !
qklbishe.com区块链毕设代做网专注|以太坊fabric-计算机|java|毕业设计|代做平台 » HuanL资料

提供最优质的资源集合

立即查看 了解详情