Given an array of integers, find two numbers such that they add up to a specific target number.The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.java
You may assume that each input would have exactly one solution.數組
Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1, index2=2less
O(1)空間 O(n^2)時間指針
經過雙重循環遍歷數組中全部元素的兩兩組合,當出現符合的和時返回兩個元素的下標code
public class Solution { public int[] twoSum(int[] nums, int target) { int[] result = new int[2]; if(nums.length < 2){ return result; } for(int i = 0 ; i < nums.length; i++){ for(int j = i + 1; j < nums.length; j++){ if((nums[i]+nums[j])==target){ result[0] = i + 1; result[1] = j + 1; return result; } } } return result; } }
O(n)空間 O(n)時間排序
第一次遍歷數組先將全部元素和它的下標做爲key-value對存入Hashmap中,第二次遍歷數組時根據目標和與當前元素之差,在Hashmap中找相應的差值。若是存在該差值,說明存在兩個數之和是目標和。此時記錄下當前數組元素下標並拿出Hashmap中數組元素下標便可。Hashmap獲取元素的時間複雜度是O(1),因此總的時間複雜度仍不超過O(n)。ci
public class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<Integer, Integer>(); int[] res = new int[2]; for(int i = 0; i < nums.length; i++){ int diff = target - nums[i]; if(map.containsKey(nums[i])){ res[0] = map.get(nums[i]) + 1; res[1] = i + 1; } map.put(diff, i); } return res; } }
2018/2 更新get
class Solution: def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ numsMap = {} for index in range(0, len(nums)): num1 = nums[index] num2 = target - num1 if num2 in numsMap: return [index, numsMap[num2]] else: numsMap[num1] = index
2018/10input
func twoSum(nums []int, target int) []int { m := make(map[int]int) result := make([]int, 2) for i := 0; i < len(nums); i++ { var curr = nums[i] var diff = target - curr result[0] = i if _, ok := m[diff]; ok { result[1] = m[diff] return result } else { m[curr] = i } } return result }
O(n)空間 O(nlogn)時間it
首先將原數組複製一遍,對新數組進行排序。排序後將雙指針指向頭部與尾部元素,進行迭代。若是雙指針指向元素之和大於目標和,則將尾部指針向前移一位,反之則將頭部指針向後移一位,直到雙指針指向元素之和等於目標和,記錄這兩個元素的值,而後再遍歷一遍舊數組,找出這兩個元素的下標。
private ArrayList<List<Integer>> twoSum(int[] nums, int target){ int left = 0, right = nums.length - 1; ArrayList<List<Integer>> res = new ArrayList<List<Integer>>(); while(left < right){ if(nums[left] + nums[right] == target){ ArrayList<Integer> curr = new ArrayList<Integer>(); curr.add(nums[left]); curr.add(nums[right]); res.add(curr); do { left++; }while(left < nums.length && nums[left] == nums[left-1]); do { right--; } while(right >= 0 && nums[right] == nums[right+1]); } else if (nums[left] + nums[right] > target){ right--; } else { left++; } } return res; }
Q:若是不須要返回數組下標,只用返回兩個數自己呢?
A:若是隻用返回兩個數自己,排序雙指針法能夠作到O(1)空間,時間複雜度還是O(nlogn)。而哈希表方法中的HashMap則能夠換成HashSet。
Q:若是要求的不是兩個數和和,而是找兩個數之差爲特定值的配對呢?A:一樣用哈希表能夠解決。若是要不用空間的話,也能夠先排序,而後將兩個指針指向頭,兩個數差小於目標時,將後指針向後移,不然將前指針向後移。