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.

代码:

 /**
* @param A: an integer array.
* @param k: a positive integer (k <= length(A))
* @param target: a integer
* @return an integer
*/
public int kSum1(int A[], int k, int target) {
// write your code here
if (target < ) {
return ;
} int len = A.length; int[][][] D = new int[len + ][k + ][target + ]; for (int i = ; i <= len; i++) {
for (int j = ; j <= k; j++) {
for (int t = ; t <= target; t++) {
if (j == && t == ) {
// select 0 number from i to the target: 0
D[i][j][t] = ;
} else if (!(i == || j == || t == )) {
D[i][j][t] = D[i - ][j][t];
if (t - A[i - ] >= ) {
D[i][j][t] += D[i - ][j - ][t - A[i - ]];
}
}
}
}
} return D[len][k][target];
}

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那张表中取值。

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

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

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

 // 2 dimension
public int kSum(int A[], int k, int target) {
// write your code here
if (target < ) {
return ;
} int len = A.length; // D[i][j]: k = i, target j, the solution.
int[][] D = new int[k + ][target + ]; // only one solution for the empty set.
D[][] = ;
for (int i = ; i <= len; i++) {
for (int t = target; t > ; t--) {
for (int j = ; j <= k; j++) {
if (t - A[i - ] >= ) {
D[j][t] += D[j - ][t - A[i - ]];
}
}
}
} return D[k][target];
}

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

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

  1. Lintcode: Subarray Sum 解题报告

    Subarray Sum 原题链接:http://lintcode.com/zh-cn/problem/subarray-sum/# Given an integer array, find a su ...

  2. LeetCode 1 Two Sum 解题报告

    LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...

  3. LeetCode 2 Add Two Sum 解题报告

    LeetCode 2 Add Two Sum 解题报告 LeetCode第二题 Add Two Sum 首先我们看题目要求: You are given two linked lists repres ...

  4. 【九度OJ】题目1174:查找第K小数 解题报告

    [九度OJ]题目1174:查找第K小数 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1174 题目描述: 查找一个数组的第 ...

  5. 【LeetCode】402. Remove K Digits 解题报告(Python)

    [LeetCode]402. Remove K Digits 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http: ...

  6. 【剑指Offer】最小的K个数 解题报告(Python)

    [剑指Offer]最小的K个数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目 ...

  7. LeetCode: Combination Sum 解题报告

    Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...

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

    zerosum解题报告----------------------------------------------------------------------------------------- ...

  9. 【LeetCode】1005. Maximize Sum Of Array After K Negations 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 小根堆 日期 题目地址:https://leetco ...

随机推荐

  1. OpenSessionInViewFilter 的配置及作用

    spring为我们解决hibernate的Session的关闭与开启问题. Hibernate 允许对关联对象.属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Sessio ...

  2. IOS封装一个微信聊天的输入工具

    1.实现微信的输入工具 实现了大部分功能,各模块实现的很清晰,有利于更好的二次开发(适合自己的需求),我自己总结出来的, 可以更快的让你实现输入工具,不需要扩展的也可以很方便的使用这个输入工具. 1) ...

  3. Static Constructors

    A static constructor is used to initialize any static data, or to perform a particular action that n ...

  4. JqueryEasyUI浅谈---视频教程公布

    http://pan.baidu.com/s/1pJqGXez 前两天我在博客园发了一个关于JqueryEasyUI浅谈本地化应用的博客,我简单的介绍了JqueryEasyUI的应用,今天我录制了了一 ...

  5. TypeScript:基本类型和接口

    返回TypeScript手册总目录 基本类型(Basic Types) 为了让程序可以使用,我们需要用到一些最简单的数据单元:数字,字符串,结构,布尔值,诸如此类.在TypeScript中,支持许多正 ...

  6. 深入理解java虚拟机【Java虚拟机垃圾收集器】

    Java堆内存被划分为新生代和年老代两部分,新生代主要使用复制和标记-清除垃圾回收算法,年老代主要使用标记-整理垃圾回收算法,因此java虚拟中针对新生代和年老代分别提供了多种不同的垃圾收集器,JDK ...

  7. Devexpress GridView内嵌dx:ASPxGridLookup取得控件值乱跳解决方案

    一 页面嵌入ASPxGridLookup控件 <dx:ASPxGridView ID="gridDetail" runat="server"        ...

  8. 编写高质量代码改善C#程序的157个建议读书笔记【11-20】

    章节索引 建议11:区别对待 == 和Equals 建议12:重写Equals也要重写GetHashCode 建议13:为类型输出格式化字符串 建议14:正确实现浅拷贝和深拷贝 建议15:使用dyna ...

  9. [BTS] The value "" for the property InboundId is invalid

    Microsoft.ServiceModel.Channels.Common.MetadataException: Retrieval of Operation Metadata has failed ...

  10. atitit.web 推送实现方案集合

    atitit.web 推送实现方案集合 1. 俩中模式 Push/Pull 1 2. 需要实现的特性 2 2.1. 推送消息广播. 2 2.2. 推送定向消息. 2 2.3. 提供连接上线前.上线.下 ...