LeetCode-Two Sum
今天做了第一道简单题。Two Sum。以下是题目。

我用一种比较笨的办法写了一下,nested loop只打败了16.12%的人。
Time complixity:O(n2) For each element, we try to find its complement by looping through the rest of array which takes O(n) time. Therefore, the time complexity is O(n2)
Space complexity : O(1).
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
for(int i=0; i<nums.size()-1; i++){ //the first number
for(int j=i+1; j<nums.size();j++){
int sum=nums[i]+nums[j];
if (target==sum){
result.push_back(i); //improve it later
result.push_back(j);
return result;
}
}
}
return vector<int>(); //empty result if we did not find the expected indices
}
};
写代码的时候我产生的疑问如下:
1. 在建立vector的时候可不可以建立长度为2的vector,这样后面我可以直接用vector[indix]进行赋值。
在网上查了一下关于vector的initialization。
Conventional STL:
int arr[] = {16,2,77,29}; vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );
常用的push_back:
v.push_back(SomeValue);
C++ 11中可以使用的赋值语句。
include <vector>
using std::vector
...
vector<int>v = {1, 3, 5, 7};
还有一些引入其他library的方法。
Using boost list_of:
#include <vector> #include <boost/assign/list_of.hpp> using std::vector; ... vector<int> vec = boost::assign::list_of(10)(20)(30);
Using boost assign
#include <vector> #include <boost/assign/std/vector.hpp> using std::vector; ... vector<int> vec; vec += 10, 20, 30;
后面两个看上去很难记住的样子。
Conventional STL with generic macros:
后面#include <vector> #define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0]) #define ARRAY_END(ar) (ar + ARRAY_SIZE(ar)) using std::vector; ... static const int arr[] = {10,20,30}; vector<int> vec (arr, ARRAY_END(arr));
Conventional STL with a vector initializer macro:
#include <vector> #define INIT_FROM_ARRAY(ar) (ar, ar + sizeof(ar) / sizeof(ar[0]) using std::vector; ... static const int arr[] = {10,20,30}; vector<int> vec INIT_FROM_ARRAY(arr);
c++中,vector永远是动态内存的,没法initialize a vector with a constant size。不过可以在初始化的时候赋予一个size:
std::vector<int> v(10); v.size(); //returns 10
2. vector.push_back的时候可否同时push两个数字
关于这点,网上给的办法是先赋值给array,再复制到vector中
int arr[] = {2,5,8,11,14}; std::vector<int> TestVector(arr, arr+5);
或者是利用insert。
std::vector<int> v; int a[5] = { 1,2,3,4,5 }; v.insert(v.end(), a, a+5);
然后下面有人指出用a+5不太安全,可以使用 v.insert(v.end(), a, a+(sizeof(a)/sizeof(a[0]))); 这样的话在a的size更改之后无需修改这条命令。
emm 反正结论就是没法直接push两个数字啦。
下面回到这道题本身,
看了一下能够提升运行时间的答案,用到了map。这里有个很值得注意的点!因为C++里map的find函数只能通过key来找value,如果想直接找value的话得直接写个循环,所以我们的设计的map的Key是number,而value才是Index。
class Solution { public: vector<int> twoSum(vector<int>& nums, int target) { map<int, int> temp;//key would be nums[i] and value would be index i vector<int> result; for(int i=0;i<nums.size();i++) { int component = target-nums[i]; if(temp.find(component)!=temp.end() && temp[component]!=i){ result.push_back(i); result.push_back(temp[component]); return result; } else temp[nums[i]]=i; //put the element into map } return result; } };
这是我写的代码,我在写条件语句的时候本来写成了 componenet!=nums[i] 这是不可以的,我们应该确认的是Index不相同,而非数本身不相同,比如testcase (3,3) 这时候我们的nums[0]和component 就是相同的。然后我就改成了 temp[component]!=i 。后来我想了一下,是否这个条件语句并不需要呢?
这个算法的逻辑我们梳理一下:
对一个nums[i],在map里寻找component,找到直接返回,没找到的话把这个nums[i]插入map里。也就是说在map寻找component这个过程中,nums[i]还不存在map里,找到的component无论如何和nums[i]对应的都不可能是同一个index。这也解释了为什么我们要先寻找component 再将nums[i]插入进去。
emm上传了这个solution后我打败了55.21%的人。虽然还不是很好,但是先这样吧。

浙公网安备 33010602011771号