leetcode1:两数求和
程序员文章站
2022-04-04 09:49:30
...
题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素
分析
题目解法很简单,暴力是最直观的解法,但是时间复杂度O(n^2)。
通过一次排序可以将时间复杂度控制在O(n),只是这种情况增加了寻找数字下标的麻烦。
提供两种通过排序解决的代码
第一种
将情况有if-else写出来,着重考虑相同元素的情况
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result,num(nums);
sort(num.begin(),num.end());
for(auto i = num.begin(),j = num.end()-1;i != j; )
{
if(*i + *j > target) --j;
else if(*i + *j < target) ++i;
else
{
if(*i == *j)
{
auto it1 = find(nums.begin(),nums.end(),*i);
auto it2 = find(it1+1,nums.end(),*j);
result.push_back(it1-nums.begin());
result.push_back(it2-nums.begin());
return result;
}
else
{
auto it1 = find(nums.begin(),nums.end(),*i);
auto it2 = find(nums.begin(),nums.end(),*j);
result.push_back(it1-nums.begin());
result.push_back(it2-nums.begin());
return result;
}
}
}
return result;
}
};
第二种
着重考虑第二个下标在原数组中是在第一个的前面还是后面。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;// 存放下标,用于返回
vector<int> num(nums); //用于排序
sort(num.begin(),num.end());
//返回首、尾迭代器,可直接解引用获得对象
for(auto i = num.cbegin(),j = num.cend()-1;i != j; )
{
if(*i + *j > target) --j;
else if(*i + *j < target) ++i;
else
{
auto beg = nums.cbegin();
auto edf = nums.cend();
auto it1 = find(beg,edf,*i);
result.push_back(it1-beg);
if(find(it1,edf,*j) != edf)//如果第二个元素下标在第一个之后
result.push_back(find(it1+1,edf,*j)-beg);
//若在之前
else result.push_back(find(beg,it1,*j)-beg);
return result;
}
}
return result;
}
};
剩余的优化情况就不在此计较了,朋友们可以自己再深究。