leetcode-494 目标和,cache的选择

  题目如上。

  我们假定,求从 nums 数组第 flag 位置开始目标和为 S 的组合数的函数为:G(nums, S, flag) 。

  那么状态转移方程的表示为:G(nums, S, flag) = G(nums,S-nums[flag],flag+1) + G(nums,S+nums[flag],flag+1) 。一个背包类问题。

  递归表示很好实现:

    public int recursion(int[] nums, int S, int flag){
        if (flag == nums.length) {
            if (S == 0) {
                return 1;
            }
            return 0;
        }
        return recursion(nums,S-nums[flag],flag+1)+recursion(nums,S+nums[flag],flag+1);
    }

  相应的,指数级时间复杂度,回归过程中存在非常多的重复计算。需要用缓存优化掉这些重复计算。

  问题就在于,如果要建立缓存,缓存需要有两个维度:S 和 flag 。我们需要沿着这两个维度前进推演最终结果,但不能用简单的二维数组建立缓存。

  因为 S 的取值范围是不固定的,最大值为 S 与 nums 中所有元素的和,最小值为 nums 中所有元素的差,且可能存在负值。

  官方题解中,将 S 加 1000,使 S 全部映射到正数空间中。

  但我认为,无论问题规模的大小,直接申请长度为 1000 的连续数组空间比较浪费,更倾向于一维数组结合哈希表的方式构建缓存。

  nums 由一维数组存储,存储的元素为一张哈希表,哈希表中存储 nums 对应的 S 的解:

    public int findTargetSumWays(int[] nums, int S) {
        if (nums == null) {
            return 0;
        }
        Map<Integer, Integer>[] dpCache = new Map[nums.length];
        return dp(nums, S, 0, dpCache);
    }

    /**
     * @Author Nxy
     * @Date 2020/4/28
     * @Description G(nums, S, flag)
     * G(nums,S-nums[flag],flag+1)+G(nums,S+nums[flag],flag+1)
     */
    public int dp(int[] nums, int S, int flag, Map<Integer, Integer>[] dpCache) {
        if (flag == nums.length) {
            if (S == 0) {
                return 1;
            }
            return 0;
        }
        if (dpCache[flag] != null) {
            Map<Integer, Integer> map = dpCache[flag];
            if (map.keySet().contains(S)) {
                return map.get(S);
            }
            int tempRe = dp(nums, S - nums[flag], flag + 1, dpCache) + dp(nums, S + nums[flag], flag + 1, dpCache);
            map.put(S, tempRe);
            return tempRe;
        }
        dpCache[flag] = new HashMap<Integer, Integer>();
        int tempRe = dp(nums, S - nums[flag], flag + 1, dpCache) + dp(nums, S + nums[flag], flag + 1, dpCache);
        dpCache[flag].put(S, tempRe);
        return tempRe;
    }

 

  

  

posted @ 2020-04-29 16:39  牛有肉  阅读(217)  评论(0编辑  收藏  举报