代码随想录算法训练营 Day 1 & 2|数组

数组part01

704. 二分查找

注意:

1. 左闭右闭和左闭右开的边界问题

2. middle = left + (left - right) // 2先算left - right,可以避免 left + right 数值过大引起的溢出

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        # 左闭右闭
        left = 0
        right = len(nums)-1

        while left <= right:
            middle = left + (right - left) // 2
             
            if nums[middle] > target:
                right = middle - 1
            elif nums[middle] < target:
                left = middle + 1
            else:
                return middle
        return -1

27. 移除元素

快慢指针:快指针用于判断,慢指针用于记录

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        slow = 0 
        fast = 0 

        while fast < len(nums):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        return slow

数组part02

977. 有序数组的平方

双指针相向而行

注意:

1. 初始化result为 res = [float('inf')] * len(nums)

2. 判断标准为left <= right 

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left = 0 
        right = len(nums) - 1
        i = len(nums) - 1
        res = [float('inf')] * len(nums)

        while left <= right:
            if nums[left] ** 2 < nums[right] ** 2:
                res[i] = nums[right] ** 2
                right -= 1
            else:
                res[i] = nums[left] ** 2
                left += 1
            i -= 1
        return res

209. 长度最小的子数组

双指针&滑动窗口

注意:

1. 最短长度的初始化:min_length = float('inf')

2. 累加值由右指针开始进行累加,当当前和大于等于目标值时,尝试缩小窗口。先用min_length记录最短长度,再更新累加值,最后更新左指针,顺序不可改变。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left = 0 
        right = 0 
        cur_sum = 0 # 当前的累加值
        min_length = float('inf')

        while right < len(nums):
            cur_sum += nums[right]
            # 当当前和大于等于目标值时,尝试缩小窗口 
            while cur_sum >= target:
                min_length = min(min_length, right - left + 1)
                cur_sum -= nums[left]
                left += 1

            right += 1 

        return min_length if min_length != float('inf') else 0

59. 螺旋矩阵II

循环不变量

注意:

1. 初始化一个各位为0的n x n矩阵:nums = [[0] * n for _ in range(n)]

2. 行和列的变化与不变的关系

3. n为奇数时,中间会留下一个空,nums[mid][mid] = count 

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        nums = [[0]*n for _ in range(n)]
        start_x, start_y = 0, 0
        loop, mid = n // 2, n // 2
        count = 1

        for offset in range(1, loop+1):
            for i in range(start_y, n-offset):
                # 行不变,列在变
                nums[start_x][i] = count
                count += 1 
            for i in range(start_x, n-offset):
                # 列不变,行在变
                nums[i][n-offset] = count
                count += 1
            for i in range(n-offset, start_y, -1):
                # 行不变,列在变
                nums[n-offset][i] = count
                count += 1
            for i in range(n-offset, start_x, -1):
                # 列不变,行在变
                nums[i][start_y] = count 
                count += 1
            start_x += 1
            start_y += 1

        if n % 2 != 0:
            nums[mid][mid] = count
        return nums

其他练习

283. 移动零

快慢指针之后填满0

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        left = 0
        right = 0 

        while right < len(nums):
            if nums[right] != 0:
                nums[left] = nums[right]
                left += 1
            right += 1
        
        for i in range(left, len(nums)):
            nums[i] = 0

56. 合并区间

Lambda函数,也称为匿名函数,是Python中一种简洁定义单行小函数的方式。Lambda函数本身是一个表达式,它会产生一个函数对象。具体语法,lambda 参数列表: 表达式

class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]: 
        # 首先,对区间列表按照每个区间的起始位置进行排序  
        intervals.sort(key=lambda x: x[0])  
          
        # 初始化一个空列表,用于存储合并后的区间  
        merged = []  
          
        # 遍历排序后的区间列表  
        for interval in intervals:  
            # 如果merged列表为空
            # 或者当前区间的起始位置大于merged列表中最后一个区间的结束位置  
            # 说明当前区间与merged列表中的区间没有重叠
            # 可以直接添加到merged列表中  
            if not merged or merged[-1][1] < interval[0]:  
                merged.append(interval)  
            else:  
                # 如果当前区间与merged列表中的最后一个区间有重叠  
                # 更新merged列表中最后一个区间的结束位置为两个区间结束位置的较大值  
                # 这样可以保证合并后的区间是尽可能大的,且不重叠  
                merged[-1][1] = max(merged[-1][1], interval[1])  
          
        # 返回合并后的区间列表  
        return merged

438. 找到字符串中所有字母异位词

建立dictionary,用list的方式表示。

class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        n = len(s)
        m = len(p)
        if n < m: 
            return []
        
        s_cnt = [0] * 26
        p_cnt = [0] * 26
        res = []

        # 构造一个长度为m的滑动窗口
        for i in range(m):
            # 统计p里的字母,记录到list
            p_cnt[ord(p[i]) - ord('a')] += 1
            # 统计s里的字母,记录到list
            s_cnt[ord(s[i]) - ord('a')] += 1
        if s_cnt == p_cnt:
            res.append(0)

        for i in range(m,n):
            # 维持窗口长度为m
            # i-m位置的字母被弹出,该字母的位置计数减1
            s_cnt[ord(s[i-m]) - ord('a')] -= 1
            # i位置的字母新加入,该字母的位置计数加1
            s_cnt[ord(s[i]) - ord('a')] += 1 
            if s_cnt == p_cnt:
                res.append(i-m+1)
        
        return res

560. 和为k的子数组

        # https://www.bilibili.com/video/BV1d54y127ri/?spm_id_from=333.337.search-card.all.click&vd_source=e3e285b6e46a418066b3eff2f933d941

class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        cur_sum = 0
        adict = {}
        adict[0] = 1
        count = 0
        for num in nums:
            cur_sum += num
            if cur_sum - k in adict:
                count += adict[cur_sum - k]
            # 每一个cur_sum 最终都必须在adict里
            if cur_sum in adict:
                adict[cur_sum] += 1
            else:
                adict[cur_sum] = 1
        return count

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值