Two Number - Leetcode

来源:互联网 发布:金融网络销售工资 编辑:程序博客网 时间:2024/06/10 00:50

最初代码。错误:Time Limit Exceeded 时间复杂度:O(n^2)

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

后面在网上学习其他人写的代码。
第一种是利用map容器来存储每个数字的值和索引,然后在map中查找是否有值为target-nums[i]的数字存在。这里只需要一个循环。map是一个关联式容器,提供一对一的数据处理能力(映射关系)。map内部数据是自建一颗红黑树(对数据有自排序的功能,因此map内部的数据是有序的),这里用到map的查找函数count(),count()函数统计一个键值出现的次序。因为map中的键值不允许重复,所以count的返回值只会是0或1。下面是代码,因为题中又说答案只有一种,可知数组里没有重复的数字。在for循环中,每插入一次数据nums[i],就进行一次target-nums[i]的查找。因此最后找到的数据的索引n一定比i小。

class Solution {public:    vector<int> twoSum(vector<int>& nums, int target) {        map<int,int> numbers;        vector<int> result;        for(int i=0;i<nums.size();i++)        {            numbers.insert(pair<int,int>(nums[i],i));            if(numbers.count(target-nums[i]))            {                int n=numbers[target-nums[i]];                if(n<i){                    result.push_back(n+1);                    result.push_back(i+1);                    return result;                }            }        }        return result;    }};[转载]

第二种,是将nums数组的值进行从小到大的排序。有序之后顺序会变,因此将数组中每一项的值和索引存入结构体。下面是代码,在我看来下面代码中处理最妙的地方是for循环中,一个i从前,一个j从后,来组成sum。后面再根据sum和target的大小比较来判断是i++还是j–。通过这样的做法可以避免嵌套for循环。

struct Node{    int num, pos;};bool cmp(Node a, Node b){    return a.num < b.num;}class Solution {public:    vector<int> twoSum(vector<int> &numbers, int target) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        vector<int> result;        vector<Node> array;        for (int i = 0; i < numbers.size(); i++)        {            Node temp;            temp.num = numbers[i];            temp.pos = i;            array.push_back(temp);        }        sort(array.begin(), array.end(), cmp);        for (int i = 0, j = array.size() - 1; i != j;)        {            int sum = array[i].num + array[j].num;            if (sum == target)            {                if (array[i].pos < array[j].pos)                {                    result.push_back(array[i].pos + 1);                    result.push_back(array[j].pos + 1);                } else                {                    result.push_back(array[j].pos + 1);                    result.push_back(array[i].pos + 1);                }                break;            } else if (sum < target)            {                i++;            } else if (sum > target)            {                j--;            }        }        return result;    }};[转载]

总结,关联容器的知识内容有些遗忘,下次补充。写代码的时候不能总是拘束于旧的思维框架中,要充分利用c++的功能。

1 0