首先看到这题的题目,觉得很像以前做的组合问题,能直接找到问题的一部分解答方案,首先动态的寻找数组,省略已经读取的数组,然后不断的更新S的值,使得最后的S到数组长度为1的时候等于数组的值就可以了,这个方法是我最开始想到的方法,也就是递归一下我们的函数,不断更新数组和最后的S值就可以了,不做详细的介绍了,代码如下:
public int findTargetSumWays(int[] nums, int S) {
int res = 0;
if (nums.length >= 2) {
return findTargetSumWays(Arrays.copyOfRange(nums, 0, nums.length - 1), S+nums[nums.length-1])
+findTargetSumWays(Arrays.copyOfRange(nums, 0, nums.length - 1), S-nums[nums.length-1]);
} else {
if (nums.length == 1 && nums[0] == S) {
res++;
}
if (nums.length == 1 && nums[0] == -S) {
res++;
}
return res;
}
}
第二种方法呢,和我昨天做的动态规划差不太多,也就是复杂的01背包问题:我们设置二维数组int[][]dp=new int[i][j];这里面的i是指的我们遍历数组的元素位置,j指的是我们遍历到数组i时候得到的和。我们对于每一个i都进行所有数组的遍历,将所有数组都进行更新,最后找到和为S的即可,代码如下:
public int findTargetSumWays(int[] nums, int S) {
int[][] dp = new int[nums.length][2001];
dp[0][nums[0] + 1000] = 1;
dp[0][-nums[0] + 1000] += 1;
for (int i = 1; i < nums.length; i++) {
for (int sum = -1000; sum <= 1000; sum++) {
if (dp[i - 1][sum + 1000] > 0) {
dp[i][sum + nums[i] + 1000] += dp[i - 1][sum + 1000];
dp[i][sum - nums[i] + 1000] += dp[i - 1][sum + 1000];
}
}
}
return S > 1000 ? 0 : dp[nums.length - 1][S + 1000];
}
}