1. 在一个既定的数组中,给定一个目标值,判断数组中是否存在和为给定数的元素。
例如,数组array={1,5,2,6,8,13}, 指定的目标值target=10,那么可以找到的array中的元素为2和8。
solution:
如果使用两次遍历,算法的时间复杂度是O(n*n)。如果是先排序,再使用两个指针分别从数组头和尾
部依次遍历,那么算法的时间复杂度度是O(nlogn)。具体来说如果两个指针对应的元素的和大于target,
那么尾指针向前移动;如果两指针对应的元素和小于target,首指针向后移动。具体的代码实现如下所示:
import java.util.Arrays;
public class question1 {
boolean hasSum(int[] array, int target) {
boolean result = false;
if (array == null || array.length < 2)
return result;
else {
Arrays.sort(array);
int i = 0, j = array.length - 1;
while (i < j) {
if (array[i] + array[j] == target) {
result = true;
break;
} else if (array[i] + array[j] > target)
j--;
else
i++;
}
}
return result; return result
}
solution:
如果采用1的解法,算法的时间复杂度只有O(nlogn)。要让算法的时间复杂度为O(n),可以使用hash函数。
两遍遍历给定的数组,第一次遍历将数组元素和index以Key-Value的形式存入hash表中。第二次遍历则查找目标元素
与当前元素的差是否在hash表中。由于hash表的查找时间复杂度是O(1)。所以算法的时间复杂度是两次遍历数组的时
间复杂度O(n)+O(n)=O(n)。具体的代码实现如下所示:
import java.util.HashMap;
public class question2 {
int[] twoSum(int[] array,int target){//return一个表示index的数组
int [] result={-1,-1};
if(array==null||array.length<2)return result;
else{
HashMap<Integer,Integer>hm=new HashMap<Integer,Integer>();//声明并指向一个HashMap集合的引用
for(int i=0;i<array.length;i++){//第一次遍历数组,将元素和下标以K-V方式存入hm中
hm.put(array[i], i);//HashMap#void put(K key,V value)
}
for(int i=0;i<array.length;i++){//第二次遍历数组,查找是否有和为target的元素对
if(hm.containsKey(target-array[i])&&(i!=hm.get(target-array[i]))){
//保证两个元素不是同一个,否则如果target恰好是某个元素的2倍时就不符合题意
//HashMap#boolean containsKey(Object key)
//HashMap#public V get(Object key){...return value;}
result[0]=i;
result[1]=hm.get(target-array[i]);
break;
}
}
}
return result;
}
}
例如,数组array={1,5,2,6,8,13}, 指定的目标值target=10,那么可以找到的array中的元素为2和8。
solution:
如果使用两次遍历,算法的时间复杂度是O(n*n)。如果是先排序,再使用两个指针分别从数组头和尾
部依次遍历,那么算法的时间复杂度度是O(nlogn)。具体来说如果两个指针对应的元素的和大于target,
那么尾指针向前移动;如果两指针对应的元素和小于target,首指针向后移动。具体的代码实现如下所示:
import java.util.Arrays;
public class question1 {
boolean hasSum(int[] array, int target) {
boolean result = false;
if (array == null || array.length < 2)
return result;
else {
Arrays.sort(array);
int i = 0, j = array.length - 1;
while (i < j) {
if (array[i] + array[j] == target) {
result = true;
break;
} else if (array[i] + array[j] > target)
j--;
else
i++;
}
}
return result; return result
}
}
solution:
如果采用1的解法,算法的时间复杂度只有O(nlogn)。要让算法的时间复杂度为O(n),可以使用hash函数。
两遍遍历给定的数组,第一次遍历将数组元素和index以Key-Value的形式存入hash表中。第二次遍历则查找目标元素
与当前元素的差是否在hash表中。由于hash表的查找时间复杂度是O(1)。所以算法的时间复杂度是两次遍历数组的时
间复杂度O(n)+O(n)=O(n)。具体的代码实现如下所示:
import java.util.HashMap;
public class question2 {
int[] twoSum(int[] array,int target){//return一个表示index的数组
int [] result={-1,-1};
if(array==null||array.length<2)return result;
else{
HashMap<Integer,Integer>hm=new HashMap<Integer,Integer>();//声明并指向一个HashMap集合的引用
for(int i=0;i<array.length;i++){//第一次遍历数组,将元素和下标以K-V方式存入hm中
hm.put(array[i], i);//HashMap#void put(K key,V value)
}
for(int i=0;i<array.length;i++){//第二次遍历数组,查找是否有和为target的元素对
if(hm.containsKey(target-array[i])&&(i!=hm.get(target-array[i]))){
//保证两个元素不是同一个,否则如果target恰好是某个元素的2倍时就不符合题意
//HashMap#boolean containsKey(Object key)
//HashMap#public V get(Object key){...return value;}
result[0]=i;
result[1]=hm.get(target-array[i]);
break;
}
}
}
return result;
}
}