目标和题目的思路探讨与源码
目标和的题目如下图,该题属于数组和动态规划类型的题目,主要考察对于数组和动态规划方法的使用和理解。本文的题目作者想到2种方法,分别是动态规划方法和深度优先搜索DFS方法,其中深度优先搜索方法使用java进行编写,而动态规划方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用深度优先搜索的方法,首先我们建立一个map去保存当前值的数组下标。然后开始遍历,每次遍历都输入数组,目标值,当前下标等参数,以下标和计算结果作为KEY去判断map里是否有这个值,如果有就返回。然后去判断下标是否到数组的最后一位,如果是则判断计算结果和目标值是否相等,并且把结果放入到map里面并返回,否则就继续进行深度优先搜索,并且把搜索的结果放入到map里面。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public int findTargetSumWays(int[] nums, int t) {
return searchDFS(nums, t, 0, 0);
}
Map<String, Integer> map = new HashMap<>();
int searchDFS(int[] nums, int t, int jr, int ind) {
String key = jr+"#"+ind;
if (map.containsKey(key)) {
return map.get(key);
}
if (jr == nums.length) {
int v = -1;
if(ind==t){
v = 1;
}else{
v = 0;
}
map.put(key,v);
return map.get(key);
}
int a = searchDFS(nums,t,(jr+1),(ind + nums[jr]));
int b = searchDFS(nums,t,(jr+1),(ind - nums[jr]));
map.put(key,(a+b));
return map.get(key);
}
}
显然,我们还可以使用动态规划的方法进行处理,首先计算数组和以及与目标差值,然后判断目标差值是否小于0或者是奇数,如果满足条件则直接返回,然后开始初始化动态规划数组,并且把数组的第一个值赋值为1,然后开始遍历数组,通过动态规划方程dp[kr] = dp[kr] + dp[kr-jr]进行计算,并且把下标减1,通过该方法遍历后最终返回结果。所以根据这个思路就可以写出代码,下面是Python代码部分:
#喷火龙与水箭龟
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
sum = 0
for ij in nums:
sum = sum + ij
ps = sum - target
if(ps < 0 or ps % 2 !=0):
return 0
ns = int(ps / 2)
dpArr = [0 for x in range(0,ns+1)]
dpArr[0] = 1
for jr in nums:
kr = ns
while kr >=jr:
dpArr[kr] = dpArr[kr] + dpArr[kr-jr]
kr = kr -1
return dpArr[ns]
从结果来说java版本的深度优先搜索方法的速度比较一般,而python版本的动态规划方法的速度不错,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。