目录
前言
碎碎念:任何一句话,你只要不说出来,那你一直是它的主人,如果你把它说出来了,那未来可能成为它的奴隶。谨言慎行。
本系列《绝境求生》记录转码算法筑基过程,以代码随想录为纲学习,leetcode_hot_100练手,在此记录思考过程,方便过后复现。内容比较粗糙仅便于笔者厘清思路,复盘总结。
今天除了刷题, 过了一遍day 1,2,3 (哈希表,数组,链表)
提示:以下是本篇文章正文内容
一、128. 最长连续序列
1、题目描述
给定一个未排序 的整数数组
nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。核心要求 :算法的时间复杂度需优化到O(n)(暴力法不满足,但用于理解逻辑)。示例
示例 1:输入
nums = [100,4,200,1,3,2]→ 输出4
- 解释:最长连续序列是
[1,2,3,4],长度为 4。示例 2:输入
nums = [0,3,7,2,5,8,4,6,0,1]→ 输出9
- 解释:最长连续序列是
[0,1,2,3,4,5,6,7,8],长度为 9。示例 3:输入
nums = []→ 输出0;输入nums = [7]→ 输出1。提示
0 <= nums.length <= 10^5-10^9 <= nums[i] <= 10^9
2、简单理解?
还不是单纯前一个数大于后一个数就行,必须步幅为1。 1,2,3才行。1,44,99不行
在数组中可以不连续,存在就行 比如【1100,4,200,1,3,2】输出是4
3、暴力法
以num为起点,不断地找num+1
3.1、能不能用图示意?
ini遍历每个num: num=100 → 找101(不在)→ 长度1 num=4 → 找5(不在)→ 长度1(重复计算,后续遍历1时会重新统计1-4) num=200 → 找201(不在)→ 长度1 num=1 → 找2(在)→ 找3(在)→ 找4(在)→ 找5(不在)→ 长度4 num=3 → 找4(在)→ 找5(不在)→ 长度2(重复计算) num=2 → 找3(在)→ 找4(在)→ 找5(不在)→ 长度3(重复计算) 全局最大值:4
3.2、初始化条件?
3.3、边界条件?
空集或者只有一个元素
3.4、代码逻辑?
剪枝,初始化最大长度 和 当前的长度为1,后面出现更大的再更新
3.5、之前见过但没注意到的?
ini
max_len=max(max_len,current_len) 没有最大,自己即为最大,出现更大,最大让位
3.6、疑惑点/新知识 ?
dart
while num+current_len in nums: 连着遍历num+1元素是否在数组中
3.7、python 代码
python
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
# 边界条件1:数组为空,返回0
if not nums:
return 0
# 初始化最大长度为1(至少有一个元素时,最小长度是1)
max_len = 1
# 外层循环:遍历每个数字作为起始点
for num in nums:
# 初始化当前连续长度为1(当前数字自身)
current_len = 1
# 内层循环:查找num+1、num+2...是否在数组中
while num + current_len in nums:
# 找到连续数,长度+1
current_len += 1
# 更新全局最大长度
max_len = max(max_len, current_len)
return max_len
4、优化法
通过哈希表解题
4.1、能不能用图示意?
ini以 nums = [100,4,200,1,3,2] 为例 步骤1:转集合 → s = {100,4,200,1,3,2} 步骤2:遍历集合中的每个num: num=100 → 检查100-1=99是否在s?不在(是起点)→ 找101(不在)→ 长度1 num=4 → 检查4-1=3是否在s?在(不是起点)→ 跳过 num=200 → 检查200-1=199是否在s?不在(是起点)→ 找201(不在)→ 长度1 num=1 → 检查1-1=0是否在s?不在(是起点)→ 找2(在)→ 找3(在)→ 找4(在)→ 找5(不在)→ 长度4 num=3 → 检查3-1=2是否在s?在(不是起点)→ 跳过 num=2 → 检查2-1=1是否在s?在(不是起点)→ 跳过 步骤3:全局最大值=4
4.2、初始化条件?
初始化current_len-0 因为 后面判断while current in nums: 会判断一次当前的current_len , 在就+1,与暴力法的current=1不同它判断的是while num+current_len是否在num中。
4.3、边界条件?
none
4.4、代码逻辑?
遍历nums中的每一个num,如果num-1存在于nums中,说明num不是最小,他就不能作为最长子序列的head,pass。 如果不在num中就+1看存不存在,长度递增返回长度
4.5、之前见过但没注意到的?
4.6、疑惑点/新知识 ?
找起点 num-1是否在nums中的思路 是减少查找的关键
4.7、python 代码
ini
from typing import List
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
# 步骤1:将数组转为集合,O(1)查找+自动去重
num_set = set(nums)
# 初始化最大长度为0(兼容空数组)
max_len = 0
# 步骤2:遍历集合中的每个数字
for num in num_set:
# 核心判断:仅当num-1不在集合中,才是序列起点(避免重复计算)
if num - 1 not in num_set:
# 初始化当前数字为序列起点,当前长度为0
current_num = num
current_len = 0
# 步骤3:查找连续数,直到找不到为止
while current_num in num_set:
# 找到连续数,长度+1,当前数字+1
current_len += 1
current_num += 1
# 步骤4:更新全局最大长度
max_len = max(max_len, current_len)
# 步骤5:返回结果(空数组时max_len仍为0)
return max_len
二、283 移动零
1、题目描述
给定一个整数数组
nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序 。核心约束:
- 必须在原数组上操作(不能拷贝额外的数组);
- 尽量减少操作次数(时间 / 空间复杂度最优);
- 非零元素的相对顺序不能改变(比如
[0,1,0,3,12]移动后必须是[1,3,12,0,0],而非[3,1,12,0,0])。示例
- 示例 1:输入
nums = [0,1,0,3,12]→ 输出[1,3,12,0,0];- 示例 2:输入
nums = [0]→ 输出[0];- 示例 3:输入
nums = [1,2,3]→ 输出[1,2,3];- 示例 4:输入
nums = [0,0,1]→ 输出[1,0,0]。提示
1 <= nums.length <= 10^4-2^31 <= nums[i] <= 2^31 - 1
3、暴力法
这题比较easy,快慢指针对换就可以解决。 其实也可以用暴力法while 连续覆盖
3.7、python 代码
ini
nums=[1,2,55,0,43,3,0,3,4,5,9,6,7,8]
def solution(nums):
n=len(nums)
slow,fast=0,0
while fast<n:
if nums[fast]!=0:
nums[slow],nums[fast]=nums[fast],nums[slow]
slow+=1
fast+=1
return nums
solution(nums)
三、11存最多水的容器
1、题目描述
给定一个未排序 的整数数组
nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。核心要求 :算法的时间复杂度需优化到O(n)(暴力法不满足,但用于理解逻辑)。示例
示例 1:输入
nums = [100,4,200,1,3,2]→ 输出4
- 解释:最长连续序列是
[1,2,3,4],长度为 4。示例 2:输入
nums = [0,3,7,2,5,8,4,6,0,1]→ 输出9
- 解释:最长连续序列是
[0,1,2,3,4,5,6,7,8],长度为 9。示例 3:输入
nums = []→ 输出0;输入nums = [7]→ 输出1。提示
0 <= nums.length <= 10^5-10^9 <= nums[i] <= 10^9
2、简单理解?
area=两条线索引的距离*较短一线的高度
3、暴力法
暴力枚举所有可能性就好了 作为一道中等题 感觉难度一般。但是暴力法超时了
3.7、python 代码
ini
# 输入:[1,8,6,2,5,4,8,3,7]
# 输出:49
height=[1,8,6,2,5,4,8,3,7]
def solution(height):
n=len(height)
max_area=0
for i in range(n):
for j in range(i+1,n):
long=j-i
width=min(height[i],height[j])
current_area=long*width
max_area=max(max_area,current_area)
return max_area
solution(height)
编辑
4、优化法
双指针法。 左短移左,右短移动右。其实优化法知道思路后也是很简单。
4.1、能不能用图示意?
css以 height = [1,8,6,2,5,4,8,3,7] 为例 初始化:left=0(h=1),right=8(h=7),max_area=0 步骤1:宽度=8,有效高度=1 → 面积=8 → max_area=8 → 左更短,left=1 步骤2:left=1(h=8),right=8(h=7)→ 宽度=7,有效高度=7 → 面积=49 → max_area=49 → 右更短,right=7 步骤3:left=1(h=8),right=7(h=3)→ 宽度=6,有效高度=3 → 面积=18 → max_area=49 → 右更短,right=6 步骤4:left=1(h=8),right=6(h=8)→ 宽度=5,有效高度=8 → 面积=40 → max_area=49 → 相等,right=5 步骤5:left=1(h=8),right=5(h=4)→ 宽度=4,有效高度=4 → 面积=16 → max_area=49 → 右更短,right=4 步骤6:left=1(h=8),right=4(h=5)→ 宽度=3,有效高度=5 → 面积=15 → max_area=49 → 右更短,right=3 步骤7:left=1(h=8),right=3(h=2)→ 宽度=2,有效高度=2 → 面积=4 → max_area=49 → 右更短,right=2 步骤8:left=1(h=8),right=2(h=6)→ 宽度=1,有效高度=6 → 面积=6 → max_area=49 → 右更短,right=1 步骤9:left=1 >= right=1 → 遍历结束,返回49
4.7、python 代码
ini
# 输入:[1,8,6,2,5,4,8,3,7]
# 输出:49
height=[1,8,6,2,5,4,8,3,7]
def solution(height):
n=len(height)
left=0
right=n-1
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
solution(height)
从利益出发它值不值得做不做,从风险出发它值不值得搏,从能力出发我能不能干,从结果出发它划不划算
飞扬跋扈得不到亲近