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. HTML5 Canvas rect()和strokeRect() 的区别

    看到 Canvas rect()和strokeRect()时,发现这俩效果一样.仔细区分后发现: 他们都接受相同的参数,但rect() 只是创建一个矩形,并不绘制,如图: 要看到实际效果需要使用 st ...

  2. FileOutputStream保存文件

    //保存文件,根据传入的路径,存放在SD卡目录下public boolean saveToPath(String title, String pageName) { Bitmap b = getCha ...

  3. Robberies(HDU2955):01背包+概率转换问题(思维转换)

    Robberies  HDU2955 因为题目涉及求浮点数的计算:则不能从正面使用01背包求解... 为了能够使用01背包!从唯一的整数(抢到的钱下手)... 之后就是概率的问题: 题目只是给出被抓的 ...

  4. C#下搭建文件格式转换服务器

    文件格式转换,相信很多涉及到office文档在线观看的都会需要,因为浏览器还不能完全支持直接打开office文档,所以很多情况下我们都需要将这些文档转换成flash能够播放的格式,但是另一个问题又来了 ...

  5. [MSSQL2008]Spatial Data in SQL Server 2008 - 根据经纬度计算两点间距离

    DECLARE @BJ GEOGRAPHY DECLARE @XT GEOGRAPHY /*     GET Latitude/Longitude FROM here:http://www.trave ...

  6. Ubuntu命令--CURL用法

    curl命令是个功能强大的网络工具,支持通过http.ftp等方式下载文件.上传文件.还可以用来抓取网页.网络监控等方面的开发,解决开发过程中遇到的问题. 常用参数curl命令参数很多,这里只列出我曾 ...

  7. SQL——系统函数

    1) CASE CASE有两种使用形式:一种是简单的CASE函数,另一种是搜索型的CASE函数. [1]简单的 CASE 函数 Format: CASE input_expression WHEN w ...

  8. [读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析

    前言 上次在公司开会时有同事分享windebug的知识, 拿的是string字符串Concat拼接 然后用while(true){}死循环的Demo来讲解.其中有提及string操作大量字符串效率低下 ...

  9. Android模拟器配置

    // 检查连接设备,为了保证运行正常,只能留一个连接设备 adb devices

  10. Python模拟用户登录

    # coding=utf8 import hashlib db = { 'michael':'e10adc3949ba59abbe56e057f20f883e', 'bob':'878ef96e861 ...