lintcode: 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?
Given [1,2,3,4], k=2, target=5. There are 2 solutions:
[1,4] and [2,3], return 2.
Tags Expand
SOLUTION 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 解题报告的更多相关文章
- Lintcode: Subarray Sum 解题报告
Subarray Sum 原题链接:http://lintcode.com/zh-cn/problem/subarray-sum/# Given an integer array, find a su ...
- LeetCode 1 Two Sum 解题报告
LeetCode 1 Two Sum 解题报告 偶然间听见leetcode这个平台,这里面题量也不是很多200多题,打算平时有空在研究生期间就刷完,跟跟多的练习算法的人进行交流思想,一定的ACM算法积 ...
- LeetCode 2 Add Two Sum 解题报告
LeetCode 2 Add Two Sum 解题报告 LeetCode第二题 Add Two Sum 首先我们看题目要求: You are given two linked lists repres ...
- 【九度OJ】题目1174:查找第K小数 解题报告
[九度OJ]题目1174:查找第K小数 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1174 题目描述: 查找一个数组的第 ...
- 【LeetCode】402. Remove K Digits 解题报告(Python)
[LeetCode]402. Remove K Digits 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http: ...
- 【剑指Offer】最小的K个数 解题报告(Python)
[剑指Offer]最小的K个数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目 ...
- LeetCode: Combination Sum 解题报告
Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...
- USACO Section2.3 Zero Sum 解题报告 【icedream61】
zerosum解题报告----------------------------------------------------------------------------------------- ...
- 【LeetCode】1005. Maximize Sum Of Array After K Negations 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 小根堆 日期 题目地址:https://leetco ...
随机推荐
- Codeforces #259 Div.2
A. Little Pony and Crystal Mine 模拟题. 用矩阵直接构造或者直接根据关系输出 B. Little Pony and Sort by Shift 模拟题. 通过提供的操作 ...
- 取td里面的内容
var rowLength = document.getElementById("table名字").rows.length; for(var i=0;i<rowLeng ...
- Excel表3级数据整理工具
前言 做专题经常会遇到做数据级联的需求,大部分需求都长一个模样.销售给你一个excel表,然后你做一个省市经销商的级联.不知道以前大家是怎么样做的,我之前是把excel复制到sublime中,然后使用 ...
- 捉BUG记(To Catch a Bug)
大约有一年整没有写一篇博客了,由于各种原(jia)因(ban)导致闲暇时间要么拿着IPad看岛国奇怪的片(dong)子(hua).要么拿着kindle看各种各样的资(xiao)料(shuo).本来想写 ...
- Spring.Net+Nhibernate
Spring.net+Nhibernate系列优秀文章导航 冬哥的Spring.Net+Nhibernate Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 NH ...
- windows平台下redis安装及配置文件介绍
1.redis介绍 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(s ...
- 04-Vue入门系列之Vue事件处理
4.1. 监听事件的Vue处理 Vue提供了协助我们为标签绑定时间的方法,当然我们可以直接用dom原生的方式去绑定事件.Vue提供的指令进行绑定也是非常方便,而且能让ViewModel更简洁,逻辑更彻 ...
- [ucgui] 对话框1——创建对话框
>_<" 小工具和对话框的区别: 小工具可以创建并独立使用,因为它们本质上就是窗口.但是,通常需要使用对话框,它是包含一个或多个小工具的窗口. 对话框通常是一个窗口,它在出现时会 ...
- atitit. groupby linq的实现(1)-----linq框架选型 java .net php
atitit. groupby linq的实现(1)-----linq框架选型 java .net php 实现方式有如下 1. Dsl/ Java8 Streams AP ,对象化的查询api , ...
- atitit.标准时间格式 互相转换 秒数 最佳实践
atitit.标准时间格式 互相转换 秒数 最佳实践 例如00:01:19 转换为秒数 79,,and互相转换 一个思路是使用div 60 mod...不过麻烦的... 更好的方法是使用stamp ...