求数组中是否存在某几个数相加等于s?
这里我使用的是Java实现:
使用递归实现
public class Test1 {
public static void main(String[] args) {
int[] arr={3,34,4,12,5,2,0};
System.out.println(dp_subset(arr,9));
System.out.println(dp_subset(arr,10));
System.out.println(dp_subset(arr,11));
System.out.println(dp_subset(arr,13));
}
/**
*使用递归实现
* @param arr 所需数组
* @param i 数组的下标
* @param s 还需要的数
* @return
*/
public static Boolean opt(int[] arr,int i,int s) {
if (s == 0) {
//如果当前s已经为0 那么直接返回true
return true;
} else if (i==0) {
//如果数组下标已经到0了,就判断此时数组的值是否等于s,若是,则返回true
return arr[i]==s;
} else if (arr[i] > s) {
//如果当前数组大于s,那么就直接进入上一层判断
return opt(arr, i - 1, s);
} else {
//取当前数组的值
Boolean A = opt(arr, i - 1, s - arr[i]);
//不取当前数组的值
Boolean B = opt(arr, i - 1, s);
if(A || B){
//如果A 或 B中有一个为true 则返回true
return true;
}
}
return false;
}
使用动态规划实现
/**
* 使用动态规划实现
* @param arr
* @param S
* @return
*/
public static boolean dp_subset(int[] arr, int S) {
//定义一个二维数组,行代表数组的下标
// 列代表从0开始的S
boolean[][] subset = new boolean[arr.length][S+1];
for(int i = 0;i<S+1;i++) {
/**
* 将第一行所有值都先设置为false
*/
subset[0][i] = false;
}
for(int i = 0;i<arr.length;i++) {
/**
* 当s=0时,每一行的第一个值都可取
* 将每一行的第一个值都设置为true
*/
subset[i][0] = true;
}
// if(S>=arr[0]) {
subset[0][arr[0]]=true;
// }
for(int i = 1;i<arr.length;i++) {
for(int s=1;s<S+1;s++) {
//遍历二维数组
if(arr[i] >s){
/**
* 若当前数组值大于所需s
* 则直接进入下一层判断
*/
subset[i][s] = subset[i-1][s];
}
else {
/**
* 是否取当前数组的值
* a代表取值
* b代表不取,直接进入下一层判断
*/
boolean a = subset[i-1][s-arr[i]];
boolean b = subset[i-1][s];
subset[i][s] = a||b;
}
}
}
return subset[arr.length-1][S];
}