跟着代码随时想录手撕代码

本文介绍了数组的基本概念及其操作难点,包括二分查找的边界处理、移除元素的方法、有序数组平方的双指针解法以及长度最小子数组的滑动窗口技巧。通过《代码随时想录》中的分类,目标是系统地复习和提升数据结构能力,每天专注于简单和中等问题,逐步挑战难题。
摘要由CSDN通过智能技术生成

总体规划

目前基础:力扣hot100已刷73题,dp相关的目前还没涉及

困难:解题思路不清晰,非常依赖题解,且对考点(数据结构)不是很确定

总体目标🎯:

  • 通过《代码随时想录》的分类,比较完善的查漏补缺的刷一遍
  • 力抓简单+中等,难题适当做
  • 先保质再保量

每日目标:

  • 完成两道编程题

Part 1、数组

概念

  1. 数组是存放在连续内存空间上的相同类型数据的集合。
  2. 读取方便,读取时时间复杂度为O(1)
  3. 删除或者增加数据的时候,需要移动一定范围的元素,时间复杂度为O(n)
  4. 数组不能删除,只能覆盖

1.二分查找

题目描述

考点

为啥能用二分查找?

  1. 关键词:有序
  2. 关键词:不重复

考你啥?

  1. 边界的处理,left,right是开还是闭

要点

为什么用mid=(right-left)//2 +left,不用mid=(right+left)//2?

——当left和right很大的时候,可以起到防止溢出的作用

完整代码

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left, right = 0, len(nums)-1
        while left <= right:
            # mid = (left + right) // 2
            mid = (right - left) //2 + left
            if nums[mid] < target:
                left = mid +1
            elif nums[mid] >target:
                right = mid - 1
            else:
                return mid
        return -1

时间复杂度:O(logn)

空间复杂度:O(1)


2.移除元素

题目描述

考点

  • 数组无法删除,只能进行覆盖

要点

  • 数组下标越界的细节掌握

完整代码

解法一:暴力法

思路:双层循环,进行覆盖,记录等于val值的数量,最后返回数组长度减去val值个数,即为删除指定元素后的长度

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        #逆序查找
        n=len(nums)
        count = 0
        for i in range(n-1, -1, -1):
            if nums[i] == val:
                count += 1
                for j in range(i, n-1):
                    nums[j]=nums[j+1]
                nums[n-1]=0
        return n-count

时间复杂度:O(n^2)

空间复杂度:O(1)

解法二:快慢指针(代优化)


3.有序数组的平方

题目描述

考点

  • 双指针

要点

  • while循环语句中left是小于等于right,因为两者相遇的时候的值即为最小值,也需要存入结果中

解法一:暴力法

直接平方后进行排序

class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        for i in range(len(nums)):
            nums[i] = nums[i] ** 2
        return sorted(nums)

时间复杂度:O(n+nlogn)=O(nlogn)

空间复杂度:O(1)

解法二:双指针

思路:定义左右指针left和right,分别指向头部和尾部,再定义一个存放结果的res,比较左右指针绝对值更大的数,将其存放在res的尾部,然后将绝对值更大的数所对应的指针向中间移动,直到两指针相遇,即存放完毕。

class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        #双指针
        #一头一尾,找更大的值,逆序存入数组中
        left , right = 0 , len(nums) - 1
        res = [0] * len(nums)
        i = len(nums) - 1
        while left <= right:
            if abs(nums[left]) <= abs(nums[right]):
                res[i] = nums[right] ** 2
                right -= 1
            else:
                res[i] = nums[left] ** 2 
                left += 1
            i -= 1
        return res

时间复杂度:O(n)

空间复杂度:O(n)


4.长度最小的子数组(需二刷)

题目描述

考点

  • 滑动窗口的灵活使用

要点

  • 第一个while用来锁定判断区间的截止位置
  • 第二个while循环用来判断当前子串是否符合条件,若符合,则计算当前子串长度,并更新当前子串和,移动左指针
  • 此次对于两个while循环的逻辑已经不清晰了,下次要注意抓出判断条件

解法一:暴力法(双层for循环O(n^2),会报错,超出时间限制)

解法二:滑动窗口

class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        #滑动窗口
        left , right = 0 , 0
        res = float('inf')
        cur_sum=0
        n = len(nums)
        while right < n :
            cur_sum += nums[right]
            while cur_sum >= target:
                res = min(res , right - left +1)
                cur_sum -= nums[left]
                left += 1
            right += 1
        return res if res!=float('inf') else 0

时间复杂度:O(n) 虽然有两个while循环,但是left和right都是向右侧移动,没有回退吗所以时间复杂度是O(n)

空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值