lintcode: k Sum 解题报告

k SumShow Result

My Submissions

http://www.lintcode.com/en/problem/k-sum/ 题目来自九章算法

13%

Accepted

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.

Tags Expand

SOLUTION 1:

唉妈,主页君做这题搞了2,3小时差点吐血。不过,做出来还是很爽嘀!

取自黄老师(九章算法)的思想:

后面的优化主页君没有管。 F[0][0][0]表示在一个空集中找出0个数,target为0,则有1个解,就是什么也不挑嘛!

其实应该这样写,也就是说,找0个数,目标为0,则一定是有1个解:

if (j == 0 && t == 0) {
  // select 0 number from i to the target: 0
  D[i][j][t] = 1;
}

1. 状态表达式:

D[i][j][t] = D[i - 1][j][t];
if (t - A[i - 1] >= 0) {
D[i][j][t] += D[i - 1][j - 1][t - A[i - 1]];
}

意思就是:

(1)我们可以把当前A[i - 1]这个值包括进来,所以需要加上D[i - 1][j - 1][t - A[i - 1]](前提是t - A[i - 1]要大于0)

(2)我们可以不选择A[i - 1]这个值,这种情况就是D[i - 1][j][t],也就是说直接在前i-1个值里选择一些值加到target.

代码:

 1 /**
 2      * @param A: an integer array.
 3      * @param k: a positive integer (k <= length(A))
 4      * @param target: a integer
 5      * @return an integer
 6      */
 7     public int  kSum1(int A[], int k, int target) {
 8         // write your code here
 9         if (target < 0) {
10             return 0;
11         }
12
13         int len = A.length;
14
15         int[][][] D = new int[len + 1][k + 1][target + 1];
16
17         for (int i = 0; i <= len; i++) {
18             for (int j = 0; j <= k; j++) {
19                 for (int t = 0; t <= target; t++) {
20                     if (j == 0 && t == 0) {
21                         // select 0 number from i to the target: 0
22                         D[i][j][t] = 1;
23                     } else if (!(i == 0 || j == 0 || t == 0)) {
24                         D[i][j][t] = D[i - 1][j][t];
25                         if (t - A[i - 1] >= 0) {
26                             D[i][j][t] += D[i - 1][j - 1][t - A[i - 1]];
27                         }
28                     }
29                 }
30             }
31         }
32
33         return D[len][k][target];
34     }

SOLUTION 2:

我们可以把最外层的Matrix可以省去。

这里最优美的地方,在于我们把target作为外层循环,并且从右往左计算。这里的原因是:

D[i][j][t] += D[i - 1][j - 1][t - A[i - 1]];

这个表达式说明D[i][j][t]是把上一级i的结果累加过来。这里我们省去了i这一级,也就是说在D[j][t]这个表里就地累加。而且t - A[i - 1]小于t。

在以下图表示就是说D[j][t]是来自于上一行的在t左边的这些值中挑一些加起来。

所以我们就必须从右往左逐列计算来避免重复的累加。

1. 如果你从左往右按列计算,每一列会被重复地加总,就会有重复计算。我们可以想象一下,len = 0为上表,len = 1为下表。

现在我们只有一个表,就是下面这个(因为第一个维度被取消了),现在如果你从左往右计算,被sum的区域会被填掉,覆盖

len = 0 那张表留下的值,下一个值的计算就不会准确了。

2. 或者如果你逐行计算,也是不可以的。因为你也是把生成D[j][t](在图里写的是D[i][j])的被sum的区域覆盖,也会造成结果不准确。

3. 所以,只要我们逐列计算,并且顺序是从右往左,即使我们只有一个二维表,我们的被sum区域也可以保持洁净,从空间角度来想,

就相当于从len=0那张表中取值。

总结:这种思维方式可能在面试里很难遇到,不过,可以开拓我们思维,这里同样是动规时如果取得上一级的值的问题,并且它考虑了省

去一级,就地利用二维空间的值,那么就要考虑我们上一级的旧表不要被覆盖。可以在大脑中构思一个三维空间,一个三维表由多个二维

表构成,如果把它们用一个表来做,再思考一下即可。

 1 // 2 dimension
 2     public int  kSum(int A[], int k, int target) {
 3         // write your code here
 4         if (target < 0) {
 5             return 0;
 6         }
 7
 8         int len = A.length;
 9
10         // D[i][j]: k = i, target j, the solution.
11         int[][] D = new int[k + 1][target + 1];
12
13         // only one solution for the empty set.
14         D[0][0] = 1;
15         for (int i = 1; i <= len; i++) {
16             for (int t = target; t > 0; t--) {
17                 for (int j = 1; j <= k; j++) {
18                     if (t - A[i - 1] >= 0) {
19                         D[j][t] += D[j - 1][t - A[i - 1]];
20                     }
21                 }
22             }
23         }
24
25         return D[k][target];
26     }

https://github.com/yuzhangcmu/LeetCode/blob/master/lintcode/dp/KSum.java

时间: 2024-12-24 10:04:41

lintcode: k Sum 解题报告的相关文章

LeetCode: Combination Sum 解题报告

Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Question Solution Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The

USACO Section2.3 Zero Sum 解题报告 【icedream61】

zerosum解题报告------------------------------------------------------------------------------------------------------------------------------------------------[题目] 给你N. 把1到N依次写出,每相邻两个数字中间加上一个字符,三选一:'+','-',' '. 如此,便可形成很多表达式,把其中计算结果为0的按字典序输出.[数据范围] 3<=N<

Lintcode: k Sum II

Given n unique integers, number k (1<=k<=n) and target. Find all possible k integers where their sum is target. Example Given [1,2,3,4], k=2, target=5, [1,4] and [2,3] are possible solutions. 这道题同Combination Sum II 1 public class Solution { 2 /** 3

CF1073E Segment Sum 解题报告

CF1073E Segment Sum 题意翻译 给定\(K,L,R\),求\(L~R\)之间最多不包含超过\(K\)个数码的数的和. \(K\le 10,L,R\le 10^{18}\) 数位dp \(dp_{i,s}\)前\(i\)位出现集合\(s\)的贡献和和出现次数 然后记忆化的时候转移一下就行了 然而写的时候还是怪麻烦的 Code: #include <cstdio> #include <cstring> #define ll long long const int mo

LeetCode: Binary Tree Maximum Path Sum 解题报告

Binary Tree Maximum Path SumGiven a binary tree, find the maximum path sum. The path may start and end at any node in the tree. For example:Given the below binary tree, 1      / \     2   3 SOLUTION 1: 计算树的最长path有2种情况: 1. 通过根的path. (1)如果左子树从左树根到任何一个N

Lintcode: Fast Power 解题报告

Fast Power 原题链接:http://lintcode.com/en/problem/fast-power/# Calculate the an % b where a, b and n are all 32bit integers. Example For 231 % 3 = 2 For 1001000 % 1000 = 0 Challenge O(logn) Tags Expand SOLUTION 1: 实际上这题应该是suppose n > 0的. 我们利用 取模运算的乘法法则:

Winter-1-D Max Sum 解题报告及测试数据

Time Limit:1000MS Memory Limit:32768KB Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. Input The f

LeetCode: Path Sum 解题报告

Path Sum Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example:Given the below binary tree and sum = 22,              5             / \        

LintCode &quot;k Sum&quot; !!

Great great DP learning experience:http://www.cnblogs.com/yuzhangcmu/p/4279676.html Remember 2 steps of DP: a) setup state transfer equation; b) setup selection strategy. a) States From problem statement, we find 3 variables: array size, k and target