数组章节 leetcode 思路&实现

704. 二分查找

思路:每次取最中间的数,比较大小,然后确定在左侧还是在右侧。区间取左闭右开

用时3:15,注意判断完nums【mid】的大小后,如果left需要调整,因为左闭右开,mid出已经判断过了,所以跳过mid,left=mid+1;如果right出需要调整,直接等于mid,因为右侧开

python 复制代码
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)
        while left<right:
            mid = (left+right)//2
            if target > nums[mid]:
                left = mid+1
            elif target < nums[mid]:
                right = mid
            else:
                return mid
        return -1

27. 移除元素

思路:移除值为val的数,也即碰到不为val的数,保存在原地。如果碰到val,慢指针停1步,快指针正常向前,并让res += 1

用时5:57.除了小问题在最后返回res的时候,应该返回nums 中与 val 不同的元素的数量。是len(nums)-res。

python 复制代码
class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        slow,fast = 0,0
        res = 0
        while fast < len(nums):
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
                fast += 1
            else:
                fast += 1
                res += 1
        return len(nums)-res
            

977. 有序数组的平方

思路:从两头开始排序,考虑左侧和右侧平方谁大,交替放到新数组里,成为一个非递增数组,然后对其排序,复杂度O(nlog⁡n),能通过

python 复制代码
class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        n = len(nums)
        ans = [0] * n
        i, j = 0, n - 1
        for p in range(n - 1, -1, -1):
            x = nums[i] * nums[i]
            y = nums[j] * nums[j]
            if x > y:
                ans[p] = x
                i += 1
            else:
                ans[p] = y
                j -= 1
        return ans
        

改进思路:建好长为n的数组,从后往前放,节省了排序的复杂度

python 复制代码
class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        slow,fast = 0, len(nums)-1
        res = [0]*len(nums)
        idx = len(nums)-1
        while slow<=fast:
            if nums[slow]**2 <= nums[fast]**2:
                res[idx] = (nums[fast]**2)
                fast -= 1
                idx -= 1
            else:
                res[idx] = (nums[slow]**2)
                slow += 1
                idx -= 1
        return res

209. 长度最小的子数组

思路:维护一个滑动窗口,记住当前窗口里的综合和长度,如果总和不够窗口长度+=1,超过-=1,记录最大窗口长度

错误出在right的初始化上,考虑初始情况下,应该长度为0,总和为0,这样比较合理。做的时候初始化左右为0,1.把第一个数放进sum,这样在只有一个数时发生错误

python 复制代码
class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        if not nums:
            return 0
        left, right = 0, 0
        sum_win = 0
        res = inf

        while right < len(nums):
            while sum_win < target and right < len(nums):
                sum_win += nums[right]
                right += 1
            while sum_win >= target:
                res = min(res, right-left)
                sum_win -= nums[left]
                left += 1
                
        return res if res != inf else 0

59. 螺旋矩阵 II

思路:考虑把所有数用完的条件下,到达边界即遍历停止。

具体来说,上下左右四个边界定义好,我这里考虑的边界在矩阵外,所以在循环中要注意range的位置,举例说明:

首先处理第一行,遍历每一个格子放好数字(这里记得数字还得从1开始),直到最后一个数,这样第一行放满了,up+=1;然后处理right-1列,right-=1;然后处理最后一行,从right-1列到left-1列;最后处理第一列,如此循环

python 复制代码
class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        up,down,left,right = 0,n,0,n
        i = 1
        res = [[0]*n for _ in range(n)]
        while i <= n**2:
            for a in range(left,right):
                res[up][a] = i
                i+=1
            up +=1
            for b in range(up,down):
                res[b][right-1] = i
                i += 1
            right -= 1
            for c in range(right-1,left-1,-1):
                res[down-1][c] = i
                i+= 1
            down -= 1
            for d in range(down-1, up-1, -1):
                res[d][left] = i
                i+=1
            left += 1
        return res
  1. 开发商购买土地

思路:考虑二维前缀和,分别获取每一列和每一行的加和,计算前缀和。用矩阵总和-2*前缀和,再取绝对值及得到了此时的价值之差,去最小的即可

简单讲一下这里的数据获取部分

python 复制代码
import sys
data  = sys.stdin.read().split()
idx = 0
n = int(data[idx])
idx+=1
m = int(data[idx])
idx+=1
arr = [[0]*m for _ in range(n)]
for i in range(n):
    for j in range(m):
        arr[i][j] = int(data[idx])
        idx+=1

使用sys.stdin.read().split()处理,获得数据的散列表,在进行处理,也可以用readline方法,依次读取每一行的数据,注意获取的都是str,需要显示转化为int和list

python 复制代码
import sys
n,m = map(int,sys.stdin.readline().split())

arr = []
for i in range(n):
    row = list(map(int,sys.stdin.readline().split()))
    arr.append(row)

后续内容相对比较简明易懂

python 复制代码
arr1 = [0]*(m+1)
arr2 = [0]*(n+1)
min_value = float('inf')

#算每一列
for j in range(m):
    sum1 = 0
    for i in range(n):
        sum1 += arr[i][j]
    arr1[j+1] = sum1 + arr1[j]
print(arr1)

#算每一行
for i in range(n):
    sum2 = 0
    for j in range(m):
        sum2 += arr[i][j]
    arr2[i+1] = sum2 + arr2[i]

#横向划分
for i in range(1,n):
    if abs(arr2[n] - 2*arr2[i])<min_value:
        min_value = abs(arr2[n] - 2*arr2[i])
#纵向划分
for j in range(1,m):
    if abs(arr1[m] - 2*arr1[j])<min_value:
        min_value = abs(arr1[m] - 2*arr1[j])

print(min_value)
相关推荐
kisshyshy14 小时前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
猿人谷21 小时前
不只是 CPU 阈值:STAR 如何用 GAT + Transformer 做容器级自动扩缩容?
人工智能·算法
复杂网络1 天前
Stable Diffusion 视觉大模型微调技术深度调研
算法
复杂网络1 天前
基于 Stable Diffusion 架构的视觉大模型代表性工作与原理深度解析
算法
MrZhao4001 天前
Agent Loop 如何用 Hook 扩展:权限、日志与工具拦截
算法
MrZhao4001 天前
Agent 为什么需要 Skills:别把所有知识都塞进 system prompt
算法
JieE2122 天前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2123 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack204 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树4 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色