问题:
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
翻译:
给定一个整数数组,找出其中两个数满足相加等于你指定的目标数字。
要求:这个函数twoSum必须要返回能够相加等于目标数字的两个数的索引,且index1必须要小于index2。请注意一点,你返回的结果(包括index1和index2)都不是基于0开始的。
你可以假设每一个输入肯定只有一个结果。
举例:
输入:numbers={2, 7, 11, 15}, target = 9
输出:index1 = 1, index2 = 2(不是基于0开始的)
解决方案一:双层循环
1 vector<int> two_sum(vector<int> &src_vec, int tagert) 2 { 3 vector<int> result; //结果容器 存放2个结果索引值 //vector作局部变量返回会自动析构 4 for (size_t i = 0; i < src_vec.size() - 1; ++i) 5 { 6 for (size_t j = i + 1; j < src_vec.size(); ++j) 7 { 8 if (tagert == (src_vec[i] + src_vec[j])) 9 { 10 result.push_back(i + 1); 11 result.push_back(j + 1); 12 return result; 13 } 14 } 15 } 16 return result; 17 }
这样写下来肯定没错,只是算法时间复杂度高(双层循环:o(n^2)).
C/C++语法补充笔记:
这里的返回类型是vector<int> ,也就是临时变量result的一个副本,结果没有问题;由于笔者之前总喜欢用引用,刚才时将返回类型写成vector<int> & ,发现并没有输出(然而单步调试临时变量result被正确计算了),所以就求助了一下互联网。发现返回vector临时变量的引用是危险的,因为当函数执行完后,临时vector作用域终止,会自动调用相关的析构函数~vector(),所以返回无效。
这里正确的返回有多种,一种是上面所说的临时变量的副本,另一种是通过形参返回(指针或引用,请看以下代码)。
解决方案二:
像这种数组无序的查找想加快速度大多可以通过空间换取时间,比如建立Hash表,或拷贝一份原数组并排序等。
这里用Hash表(映射)来解决,代码如下:
1 vector<int> map_twoSum(vector<int> &src, int target) 2 { 3 vector<int> result; 4 map<int, int> m; 5 if (src.size() < 2) 6 { 7 return result; 8 } 9 for (size_t i = 0; i < src.size();++i) 10 { 11 m[src[i]] = i; //在这里发生映射 用空间换取时间 12 } 13 map<int, int>::iterator it; 14 for (int i = 0; i < src.size();++i) 15 { 16 if ((it = m.find(target-src[i])) != m.end()) //找到了索引 17 { 18 if (i == it->second)//i与映射结果相同 19 { 20 continue; 21 } 22 result.push_back(i + 1); 23 result.push_back(it->second + 1); 24 return result; 25 } 26 } 27 return result; 28 }
总结:写代码,细节真多。由于我比较笨,感觉没什么捷径,就小计一笔洛。
附:完整代码(带测试):
1 #include <iostream> 2 #include <vector> 3 #include <map> 4 5 using namespace std; 6 7 class two_Sum 8 { 9 public: 10 /************************************************************************/ 11 /* 12 成功返回1 13 失败返回0 14 */ 15 /************************************************************************/ 16 int two_sum(vector<int> &src_vec, int tagert, vector<int> &result) 17 { 18 // vector<int> result; //结果容器 存放2个结果索引值 //vector作局部变量返回会自动析构 19 for (size_t i = 0; i < src_vec.size() - 1; ++i) 20 { 21 for (size_t j = i + 1; j < src_vec.size(); ++j) 22 { 23 if (tagert == (src_vec[i] + src_vec[j])) 24 { 25 result.push_back(i + 1); 26 result.push_back(j + 1); 27 return 1; 28 } 29 } 30 } 31 return 0; 32 } 33 /************************************************************************/ 34 /* 35 返回临时变量的副本 36 */ 37 /************************************************************************/ 38 vector<int> two_sum(vector<int> &src_vec, int tagert) 39 { 40 vector<int> result; //结果容器 存放2个结果索引值 //vector作局部变量返回会自动析构 41 for (size_t i = 0; i < src_vec.size() - 1; ++i) 42 { 43 for (size_t j = i + 1; j < src_vec.size(); ++j) 44 { 45 if (tagert == (src_vec[i] + src_vec[j])) 46 { 47 result.push_back(i + 1); 48 result.push_back(j + 1); 49 return result; 50 } 51 } 52 } 53 return result; 54 } 55 /************************************************************************/ 56 /* 57 返回临时变量的引用(危险) 58 */ 59 /************************************************************************/ 60 // vector<int>& two_sum(vector<int> &src_vec, int tagert) 61 // { 62 // vector<int> result; //结果容器 存放2个结果索引值 //vector作局部变量返回会自动析构 63 // for (size_t i = 0; i < src_vec.size() - 1; ++i) 64 // { 65 // for (size_t j = i + 1; j < src_vec.size(); ++j) 66 // { 67 // if (tagert == (src_vec[i] + src_vec[j])) 68 // { 69 // result.push_back(i + 1); 70 // result.push_back(j + 1); 71 // return result; 72 // } 73 // } 74 // } 75 // return result; 76 // } 77 vector<int> map_twoSum(vector<int> &src, int target) 78 { 79 vector<int> result; 80 map<int, int> m; 81 if (src.size() < 2) 82 { 83 return result; 84 } 85 for (size_t i = 0; i < src.size();++i) 86 { 87 m[src[i]] = i; //在这里发生映射 用空间换取时间 88 } 89 map<int, int>::iterator it; 90 for (int i = 0; i < src.size();++i) 91 { 92 if ((it = m.find(target-src[i])) != m.end()) //找到了索引 93 { 94 if (i == it->second)//i与映射结果相同 95 { 96 continue; 97 } 98 result.push_back(i + 1); 99 result.push_back(it->second + 1); 100 return result; 101 } 102 } 103 return result; 104 } 105 }; 106 /************************************************************************/ 107 /* 108 函数功能:打印int型vector 109 形参:vector的引用 110 */ 111 /************************************************************************/ 112 void Print_vector(const vector<int> &vec) 113 { 114 for (size_t i = 0; i < vec.size();++i) 115 { 116 cout << vec[i] << " "; 117 } 118 } 119 int main() 120 { 121 vector<int> src_verc = { 1, 3, 4, 2, 4, 5, 6, 7 }; 122 Print_vector(src_verc); 123 cout << endl; 124 int target = 9; 125 two_Sum two_sumTest; 126 vector<int> result; 127 // two_sumTest.two_sum(src_verc, target,result); 128 // result = two_sumTest.two_sum(src_verc, target); 129 result = two_sumTest.map_twoSum(src_verc, target); 130 131 Print_vector(result); 132 cout << endl; 133 134 return 0; 135 136 }
参考:
http://www.aichengxu.com/view/42358
http://blog.chinaunix.net/uid-17102734-id-2830014.html
浙公网安备 33010602011771号