https://leetcode-cn.com/problems/two-sum/solution/liang-shu-zhi-he-by-leetcode-2/
一、暴力法(java实现)
暴力法很简单,遍历每个元素 x,并查找是否存在一个值与 target−x 相等的目标元素。
class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[j] == target - nums[i]) { return new int[] { i, j }; } } } throw new IllegalArgumentException("No two sum solution"); } }
二、一遍hash(java实现)
class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); for (int i=0;i<nums.length;i++){ if (map.containsKey(target-nums[i])){ return new int[]{map.get(target-nums[i]), i}; } else{ map.put(nums[i],i); } } // 应该是能找到,提前就return了 return new int[]{0,0}; }
三、两遍hash(java实现)
class Solution { public int[] twoSum(int[] nums, int target) { // 因为相同的key会被覆盖,假设输入为[3,3,3,4,5] 6 // 那么第一次hashmap初始化,存的是<3,2>,<4,3>, <5,4> // 接下来for循环数组,当i=1的时候,nums[i]=nums[1]=3,查询hashmap的时候map.get(3),得到的为<3,2>, // 于是就可以返回找到的元素的索引值为[0,2] // 还有这种情况 输入为[4,2,6] 8 // 那么第一次hashmap初始化,存的是<4,0>,<2,1>,<6,2> // 接下来for循环数组,当i=0的时候,map.get(4)得到的为<4,0>,得到的是这个元素本身 // 所以需要添加一个条件map.get(complement) != i 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"); } }
四、双指针(python实现)
需要先排序,使用双指针,分别指向头、尾。如果两数之和大于target,尾指针前移,如果两数之和小于target,首指针后移。
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: r=zip(nums,range(len(nums))) r = sorted(r, key=lambda x:x[0]) i, j=0,len(nums)-1 while i<j: sum=r[i][0]+r[j][0] if sum<target: i+=1 elif sum>target: j-=1 else: break return [r[i][1],r[j][1]]