• 二刷力扣--数组


    最近在准备找工作,跟着代码随想录上的刷题顺序刷一遍LeetCode。虽然也刷过几百道LeetCode题了,但是没有按照题目的类别去刷,这次系统地刷一遍题目,总结一下方法和套路。
    原网站的题解是C++版本的,我使用的是Python,会额外记录Python刷题时一些坑以及技巧。

    数组

    数组理论基础

    数组是存放在连续内存空间上的相同类型数据的集合。

    Python中的list不要求相同类型。 Python中的array.array中的元素是相同类型的。

    二分查找(704)

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

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            left = 0
            right = len(nums) - 1
            while left <= right:
                mid =  left  + (right - left) // 2
                if nums[mid] == target:
                    return mid
                elif nums[mid] < target:
                    left = mid+1 
                elif nums[mid] >target:
                    right = mid-1  
            return -1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    移除元素(27)

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

    方法一:双指针。(覆盖)

    class Solution:
        def removeElement(self, nums: List[int], val: int) -> int:
            fast = 0
            slow = 0 
            while fast < len(nums):
                if nums[fast] == val:
                    fast += 1
                else:
                    nums[slow] = nums[fast]
                    fast += 1
                    slow += 1
            return slow
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    方法二:pop。

    class Solution:
        def removeElement(self, nums: List[int], val: int) -> int:
            for i in range(len(nums)-1, -1, -1):# 注意顺序
                if nums[i] == val:
                    nums.pop(i)
            
            return len(nums)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    有序数组的平方(977)

    #双指针
    给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

    class Solution:
        def sortedSquares(self, nums: List[int]) -> List[int]:
            res = [0]*len(nums)
            i = 0
            j = len(nums) - 1
            end = len(nums)-1
            while j >= i:
                if abs(nums[i]) > abs(nums[j]):
                    res[end] = nums[i]**2
                    i += 1
                else:
                    res[end] = nums[j]**2
                    j -= 1
                end -= 1
            return res
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    长度最小的子数组(209)

    #滑动窗口

    class Solution:
        def minSubArrayLen(self, target: int, nums: List[int]) -> int:
            res = 10**6
            s = 0
            i = 0 # 窗口左边界
           
            for j in range(len(nums)): # j是窗口的右边界
                s += nums[j]
                # 每次更新i(起始位置)
                while s >= target:
                    subLength = j-i+1
                    res = res if  res < subLength else subLength
                    s -= nums[i]
                    i += 1
    
            return res if res != 10**6 else 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    如果使用暴力搜索,是O(n^2)。
    而窗口法只遍历右边界j,左边界i通过(s >= target)条件下向右滑。

    python 缩进好容易看错,尤其是在leetcode的编辑器中。

    螺旋矩阵(59)

    #模拟
    模拟在矩阵里行走的过程。

    class Solution:
        def generateMatrix(self, n: int) -> List[List[int]]:   
            def next_(i,j,direction):       
                if direction == 'right':
                    if j < n-1 and mat[i][j+1] == 0 :
                        j += 1
                    else:
                        direction = 'down'
                        i += 1
                elif direction == 'down':
                    if i < n-1 and mat[i+1][j] == 0:
                        i += 1
                    else:
                        direction = 'left'
                        j -= 1
                elif direction == 'left':
                    if j > 0 and mat[i][j-1] == 0:
                        j -= 1
                    else:
                        direction = 'up'
                        i -= 1
                elif direction == 'up':
                    if i > 0 and mat[i-1][j] == 0:
                        i -= 1
                    else:
                        direction = 'right'
                        j += 1
                return i, j, direction
                        
            mat = [[0 for j in range(n)] for i in range(n)]
            i,j = 0,0
            direction = 'right'
            for x in range(1, 1+n**2):
                mat[i][j] = x
                i,j,direction = next_(i,j,direction)
                print(i,j,direction)
            
            return mat
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    LeetCode官网给出的题解更简洁。参考官网的解后优化了一下自己的代码:

    class Solution:
        def generateMatrix(self, n: int) -> List[List[int]]:
            directions = [(0,1), (1,0), (0,-1), (-1,0)] # 右 下 左 上
            def next_(i,j,directionIndex): 
                direction = directions[directionIndex]
                t_i, t_j =  i + direction[0], j + direction[1]      
                if not (0<= t_i <= n-1) or not (0<= t_j <= n-1) or mat[t_i][t_j] != 0:
                    directionIndex = (directionIndex +1) % 4
                direction = directions[directionIndex]
                t_i, t_j =  i + direction[0], j + direction[1]     
                return t_i, t_j, directionIndex
                
                        
            mat = [[0 for j in range(n)] for i in range(n)]
            i,j = 0,0
            directionIndex = 0  # 右
            for x in range(1, 1+n**2):
                mat[i][j] = x
                i,j,directionIndex = next_(i,j,directionIndex)
            
            return mat
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    数组小结

    数组是一种基础的数据结构,在Python中一般用list来实现。
    LeetCode中的题目需要注意给出的数组是否有序。通常会用到双指针滑动窗口等技巧。
    长度最小的子数组(209)比较有难度,要想到滑动窗口,还要想到遍历窗口的终止位置j,滑动起始位置i。

  • 相关阅读:
    生产力工具如何选择?印象笔记 Verse、Notion、FlowUs
    前端常见的设计模式
    flutter布局中的一些细节
    Spark读取多目录
    C语言数据结构串【BF\KMP算法】
    NC65 rest接口 开发 NC65接口开发
    JavaScript历史上的今天是星期几
    JDK动态代理和CGLIB动态代理
    【Spring MVC】统一功能处理
    如何使用SQL系列 之 如何在SQL中使用视图
  • 原文地址:https://blog.csdn.net/qq_41068877/article/details/132816964