1、描述 两数之和=target_输出下标
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
链接
思路
双指针,+ 二分
# 解法一:双指针
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int>res;
int i = 0;
int j = numbers.size() - 1;
while(i < j) {
if(numbers[i] + numbers[j] == target) {
return {i + 1, j + 1};
} else if(numbers[i] + numbers[j] < target) {
i++;
} else{
j--;
}
}
return {0, 0};
}
};
# 解法二:双指针 + 二分
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
vector<int>res;
int i = 0;
int j = numbers.size() - 1;
while(i < j) {
int mid = i + (j - i) / 2;
if(numbers[i] + numbers[mid] > target) { // 这里>target ,直接把左边的区间排除了。
j = mid - 1;
} else if(numbers[j] + numbers[mid] < target) {
i = mid + 1;
} else if(numbers[i] + numbers[j] > target) {
j--;
} else if(numbers[i] + numbers[j] < target) {
i++;
} else{
return {i + 1, j + 1};
}
}
return {0, 0};
}
};
2、三数之和=0
15给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组
来源:力扣(LeetCode)
链接:
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
2、思路
1、排个序,把数组重复的元素删除,(错误想法,因为直接删除就会删除-1,-1,2这种答案序列),3层循环暴力求解
2、从左边循环固定一个,然后双指针遍历剩下的
3、notes
1、sort(v.begin(),v.end());
2、双指针的循环体写法用while
3、花括号表示一个数据集
v.push_back({10,20,30});
1
4、内层while(j<k&&)不写会有如下错
Line 924: Char 34: runtime error: addition of unsigned offset to 0x602000000590 overflowed to 0x60200000058c (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_vector.h:933:34
4、复杂度
时间:O(n平方)
空间:排序的时候sort()函数,O(logN)
如果不能原数组排序,拷贝一个新的,就是O(N)
5、code
ac
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n=nums.size();
vector<vector<int>> ve;
//if(n<3) return ve;
int i,j,k;
sort(nums.begin(),nums.end());//排序
for(i=0;i<n-2 && nums[i]<=0;i++)
{
//if(nums[i]==nums[i+1]) continue; // 如果这么写的话,[-1,-1,2],这种情况就排除了
if (i > 0 && nums[i] == nums[i - 1]) continue; // 从后往前, (i > 0)防止越界
j=i+1;
k=n-1;
while(j<k && nums[k]>=0) // =0 是为了{0,0,0} // 双指针的标准循环
{
if(nums[i]+nums[j]+nums[k]==0)
{
ve.push_back({nums[i],nums[j],nums[k]});
//while(nums[i]==nums[i+1]) i++;
while(j<k && nums[j]==nums[j+1]) j++; // j<k 此半句很重要
while(j<k && nums[k]==nums[k-1]) k--;
j++,k--; // 逗号,这么写 // 同时别忘了写这句话
}
else if(nums[i]+nums[j]+nums[k]<0)
{
j++;
}
else
k--;
}
}
return ve;
}
};
WA
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n=nums.size();
vector<vector<int>> ve;
if(n<3) return ve;
vector<int> v11;
int i,j,k;
sort(nums.begin(),nums.end());//排序
/* vector<int> v; //如果这么更新数组则会把 {-1,-1 ,2}给错过
int t=nums[0];
j=0;
v.push_back(t);
for(i=1;i<n;i++)
{
if(nums[i]==v[j])
continue;
v.push_back(nums[i]);
j++;
}
n=v.size(); */
for(i=0;i<n-2&&nums[i]<=0;i++)
{
for(j=i+1;j<n-1;j++)
{
for(k=n-1;k<j;k--)
{
if(nums[i]+nums[j]+nums[k]==0)
{
//v11.erase(v11.begin(),v11.end());
//v11.push_back(v[i]);
//v11.push_back(v[j]);
//v11.push_back(v[k]);
ve.push_back({nums[i],nums[j],nums[k]});
while(nums[i]==nums[j]) i++;
while(nums[k]==nums[k-1]) k--;
}
else if(nums[i]+nums[j]+nums[k]<0)
{
j++;
}
else
k--;
}
}
}
return ve;
}
};