简单介绍
- 与同向双指针区别就是,同向查找的是子串
- 最明显得区别就是两侧进行搜索比较快
基本得模板如下
while(left < right)
{
if( )
{
}else if()
{
}else
{ // left与right得遍历
while()
{
}
}
}
具体以题目为例
两数之和比较简单 不展示了
leetcode 15 三数之和
这个可以用双向指针得原理就是 可以固定一个数 然后中间进行双指针加速
代码示例
这里就不放精简之后得代码 放最原始得代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size() - 1;
vector<vector<int>> res;
for(int i=0; i<n-1; i++)
{
int head = nums[i];
int left = i + 1;
int right = n;
if(i>0 && head==nums[i-1])
{ // 去重
continue;
}
if(head+nums[i+1]+nums[i+2] > 0)
{
break;
}
if(head+nums[n]+nums[n-1] < 0)
{
continue;
}
while(left < right)
{
int sum = head + nums[left] + nums[right];
if(sum > 0)
{
--right;
}else if(sum < 0)
{
++left;
}else
{
vector<int> vec = {nums[i], nums[left], nums[right]};
res.push_back(vec);
++left;
while(left<right && nums[left]==nums[left-1])
{ // 去重
++left;
}
--right;
while(right>left && nums[right]==nums[right+1])
{ // 去重
--right;
}
}
}
}
return res;
}
};
leetcode 16 最接近得三数之和
和15是基本一样的 最接近用绝对值即可
代码示例
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int res = nums[0] + nums[1] + nums[2]; // 给一个初始值
int n = nums.size();
for(int i=0; i<n-2; i++)
{
int head = nums[i];
int left = i + 1;
int right = n - 1;
while(left < right)
{
int sum = head + nums[left] + nums[right];
if(abs(target-sum) < abs(target-res))
{ // 每次进行更新
res = sum;
}
if(sum > target)
{
--right;
}else if(sum < target)
{
++left;
}else
{
return res;
}
}
}
return res;
}
};
leetcode 18 四数之和
四数之和与三数之和类似 再套一个for循环即可
代码示例
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
if(nums.size() < 4)
{
return res;
}
sort(nums.begin(), nums.end());
int m = nums.size();
for(int i=0; i<m-3; i++)
{
int first = nums[i];
if(i>0 && first == nums[i-1])
{
continue;
}
for(int j=i+1; j<m-2; j++)
{
int second = nums[j];
if(j>i+1 && second==nums[j-1])
{
continue;
}
int left = j+1;
int right = m-1;
while(left<right)
{ // 溢出很恶心 查了一个多小时
long long int sum = (long) first + second + nums[left] + nums[right];
if(sum > target)
{
--right;
}else if(sum < target)
{
++left;
}else
{
vector<int> vec = {first, second, nums[left], nums[right]};
res.push_back(vec);
while(left<right && nums[right]==nums[right-1])
{
--right;
}
--right;
while(left<right && nums[left]==nums[left+1])
{
++left;
}
++left;
}
}
}
}
return res;
}
};
leetcode 611 有效三角形的个数
这里有这样一个理论
排序之后 从最后一个元素开始 第一个+倒数第二个大于最后一个 那么意味着 right之前的都可以
然后再进行更改right即可
代码示例
class Solution {
public:
int triangleNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
int res = 0;
if(n < 3)
{
return res;
}
for(int i=n-1; i>1; --i)
{
int tail = nums[i];
int left = 0;
int right = i-1;
while(left<right)
{
if(nums[left]+nums[right] > tail)
{
res += right - left;
--right;
continue;
}else
{
++left;
}
}
}
return res;
}
};