原题链接:https://leetcode.com/problems/two-sum/description/
意思是给定输入数组和目标数,要求输出数组中两个相加刚好为目标数的元素下标
我的实现(Brute Force):
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int>& nums, int target) { 4 vector<int> answer; 5 for (int i = 0; i < nums.size(); i++) { 6 for (int j = i; j < nums.size(); j++) { 7 if (nums[i] + nums[j] == target && i != j) { 8 answer.push_back(i); 9 answer.push_back(j); 10 return answer; 11 } 12 } 13 } 14 return answer; 15 } 16 };
时间复杂度:O(n2).
空间复杂度:O(1).
怎么样提高算法效率呢?
先将数列每个元素存到哈希表,然后遍历数列看(目标数-当前元素)的值在hash table中是否存在即可,注意判断下标不能重复。
public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { map.put(nums[i], i); } for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement) && map.get(complement) != i) { return new int[] { i, map.get(complement) }; } } throw new IllegalArgumentException("No two sum solution"); }
时间复杂度:O(n).
空间复杂度:O(n).
为了进一步减小需要的存储空间,做法是不需要提前将数列元素保存在哈希表中,可以边遍历数组边加入hash table。这样如果存在数组之前元素与当前元素之和为目标数我们就能输出结果,代码:
public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[] { map.get(complement), i }; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); }
时间复杂度:O(n).
空间复杂度:O(n).(PS:需要存储空间最多为存储n个元素的hash table)
总结:Hash Table,空间换时间。