【LeetCode】001. 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.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
题解:
首先想到暴力解,TLE(Time Limit Exceeded)问题先不考虑。从数组头开始,依次与其他元素比较,然后向后移动开始位置,需要注意的是返回的位置是从0开始的
Solution 1 (TLE)
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int> &numbers, int target) { 4 vector<int> result; 5 int n = numbers.size(); 6 for (int i = 0; i < n; i++) { 7 for (int j = i + 1; j < n; j++) { 8 if (numbers[i] + numbers[j] == target) { 9 result.push_back(i); 10 result.push_back(j); 11 } 12 } 13 } 14 return result; 15 } 16 };
那怎样才能降低时间复杂度呢?这里有个经验准则,数组及字符串问题往往与(unordered)map、(unordered)set有关。这里使用unordered_map,用于查找;首先想到的思路是先遍历一遍数组,建立map映射表(元素值和位置的映射),然后再遍历一遍查找与当前元素之和为目标值的元素。建立m(数组元素)与m的位置的映射。
Solution 2
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int>& nums, int target) { 4 unordered_map<int, int> m; 5 int n = nums.size(); 6 vector<int> result; 7 for (int i = 0; i < n; ++i) { 8 m[nums[i]] = i; 9 } 10 for (int i = 0; i < n; ++i) { 11 int t = target - nums[i]; 12 //m.find(t) != m.end() 可以用 m.count(t)代替 13 //you may not use the same element twice. 14 if (m.find(t) != m.end() && m[t] != i) { 15 result.push_back(i); 16 result.push_back(m[t]); 17 break; 18 } 19 } 20 return result; 21 } 22 };
有一种优化方法,思路是从数组头开始,依次将元素对应的加数加入map中,在建立映射的过程中,若发现map中已经存在了一个元素,由于这个元素的存在是之前的操作才加入到map中,及此元素对应的加数在之前已经存在,故直接返回即可。题设 each input would have exactly one solution。建立target-m与m的位置的映射。
Solution 3
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int>& nums, int target) { 4 unordered_map<int, int> m; 5 vector<int> result; 6 for(int i=0; i<nums.size(); i++) 7 { 8 if (m.find(nums[i])==m.end() ) 9 { 10 m[target - nums[i]] = i; 11 } 12 else 13 { 14 result.push_back(m[nums[i]]); 15 result.push_back(i); 16 break; 17 } 18 } 19 return result; 20 } 21 };