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)。