结果
代码如下:
class Solution {
public int[] twoSum(int[] nums, int target) {
if(nums.length<=2){
int []resutl = new int[2];
for(int i = 0;i < nums.length;i++){
int now = nums[i];
for(int j = i+1;j< nums.length;j++){
int next = nums[j];
if(now+next==target){
resutl[0] = i;
resutl[1] = j;
return resutl;
}
}
}
return resutl;
}
Map<Integer, LinkedList<Integer>> map = new HashMap<>();
for(int i = 0;i < nums.length;i++){
if(map.containsKey(nums[i])){
map.get(nums[i]).add(i);
}else{
LinkedList<Integer> list = new LinkedList<>();
list.add(i);
map.put(nums[i],list);
}
}
Arrays.sort(nums);
int centerIndex = -1;
int center = target/2;
boolean judge =false;
for(int i = 0;i < nums.length;++i){
if(!judge&&nums[i]==center){
judge = true;
centerIndex = i;
continue;
}
if(nums[i]>=center){
if(judge&&nums[i]==nums[i-1]){
centerIndex = i;
}else if(judge){
break;
}else{
centerIndex = i;
break;
}
}
}
int []result = new int[2];
int lowIndex = 0;
int bigIndex = nums.length-1;
int num ;
while(lowIndex<centerIndex&&bigIndex>=centerIndex){
num= nums[lowIndex];
for(int i = bigIndex;i>=centerIndex;--i){
if(num+nums[i]==target){
result[0] = map.get(num).get(0);
if(num==nums[i]){
result[1] = map.get(nums[i]).get(1);
}else{
result[1] = map.get(nums[i]).get(0);
}
return result;
}else if(num + nums[i] < target){
bigIndex = i;
break;
}
}
++lowIndex;
}
return result;
}
}
过程
代码又丑又长,不过这是因为对于题目不了解缝缝补补的结果。
主体代码思路是:先将数组排序,然后找到target一半的值(这里成为中间值,虽然有点不恰当),两个中间值的和就是target,所以可以查找可以分为两部分,一个是从小于中间值,另一个是从数组末尾向中间值查找。以小的那部分第一个值(low)为例,那么从大的那部分末尾开始查找(big),一开始low+big肯定大于等于target,如果等于就是结果,如果不是那么big就向前移(变小),当移到low+bigtarget的位置就是结果,如果low+big<target,证明这时候再移动big已经不可能target了,所以这时候移动low,让low变大,再移动big,看看是否是结果。这样两边移动速度更快一些。当然里面要考虑同一个值出现多次的情况,所以我map里面存的是list。
至于开头代码是因为数组很小的时候没有必要采用那么复杂的思路,直接暴力解就够了,数值2是试出来的结果,当然leetcode的oj时间性能是个玄学,不用太在意。