没出息的我怎么老是无办法坚持下去学算法呢!!!可能也是我太笨了!!!接下来边做Leetcode上的题,边学算法,加油加油!!!
好的开始是成功的一半,所以先来看“Hello World”。
题目描述
给定一个包含多个元素的数组和一个目标值,看数组中是否存在两个元素,使他们的和正好为目标值,如果存在的话就返回对应的索引。
- 能想到的最直接的想法就是采用暴力求解的方式,逐个遍历元素,判断两数相加是否等于目标值。但是这样做的时间复杂度为O(n^2),可能会超出时间限制。
//暴力求解
vector<int> twosum_2(vector<int>& nums,int target){
vector<int> res;
for(int i = 0;i!=nums.size() - 1;i++)
for (int j = i + 1;j < nums.size();j++){
if(nums[i] + nums[j] == target){
res.push_back(i);
res.push_back(j);
return res;
}
}
}
- 既然暴力求解的方式时间复杂度不在我们可接受的范围内,那么我们可以转换下思路,采用空间换时间的做法。通过将值和它的索引进行匹配,我们就可以在O(n)的时间复杂度范围内求出结果。
vector<int> twoSum_1(vector<int>& nums, int target){
vector<pair<int,int> > nums1;
//将vector中的数据和序号进行匹配
for(int i = 0;i < nums.size();++i)
nums1.push_back(make_pair(nums[i],i));
sort(nums1.begin(),nums1.end()); //排序
int i = 0,j = nums1.size() - 1;
vector<int> ret;
while(i < j){
//如果两个元素相加的值等于目标值,将序号放入ret
if(nums1[i].first + nums1[j].first == target){
ret.push_back(nums1[i].second);
ret.push_back(nums1[j].second);
return ret;
}
//如果和小于target,说明前面的那个值小,往后取,否则说明后面的大了,往前取
nums1[i].first +nums1[j].first < target ? ++i : --j;
}
}
//利用map存储索引和值值之间的关系
vector<int> twosum_3(vector<int>& nums,int target){
vector<int> res;
map<int,int> m;
for(int i=0;i<nums.size();i++){
m.insert(pair<int,int>(nums[i],i));
}
//
for(int i=0;i < nums.size();++i){
int t = target - nums[i];
if(m.count(t)){
res.push_back(i);
res.push_back(m[t]);
break;
}
}
return res;
}
上面在map的地方使用unordered_map效率会更高一些,但是我的编译器不支持这个库,所以就没用。
关于map的相关知识可参见:
map 学习(上)——C++中 map 的使用
map 学习(下)——C++ 中的 hash_map, unordered_map
C/C++ - Map (STL) 用法與心得完全攻略
具体的运行代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <hash_map>
#include <map>
using namespace std;
class Solution{
public:
vector<int> twoSum_1(vector<int>& nums, int target){
vector<pair<int,int> > nums1;
//将vector中的数据和序号进行匹配
for(int i = 0;i < nums.size();++i)
nums1.push_back(make_pair(nums[i],i));
sort(nums1.begin(),nums1.end()); //排序
int i = 0,j = nums1.size() - 1;
vector<int> ret;
while(i < j){
//如果两个元素相加的值等于目标值,将序号放入ret
if(nums1[i].first + nums1[j].first == target){
ret.push_back(nums1[i].second);
ret.push_back(nums1[j].second);
return ret;
}
//如果和小于target,说明前面的那个值小,往后取,否则说明后面的大了,往前取
nums1[i].first +nums1[j].first < target ? ++i : --j;
}
}
//暴力求解
vector<int> twosum_2(vector<int>& nums,int target){
vector<int> res;
for(int i = 0;i!=nums.size() - 1;i++)
for (int j = i + 1;j < nums.size();j++){
if(nums[i] + nums[j] == target){
res.push_back(i);
res.push_back(j);
return res;
}
}
}
//利用hash_map存储索引和值值之间的关系
vector<int> twosum_3(vector<int>& nums,int target){
vector<int> res;
map<int,int> m;
for(int i=0;i<nums.size();i++){
m.insert(pair<int,int>(nums[i],i));
}
//
for(int i=0;i < nums.size();++i){
int t = target - nums[i];
if(m.count(t)){
res.push_back(i);
res.push_back(m[t]);
break;
}
}
return res;
}
};
int main(){
int num[] = {2,7,11,5};
vector<int> nums(num,num+4);
int target = 9;
Solution s;
vector<int> res = s.twoSum_1(nums,target);
vector<int>::iterator i;
for(i = res.begin();i != res.end();i++)
cout<<*i<<" ";
return 0;
}
结果