判断数组中是否存在若干元素和为目标值问题
视频地址
将其变成选和不选问题
找到递归出口
递归版本
public class Test {
public static boolean rec_subset(int[] arr, int len,int s) {
if(s==0)
return true;
else if(len==0)
return arr[0]==s;
else if(arr[len]>s)
return rec_subset(arr, len-1, s);
else {
boolean A=rec_subset(arr, len-1, s-arr[len]);
boolean B=rec_subset(arr, len-1, s);
return A||B;
}
}
public static void main(String[] args) {
int[] array = {3,34,4,12,5,2};
int length = array.length-1;
System.out.println(rec_subset(array,length,9));
}
}
非递归版本
用一个数组来保存中间的所有动态过程。先填出口,第一列(s=0)全为true,第一列除了arr[0]=s全为false。然后一行行的填,填到最后一个元素得出结果。
public class Test {
public static boolean dp_subset(int[] arr,int S) {
boolean[][] subset = new boolean[arr.length][S+1];
for(int i = 0;i<arr.length;i++) {
subset[i][0] = true;
}
for(int i = 0;i<S+1;i++) {
subset[0][i] = false;
}
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)
subset[i][s]=subset[i-1][s];
else {
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];
}
public static void main(String[] args) {
int[] array = {3,34,4,12,5,2};
System.out.println(dp_subset(array,9));
}
}