Problem:

There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.

The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses.

Note:
All costs are positive integers.

Follow up:
Could you solve it in O(nk) runtime?

Analysis:

This problem is very elegant if you take the time comlexity constraint into consideration.
It actually share the same dynamic programming idea as Paint House |. If we continue follow the old coding structure, we definitely would end up with the time complexity: O(nk^2).
level 1: n is the total number of houses we have to paint.
level 2: the first k represent for each house we need to try k colors.
level 3: the second k was caused by the process to search the minimum cost (if not use certain color). Apparently, if we want reach the time complexity O(nk), we have to optimize our operation at level 3.
If we choose the color[i][j], how could we reduce the comparision between (color[i-1][0] to color[i-1][k], except color[i-1][j])
And we know there are acutally extra comparisions, since fore each color, we have to find the smallest amongst other colors. There must be way to solve it, Right?
Yup!!! There is a magic skill for it!!!
Let us assume, we have "min_1" and "min_2".
min_1 : the lowest cost at previous stage.
min_2 : the 2nd lowest cost at previous stage. And we have the minimum costs for all colors at previous stage.
color[i-1][k] Then, iff we decide to paint house "i" with color "j", we can compute the minimum cost of other colors at "i-1" stage through following way.
case 1: iff "color[i-1][j] == min_1", it means the min_1 actually records the minimum value of color[i-1][j] (previous color is j), we have to use min_2;
case 2: iff "color[i-1][j] != min_1", it means min_1 is not the value of color[i-1][j] (previous color is not j), we can use the min_1's color.
Note: iff "pre_min_1 == pre_min_2", it means there are two minimum costs, anyway, no matter which color is pre_min_1, we can use pre_min_2.
----------------------------------------------------------
if (dp[j] != pre_min_1 || pre_min_1 == pre_min_2) {
dp[j] = pre_min_1 + costs[i][j];
} else{
dp[j] = pre_min_2 + costs[i][j];
}
----------------------------------------------------------
The way to maintain "min_1" and "min_2".
for (int i = 0; i < len; i++) {
...
min_1 = Integer.MAX_VALUE;
min_2 = Integer.MAX_VALUE;
...
if (dp[j] <= min_1) {
min_2 = min_1;
min_1 = dp[j];
} else if (dp[j] < min_2){
min_2 = dp[j];
}
} Note:
To reduce the burden of handling case, we absolutely could start from i=0, when we could assume all previous cost is 0 since we have no house.

Solution:

public class Solution {
public int minCostII(int[][] costs) {
if (costs == null)
throw new IllegalArgumentException("costs is null");
if (costs.length == 0)
return 0;
int len = costs.length;
int k = costs[0].length;
int min_1 = 0, min_2 = 0;
int pre_min_1, pre_min_2;
int[] dp = new int[k];
for (int i = 0; i < len; i++) {
pre_min_1 = min_1;
pre_min_2 = min_2;
min_1 = Integer.MAX_VALUE;
min_2 = Integer.MAX_VALUE;
for (int j = 0; j < k; j++) {
if (dp[j] != pre_min_1 || pre_min_1 == pre_min_2) {
dp[j] = pre_min_1 + costs[i][j];
} else{
dp[j] = pre_min_2 + costs[i][j];
}
if (dp[j] <= min_1) {
min_2 = min_1;
min_1 = dp[j];
} else if (dp[j] < min_2){
min_2 = dp[j];
}
}
}
return min_1;
}
}

[LeetCode#265] Paint House II的更多相关文章

  1. [leetcode]265. Paint House II粉刷房子(K色可选)

    There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...

  2. [LeetCode] 265. Paint House II 粉刷房子

    There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...

  3. leetcode 198. House Robber 、 213. House Robber II 、337. House Robber III 、256. Paint House(lintcode 515) 、265. Paint House II(lintcode 516) 、276. Paint Fence(lintcode 514)

    House Robber:不能相邻,求能获得的最大值 House Robber II:不能相邻且第一个和最后一个不能同时取,求能获得的最大值 House Robber III:二叉树下的不能相邻,求能 ...

  4. 265. Paint House II

    题目: There are a row of n houses, each house can be painted with one of the k colors. The cost of pai ...

  5. 265. Paint House II 房子涂色K种选择的版本

    [抄题]: There are a row of n houses, each house can be painted with one of the k colors. The cost of p ...

  6. LC 265. Paint House II

    There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...

  7. [LintCode] Paint House II 粉刷房子之二

    There are a row of n houses, each house can be painted with one of the k colors. The cost of paintin ...

  8. LeetCode Single Number I / II / III

    [1]LeetCode 136 Single Number 题意:奇数个数,其中除了一个数只出现一次外,其他数都是成对出现,比如1,2,2,3,3...,求出该单个数. 解法:容易想到异或的性质,两个 ...

  9. [array] leetcode - 40. Combination Sum II - Medium

    leetcode - 40. Combination Sum II - Medium descrition Given a collection of candidate numbers (C) an ...

随机推荐

  1. jQuery滑动并响应事件

    jQuery滑动并打开指定页面: <!DOCTYPE html> <html> <head> <script src="http://code.jq ...

  2. 服務器提交協議衝突 (The server committed a protocol violation.)

    ---解決方法 (放在 app.config / web.config)--- <system.net> <settings> <httpWebRequest useUn ...

  3. android系统体系结构

    android系统底层是建立在Linux系统之上的,如下图 从上图可以看出android系统有五部分组成 1.APPLICATIONS(应用程序层) 包含一些核心应用程序,电子邮件,日历,地图,浏览器 ...

  4. mvc5 + ef6 + autofac搭建项目(四)

    在列表页面,点击新增,弹出窗口实现视屏上传,这里存在一个问题,就是大文件上传的问题,iis出于安全问题,有限制,当然这不是大问题,解决也很容易: 见截图: 请忽略视屏文件,看得懂的请装作不懂. 源码 ...

  5. CentOS PHP-5.4.8 编译安装之初体验

    1. 下载5.4.8 版本 [root@Test data] wget http://museum.php.net/php5/php-5.4.8.tar.gz 2. 解压 [root@Test php ...

  6. IOS多线程知识总结/队列概念/GCD/串行/并行/同步/异步

    进程:正在进行中的程序被称为进程,负责程序运行的内存分配;每一个进程都有自己独立的虚拟内存空间: 线程:线程是进程中一个独立的执行路径(控制单元);一个进程中至少包含一条线程,即主线程. 队列:dis ...

  7. UIButton 使用imageEdgeInsets和titleEdgeInsets属性

    现在App的底部栏.侧边栏.顶部栏经常出现一些包含图像和文字的Item,以前用按钮上面添加label和imageView,  想想实在是对资源的浪费..                 图1 — 底部 ...

  8. OC相关-02:oc和c的基本差异

    前言: 面向过程和面向对象. 简单的说,面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用. 面向对象是把构成问题事务分解成各个对象,建立对象的目的不 ...

  9. BestCoder Round #85 sum

    大晚上的更一道下午的水题吧.(虽然WA了好多次= =,但真实情况是我比较水) 描述 Given a sequence, you're asked whether there exists a cons ...

  10. c、c++混编实现查询本地IP地址

    一.思路 1.要想得到本地IP地址,可以通过本机名来查询,所以首先得得到本机名. 2.牵涉到IP地址,首先想到牵涉到网络协议,因此得加载套接字协议,所以先使用WSAStartup函数完成对Winsoc ...