1. 题目描述:
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
2. 解题思路
2.1 暴力法(C++)--不推荐
用两个for循环遍历所有可能,时间复杂度为O(n^2)。
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int>& nums, int target) { 4 int i, j; 5 for(i = 0; i < nums.size()-1; i++) { 6 for(int j = i + 1; j < nums.size(); j++) { 7 if((nums[i] + nums[j]) == target){ 8 return{i, j}; 9 } 10 } 11 } 12 return {}; 13 } 14 };
2.2 一遍hash(C++)--推荐
在容器中插入元素的同时,检查容器中是否存在差值。
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int>& nums, int target) { 4 map<int, int> temp; // map<key, value> 5 vector<int> current(2, 0); // 存储结果,初始化一个大小为2,值为0的容器。 6 for(int i=0;i<nums.size();i++){ 7 if(temp.count(target-nums[i])>0){ // 在temp中查找target-nums的个数, 8 // 大于0表示 9 current[0] = temp[target-nums[i]]; // 存储第一个数的key 10 current[1] = i; // 存储第二个key 11 break; 12 } 13 temp[nums[i]] = i; // 将前面所有不符合条件的都放入map, 14 // key为nums值,value为下标。 15 } 16 return current; 17 } 18 };
2.3 std::unordered_map方式实现--推荐
C++中map,有三种类型,推荐使用第三种,效率更高。
映射 | 底层实现 | 是否有序 | 数值是否可以重复 | 能否更改数值 | 查询效率 | 增删效率 |
std::map | 红黑树 | key有序 | key不可重复 | key不可修改 | O(log(n)) | O(log(n)) |
std::multimap | 红黑树 | key有序 | key可重复 | key不可修改 | O(log(n)) | O(log(n)) |
std::unordered_map | 哈希表 | key无序 | key不可重复 | key不可修改 | O(1) | O(1) |
1 class Solution { 2 public: 3 vector<int> twoSum(vector<int>& nums, int target) { 4 std::unordered_map<int, int> temp; 5 for(int i=0; i<nums.size(); i++){ 6 auto iter = temp.find(target-nums[i]); 7 if(iter!=temp.end()){ 8 return {iter->second, i}; 9 } 10 temp.insert(pair<int, int>(nums[i], i)); 11 } 12 return {}; 13 14 } 15 };
2.4 暴力法(Java)--不推荐
class Solution { public int[] twoSum(int[] nums, int target) { int n = nums.length; for(int i = 0; i < n-1; i++) { for(int j = i +1; j < n; j++) { if(nums[i] + nums[j] == target){ return new int[]{i, j}; } } } throw new IllegalArgumentException("No two sum solution"); } }
2.5 一遍hash(Java)--推荐
1 class Solution { 2 public int[] twoSum(int[] nums, int target) { 3 Map<Integer, Integer> temp = new HashMap<>(); 4 int n = nums.length; 5 for(int i=0; i<n; i++){ 6 int val = target-nums[i]; 7 if(temp.containsKey(val)){ 8 return new int[]{temp.get(val), i}; 9 } 10 temp.put(nums[i], i); 11 } 12 throw new IllegalArgumentException("No two sum solution"); 13 } 14 }
2.6 暴力法(Python)--不推荐
1 class Solution: 2 def twoSum(self, nums: List[int], target: int) -> List[int]: 3 # 1.暴力 4 for i in range(len(nums)): 5 for j in range(i+1, len(nums)): 6 if nums[i] + nums[j] == target: 7 return [i, j] 8 return []
2.7 暴力法(hash)--推荐
1 class Solution: 2 def twoSum(self, nums: List[int], target: int) -> List[int]: 3 temp = {} 4 lens = len(nums) 5 for i in range(lens): 6 current = temp.get(target - nums[i]) 7 if current is not None: 8 return [current, i] 9 temp[nums[i]] = i
3. 结语
努力去爱周围的每一个人,付出,不一定有收获,但是不付出就一定没有收获! 给街头卖艺的人零钱,不和深夜还在摆摊的小贩讨价还价。愿我的博客对你有所帮助(*^▽^*)(*^▽^*)!
如果客官喜欢小生的园子,记得关注小生哟,小生会持续更新(#^.^#)(#^.^#)。