zoukankan      html  css  js  c++  java
  • 刷力扣明白了官网代码的小心机(代码的优化)

    刷力扣明白了官网代码的小心机(代码的优化)

    1、203_移除链表元素:

        //我这道题这样干的话,就得去分开讨论最后一个结点是val时要怎么处理了
    //    public ListNode removeElements2(ListNode head, int val) {
    //        if(head == null) return null;
    //        //好处,我想到了就是定义进入一个虚拟头结点
    //        ListNode newHead = new ListNode(0);
    //        newHead.next = head;
    //        while(head != null) {
    //            if(val == head.val) {    //找到了(还得考虑head.next是否为空,同时若当前待删除结点是最后一个的话,咱还得找到前一个,(解决可以定义一个prev 指针变量))
    //                head.val = head.next.val;
    //                head.next = head.next.next;
    //            }else {
    //                head = head.next;
    //            }
    //            
    //        }        
    //        return newHead.next;
    //    }

    官网:

        //官网:秒啊: while (temp.next != null) ,
        //如果我直接在 while(head != null) 改成: while(head.next != null) 导致到了最后一个结点的next是空,直接跳出循环,最后一个结点得不到判断
        // 官网的小心机是:以下的一个代码框架:

    (通过 当前结点的next 去判断是否是待删除结点,若是,当前结点就相当于待删除结点的前一个结点了)


        /** 将开始遍历的位置移动到了虚拟头结点的位置(然后,通过next进行判断),这样即使最后一个结点就是待删除结点,也可以轻轻松松删除
                dummyHead.next = head;
                ListNode temp = dummyHead;
                while (temp.next != null) {

          ...

          }
         */

    //官网代码:
    class Solution {
            public ListNode removeElements(ListNode head, int val) {
                ListNode dummyHead = new ListNode(0);
                dummyHead.next = head;
                ListNode temp = dummyHead;
                while (temp.next != null) {
                    if (temp.next.val == val) {
                        temp.next = temp.next.next;
                    } else {
                        temp = temp.next;
                    }
                }
                return dummyHead.next;
            }
        }
        

    2、2_两数相加:

    //自己写的就是代码太啰嗦了(思路跟官网一样)
         public ListNode addTwoNumbers2(ListNode l1, ListNode l2) {
            if(l1 == null && l2 == null)    return null;
            if(l1 == null && l2 != null)    return l2;
            if(l1 != null && l2 == null)    return l1;
            ListNode ptr1 = l1;
            ListNode ptr2 = l2;
            ListNode head = new ListNode(0);
            ListNode tmp = head;
            int carry = 0;
            int sum = 0;
            
            while(ptr1 != null && ptr2 != null) {
                sum = ptr1.val + ptr2.val + carry;    //考虑到进位的情况
                //考虑进位
                carry = sum / 10;
                sum %= 10;
                ListNode p = new ListNode(sum);
                tmp.next = p;
                tmp = p;
            
                ptr1 = ptr1.next;
                ptr2 = ptr2.next;
            }
            while(ptr1 != null) {
                //tmp 继续走
                sum = ptr1.val + carry;    //考虑到进位的情况
                carry = sum / 10;
                sum %= 10;
                ListNode p = new ListNode(sum);
                tmp.next = p;
                tmp = p;
                ptr1 = ptr1.next;
            }
            while(ptr2 != null) {
                //tmp 继续走
                sum = ptr2.val + carry;    //考虑到进位的情况
                carry = sum / 10;
                sum %= 10;
                ListNode p = new ListNode(sum);
                tmp.next = p;
                tmp = p;
                ptr2 = ptr2.next;
            }
            if(carry != 0){//最后一位处理
                ListNode p = new ListNode(carry);
                tmp.next = p;
            }
            return head.next;
        }


        //官网的方法:官网用 || 把所有情况考虑在一起了,
        //(我是详细的分成四种情况 l1、l2同时为空; 11 为空,12 不为空; l1不为空,l2 为空; l1 、 l2 同时不为空)
        //而且我分析到 l1 、 l2 同时不为空 时,使用while(l1 != null && l2 != null), 后边就还得再次考虑 l1 (l2)链表还有剩下结点没有被访问到呢
         /**
           官网的框架:
            while (l1 != null || l2 != null){
                       if (l1 != null) {    
                         l1 = l1.next;
                     }
                     if (l2 != null) {
                         l2 = l2.next;
                     }        
             }

      */
        // 比我的框架少写了好多重复代码啦

        //然后 在 || 的情况下,拿到头结点的初始值(经过是否为空,空的初始值 为 0,否则就是头结点的值)
         class Solution2 {
             public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
                 ListNode head = null, tail = null;    //从无到有,硬生生构建出一条链表(需要有两个指针(或者一个头结点和一个指针):其中一个指针用来实现遍历到下一个位置去创建结点,然后next 连起来,一个就是head啦)
                 int carry = 0;
                 while (l1 != null || l2 != null) {
                     //拿到头结点的初始值(经过是否为空,空的初始值 为 0,否则就是头结点的值)
                     int n1 = l1 != null ? l1.val : 0;
                     int n2 = l2 != null ? l2.val : 0;
                     
                     int sum = n1 + n2 + carry;
                     if (head == null) {    //构建第一个结点时
                         head = tail = new ListNode(sum % 10);
                     } else {
                         tail.next = new ListNode(sum % 10);
                         tail = tail.next;
                     }
                     carry = sum / 10;
                     if (l1 != null) {    
                         l1 = l1.next;
                     }
                     if (l2 != null) {
                         l2 = l2.next;
                     }
                 }
                 if (carry > 0) {    //最后一位的考虑
                     tail.next = new ListNode(carry);
                 }
                 return head;
             }
         }
        
     
  • 相关阅读:
    Google Protocol Buffers学习
    C学习笔记-一些知识
    前端相关
    Spark笔记-gz压缩存储到HDFS【转】
    maven笔记-将本地jar包打包进可执行jar中
    Spark运行时错误与解决
    机器学习笔记
    Spark笔记-DataSet,DataFrame
    云平台各层解释
    linux笔记-多服务器同时执行相同命令
  • 原文地址:https://www.cnblogs.com/shan333/p/15450136.html
Copyright © 2011-2022 走看看