1. 两数之和---双指针篇七
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1. 两数之和---双指针篇七相关的知识,希望对你有一定的参考价值。
引言
本题的双指针解法解释的可能不够清楚,建议大家先看这篇文章:
leetcode 167. 两数之和 II - 输入有序数组----双指针篇六,二分篇二
暴力法
思路:
枚举所有nums[i]+nums[j]的可能结果,从中找出等于目标值的结果,然后返回对应下标
注意:这里不能对nums数组进行降序排列,到达减枝效果,因为这样会导致元素下标发生改变,如果非要做,可以考虑用哈希表保存元素在原数组的下标
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
for (int i = 0; i < nums.size(); i++)
{
for (int j = i+1; j < nums.size(); j++)
{
if (nums[j] + nums[i] == target) return vector<int>({ i ,j });
}
}
return vector<int>();
}
};
哈希法
思路:
我们遍历到数字 a 时,用 target 减去 a,就会得到 b,若 b 存在于哈希表中,我们就可以直接返回结果了。若 b 不存在,那么我们需要将 a 存入哈希表,好让后续遍历的数字使用。
图解:
代码:
class Solution {
unordered_map<int, int> map;
public:
vector<int> twoSum(vector<int>& nums, int target)
{
for (int i = 0; i < nums.size(); i++)
{
if (map.find(target - nums[i]) != map.end()) return { map[{target - nums[i]}],i };
map[nums[i]] = i;
}
return {};
}
};
排序加二分查找
思路:
先对指定数组进行排序,排序前用一个数组保存原数组元素对应的下标。
通过两个指针i和j,固定一个指针i,那么另外一个指针j指向的元素的值也是确定的,为target-nums[i]
我们只需要再剩余指定区间[i+1,size)中利用二分查找,查找对于元素的值等于target-nums[i]
这里我们利用一个索引数组记录对应元素的下标
代码:
class Solution {
vector<int> index;
public:
vector<int> twoSum(vector<int>& nums, int target)
{
index.resize(nums.size());
for (int i = 0; i < nums.size(); i++)
index[i] = i;
//选择排序
for (int i = 0; i < nums.size() - 1; i++)
{
int MIN = i;
for (int j = i + 1; j < nums.size(); j++)
{
if (nums[MIN] > nums[j])
MIN = j;
}
if (MIN != i)
{
swap(nums[MIN], nums[i]);
swap(index[MIN], index[i]);
}
}
for (int i = 0; i < nums.size(); i++)
{
int targetNum = target - nums[i];
int left = i + 1;
int right = nums.size() - 1;
while (left < right)
{
int mid = (left + right) / 2;
if (nums[mid] < targetNum)
left = mid + 1;
else if (nums[mid] > targetNum)
right = mid - 1;
else
return { index[i],index[mid] };
}
if (left<nums.size()&&nums[left] == targetNum)
{
return { index[i],index[left] };
}
}
return {};
}
};
双指针
先将数组复制一份(防止之后打乱下标),然后对复制的数组排序。
接着,在其两端放两个指针,相向而行,往中间靠,同时检查两数和,查出来就停止。
代码:
class Solution {
vector<int> index;
public:
vector<int> twoSum(vector<int>& nums, int target)
{
index.resize(nums.size());
for (int i = 0; i < nums.size(); i++)
index[i] = i;
//选择排序
for (int i = 0; i < nums.size() - 1; i++)
{
int MIN = i;
for (int j = i + 1; j < nums.size(); j++)
{
if (nums[MIN] > nums[j])
MIN = j;
}
if (MIN != i)
{
swap(nums[MIN], nums[i]);
swap(index[MIN], index[i]);
}
}
//双指针
int i = 0, j = nums.size() - 1;
while (i < j)
{
if (nums[i] + nums[j] < target)
i++;
else if (nums[i] + nums[j] > target)
j--;
else
return { index[i],index[j] };
}
return {};
}
};
以上是关于1. 两数之和---双指针篇七的主要内容,如果未能解决你的问题,请参考以下文章