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%的人。虽然还不是很好,但是先这样吧。

 

posted @ 2018-04-15 09:22  吹离了空白  阅读(102)  评论(0)    收藏  举报