数组章节 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)
相关推荐
荣光属于凯撒2 小时前
P2176 [USACO11DEC] RoadBlock S / [USACO14FEB] Roadblock G/S
算法·图论
雨季mo浅忆2 小时前
记录利用Cursor快速实现拖拽式问卷题型创建
算法
酉鬼女又兒2 小时前
零基础快速入门前端Web存储(sessionStorage & localStorage)知识点详解与蓝桥杯考点应用(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·javascript·职场和发展·蓝桥杯·html
Yzzz-F2 小时前
2018-2019 ACM-ICPC, Asia Dhaka Regional ContestC[数论]
算法
Frostnova丶2 小时前
LeetCode 3474. 字典序最小的生成字符串
算法·leetcode·职场和发展
REDcker2 小时前
Nagle 算法与 TCP_NODELAY、TCP_CORK 详解
网络·tcp/ip·算法
AlenTech2 小时前
136. 只出现一次的数字 - 力扣(LeetCode)
leetcode
β添砖java2 小时前
深度优先搜索DFS
算法·深度优先
小糯米6012 小时前
C++ 并查集
java·c++·算法