递归和动态规划——整数和
给你一个数组arr, 和一个整数aim。 如果可以任意选择arr中的数字, 能不能累加得到aim, 返回true或者false
类似于字符串的子串,数组中的每个数字都可以在求和结果中,也可以不在
所以使用递归可以求得
public static boolean isSum(int[] arr, int aim){
if(arr.length == 0 || arr == null) return false;
return sum(arr, aim, 0, 0);
}
public static boolean sum(int[] arr, int aim, int index, int res){
if(index == arr.length){
return aim == res;
}
return sum(arr, aim, index + 1, res + arr[index]) || sum(arr, aim, index + 1, res);
}
改为动态规划:
* dp维度:位置index和当前的求和结果res,所以dp[arr.length + 1][aim + 1]是二维的(因为在分析可变参数时,最终的返回结果是i == arr.length,会碰到最后一行,所以长度要+1)
* 行代表数组中的第几个元素,列代表求和的结果
* 普通位置(i, j)依赖的位置有(i + 1, arr[i] + j)和(i + 1, j)
public static boolean isSum2(int[] arr, int aim){
if(arr.length == 0 || arr == null) return false;
boolean[][] dp = new boolean[arr.length + 1][aim + 1];
//在最后一行其余位置上的值均不为aim,所以就是false
for(int i = 0; i < aim; i++){
dp[arr.length][i] = false;
}
//不被依赖的位置 (arr.length, aim)是true
dp[arr.length][aim] = true;
for(int i = arr.length - 1; i >= 0; i--){
for(int j = aim; j >= 0; j--){
dp[i][j] = dp[i + 1][j];
if(arr[i] + j <= aim){
dp[i][j] = dp[i][j] || dp[i + 1][j + arr[i]];
}
}
}
return dp[0][0];
}

浙公网安备 33010602011771号