【每天一算法】给定一个整数数组,找出其中两个数相加等于目标值

要求:这个函数twoSum必须要返回能够相加等于目标数字的两个数的索引,且index1必须要小于index2。
* 请注意一点,你返回的结果(包括index1和index2)都不是基于0开始的。你可以假设每一个输入肯定只有一个结果。
题目的要求是给定一个数组,找出数组中和为一定值的两个数。也就是给定一定值target,从数组中要找出a+b=target。等式转换一下,我们可以知道,a=target-b。所以我们要做的事情可以翻译为,找到一个数a,满足a与target-a都在数组之中。
第一个思路,遍历数组中的某一个数,对于每个数再一次遍历数组中的所有数,找到满足条件的两个数。这个算法的时间复杂度为O(n2),空间复杂度为O(1)。
第二个思路,在前一个算法的基础上降低时间复杂度。我们可以将数组排序,然后定义两个指针,一个指针从左向右,另一个从右向左,遍历直到找到满足条件的两个数。
由于排序的最佳时间复杂度为O(nlogn),两个指针的遍历时间复杂度为O(n)。所以总的时间复杂度为O(nlogn)
第三个思路,我希望通过O(n)的时间复杂度完成要求。第一遍O(n)的算法将每个数据a对应的target-a建立查询的数据结构,例如Hash表;第二遍遍历时,查询每个数
是否在Hash表中,每次查询时间复杂度为O(1),总的时间复杂度是O(n)。但是Hash表将需要一定的存储空间,为了节省空间,我们可以采用bitmap的方法来最大化的压
缩空间复杂度。

第二个思路

public int[] sum(int[] nums, int target) {
int[] result = {0, 0};

Node[] tmp = new Node[nums.length];
for (int i = 0; i < nums.length; i++) {
tmp[i] = new Node(nums[i], i+1);
}

Arrays.sort(tmp);

int lo = 0;
int hi = nums.length - 1;


while (lo < hi) {
if (tmp[lo].val + tmp[hi].val == target) {

if (tmp[lo].idx > tmp[hi].idx) {
result[0] = tmp[hi].idx;
result[1] = tmp[lo].idx;
} else {
result[0] = tmp[lo].idx;
result[1] = tmp[hi].idx;
}
break;
} else if (tmp[lo].val + tmp[hi].val > target) {
hi--;
} else {
lo++;
}
}
return result;
}

第三个思路 话说当年面试被这个难住了-。-

public int[] sum(int[] numbers, int target) {
HashMap map = new HashMap();
for(int i = 0; i < numbers.length; i++) map.put(numbers[i], i+1);
for(int i = 0; i < numbers.length; i++){
int value = target - numbers[i];
if(map.containsKey(value) && map.get(value) != i+1){
int index = map.get(value) ;
if(i+1 < index) return new int[]{i+1, index};
return new int[]{index, i+1};
}
}
return new int[0];
}

你可能感兴趣的:(【每天一算法】给定一个整数数组,找出其中两个数相加等于目标值)