目录
学习计划链接
题目解析
1. 剑指 Offer II 007. 数组中和为 0 的三个数
1) 问题描述
2) 思路分析
题意转换为找出数组两元素之和为target(target为可变的且为数组中的任意元素);如:a+b+c=0等价于a+b=-c(-c为target)
- 排序
- 遍历排好序的数组,分别将每个元素作为target值,找出满足nums[m]+nums[n]=-target条件的三个数(需考虑存在重复数的情况),并将其插入待返回二维数组中。
3) leetcode链接
4) 代码实现
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
//1.排序
sort(nums.begin(),nums.end());
//2. 遍历排好序的数组,分别将每个元素作为target值,找出满足nums[m]+nums[n]=-target条件的三个数,并将其插入待返回二维数组中。
vector<vector<int>> res;
for(int i=0;i<nums.size();++i)
{
int target=-nums[i];
//去重
if(i!=0 && nums[i]==nums[i-1])
{
continue;
}
int left= i+1;
int right=nums.size()-1;
while(left<right)
{
int sum=nums[left]+nums[right];
if(sum==target)
{
res.push_back({-target,nums[left],nums[right]});
//判断left下一个是否和当前的nums[left]值一样,若相同则直接跳过。
// while(left<right && nums[left]==nums[left+1])
// {
// left++;
// }
int temp = nums[left];
while (nums[left] == temp && left < right) {
left++;
}
}
else
{
sum>target?--right:++left;
}
}
}
return res;
}
};
2. 剑指 Offer II 008. 和大于等于 target 的最短子数组
1) 问题描述
2) 思路分析
双指针
从开始位置开始累加,直到累加和大于或等于target值时,记录当前的最小长度。更新左边指针——进行右移,再判断是否仍满足该情况。
3) leetcode链接
剑指 Offer II 008. 和大于等于 target 的最短子数组
4) 代码实现
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
//双指针
int left=0;
int sum=0;
int minLen=INT_MAX;
//从开始位置开始累加,直到累加和大于或等于target值时,记录当前的最小长度。更新左边指针——进行右移,再判断是否仍满足该情况。
for(int right =0;right<nums.size();++right)
{
sum+=nums[right];
while(left<=right&&sum>=target)
{
minLen=min(minLen,right-left+1);
sum-=nums[left++];
}
}
return (minLen==INT_MAX)?0:minLen;
}
};
3. 剑指 Offer II 009. 乘积小于 K 的子数组
1) 问题描述
2) 思路分析
双指针法
- 子数组的乘积 mul 应该用 long long类型,因为数值很大;
- 若当前 left 和 right 确定的子数组乘积小于 k,那么右移 left 的所有子数组均符合,即区间有(left-right+1);
3) leetcode链接
4) 代码实现
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
int mul=1;
int res=0;
int left=0;
for(int right=0;right<nums.size();++right)
{
mul*=nums[right];
while(left<=right && mul>=k)
{
mul/=nums[left++];
}
res+= ((left<=right)? right-left+1:0);
}
return res;
}
};