1.题意理解
给定一个整实数数组和一个目标数值,返回数组中满足两个整数的和等于目标数值的两个整数在数组中的下标,可以假定所有的输入有且只有一个结果。
例如:
给定数组 nums = [2, 7, 11, 15],目标数值 target = 9,
因为 nums[0] + nums[1] = 2 + 7 = 9,
所以返回 [0, 1]。
2.个人解答
public class Solution {
public int[] twoSum(int[] nums, int target) {
//定义结果数组
int[] result = new int[2];
//如果数组,如果数组长度小于2,则直接返回结果数组
if (nums == null || nums.length < 2)
return result;
//算法开始
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
result[0] = i;
result[1] = j;
break;
}
}
}
//返回结果
return result;
}
}
算法思路:此算法为暴力算法,其主要思想为从头到尾遍历数组,每次遍历到一个数组元素,就依次和该元素之后的每个元素进行求和运算,若其结果正好是目标数值,则将这两个元素的下标添加到结果数组中,并退出算法,直接返回结果。
时间复杂度:O(n^2)
3.网上参考算法
方案一:
public class Solution {
public int[] twoSum(int[] nums, int target) {
//定义结果数组
int[] result = new int[2];
//若给定的数组为空或者数组长度小于2,直接返回结果
if (nums == null || nums.length < 2)
return result;
//定义HashMap对象
Map<Integer,Integer> hashMap = new HashMap<Integer,Integer>();
//算法开始
for (int i = 0; i < nums.length; i++) {
if (!hashMap.containsKey(target - nums[i])) {
hashMap.put(nums[i], i);
} else {
result[0] = hashMap.get(target - nums[i]);
result[1] = i;
}
}
//返回结果
return result;
}
}
算法思路:这种算法的主要思想就是利用Map这种数据结构来简化运算,降低时间复杂度,在Java中是利用HashMap类来实现。在HashMap对象中,key值为数组中个各个数值,value值为其对应的数组下标index,开始时HashMap对象为空。当遍历数组时,首先检查HashMap对象中是否存在以target-nums[i]为key值得元素,即若当前所遍历的数组元素为一个答案,那么另一个答案是是否存在于在该元素之前的数组中,若存在,则结束循环,输出这两个结果;若不存在,则将这个数组元素和它所对应的数组下标index存入HashMap对象中,继续继续进行遍历,查看下一个数组元素。
时间复杂度:由于只是遍历一遍数组,所以时间复杂度是O(n),但相应的空间复杂度是O(n)
方案二:
public class Solution {
public int[] twoSum(int[] nums, int target) {
//定义结果数组
int[] result = new int[2];
//若给定的数组为空或者数组长度小于2,直接返回结果
if (nums == null || nums.length < 2)
return result;
//复制给定的数组
int[] copyNums = new int[nums.length];
System.arraycopy(nums, 0, copyNums, 0, nums.length);
//对复制的数组进行排序
Arrays.sort(copyNums);
//创建两个指针,分别指向复制数组的第一个元素和最后一个元素
int low = 0;
int high = nums.length - 1;
//算法开始
while (low < high) {
if (copyNums[low] + copyNums[high] < target)
low++;
else if (copyNums[low] + copyNums[high] > target)
high--;
else {
result[0] = copyNums[low];
result[1] = copyNums[high];
break;
}
}
//在原来的数组中找到目标的两个数字的下标
int index1 = -1, index2 = -1;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == result[0] && index1 == -1)
index1 = i;
else if (nums[i] == result[1] && index2 == -1)
index2 = i;
}
result[0] = index1;
result[1] = index2;
Arrays.sort(result);
//返回结果
return result;
}
}
算法思路:这种算法的主要思想是就是对给定的数组进行排序,然后用二分查找的方法来找到答案。首先,需要对给定的数组进行排序,因为原数组不能改变,所以先将原数组进行复制,对复制的数组进行排序;第二步,定义两个指针low和high,分别指向排序好的数组中的第一个元素和最后一个元素,用二分查找的方式来进行查找答案;第三步,找到答案之后,从原数组中查找这答案中的两个数字的下标index,最后返回结果即可。
时间复杂度:数组进行复制的时间复杂度为O(n),对复制后的数组进行排序需要时间O(nlogn),二分查找的时间为O(n),最后遍历原数组找到指定下标Index的时间为O(n),所以总的世间复杂度为O(n+nlogn+n+n)=O(nlogn)