zoukankan      html  css  js  c++  java
  • K Sum

    Given n distinct positive integers, integer k (k <= n) and a number target.

    Find k numbers where sum is target. Calculate how many solutions there are?

    Example

    Given [1,2,3,4], k = 2, target = 5.There are 2 solutions: [1,4] and [2,3].Return 2.

    这是sum一系列问题中的终极版本,即求给出的n个数字中,取其中k个数字,最终和为target的组合有多少。

    注意这题问的是有多少,并不是要求给出所有的符合条件的k个数组的全部组合。按照前面的2 sum, 3sum, 4sum等题推理如果采用排序加双指针夹逼的方法,复杂度是O(n^(k-1))的,如果采用4sum这种利用2sum hashmap的做法,则最优的复杂度为有降低,但是4sum这种已经很复杂,对于更大的k为偶数的情况,会变得特别复杂。以上分析可以看出DP是这时候的好选择。

    首先看这题本身的描述,n个取k个,组成和为target的情况,其实看描述非常像背包问题,容量是这里的target,但是背包问题本身不要求知道一共是多少个物体组成,且不需要知道方案数,所以二维的DP无法解决。我们可以定义3维的DP状态:f[i][j][t]即前i个字母中取出j个能组成和为t的情况的种数。

    定义转换状态:f[i][j][t] = f[i-1][j][t] + f[i-1][j-1][t-nums[i-1]]和背包问题一样,我们需要对取不取第i 个数字做一个判断。

    初始化,这个是最tricky的地方,究竟如何初始化才对。首先数组中的所有的数字都是正数,且都不相同。所以f[i][1][A[i-1]]应该都是1. f[i][1][A[j]] = f[i-1][1][A[i]]+f[i-1][0][0], f[i-1][1][A[i]]肯定是0,所以f[i-1][0][0]的值是1.可以先进行初始化。

    最后的结果是f[n][k][target].复杂度为O(k*n*target).上述空间复杂度可以采用滚动数组优化为二维的(在n这一维度进行优化)。

    代码如下:

    class Solution:
        """
        @param A: An integer array.
        @param k: a positive integer (k <= length(A))
        @param target: integer
        @return an integer
        """
        def kSum(self, A, k, target):
            n = len(A)
            dp = [[[0] * (target+1) for i in xrange(k+1)] for j in xrange(n+1)]
            for i in xrange(0, n+1):
                dp[i][0][0] = 1
            for i in xrange(1, n+1):
                for j in xrange(1, min(k+1,i+1)):  #j的范围一定要注意
                    for t in xrange(1, target+1):
                        if t < A[i-1]:
                            dp[i][j][t] = dp[i-1][j][t]
                        else:
                            dp[i][j][t] = dp[i-1][j][t] + dp[i-1][j-1][t-A[i-1]]
            
            
            return dp[n][k][target]

    这题三维的滚动数组优化比较困难,尝试了几次都有问题。后序再说。

    这题难度比较高,面试中出现的概率比较低,但仍然是一道不错的DP题。

  • 相关阅读:
    分享一个难得的YiBo微博客户端应用源码Android版
    js的cookie操作及知识点详解
    c#中out参数的作用
    取消安卓listview,scrollview,gridview滑动时候边缘模糊问题
    分块+deque维护 Codeforces Round #260 (Div. 1) D. Serega and Fun
    并发
    感想
    windows服务器允许MySQL远程连接
    C. Vasya And The Mushrooms
    cf1017 D. The Wu
  • 原文地址:https://www.cnblogs.com/sherylwang/p/5626291.html
Copyright © 2011-2022 走看看