之前做过两道题,所以从第三题开始记录
128. 最长连续序列
题目链接:128. 最长连续序列
难度:中等
刷题状态:1刷
新知识:
解题过程
思考
示例 1:
输入:nums = [100,4,200,1,3,2] 输出:4 解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
不难,但重点是要O(n)
题解分析
参考题解链接:哈希表 O(n) 做法(Python/Java/C++/C/Go/JS/Rust)
详细分析如下
javascript">/*** @param {number[]} n ums* @return {number}*/
var longestConsecutive = function(nums) {let set=new Set(nums)let res=0for(let s of set){if(set.has(s-1)){continue//跳过本次循环,确保下面的s是从某个连续数组开始的//也就是确保下面的s是某连续数组的起点}let y=s+1//s是连续数组的起点,所以后面要减掉//这里是核心代码while(set.has(y)){y++}res=Math.max(res,y-s)}return res
};
手搓答案(无非废话版)
javascript">var longestConsecutive = function(nums) {let res=0let set=new Set(nums)for(let s of set){if(set.has(s-1)) continuelet y=s+1while(set.has(y)){y++}res=Math.max(res,y-s)}return res
}
总结
重点是要理解什么情况下开始y++的循环
283. 移动零
题目链接:283. 移动零
难度:简单
刷题状态:1刷
新知识:
解题过程
思考
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
不复制的意思就是插入,直接修改数组,还要用双指针法
我自己倒是手搓出来了,但是速度太慢了O(N2)
题解分析
参考题解链接:移动零
答案这里用的快慢指针,slow标记非0数的结尾,fast遍历数组
大概逻辑是,fast往前跑,碰到非零数就往slow的位置一扔,slow++为填入下一个非0数做准备
这样只用遍历一遍O(N)
javascript">/*** @param {number[]} nums* @return {void} Do not return anything, modify nums in-place instead.*/
var moveZeroes = function(nums) {let slow=0,fast=0//slow是while(fast<nums.length){if(nums[fast]!=0){//0 交换nums[slow] nums[fast]let n=nums[slow]nums[slow]=nums[fast]nums[fast]=nslow++}fast++}return nums
};
手搓答案(无非废话版)
javascript">var moveZeroes = function(nums) {let slow=0,fast=0while(fast<nums.length){if(nums[fast]){let tmp=nums[slow]nums[slow]=nums[fast]nums[fast]=tmpslow++}fast++}return nums
}
总结
双指针不是left right 就是slow fast
11. 盛最多水的容器
题目链接:11. 盛最多水的容器
难度:中等
刷题状态:2刷
新知识:
解题过程
思考
示例 1:
输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
直接拿下~
题解分析
参考题解链接:盛最多水的容器
手搓答案(无非废话版)
javascript">/*** @param {number[]} height* @return {number}*/var maxArea = function(height) {let left=0,right=height.length-1let res=0while(left<right){let v=Math.min(height[left],height[right])*(right-left)res=Math.max(res,v)if(height[left]<height[right]){left++}else{right--}}return res
}
总结
在灵神题库刷过啦~
15. 三数之和
题目链接:15. 三数之和
难度:中等
刷题状态:2刷
新知识:
解题过程
思考
示例 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刷啦~
三数之和为0,双指针做法
好吧,忘记套路了,自己也没有试出来5555
题解分析
参考题解链接:三数之和
1刷的过程放下
javascript">var threeSum = function(nums) {
// nums = [-1,0,1,2,-1,-4]let a=["T15-出罐交点-1", "250-CO-101/T15"]let b=a[0]+a[1]console.log('b',typeof b)//先排序
nums.sort((a,b)=>a-b)
//[-4,-1,-1,0,1,2]
let res=[]
let n=nums.length
for(let i=0;i<n;i++){if(nums[i]>0){break//如果第一个大于0,后面的都没意义} let left=i+1//第一个后面的第一个let right=n-1//第一个后面的最后一个if(i>0&&nums[i]==nums[i-1]){continue//如果当前不是第一个而且和前一个是一样的,跳过当前循环,避免x重复} // console.log(x)成功跳过重复xwhile(left<right){let sum=nums[i]+nums[left]+nums[right]if(sum==0){res.push([nums[i],nums[left],nums[right]])//接下来去掉重复ywhile(left<right&&nums[left]==nums[left+1]){left++}while(left<right&&nums[right]==nums[right-1]){right--}}sum>0?right--:left++}}
return res
};
看了解答之后思路还是很清晰的,但是有个地方需要注意
javascript">if(sum==0){res.push([nums[i],nums[left],nums[right]])while(left<right&&nums[left+1]==nums[left]){left++}while(left<right&&nums[right-1]==nums[right]){right--}}
//这里一定是要分开写的,不能else if(sum<0)
//因为上面内部left,right有调整,出来之后的sum相当于重新计算过了
//等同于这里也有
//sum=nums[i]+nums[left]+nums[right]if(sum<0){left++}else{right--}
手搓答案(无非废话版)
javascript">var threeSum = function(nums) {nums.sort((a,b)=>a-b)let res=[],n=nums.lengthif(nums[0]>0||nums[n-1]<0) return resfor(let i=0;i<n;i++){let left=i+1,right=n-1if(i>0&&nums[i]==nums[i-1]) continuewhile(left<right){let sum=nums[i]+nums[left]+nums[right]if(sum==0){res.push([nums[i],nums[left],nums[right]])while(left<right&&nums[left+1]==nums[left]){left++}while(left<right&&nums[right-1]==nums[right]){right--}}sum<0?left++:right--}}return res
}
总结
else if 那里还真是个坑,,多刷多练吧,查漏补缺