1. 2Sum---Array--HashMap--LeetCode

来源:互联网 发布:陕西易通网络服务公司 编辑:程序博客网 时间:2024/06/04 17:48

1. 笨办法O(N2)

class Solution {public:    vector<int> twoSum(vector<int>& nums, int target)     {        vector<int> output;        for(int i = 0; i < nums.size(); ++i)        {            for(int m = i + 1; m < nums.size(); ++m)            {                if(nums[i] + nums[m] == target)                {                    output.push_back(i);                    output.push_back(m);                    std::sort(output.begin(), output.end());                    return output;                }            }        }        return output;    }};


2. 超时,看不出结果正确与否

对原数据排序,再比较

class Solution {public:    vector<int> twoSum(vector<int>& nums, int target)     {        vector<int> input(nums);        vector<int> output;        std::sort(input.begin(), input.end());                int i = 0, j = input.size() - 1;        while(i < j)        {            int sum = input[i] + input[j];            if(sum > target)                --j;            else if(sum < target)                ++i;            else            {                output.push_back(input[i]);                output.push_back(input[j]);                                // 找值i、j对应的下标                int index1, index2;                for(int i = 0; i < input.size(); ++i)                {                    if(input[i] == output[0])                    {                        index1 = i;                        break;                    }                }                for(int i = 0; i < input.size(); ++i)                {                    if(input[i] == output[1])                    {                        index2 = i;                        break;                    }                }                                output.clear();                if(index1 <= index2)                {                    output.push_back(index1);                    output.push_back(index2);                }                else                {                    output.push_back(index2);                    output.push_back(index1);                }             }         }                return output;    }};


3. 仍然排序

但是新建一个结构体,存储原始下标,O(N)

class Solution {public:    struct CNumSet    {        int val;        int index;        CNumSet(int v, int i)            :val(v),            index(i) {}    };    static bool myOrder(struct CNumSet a, struct CNumSet b)    {        return (a.val <= b.val);    }public:    vector<int> twoSum(vector<int>& nums, int target)     {        vector<CNumSet> v;        vector<int> output;        for(int i = 0; i < nums.size(); ++i)            v.push_back(CNumSet(nums[i], i));                std::sort(v.begin(), v.end(), myOrder);                for(int i = 0, j = v.size() - 1; i <= j; )        {            int sum = v[i].val + v[j].val;            if(sum < target)                ++i;            else if(sum > target)                --j;            else            {                output.push_back(v[i].index);                output.push_back(v[j].index);                std::sort(output.begin(), output.end());                return output;            }        }        return output;    }};


法4:用unordered_map,通过vector的值,查找vector的下标

class Solution {public:    vector<int> twoSum(vector<int>& nums, int target)     {        unordered_map<int, int> myMap;        vector<int> output;        int sz = nums.size();        for(int i = 0; i < sz; ++i)            myMap[nums[i]] = i;     // map的键是vector的值,map的值是vector的下标(因为map是按照键查找,O(1)时间)                    for(int i = 0; i < sz; ++i)        {            int anotherNumber = target - nums[i];            if(myMap.find(anotherNumber) != myMap.end())            {                int anotherIndex = myMap[anotherNumber];                if(anotherIndex == i)                    continue;                else                {                    output.push_back(i);                    output.push_back(anotherIndex);                    std::sort(output.begin(), output.end());                    return output;                }            }        }        return output;    }};


法5:比法4更简洁,不需判断找到的anotherNumber是否重复。因为如果重复,放入myMap时会被覆盖。

(map和unordered_map里的键是唯一的,不可能重复,否则查找一个键会出现2个值)

参考https://discuss.leetcode.com/topic/3294/accepted-c-o-n-solution

class Solution {public:    vector<int> twoSum(vector<int>& nums, int target)     {        unordered_map<int, int> myMap;        vector<int> output;        int sz = nums.size(); //     /for(int i = 0; i < sz; ++i) //         myMap[nums[i]] = i;     // map的键是vector的值,map的值是vector的下标(因为map是按照键查找,O(1)时间)                    for(int i = 0; i < sz; ++i)        {            int anotherNumber = target - nums[i];            if(myMap.find(anotherNumber) != myMap.end())    // O(1)            {                int anotherIndex = myMap[anotherNumber];                output.push_back(i);                output.push_back(anotherIndex);                std::sort(output.begin(), output.end());                return output;            }            else   // 若没找到anotherNumber,把nums[i]放进myMap。若(在之前已放入myMap的元素中)找到了,结束。                myMap[nums[i]] = i; // 如果nums[i]重复,会被覆盖。如原来nums为{3,2,2,4,3,5},                                    // 则myMap剩下{(3, 0), (2, 1), (4, 2), (5, 3)}        }        return output;    }};




0 0
原创粉丝点击