双指针——两数之和&三数之和
1.1双指针法简介
双指针法已经在前博客中介绍过,见下地址。
双指针法-删除数组中的重复元素以及奇偶排序
1.2两数求和
1.2.1题目描述
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。函数应该返回这两个下标值
i
n
d
e
x
1
index1
index1和
i
n
d
e
x
2
index2
index2,其中
i
n
d
e
x
1
index1
index1必须小于
i
n
d
e
x
2
index2
index2。
输入:
n
u
m
b
e
r
s
=
[
2
,
3
,
9
,
18
]
,
t
a
r
g
e
t
=
12
numbers = [2, 3, 9, 18], target = 12
numbers=[2,3,9,18],target=12
输出:
[
1
,
2
]
[1,2]
[1,2]
解释:
3
与
9
之
和
等
于
目
标
数
12
。
因
此
i
n
d
e
x
1
=
1
,
i
n
d
e
x
2
=
2
3 与 9 之和等于目标数 12。因此 index1 = 1, index2 = 2
3与9之和等于目标数12。因此index1=1,index2=2
1.2.2代码实现
vector<int> twoSum(vector<int>& numbers, int target)
{
int numLen = numbers.size();
int j = numLen - 1, i = 0;
while (j > i)
{
int sum = numbers[i] + numbers[j];
if (sum == target)
{
return {i, j};
}
else if (sum > target)
{
j--;
}
else
{
i++;
}
}
return {};
}
1.3三数求和
1.3.1题目描述
给定一个无序数组,找到三个数使得它们相加之和等于零,并找出数组中所有的这种三个数,并返回。
输入:
n
u
m
b
e
r
s
=
[
−
1
,
0
,
2
,
1
,
−
1
]
,
t
a
r
g
e
t
=
12
numbers = [-1, 0, 2, 1, -1], target = 12
numbers=[−1,0,2,1,−1],target=12
输出:
[
−
1
,
0
,
1
]
,
[
−
1
,
2
,
−
1
]
[-1,0,1],[-1,2,-1]
[−1,0,1],[−1,2,−1]
1.3.2代码实现
vector<vector<int>> threeSumL(vector<int>& nums)
{
if (nums.size() < 3) //若数组小于3,则不满足题目要求
{
return{};
}
vector<int> temp;
vector<vector<int>> result;
sort(nums.begin(), nums.end()); //对数组排序-升序
//int i = 0, int n = 0;
int numLength = nums.size();
for (int i = 0; i < numLength; i++) //遍历整个数组
{
if (nums[i] > 0) //若第一个数就大于零,则不可能存在和为零
{
break;
}
if (i > 0 && nums[i] == nums[i - 1]) //去除重复的数
{
continue;
}
int p = i + 1, q = numLength - 1; //前后两个指针
while (p < q) //从两端向中间开始遍历
{
int sum = nums[p] + nums[q] + nums[i];
if (sum == 0) //如果等于零,则储存元素,并去重
{
temp.push_back(nums[i]);
temp.push_back(nums[p]);
temp.push_back(nums[q]);
result.push_back(temp);
temp.clear();
while (p < q && nums[p] == nums[p + 1])
{
p++;
}
while (p < q && nums[q] == nums[q - 1])
{
q--;
}
p++;
q--;
}
else if (sum > 0)
{
q--;
}
else if (sum < 0)
{
p++;
}
}
}
return result;
}