解法一:首先想到的是循环,从第一个数开始,1+2,1+3....1+n; 2+3,2+4...2+n;执行结果通过,但是时间是57ms。
注意的点:
1)、在剑指offer上看到,要判断输入是否为空,所以判断了一下null != nums。
2)、LeetCode上没有提示,要注意数组的长度是nums.length,而不是nums.length()。
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] area = new int[2];
int source = 0;
int testTarget = 0;
if(null != nums){
for(int i = 0; i < nums.length; i++){
source = nums[i];
for(int j = i + 1; j < nums.length; j++){
testTarget = source + nums[j];
if(testTarget == target){
area[0] = i;
area[1] = j;
return area;
}
}
}
}
return null;
}
}
解法二:官方给的最优解,一次hash。通过,执行时间7s。
将 目标值 - nums[i] 保存在map中,判断结果是否已存在于map,若存在获取结果与nums[i]的下标并返回。
由于返回的是下标,所有在map中保存时key是nums[i],value为i。
要注意的点:
1)、throw new Exception会编译失败,需要处理此异常。而throw new IllegalArgumentException就不会,因为IllegalArgumentException是运行时异常,编译不会报错。(除了RuntimeException及其子类,其他的Exception及其子类是非运行时异常,编译器检测)。
2)、map.containsKey(); map.containsValue();
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
int com = 0;
if(null != nums){
for (int i = 0; i < nums.length; i++){
com = target - nums[i];
if(map.containsKey(com)){
return new int[]{map.get(com),i};
}
map.put(nums[i],i);
}
}
throw new IllegalArgumentException("No two sum solution");
}
}
选择hash表的原因(LeetCode官方题解中的说法):
hash表是保存数组中每个元素与其索引相互对应最好的方式。
hash表查找时间为O(1),它支持以“近似”恒定的时间进行快速查找。“近似”:一旦出现冲突,查找用时可能会退化到O(n)--java8以后引入红黑树查找用时最多为O(log n),但只要挑选合适的hash函数,在hash表中进行查找的用时应当被摊销为O(1)。