283. 移动0
bash
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:你能尽量减少完成的操作次数吗?
python
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
fast = 0
slow = 0
while fast < len(nums):
if nums[fast] != 0:
nums[slow] = nums[fast]
slow+=1
fast+=1
while slow < len(nums):
nums[slow] = 0
slow+=1
return
LCR 006. 两数之和 II - 输入有序数组
bash
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 ,所以答案数组应当满足 0 <= answer[0] < answer[1] < numbers.length 。
假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。
示例 1:
输入:numbers = [1,2,4,6,10], target = 8
输出:[1,3]
解释:2 与 6 之和等于目标数 8 。因此 index1 = 1, index2 = 3 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[0,2]
示例 3:
输入:numbers = [-1,0], target = -1
输出:[0,1]
提示:
2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案
python
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
# 注意数组是升序的,向右走变大,向左走变小
left = 0
right = len(numbers)-1
while left != right:
if numbers[left] + numbers[right] == target:
break
if numbers[left] + numbers[right] > target:
right-=1
if numbers[left] + numbers[right] < target:
left+=1
return [left, right]
15. 三数之和
bash
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105
python
class Solution:
def threeSum(self, nums: list[int]) -> list[list[int]]:
## 问题可以转换成nums[i] = -(nums[j]+nums[k]),
# 进行排序,和两数之和II的问题思路一致
nums.sort()
ans = []
n = len(nums)
# 剪枝
if nums[0]+nums[1]+nums[2]>0: return ans
if nums[n-1]+nums[n-2]+nums[n-3]<0:return ans
for i in range(len(nums)-2):
target = nums[i]
# 去除重复元素
if i > 0 and target == nums[i-1]: continue
j = i+1
k = len(nums) - 1
while j < k:
s = target + nums[j] + nums[k]
if s > 0:
k-=1
elif s < 0:
j+=1
else:
ans.append([nums[i],nums[j],nums[k]])
j+=1
while j<k and nums[j]==nums[j-1]:
j+=1
k-=1
while j<k and nums[k] == nums[k+1]:
k-=1
return ans
11. 盛最多水的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, heighti) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
示例 1:

输入:1,8,6,2,5,4,8,3,7
输出:49
解释:图中垂直线代表输入数组 1,8,6,2,5,4,8,3,7。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = 1,1
输出:1
提示:
n == height.length
2 <= n <= 10^5
0 <= heighti <= 10^4
python
class Solution:
def maxArea(self, height: List[int]) -> int:
# 水容量=两条线之间的距离d✖️高度【min(两条线)】
# 定义左右指针向中间移动
left = 0
right = len(height)-1
# 向中间移动,当前的容量必定是短边h参与的所有容量中最大的:假设短边h不动,另一边向中间移动。
# 因为向中间移动长度变小,要么另一边找到的大于这个短边h(短板效应面积变小),要么另一边移动后小于等于这个短边h,根据公式只会小于等于当前的面积,所以短边不动动另一边没有意义,应该移动短边。
#因为移动短边,虽然距离d变小,但是高度有可能会变大,从而面积可能会变大
max_area = 0
while left < right:
area = (right-left)*min(height[left], height[right])
max_area = max(area, max_area)
if height[left] < height[right]:
left+=1
else:
right-=1
return max_area
42. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:

输入:height = 0,1,0,2,1,0,1,3,2,1,2,1
输出:6
解释:上面是由数组 0,1,0,2,1,0,1,3,2,1,2,1 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = 4,2,0,3,2,5
输出:9
提示:
n == height.length
1 <= n <= 2 * 10^4
0 <= heighti <= 10^5
把每块区域看做宽度为1的水桶,则每个水桶能接的雨水就是min(真正左右水板)-水桶的高度
所以我们需要求每个水桶的真正的左右水板(前后缀)
灵茶山爱府:

python
class Solution:
def trap(self, height: List[int]) -> int:
n = len(height)
# 创立两个数组,存储每个水桶的前后缀
pre_max = [0] * n
suf_max = [0] * n
pre_max[0] = height[0]
suf_max[n-1] = height[n-1]
for i in range(1, n):
pre_max[i] = max(pre_max[i-1], height[i])
for i in range(n-2, -1, -1):
suf_max[i] = max(suf_max[i+1], height[i])
s = 0
for h, pre, suf in zip(height, pre_max, suf_max):
s+=min(pre, suf)-h
return s