数组章节 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)
相关推荐
语戚5 分钟前
力扣 3161. 块放置查询:线段树解法(Java 实现)
java·算法·leetcode·面试·线段树·力扣·
天天进步201512 分钟前
Python全栈项目实战:从零构建校园心理健康咨询平台
面试·职场和发展
CS创新实验室1 小时前
从顺序表到动态数组:数据结构的永恒基石与现代语言的优雅封装
数据结构·算法
Black蜡笔小新1 小时前
自动化AI算法训练服务器DLTM训推一体化平台助力农业生产管理实现安全智能化
人工智能·算法·自动化
武子康2 小时前
调查研究-151 Slack vs Jira:区别、使用指南与团队选择方法
人工智能·科技·深度学习·ai·职场和发展·jira·slack
8Qi82 小时前
LeetCode 23. 合并 K 个升序链表 —— 小顶堆(PriorityQueue)
数据结构·算法·leetcode·链表·
QiLinkOS3 小时前
《打破“用爱发电”:一种基于 Gitee 与时间戳的开源权益分配机制探索》
c语言·数据结构·c++·科技·算法·gitee·开源
松间听晚3 小时前
Agentic RL 环境和代码学习:以HGPO为例
算法
智者知已应修善业3 小时前
【51单片机用T0定时器方式1,实现0.5S的时间间隔实现第一次一个灯亮、第二次二个灯亮,直到全部灯亮,然后重复整个过程】2023-12-29
c++·经验分享·笔记·算法·51单片机
小许同学记录成长3 小时前
几何体编辑与布尔运算
算法·无人机