题目:https://leetcode-cn.com/problems/two-sum/
给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
1 #include<cstdio> 2 #include<vector> 3 #include<map> 4 using namespace std; 5 6 class Solution{ 7 public: 8 vector<int> twoSum(vector<int>& nums, int target){ 9 map<int, int> p; 10 map<int, int> ::iterator it; 11 vector<int> res; 12 for(unsigned i=0;i<nums.size();i++){ 13 int comp = target - nums[i]; 14 it = p.find(comp); 15 // printf("过程%d,%d,%d,%d ",i,nums[i],p.find(comp)->first,p.find(comp)->second); 16 if(it != p.end()){ 17 res.push_back(i); 18 res.push_back(p.find(comp)->second); 19 // printf("找到啦%d,%d,%d ",i,p.find(comp)->first,p.find(comp)->second); 20 return res; 21 } 22 // p[nums[i]] = i; //这是一种导入方法; 23 p.insert (pair<int,int>(nums[i],i)); //这是另一种导入方法; 24 } 25 res.push_back(-1); 26 return res; 27 } 28 }; 29 30 int main(){ 31 vector<int> nums; 32 vector<int> bb; 33 nums.push_back(2); 34 nums.push_back(6); 35 nums.push_back(7); 36 nums.push_back(1); 37 nums.push_back(3); 38 nums.push_back(9); 39 nums.push_back(4); 40 41 printf("%d ",nums.back()); 42 printf("%d ",nums.front()); 43 44 int target = 15; 45 Solution t; 46 bb = t.twoSum(nums,target); 47 printf("%d,%d",bb.back(),bb.front()); 48 return 0; 49 }
总结:
1这是个非常简单的题目,普通的暴力算法,应该是O(n^2);为了将时间复杂度降低,有两个方向,其中一个就是提高空间复杂度到O(N),利用map的查找功能,快速定位目标。我这里利用map查找,所以时间复杂度只能是O(logN); 如果用hash_map还能继续降低到O(n);
2还有一个角度是,基于target的数值;首先假设数值是有序数组,利用+方法的递增的性质,可以避免很多计算,甚至可以利用猜测的方法,快速找到目标。但是这样一来将会用使得程序比较复杂;
3使用hash_map 需要加上using namespace __gnu_cxx;