题目: Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
解题思路:
最直接的就是暴力法。两层循环搞定。时间复杂度o(n^2),空间复杂度o(1)。
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result=new int[2];
for(int i=0;i<nums.length;i++)
{
for(int j=i+1;j<nums.length;j++)
{
if(target==(nums[i]+nums[j]))
{
result[0]=i;
result[1]=j;
return result;
}
}
}
return null;
}
}
运行时间38 ms。排在39.15%。
o(n^2)的答案还是太慢了。再优化一下。可以利用java的集合类HashMap。把数组中的值当作key,数组下标作为value。遍历数组,如果目标值与当前值的差值不在HashMap中则把当前值添加到HashMap中。否则返回正确结果。时间复杂度o(n),空间复杂度o(n)。
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result=new int[2];
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++)
{
Integer value=target-nums[i];
if(map.containsKey(value))
{
result[0]=map.get(value);
result[1]=i;
return result;
}
map.put(nums[i], i);
}
return result;
}
}
运行时间 8 ms。排在91.85%。可以看到这里也是一个峰值点,说明很多人也是这么做的。想进99%,还得有更优化的算法。
由于前面的解法已经是o(n)的了。所以只能先从编程技巧的角度来考虑一下。代码中有一个计算diff的计算。这里涉及到了类型转换。diff 的结果是int类型的,而定义的变量是Integer类型的。加上一个强制类型转换会快一些。
class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] result=new int[2];
HashMap<Integer,Integer> hash = new HashMap<Integer,Integer>();
for(int i = 0; i < numbers.length; i++){
Integer diff = (Integer)(target - numbers[i]);
if(hash.containsKey(diff)){
result[0]=hash.get(diff);
result[1]=i;
return result;
}
hash.put(numbers[i], i);
}
return null;
}
}
加上强制类型转换后,运行时间为7ms,排在98.68%。
最后再贴一个运行时间再6ms,排在99.61%的code。
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums == null)
return null;
int[] nums2 = Arrays.copyOf(nums, nums.length);
Arrays.sort(nums2);
int a = 0, b = 0;
int start = 0, end = nums2.length-1;
while(start<end){
int sum = nums2[start] + nums2[end];
if(sum < target)
start++;
else if(sum > target)
end--;
else{
a = nums2[start]; b = nums2[end];
break;
}
}
int[] res = new int[2];
for(int i = 0; i < nums.length; i++){
if(nums[i] == a){
res[0] = i;
break;
}
}
if(a != b){
for(int i = 0; i < nums.length; i++){
if(nums[i] == b){
res[1] = i;
break;
}
}
} else{
for(int i = 0; i < nums.length; i++){
if(nums[i] == b && i != res[0]){
res[1] = i;
break;
}
}
}
return res;
}
}