LeetCode打卡之TwoSum

原题

Given an array of integers, return indices of the two numbers 
such that they add up to a specific target.
You may assume that each input would have exactly one solution, 
and you may not use the same element twice.

大意就是给定数字列表和一个目标值(target), 假设列表中有且仅有(one solution)两个数相加等于目标值, 而我们需要做的就只找出这两个数的目标值。
例如:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

思路一

看到这题目,第一反应就是两层循环,很简单嘛,上代码


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

这方法很轻松的通过了,不过时间复杂度,你懂得,两层循环,O( n 2 ), 运行时间老久了,一看排名老靠后了,得另想办法。

思路二

第二种思路就是我们先将数组排序好,这里假设是从小到大, 然后数组两边的值相加(假设i为小的数的下标, j为大的数的下标, 一开始i=0, j = size()-1),如果大于目标值,j-1, 如果小于目标值, i+1。 大致代码如下

struct tag {
    int num;
    int index;
};

vector<int> twoSum(vector<int>& nums, int target) {
    vector<tag> tags;
    for (int i = 0; i < nums.size(); ++i) {
        tag t;
        t.index = i;
        t.num = nums[i];
        tags.push_back(t);
    }
    sort(tags.begin(), tags.end(), [&](tag a, tag b) -> bool {
        return a.num < b.num;
    });
    int i = 0, j = tags.size()-1;
    while(i!=j) {
        if(tags[i].num + tags[j].num > target) {
            --j;
        } 
        else if (tags[i].num + tags[j].num < target) {
            ++i; 
        } 
        else {
            vector<int> v;
            v.push_back(tags[i].index);
            v.push_back(tags[j].index);
            return v;
        }  
    }
}

这里我们需要用一个结构体记录一下nums中的值和下标,因为如果直接对nums进行排序,那么原来的数的下标就被破坏了,所以我们需要用一个结构体来记录 原来的数值和下标。
在这里对结构题赋值和最后的寻找下标实践复杂度都是 O ( n ) , 所以这个算法的最终的时间复杂度主要取决于sort函数的实践复杂度。 据了解,c++中sort算法是使用快排实现的,而快排算法的实践复杂度为 O ( n l o g n ) , 所以这个方法的最终时间复杂度为 O ( n l o g n )

思路三

该思路是网上很多大神都是用的一种方法。 该思路的主要思路为,用一个map将来存储nums[i]与i对应起来, 通过判断target-num[i]是否存在map中来寻找索引值, 大致代码如下

vector<int> twoSum(vector<int>& nums, int target) {
    map<int, int> m;
    for (int i = 0; i < nums.size(); ++i) {
        m[nums[i]] = i;
    }
    for (int i = 0; i < nums.size(); ++i) {
        if(m.count(target-nums[i])&& i != m[target-nums[i]]) {
            vector<int> v;
            v.push_back(i);
            v.push_back(m[target-nums[i]]);
            return v;
        }
    }
}

本来是想用hashmap的,但是leetcode不支持hashmap, 如果使用hashmap的话,时间复杂度为降低很多,因为hashmap插入和获取的时间复杂度都是 O ( 1 ) , 所以该方法使用hashmap的话时间复杂度会降低到 O ( n ) , 而map的时间复杂度为 O ( l o g n ) ,所以使用map的时间复杂度为 O ( n l o g n ) (不知道为啥,运行时间比排序那个还久)

猜你喜欢

转载自blog.csdn.net/qq_36297981/article/details/82557289