1. 题目链接:494. 目标和
2. 题目描述:
给你一个非负整数数组
nums和一个整数target。向数组中的每个整数前添加
'+'或'-',然后串联起所有整数,可以构造一个 表达式 :
- 例如,
nums = [2, 1],可以在2之前添加'+',在1之前添加'-',然后串联起来得到表达式"+2-1"。返回可以通过上述方法构造的、运算结果等于
target的不同 表达式 的数目。示例 1:
输入:nums = [1,1,1,1,1], target = 3 输出:5 解释:一共有 5 种方法让最终目标和为 3 。 -1 + 1 + 1 + 1 + 1 = 3 +1 - 1 + 1 + 1 + 1 = 3 +1 + 1 - 1 + 1 + 1 = 3 +1 + 1 + 1 - 1 + 1 = 3 +1 + 1 + 1 + 1 - 1 = 3示例 2:
输入:nums = [1], target = 1 输出:1提示:
1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000
3. 解法(回溯):
3.1 算法思路:
对于每个数,可以选择加上或减去它,依次枚举每一个数字,在每个数都被选择时检查得到的和是否等于目标值。如果等于,则记录结果。
需要注意的是,为了优化时间复杂度,可以提前计算出数组中所有数字的和,以及数组的长度。这样可以快速判断当前的和减去剩余的数是否已经超过了目标值target,或者当前的和加上剩下的数的和是否小于目标值target,如果满足条件,则可以直接回溯
3.2 递归流程:
-  递归结束条件: pos与数组长度相等,判断当前状态的path是否与目标值相等,若是计数加一
-  选择当前元素进行加操作,递归下一个位置,并更新参数 path
-  选择当前元素进行减操作,递归下一个位置,并更新参数 path

3.3 C++算法代码:
class Solution {
    int ret, aim; // ret用于记录满足条件的路径数量,aim用于存储目标和
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        aim = target; // 初始化目标和
        dfs(nums, 0, 0); // 从数组的第一个元素开始搜索
        return ret; // 返回满足条件的路径数量
    }
    void dfs(vector<int>& nums, int pos, int path) {
        if (pos == nums.size()) { // 如果已经遍历完数组
            if (path == aim) ret++; // 如果当前路径的和等于目标和,则增加满足条件的路径数量
            return; // 结束当前递归
        }
        dfs(nums, pos + 1, path + nums[pos]); // 选择当前元素,将其加入路径中,继续搜索下一个元素
        dfs(nums, pos + 1, path - nums[pos]); // 不选择当前元素,将当前元素从路径中移除,继续搜索下一个元素
    }
};



















