动态规划
指定数组中找到所有的和为指定值的数组java实现
简单粗暴的方案是多重循环遍历,但该方案的运行时间,会随着数组长度的增加而指数性的增加其运行的时间复杂度为O(nn)。
相对来说更好一点的方案是使用动态规划,在循环遍历的过程中,每一次循环时,都不处理上一次已完成循环遍历的数字,并且将循环过程中的数字记录到数组中,如此时间复杂度可达到nn-1n-2*…*1 相较于O(nn)有所减少(依然很大),但是如果先将数组排序,则复杂度会再次降低(不同的排序算法处理时间复杂度也不同,但排序的复杂度小于n2加上优化后的动态规划算法,大多数情况下会更快),如下代码是假定已完成排序后使用递归查找数组。
public static void main(String[] args) {
int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40};
int target = 15;
int[] dpArr = new int[0];
List<int[]> targetArr = new ArrayList<>();
handle(arr, dpArr, target , 0, targetArr);
}
private static void handle(int[] arr, int[] dpArr, int target, int count, List<int[]> targetArr) {
for (int i = count; i < arr.length; i++) {
if (count >= arr.length) {
return;
}
int[] temp = new int[dpArr.length + 1];
System.arraycopy(dpArr, 0, temp, 0, dpArr.length);
temp[dpArr.length] = arr[i];
int dp = getSum(temp);
if (dp < target) {
count = count + 1;
} else if (dp == target) {
targetArr.add(temp);
// 若数组未排序可放开当前注释的代码,并注释掉return行
//temp = dpArr;
//count = count + 1;
return;
} else {
// 若数组未排序可放开当前注释的代码,并注释掉return行
//temp = dpArr;
//count = count + 1;
return;
}
handle(arr, temp, target, count, targetArr);
}
}
private static Integer getSum(int[] arr) {
int num = 0;
for (int i = 0; i < arr.length; i++) {
num += arr[i];
}
return num;
}