其和可被k除

时间:2019-01-05 01:19:13

标签: python algorithm recursion dynamic-programming

我刚为一家公司进行编码挑战,但无法解决此问题。问题陈述如下:

给出一个整数数组,找到该数组中总和可以被k整除的子序列数,其中k是某个正整数。

例如,对于[4, 1, 3, 2]k = 3,解为5。[[3], [1, 2], [4,3,2], [4,2], [1,3,2]]是其和可被k整除的子序列,即current_sum + nums[i] % k == 0,其中nums[i]是数组中的当前元素。

我试图递归地解决这个问题,但是,我无法通过任何测试用例。我的递归代码如下所示:

def kSum(nums, k):
    def kSum(cur_sum, i):
        if i == len(nums): return 0
        sol = 1 if (cur_sum + nums[i]) % k == 0 else 0
        return sol + kSum(cur_sum, i+1) + kSum(cur_sum + nums[i], i+1)
    return kSum(0, 0)

这种递归方法有什么问题,我该如何纠正?我对迭代解决方案不感兴趣,我只想知道为什么此递归解决方案是错误的,以及如何纠正它。

3 个答案:

答案 0 :(得分:1)

您确定这不是案例测试吗?例如:

fixInNamespace

[4, 1, 3, 2], k = 3

因此,您的功能正确(它给了我5分),我认为您的功能没有重大问题。

答案 1 :(得分:0)

这是您用一些控制台日志编写的内容的javascript复制,以帮助解释其行为。

function kSum(nums, k) {
  let recursive_depth = 1;
  function _kSum(cur_sum, i) {
    recursive_depth++;
    
    if (i == nums.length) {
      recursive_depth--;
      return 0;
    }
    let sol = 0;
    if (((cur_sum + nums[i]) % k) === 0) {
      sol = 1;
      console.log(`Found valid sequence ending with ${nums[i]} with sum = ${cur_sum + nums[i]} with partial sum ${cur_sum} at depth ${recursive_depth}`);
    }
    const _kSum1 = _kSum(cur_sum, i+1);
    const _kSum2 = _kSum(cur_sum + nums[i], i+1);
    const res = sol + _kSum1 + _kSum2;
    
    recursive_depth--;
    return res; 
  }
  return _kSum(0, 0);
}

let arr = [4, 1, 3, 2], k = 3;
console.log(kSum(arr, k));

我认为这段代码实际上得到了正确的答案。我不太精通Python,但是我可能无意中修复了您代码中的错误,尽管在(cur_sum + nums[i]) % k

周围加上了括号。

答案 2 :(得分:0)

在我看来,您的解决方案是正确的。它通过尝试所有具有2^n复杂性的子序列来解决问题。我们可以在O(n*k)搜索空间中递归地表述它,尽管表编制可能会更有效。令f(A, k, i, r)表示使用不超过r的元素,当它们的总和除以k时剩下多少A[i]的子序列。然后:

function f(A, k, i=A.length-1, r=0){
  // A[i] leaves remainder r
  // when divided by k
  const c = A[i] % k == r ? 1 : 0;

  if (i == 0)
    return c;
  
  return c +  
    // All previous subsequences 
    // who's sum leaves remainder r
    // when divided by k
    f(A, k, i - 1, r) +

    // All previous subsequences who's
    // sum when combined with A[i]
    // leaves remainder r when
    // divided by k
    f(A, k, i - 1, (k + r - A[i]%k) % k);
}

console.log(f([1,2,1], 3));
console.log(f([2,3,5,8], 5));
console.log(f([4,1,3,2], 3));
console.log(f([3,3,3], 3));