LeetCode 1: Two Sum

Description: 

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.

Example:

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

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

 

描述:

给定一个整数数组,返回数组中两个数字的索引,使得这两个数字的和为给定的目标值。

假设每个输入数组只有一个解,并且数组中每个元素只使用一次。

示例:

给定的数组 nums = [2, 7, 11, 15], 目标值为 9,
因为nums[0] + nums[1] = 2 + 7 = 9,
返回值为:[0, 1].

 

方法1:暴力搜索

思路:遍历数组中任意两个元素,并计算两个元素的和,如果两个元素的和等于给定的目标值,则返回两个元素的索引。

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

本方法包含两层循环,时间复杂度为Ο(n2),空间复杂度为O(1).

 

方法二:

分析方法一,发现其包含两层循环,一种直观的想法是降低循环的层数。为此,本方法首先遍历一遍数组,采用map结构保存数组中每个元素和其对应索引值。

接着,再次遍历数组,判断数组元素值val和该元素对应的目标值的补值(即target - val)是否在map结构中。如果存在,则返回这两个元素的索引值。

本方法将方法一中的两层循环遍历,更改为两次对数组的遍历,降低了时间复杂度。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int, int> val2Idx;
        vector<int> res;
        for(int i = 0; i < nums.size(); i++) {
            val2Idx.insert(make_pair(nums[i], i));
        }
        
        for(int i = 0; i < nums.size(); i++) {
            int val = target - nums[i];
            if(val2Idx.find(val) != val2Idx.end() && val2Idx[val] != i) {
                int idx = val2Idx[val];
                int idx2 = i;
                if(idx < idx2) {
                    res.push_back(idx);
                    res.push_back(idx2);
                } else {
                    res.push_back(idx2);
                    res.push_back(idx);
                }
                break;
            }
        }
        return res;
    }
};

本方法的时间复杂度为O(n),空间复杂度为O(n)。

 

方法三:

方法二通过遍历数组构建元素值和相应索引的map结构。因此,需要遍历数组两次。本方法通过将构建map结构和数组遍历放在同一个素组遍历过程中,优化程序。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int, int> val2Idx;
        vector<int> res;
        for(int i = 0; i < nums.size(); i++) {
            val2Idx.insert(make_pair(nums[i], i));
            int val = target - nums[i];
            if(val2Idx.find(val) != val2Idx.end() && val2Idx[val] != i) {
                int idx = val2Idx[val];
                int idx2 = i;
                if(idx < idx2) {
                    res.push_back(idx);
                    res.push_back(idx2);
                } else {
                    res.push_back(idx2);
                    res.push_back(idx);
                }
                break;
            }
        }
        return res;
    }
};

 本方法的时间复杂度为O(n),空间复杂度为O(n)。 

posted @ 2018-08-13 16:08  双肩包码农  阅读(142)  评论(0编辑  收藏  举报