本来以为是一道水题,结果居然能从n^2, n*log(n)一直优化到n。感慨啊~
O(n^2): 暴力
public class Solution { public int[] twoSum(int[] numbers, int target) { // Start typing your Java solution below // DO NOT write main() function int[] r = new int[2]; for (int i = 0; i < numbers.length; i++) { for (int j = i+1; j < numbers.length; j++) { if (numbers[i] + numbers[j] == target) { r[0] = i+1; r[1] = j+1; break; } } } return r; } }
O(n*log(n)): 排序。用了O(n)的空间记录原来的数组,然后开始和最后O(n)的扫一遍,不过不改变总体复杂度。当然有的人用数据结构记录原来的和后来的联系,那也就是另外O(n)的空间省最后扫一遍而已。解题过程中一开始忘了记录原来的数组,后来忘了排序后的第一第二和排序后的也可能不同。
import java.util.Arrays; public class Solution { public int[] twoSum(int[] numbers, int target) { // Start typing your Java solution below // DO NOT write main() function int[] result = new int[2]; int[] tmp = new int[numbers.length]; for (int i = 0; i < numbers.length; i++) { tmp[i] = numbers[i]; } Arrays.sort(tmp); int l = 0; int r = tmp.length - 1; int sum = tmp[l] + tmp[r]; while( sum != target && r > l) { if (sum > target) { r--; } else { l++; } sum = tmp[l] + tmp[r]; } int index = 0; for (int i = 0; i < numbers.length; i++) { if (tmp[l] == numbers[i] || tmp[r] == numbers[i]) { result[index] = i + 1; index++; if (index > 1) break; } } return result; } }
O(n): 果然无耻的用了Hash,那么也就不神奇了。所以真实的复杂度考虑到Hash的实现,会比O(n)要大些。
import java.util.HashMap; public class Solution { public int[] twoSum(int[] numbers, int target) { // Start typing your Java solution below // DO NOT write main() function int[] result = new int[2]; HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int i = 0; i < numbers.length; i++) { if (map.containsKey(target - numbers[i])) { result[0] = map.get(target-numbers[i]) + 1; result[1] = i + 1; break; } else { map.put(numbers[i], i); } } return result; } }