力扣面试150(29/100)
7.11 15. 三数之和
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请你返回所有和为 0
且不重复的三元组。
**注意:**答案中不可以包含重复的三元组。
我的思路:
我最开始想的就是固定一个数,然后移动双指针找到剩下的两个值。一直答案错误,看了一下题解,他也是差不多的,只是在双指针遍历的时候,和我有差别,我是直接在固定的那个数后面找,但是它是设置了一个左指针和一个右指针,在两数之和有序数组的基础上进行修改的。但是有一个很重要的问题,就是去重
while (left < right && nums[left] === nums[left + 1]) left++;while (left < right && nums[right] === nums[right - 1]) right--;left++;right--;}
我的代码:
/*** @param {number[]} nums* @return {number[][]}*/
var threeSum = function(nums) {let i = 0 ; let ans = [];nums.sort((a , b) => a - b);for(i ; i < nums.length - 2 ; i++){// 去重if(i > 0 && nums[i - 1] === nums[i]){continue;}// 先固定一个数字let left = i + 1;let right = nums.length - 1 ;while(left < right){let sum = nums[i] + nums[left] + nums[right];if(sum > 0){right--;}else if (sum < 0){left++;}else if (sum === 0){ans.push([nums[i] , nums[left] , nums[right]]);// 需要跳过循环的袁旭while (left < right && nums[left] === nums[left + 1]) left++;while (left < right && nums[right] === nums[right - 1]) right--;left++;right--;}}}return ans;};
// 我的思路:
// -n + n = 0
// 先用双指针先求出+n ,然后遍历第二个指针找到-n
总结:
先对数组排序,然后固定一个数,再用双指针法在剩余部分寻找另外两个数,使得三数之和为零,同时通过跳过重复元素来避免重复解。
7.12 209. 长度最小的子数组
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其总和大于等于 target
的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度**。**如果不存在符合条件的子数组,返回 0
。
我的思路:就是滑动i和j,如果sum>target就代表可以减少一个数字了,i++,sum也要减,要是sum<target酒标掉需要添加数字,j++
我的代码:
var minSubArrayLen = function(target, nums) {let i = 0 ; let j = 0;let min = Infinity;let sum = nums[i] ;while(j < nums.length && i < nums.length){if(sum < target){j++;sum += nums[j];}else if(sum >= target){min = min > j - i + 1 ? j - i + 1 : min;sum -= nums[i];i++;}}if(min === Infinity){return 0}else {return min;}};
总结:使用滑动窗口法,在数组中寻找和至少为 target
的最短连续子数组的长度,如果不存在则返回 0