二刷力扣--数组

简介: 二刷力扣--数组

最近在准备找工作,跟着代码随想录上的刷题顺序刷一遍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

移除元素(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

方法二: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)

有序数组的平方(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

长度最小的子数组(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

如果使用暴力搜索,是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

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

数组小结

数组是一种基础的数据结构,在Python中一般用list来实现。

LeetCode中的题目需要注意给出的数组是否有序。通常会用到双指针滑动窗口等技巧。

长度最小的子数组(209)比较有难度,要想到滑动窗口,还要想到遍历窗口的终止位置j,滑动起始位置i。

相关文章
|
7天前
|
存储 算法 Python
二刷力扣--哈希表
二刷力扣--哈希表
|
7天前
|
算法
二刷力扣--二叉树(3)
二刷力扣--二叉树(3)
|
7天前
二刷力扣--二叉树(2)
二刷力扣--二叉树(2)
|
7天前
二刷力扣--二叉树(1)基础、遍历
二刷力扣--二叉树(1)基础、遍历
|
7天前
|
存储 算法 Python
二刷力扣--栈和队列
二刷力扣--栈和队列
|
7天前
|
算法 索引 Python
二刷力扣--字符串
二刷力扣--字符串
|
7天前
|
Java Python
二刷力扣--链表
二刷力扣--链表
|
12天前
|
存储 SQL 算法
LeetCode第53题:最大子数组和【python 5种算法】
LeetCode第53题:最大子数组和【python 5种算法】
|
8天前
|
索引
【LeetCode刷题】二分查找:山脉数组的峰顶索引、寻找峰值
【LeetCode刷题】二分查找:山脉数组的峰顶索引、寻找峰值
|
9天前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素