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.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
1 public static List<int> TwoSum(List<int> numbers, int target) 2 { 3 List<int> ret = new List<int>(); 4 for (int index1 = 0; index1 < numbers.Count - 1; index1++) 5 { 6 for (int index2 = index1 + 1; index2 < numbers.Count; index2++) 7 { 8 if (numbers[index1] + numbers[index2] == target) 9 { 10 ret.Add(index1 + 1); 11 ret.Add(index2 + 1); 12 } 13 } 14 } 15 16 return ret; 17 }
代码分析:
这。。。。好像也没有难点吧。题目说了肯定只有一个解。反正,大小case都过了。
不过这时间复杂度是O(n2)。
下面是O(nlog n) 的代码。感谢 heartfire.cc
1 public static List<int> TwoSumOpt(List<int> numbers, int target) 2 { 3 int i = 0, j = numbers.Count - 1; 4 List<int> ret = new List<int>(); 5 6 Dictionary<int, int> indices = new Dictionary<int,int>(); 7 8 for (int k = 0; k < numbers.Count; k++) 9 { 10 if (!indices.ContainsKey(numbers[k])) 11 { 12 indices.Add(numbers[k], k + 1); 13 } 14 //duplicates cannot be solutions unless they sum up to target 15 else if (numbers[k] * 2 == target) 16 { 17 ret.Add(indices[numbers[k]]); 18 ret.Add(k + 1); 19 return ret; 20 } 21 } 22 23 numbers.Sort(); 24 while (i < j) 25 { 26 if (numbers[i] + numbers[j] > target) 27 { 28 j--; 29 } 30 else if (numbers[i] + numbers[j] < target) 31 { 32 i++; 33 } 34 else 35 { 36 ret.Add(Math.Min(indices[numbers[i]], indices[numbers[j]])); 37 ret.Add(Math.Max(indices[numbers[i]], indices[numbers[j]])); 38 break; 39 } 40 } 41 42 return ret; 43 }
代码分析:
先把numbers 的 value 与 index 放到HashMap中,发现重复就看看他的2倍是否等于target,如果等于返回他们的indices。
然后SORT一下啊numbers,这就是O(nlog n)所在。因为前后的步骤都是O(n)。
第三步,两个指针,一头一尾,往中间靠,> target 右边指针左一,< target 左边指针右移, 直到找到为止。注意找到后要把小的放前面,打的放后面,这是题目的要求。