问题表示提供一个整数数组nums,以及一个目标target,要找到两个下标i与j,使得nums[i] + nums[j] = target。
最简单的思路是两次循环:
for a in nums
for b in nums
if a + b = target then
return [a.index, b.index]
这样的代码的时间复杂度是O(n^2),其中n表示nums的长度。当n为1e4时,执行时间高达?e8,其中?是一个有上界的数值。
可以利用排序和二分查找优化这一过程:
sort(nums)
for a in nums
b = target - a
bIndex = binarySearch(nums, b)
if bIndex >= 0 then
return [a.index, bIndex]
这样代码的时间复杂度为排序时间复杂度+nx二分查找时间复杂度,这里采用归并排序来排序,因此结果为O(nlogn)+nxO(logn)=O(nlogn)。当n为1e4时,执行时间为?e5左右,其中?是一个有上界的数值。
最后贴上Java的完整实现代码给有需要的人:
package cn.dalt.leetcode; import java.util.Arrays; import java.util.Comparator; public class TwoSum { public static void main(String[] arg) { System.out.println(Arrays.toString( new TwoSum().twoSum(new int[]{3, 3}, 6) )); } static class Element { final int num; final int index; public Element(int num, int index) { this.num = num; this.index = index; } @Override public int hashCode() { return num; } @Override public boolean equals(Object obj) { return num == ((Element) obj).num; } } static final Comparator<Element> ELEMENT_COMPARATOR = new Comparator<Element>() { @Override public int compare(Element o1, Element o2) { return o1.num > o2.num ? 1 : o1.num < o2.num ? -1 : 0; } }; public int[] twoSum(int[] nums, int target) { Element[] elements = new Element[nums.length]; for (int i = 0, bound = nums.length; i < bound; i++) { elements[i] = new Element(nums[i], i); } //Sort the array with ascending order Arrays.sort(elements, ELEMENT_COMPARATOR); //Quickly find solution with binarysearch for (int i = 0, bound = elements.length; i < bound; i++) { Element a = elements[i]; Element b = new Element(target - a.num, -1); if (a.num == b.num) { if (i < elements.length - 1 && elements[i + 1].num == a.num) { return new int[]{a.index, elements[i + 1].index}; } } int bindex = Arrays.binarySearch(elements, b, ELEMENT_COMPARATOR); if (bindex >= 0) { return new int[]{a.index, elements[bindex].index}; } } return null; } }