LeetCode:兩數之和

兩數之和

題目:

給定一個整數數組和一個目標值,找出數組中和爲目標值的兩個數。你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。

示例:

給定 nums = [2, 7, 11, 15], target = 9
因爲 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

C++

第一反應(最不動腦子):
兩個for就遍歷出所有可能就能找到,於是代碼如下:

class Solution 
{
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        vector<int> result;
        int size = nums.size();
        for(int i = 0; i < size; ++i)
        {
            for(int j = i + 1; j < size; ++j)
            {
                if(nums[i] + nums[j] == target)
                {
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
        }

        return result;
    }
};

很順利的通過,結果代碼跑了108 ms,只戰勝了48.33%的人。。。(╯‵□′)╯︵┻━┻

看了看居然有人的代碼4 ms就能跑完???
4 ms代碼如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::unordered_map<int, int> index;
        for (size_t i = 0 ; i < nums.size(); ++i)
        {
            auto x = target - nums[i];
            if (index.count(x) > 0)
                return {index[x], i};
            index[nums[i]] = i ; 
        }
    }
};

上面代碼在unordered_map中尋找 目標結果減去數組當前項的結果;如果沒找到就把該項存入,如果找到了就說明匹配上,直接返回。

總結:

4 ms代碼只需要循環一次就可匹配出結果,比我的兩個for快了很多。

unordered_map:

是C++ 11中新增的無序map,內部實現爲HASH表,內部數據無序,通過鍵值訪問數據速度比map快,但是遍歷效率不高。

map:

內部實現爲紅黑樹,內部數據有序

C語言

C++用HASH表,C沒有,該乖乖用for嵌套了吧?果斷上代碼,結果只超過65.63%:

int* twoSum(int* nums, int numsSize, int target) 
{
    int *result = (int*)malloc(sizeof(int) * 2);

    for (int i = 0; i < numsSize; ++i)
    {
        for (int j = i + 1; j < numsSize; ++j)
        {
            if (nums[i] + nums[j] == target)
            {
                result[0] = i;
                result[1] = j;
                return result;
            }
        }
    }

    return result;
}

嗯。。。看來還是有騷操作。。。

0 ms代碼:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target) {
    int i, min = nums[0];
    int* indices = malloc(2*sizeof(int));
    /* find the min of nums[numsSize] */
    for (i = 1; i < numsSize; i++)
        if (min > nums[i])
            min = nums[i];

    int hashSize = target - min - min + 1;
    int hash[hashSize];
    /* initialization of hash */
    for (i = 0; i < hashSize; i++)
        hash[i] = INT_MIN;
    /* loop of nums
       1 skip the elements larger than target-min
       2 tag the corresponding element
       3 when find the tag, return the two indices
    */
    for (i = 0; i < numsSize; i++){
        if (nums[i] > target-min)
            continue;
        else if (hash[nums[i]-min] == INT_MIN)
            hash[target-nums[i]-min] = i;
        else{
            indices[0] = hash[nums[i] - min];
            indices[1] = i;
            return indices;
        }
    }
    return NULL;
}

大佬手寫HASH表,我認輸了。

總結:

學會手寫HASH表

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章