ARTS(04)

2022-02-09  本文已影响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]);
}

前置知识

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

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

代码

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. 简单的不可自动化工作的时间:第三种半有效时间就是相对于比较重复但是却没法自动化的工作,它们有既定的流程,基本上不会出错。就比如说粗剪一段视频或者音频,消除相应的错句或杂音,它在现有的技术条件下没办法完全自动化,但是本身的工作又是不可以缺失的。这种类型的半有效时间并没有创造出关键的成果,但是好像又是不可缺少的一步,或者说它是有效时间之前的预备步骤。
上一篇下一篇

猜你喜欢

热点阅读