ARTS(04)

作者: 本一和他的朋友们 | 来源:发表于2022-02-09 11:21 被阅读0次

    什么是 ARTS?

    1. 算法(Algorithm): 每周至少一道 LeetCode 算法题,加强编程训练和算法学习
    2. 阅读(Review): 阅读并点评至少一篇英文技术文章,提高英文水平
    3. 技巧 (Tip):学习至少一个技术技巧,总结、归纳日常工作中遇到的知识点
    4. 分享(Share):分析一篇有观点和思考的技术文章,建立影响力,输出价值观

    时间周期:

    2022 年 1 月 31 日至 2 月 6 日

    一:算法

    删除排序数组中的重复项
    题目描述:
    给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
    不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
    示例 1:
    给定数组 nums = [1,1,2],
    函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
    你不需要考虑数组中超出新长度后面的元素。 示例 2:
    给定 nums = [0,0,1,1,1,2,2,3,3,4],
    函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
    你不需要考虑数组中超出新长度后面的元素。
    说明:
    为什么返回数值是整数,但输出的答案是数组呢?
    请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
    你可以想象内部操作如下:
    
    // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
    int len = removeDuplicates(nums);
    // 在函数里修改输入数组对于调用者是可见的。
    // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
    for (int i = 0; i < len; i++) {
        print(nums[i]);
    }
    

    前置知识

    • 数组
    • 双指针

    思路
    使用快慢指针来记录遍历的坐标。

    • 开始时这两个指针都指向第一个数字
    • 如果两个指针指的数字相同改,则快指针向前一步
    • 如果不同,则两个指针都向前走一步
    • 当快指针走完整个数组后,慢指针当前的坐标加1就是数组中不同数字的个数

    总结:实际上这就是双指针中的快慢指针。在这里快指针是读指针,慢指针是写指针。从读写指针考虑,我觉得更符合本质。

    代码

    JavaScript 实现及其拓展资料

    let targetNums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4]
    function removeDuplicates (nums) {
      const numLength = nums.length
      if (numLength == 0) {
        return 0
      }
    
      let slowP = 0
      for (let fastP = 0; fastP < numLength; fastP++) {
        if (nums[fastP] !== nums[slowP]) {
          slowP++
          nums[slowP] = nums[fastP]
        }
      }
      return slowP + 1
    }
    
    let result = removeDuplicates(targetNums)
    
    // 结果应该是:5
    console.log("result is ===>>>", result)
    

    Python 实现及其拓展资料

    class Solution:
      def removeDuplicates(self, nums: List[int]) -> int:
        if nums:
          slow = 0
          for fast in range(1, len(nums)):
            if nums[fast] != nums[slow]:
              slow += 1
              nums[slow] = nums[fast]
          return slow + 1
        else
          return 0
    

    Java 实现及其拓展资料

    class Solution {
      public int removeDuplicates(int[] nums) {
        int n = nums.length;
        if (n == 0) {
          return 0;
        }
        int fast = 1;
        int slow = 1;
    
        while (fast < n) {
          if (nums[fast] !== nums[fast - 1]) {
            nums[slow] = nums[fast];
            ++slow;
          }
          ++fast;
        }
    
        return slow;
      }
    }
    

    Go 实现及其拓展资料

    func removeDuplicates(nums []int) int {
      n := len(nums)
      if n == 0 {
        return 0
      }
      slow := 1
      for fast := 1; fast < n; fast++ {
        if nums[fast] !== nums[fast - 1]{
          nums[slow] = nums[fast]
          slow++
        }
      }
      return slow
    }
    

    二:阅读,英文技术文章

    Making the web better. With blocks! – Joel on Software
    Block Protocol - Documentation

    三:技巧

    如何实现图片懒加载
    图片懒加载的核心思想是:将img的src属性使用一张本地占位符,或者为空,然后真实的图片路径再定义一个data-set属性存起来,待达到一定条件时将data-img的属性赋给src。
    手摸手教你实现图片懒加载 - SegmentFault 思否

    四:分享

    当我们谈论效率的时候,我们在谈论什么 - 少数派
    给我启发的知识:
    对于有效、无效和半有效时间的定义

    1. 有效时间指的是那些真正有突出的进展的时间,它只占整块时间的很小一部分。突出的进展就类似解决了某个 bug,看懂了某个原理。这样的时间也可以被认为是做事时真正有用的时间。
    2. 所谓无效时间指的是做一件事情的过程中完全不用花的时间,这段时间纯粹是无用时间。举个例子,如果要使用远程服务器跑一段程序,那么设置 IDE 的远程连接可以说是在这个场景下最优的做法,而其他的方法,比如将代码文件传输到远程服务器再进行操作就可以说是一种更花时间也更不便利的做法,而后者所花费的无用的调试、修改、重新传输文件的时间,就可以被认为是无用时间的一种,它完全不创造任何成果。
    3. *半有效时间指的就是表面上看起来并没有什么成效、但是却不可避免的出现在工作或学习的场景下的那些时间。半有效时间大概可以分为三类:
      1. 错误路径的探索时间:它有可能是在不同的道路里进行探索时所花的时间。当实现某件事的正确路径是 A,那么在实现A之前,可能花了一定的时间探索还探索了错误的路径 BCDE。但是,即使走一个错误的路径,至少也返回了一个信息就是:此路不通。所以这种类型的半有效时间并不算是无效的,而且它几乎不可能被完全消除。
      2. 进入状态的准备时间:第二种典型的半有效时间就是刚开始进入工作状态的时间。这段时间取决于进入状态的速度和当时的心情。有些人能够很快地进入状态,有些人可能进入状态需要花的时间比较长。而且,在这种情况下,半有效时间和有效时间的界限其实是比较模糊的,进入做事状态和进入做事状态的时间其实是没办法被明确地量化的,因此它根本上也无法被统计,而这种无法统计的时间只能训练自己的感觉来明确地意识到。
      3. 简单的不可自动化工作的时间:第三种半有效时间就是相对于比较重复但是却没法自动化的工作,它们有既定的流程,基本上不会出错。就比如说粗剪一段视频或者音频,消除相应的错句或杂音,它在现有的技术条件下没办法完全自动化,但是本身的工作又是不可以缺失的。这种类型的半有效时间并没有创造出关键的成果,但是好像又是不可缺少的一步,或者说它是有效时间之前的预备步骤。
    • 消除无效时间,还可以细分为两个方面
        • 第一个方面是比较宏观的,将整块的没在做事的无效时间转化成在做事的时间。也就是不要把本应该做事的时间浪费掉,变成一段很长的无效时间。这里就需要一个良好的日程管理系统。现在的日程管理工具和方法,比如 To-do list 或者子弹笔记,这些工具被设计出来的目的其实都是提前规划自己的工作和学习的时间,减少无效时间,让人在应该学习和工作的时候不要玩得太脱,把无效时间转化成半有效或者有效时间。
        • 另一个方面是使用快捷的操作或流畅的工作流来降低实际做事时花费的无效时间。 在做事前的无效的时间,往往是由于一个不顺畅的流程导致的。而要想消除这样的无效时间,就应该让做事的流程变得更加顺畅。这里根据不同工作的具体需求,应该会更偏向具体领域知识。下面的章节我会具体介绍在学术科研领域中,我在阅读论文时的工作流程和使用到的工具。
    • 减少半有效时间,可以从两方面入手
      • 第一个是找到把半有效时间转换为有效时间的方法。比如番茄钟,它本质上是为了增加有效时间,用番茄钟的规则来限定自己专注的时长,从而最大程度地改变自己对待时间的态度来尽可能地让半有效时间转变为有效时间
      • 第二个是改变自己的能力,调整自己的状态,从根本上减少有效时间。让自己自然而然地掌握快速进入状态的能力,或者是长期地提升自己的专业能力,从而减小自己走向错误路径的可能性。

    相关文章

      网友评论

          本文标题:ARTS(04)

          本文链接:https://www.haomeiwen.com/subject/lmjwkrtx.html