leetcode 1:two sum

给定一个数组和一个目标数字target,返回数组中的两个下标,这两个下标对应的数字的和为target。(约定数组中满足要求的数字对是唯一的,每个数组只能使用一次)
例子:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

解题思路1 暴力法

最暴力的方法就是枚举所有两个数字组合的情况,对于每个数字都和其他数字组合,然后判断是否满足条件,时间复杂度是O(n^2)

    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)
                    return {i,j};
            }
        }
        return {};
    }

解题思路2 预处理法

暴力方法往往时间复杂度不够好,可以通过对数组进行预处理,比如先用O(nlogn)的复杂度对数组进行排序,令数组有递增的特性后,就可以用两个指针的方法来找这两个数。left指针指向数组头部,right指针指向数组尾部,若和小于target则left右移,若大于target则right左移,知道找到目标的两个数为止,每次有一个指针移动,因此最多只需要遍历数组一次。总的时间复杂度为O(nlogn)
这种方法适合用在需要找出这两个数的情况,在本题中要找的是下标,因为排序的过程中下标会改变,因此还需要额外的空间和时间。

解题思路3 哈希

最快的解决方法是O(n)的哈希法,因为在哈希表中找一个数字的时间复杂度是O(1),因此可以牺牲空间换时间,建立一个哈希表,从左往右遍历数组,将遍历过的数字加入哈希表,对于每个新遍历的数字num,查找target-num是否在哈希表中(即是否已经出现在数组中),从而得到要求的数字下标对。在这里使用c++11的unordered_map作为哈希表。

    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> num2index;

        for(int i=0;i<nums.size();i++){
            if (num2index[target-nums[i]])
                return {num2index[target-nums[i]]-1,i};
            num2index[nums[i]] = i+1;            
        }
    }

猜你喜欢

转载自blog.csdn.net/acelove40/article/details/79802610