代码随想录Day1:数组

433 阅读3分钟

Day1 学习任务:

数组理论基础,704. 二分查找,27. 移除元素

学习链接:代码随想录 (programmercarl.com)

理论部分笔记:

Day1 数组.jpg

题目一:二分查找(704)

题目: 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

提示:

  1. 你可以假设 'nums'中的所有元素是不重复的。
  2. 'n'将在[1, 10000]之间
  3. 'nums' 的每个元素都将在[-9999, 9999]之间

第一想法

  • 有关有序列表中的顺序搜索问题
  • 要注意元素比较,形成升序
  • 要注意元素的区间范围

看完代码随想录之后的总结

视频讲解文章讲解的重点笔记:

  • 定义的区间要合法且有效,即:使得left=right在区间里有意义
  • 边界处理规则根据区间定义来决定
  • The single forward slash / operator is known as float division, which returns a floating point value. On the other hand, the double forward slash // operator returns a floored value, specifically either a floored integer or floating point value.

题目二:移除元素 (27)

题目:给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。

  • 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。

  • 元素的顺序可以改变。你。

提示:

  1. 0 <= nums.length <= 100
  2. 0 <= nums[i] <= 50
  3. 0 <= val <= 100

第一想法

  • 不需要考虑数组中超出新长度后面的元素是因为数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖
  • 想到用双循环但是不符合O(1)的要求

看完代码随想录之后的总结

视频讲解文章讲解的的重点笔记:

  • erase()函数的功能是用来删除容器中的元素,是一个O(n)的操作
  • 如果刷算法题用库函数可以直接解决,那最好不要用库函数,或者明白库函数里的实质
  • 暴力解法就是两层for循环,一个for循环遍历数组元素 ,第二个for循环更新数组
  • 快慢双指针的思路:(1) 使用双指针时要明白两个指针都各自代表什么 (2) 双指针法(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作
class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        if nums is None or len(nums)==0: 
            return 0 
        # fast alow two pointers
        slow=0
        for fast in range(len(nums)):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
        return slow      
  • 相向双指针的思路使用双指针,两个指针初始时分别位于数组的首尾,向中间移动遍历该序列。我们令这两个指针为左右指针。每当左指针指向的元素等于val时,我们用右指针指向的元素覆盖此时左指针的位置。这样做的好处是当左右指针重合的时候,左右指针合起来在最坏的情况之下也只需要遍历数组一次。
class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        if nums is None or len(nums)==0: 
            return 0 
        l=0
        r=len(nums)-1
        while l<r: 
            while(l<r and nums[l]!=val):
                l+=1
            while(l<r and nums[r]==val):
                r-=1
            nums[l], nums[r]=nums[r], nums[l]
        print(nums)
        if nums[l]==val: 
            return l 
        else: 
            return l+1

今日刷题总结和感悟:

  1. 应该提高对于双指针思想的敏感度,在遍历对象的过程中,双指针仍有两种用法,相同方向的快慢双指针算法相反方向的对撞双指针算法。但是这两种算法有没有各自特别适用的情形呢?
  2. 已经很久没有接触数据结构和算法的知识了,感觉自己当初学的内容好像是秋天的微风吹着夏天的树叶一样,思绪不会像秋天的落叶随风舞动,反倒像是结结实实长在树上的新叶子。脑袋里有一种似曾相识的感觉但是细节都不记得。今天的视频课收获很大,没有废话,每一个提及的问题都是直击我在思考这个算法题时候的困惑。希望自己在以后的刷题中一点点捡回来自己的编程能力。坚持呀!