坐标&接龙型动态规划 - 20181026
109. Triangle
此题还可以用DFS,记忆化搜索去做,二刷实现
public class Solution {
/**
* @param triangle: a list of lists of integers
* @return: An integer, minimum path sum
*/
public int minimumTotal(int[][] triangle) {
// write your code here
if (triangle == null || triangle.length == 0 || triangle[0] == null || triangle[0].length == 0) {
return -1;
}
int r = triangle.length;
//定义f[][]为0,0到x,y的最小路径
int[][] f = new int[r][r];
f[0][0] = triangle[0][0];
//初始化两条边
for (int i = 1; i < r; i++) {
f[i][0] = f[i - 1][0] + triangle[i][0];
f[i][i] = f[i - 1][i - 1] + triangle[i][i];
}
for (int i = 1; i < r; i++)
for (int j = 1; j < i; j++) {
f[i][j] = triangle[i][j] + Math.min(f[i - 1][j], f[i - 1][j - 1]);
}
int minTotal = f[r-1][0];
for (int i = 0; i < r; i++) {
minTotal = f[r - 1][i] < minTotal ? f[r - 1][i] : minTotal;
}
return minTotal;
}
}
110. Minimum Path Sum
public class Solution {
/**
* @param grid: a list of lists of integers
* @return: An integer, minimizes the sum of all numbers along its path
*/
public int minPathSum(int[][] grid) {
// write your code here
if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) {
return -1;
}
//定义f为0,0到x,y的最小路径和
int r = grid.length;
int c = grid[0].length;
int[][] f = new int[r][c];
f[0][0] = grid[0][0];
//初始化两条边
for (int i = 1; i < c; i++) {
f[0][i] = grid[0][i] + f[0][i - 1];
}
for (int i = 1; i < r; i++) {
f[i][0] = grid[i][0] + f[i - 1][0];
}
for (int i = 1; i < r; i++)
for (int j = 1; j < c; j++) {
f[i][j] = grid[i][j] + Math.min(f[i - 1][j], f[i][j - 1]);
}
return f[r - 1][c - 1];
}
}
114. Unique Paths
public class Solution {
/**
* @param m: positive integer (1 <= m <= 100)
* @param n: positive integer (1 <= n <= 100)
* @return: An integer
*/
public int uniquePaths(int m, int n) {
// write your code here
if (m <= 0 || n <= 0) {
return -1;
}
int[][] sum = new int[m][n];
for (int i = 0; i < m; i++) {
sum[i][0] = 1;
}
for (int i = 0; i < n; i++) {
sum[0][i] = 1;
}
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1];
}
return sum[m - 1][n - 1];
}
}
111. Climbing Stairs
public class Solution {
/**
* @param n: An integer
* @return: An integer
*/
public int climbStairs(int n) {
// write your code here
if (n <= 0) {
return 0;
}
if(n==1){
return 1;
}
int[] f = new int[n+1];
f[1] = 1;
f[2] = 2;
for (int i = 3; i <= n; i++) {
f[i] = f[i - 1] + f[i - 2];
}
return f[n];
}
}
Method1: DP
116. Jump Game
public class Solution {
/**
* @param A: A list of integers
* @return: A boolean
*/
public boolean canJump(int[] A) {
// write your code here
if (A == null || A.length == 0) {
return false;
}
boolean[] can = new boolean[A.length];
can[0] = true;
for (int i = 0; i < A.length; i++) {
int canJumpLen = A[i];
for (int j = 0; j <= canJumpLen; j++) {
if (i + j > A.length - 1) {
break;
}
can[i + j] = true & can[i];
}
}
return can[A.length - 1];
}
}
117. Jump Game II
public class Solution {
/**
* @param A: A list of integers
* @return: An integer
*/
public int jump(int[] A) {
// write your code here
if(A==null || A.length==0){
return 0;
}
int[] f = new int[A.length];
f[0] = 0;
for(int i=1;i<A.length;i++){
f[i] = Integer.MAX_VALUE;
for(int j=0;j<i;j++){
if(j+A[j]>=i){
f[i] = Math.min(f[i],f[j]+1);
}
}
}
return f[A.length-1];
}
}
Method2:Greedy(二刷)
76. Longest Increasing Subsequence
public class Solution {
/**
* @param nums: An integer array
* @return: The length of LIS (longest increasing subsequence)
*/
public int longestIncreasingSubsequence(int[] nums) {
// write your code here
if (nums == null || nums.length == 0) {
return 0;
}
int[] f = new int[nums.length];
f[0] = 1;
for (int i = 0; i < nums.length; i++) {
f[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
f[i] = Math.max(f[i], f[j] + 1);
}
}
}
int maxLen = 1;
for (int i = 0; i < f.length; i++) {
maxLen = Math.max(f[i], maxLen);
}
return maxLen;
}
}
二分法:AC的答案是错误的,二分时重复情况应踢掉,见602题解答
public class Solution {
/**
* @param nums: An integer array
* @return: The length of LIS (longest increasing subsequence)
*/
public int longestIncreasingSubsequence(int[] nums) {
// write your code here
if (nums == null || nums.length == 0) {
return 0;
}
int[] tails = new int[nums.length];
tails[0] = nums[0];
int len = 1;
for (int i = 1; i < nums.length; i++) {
if (nums[i] == tails[0] || nums[i] == tails[len - 1]) {
continue;
}
if (nums[i] < tails[0]) {
tails[0] = nums[i];
continue;
}
if (nums[i] > tails[len - 1]) {
tails[len] = nums[i];
len++;
continue;
}
if (nums[i] > tails[0] && nums[i] < tails[len - 1]) {
//第一个大于nums[i]的位置
int index = binarySearch(tails, nums[i],len);
if (index >= 0 && index <= len - 1) {
tails[index] = nums[i];
}
}
}
return len;
}
public int binarySearch(int[] nums, int target,int len) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = len - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
start = mid;
}
if (nums[mid] > target) {
end = mid;
}
if (nums[mid] < target) {
start = mid;
}
}
if (nums[start] > target) {
return start;
}
if (nums[end] > target) {
return end;
}
return -1;
}
}
602. Russian Doll Envelopes
DP会TLE,考虑用二分优化时间复杂度
method1:DP(时间复杂度o(n^2))
public class Solution {
/*
* @param envelopes: a number of envelopes with widths and heights
* @return: the maximum number of envelopes
*/
public int maxEnvelopes(int[][] envelopes) {
// write your code here
if (envelopes == null || envelopes.length == 0 || envelopes[0] == null || envelopes[0].length == 0) {
return 0;
}
Comparator<int[]> comparator = new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0];
}
};
Arrays.sort(envelopes, comparator);
int[] f = new int[envelopes.length];
f[0] = 1;
int maxLen = 1;
for (int i = 1; i < f.length; i++) {
f[i] = 1;
for (int j = 0; j < i; j++) {
if (envelopes[i][0] > envelopes[j][0] && envelopes[i][1] > envelopes[j][1])
f[i] = Math.max(f[i], f[j] + 1);
}
maxLen = Math.max(f[i], maxLen);
}
return maxLen;
}
}
method2: 二分(o(NlogN))注意初次排序时按宽度递增排序,宽度相同时高度递减,将问题简化为求最长子序列(递减可以易于去除宽度相同的序列)
public class Solution {
/*
* @param envelopes: a number of envelopes with widths and heights
* @return: the maximum number of envelopes
*/
public int maxEnvelopes(int[][] envelopes) {
// write your code here
if (envelopes == null || envelopes.length == 0 || envelopes[0] == null || envelopes[0].length == 0) {
return 0;
}
//按宽度递增排序,宽度相同时高度递减 求最长子序列(递减可以易于去除宽度相同的序列)
Comparator<int[]> comparator = new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0];
}
};
Arrays.sort(envelopes, comparator);
return longestIncreasingSubsequence(envelopes);
}
public int longestIncreasingSubsequence(int[][] envelopes) {
// write your code here
if (envelopes == null || envelopes.length == 0) {
return 0;
}
int[] tails = new int[envelopes.length];
tails[0] = envelopes[0][1];
int len = 1;
for (int i = 1; i < envelopes.length; i++) {
if (envelopes[i][1] == tails[0] || envelopes[i][1] == tails[len - 1]) {
continue;
}
if (envelopes[i][1] < tails[0]) {
tails[0] = envelopes[i][1];
continue;
}
if (envelopes[i][1] > tails[len - 1]) {
tails[len] = envelopes[i][1];
len++;
continue;
}
if (envelopes[i][1] > tails[0] && envelopes[i][1] < tails[len - 1]) {
//第一个大于nums[i]的位置
int index = binarySearch(tails, envelopes[i][1],len);
if (index >= 0 && index <= len - 1) {
tails[index] = envelopes[i][1];
}
}
}
return len;
}
public int binarySearch(int[] nums, int target,int len) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = len - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) {
//重复情况要踢掉,以免替换了后面的大数,会造成wrong answer
return -1;
}
if (nums[mid] > target) {
end = mid;
}
if (nums[mid] < target) {
start = mid;
}
}
if (nums[start] > target) {
return start;
}
if (nums[end] > target) {
return end;
}
return -1;
}
}
坐标&接龙型动态规划 - 20181026的更多相关文章
- LeetCode: 221_Maximal Square | 二维0-1矩阵中计算包含1的最大正方形的面积 | Medium
题目: Given a 2D binary matrix filled with 's and return its area. For example, given the following ma ...
- 九章算法系列(#4 Dynamic Programming)-课堂笔记
前言 时隔这么久才发了这篇早在三周前就应该发出来的课堂笔记,由于懒癌犯了,加上各种原因,实在是应该反思.好多课堂上老师说的重要的东西可能细节上有一些急记不住了,但是幸好做了一些笔记,还能够让自己回想起 ...
- C#基础教程/适合初学者
C#基础教程 第一章 C#语言基础 本章介绍C#语言的基础知识,希望具有C语言的读者能够基本掌握C#语言,并以此为基础,能够进一步学习用C#语言编写window应用程序和Web应用程序.当 ...
- 动态规划 Dynamic Programming
March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...
- 面试题目——《CC150》递归与动态规划
面试题9.1:有个小孩正在上楼梯,楼梯有n个台阶,小孩一次可以上1阶.2阶或者3阶.实现一个方法,计算小孩有多少种上楼梯的方式. 思路:第4个数是前三个数之和 注意:能不能使用递归,能不能建立一个很大 ...
- TSP问题——动态规划
Traveling Salesman Problem Description: Time Limit: 4sec Memory Limit:256MB 有编号1到N的N个城市,问从1号城市出发, ...
- {POJ}{动态规划}{题目列表}
动态规划与贪心相关: {HDU}{4739}{Zhuge Liang's Mines}{压缩DP} 题意:给定20个点坐标,求最多有多少个不相交(点也不相交)的正方形 思路:背包问题,求出所有的正方形 ...
- poj 动态规划题目列表及总结
此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 11 ...
- [NOIP 2014复习]第三章:动态规划——NOIP历届真题回想
背包型动态规划 1.Wikioi 1047 邮票面值设计 题目描写叙述 Description 给定一个信封,最多仅仅同意粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定全部的邮票数量都 ...
随机推荐
- python3-递归
# Auther: Aaron Fan """递归特性:1. 必须有一个明确的结束条件2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少3. 递归效率不高,递 ...
- Part10-C语言环境初始化-栈初始化lesson1
1.概念解析 ARM系统使用的是满栈! ARM采用降栈!!! 栈帧 每一个进程会有一个栈,该进程中的每一个函数会分割栈的一部分,那么每一个函数使用的那部分栈就叫做栈帧.那么所有栈帧组成了整个栈. 子函 ...
- canvas基础学习笔记
canvas基本用法 1.什么是canvas(画布) <canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形,例如,它可以用于绘制图形,创建动 ...
- (转)Expression 表达式树学习整理
原文地址:http://www.cnblogs.com/li-peng/p/3154381.html 整理了一下表达式树的一些东西,入门足够了 先从ConstantExpression 开始一步一步的 ...
- 关于spring”通配符的匹配很全面, 但无法找到元素 'context:component-scan' 的声明“的错误
关于spring配置的问题 近日学习spring时遇到了这个问题: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreExcept ...
- .net Stream篇(七)
NetworkStream 目录: NetworkStream的作用 简单介绍下TCP/IP 协议和相关层次 简单说明下 TCP和UDP的区别 简单介绍下套接字(Socket)的概念 简单介绍下Tcp ...
- laravel中get方式表单提交后, 地址栏数据重复的问题
csrf_field这个要放form表单下面第一行的位置
- .Net Core 项目部署IIS简单步骤
1.新建一个解决方案: 我习惯会把运行文件移至一级目录 然后清除CoreTest 文件夹里面的文件 2.在解决方案中新建一个项目 点击确认有,这里有几种选择类型,我一般选择空类型(这里需要注意一下,空 ...
- .Net Core .Net Core的学习
.Net Core 学习 一.什么是.net core? 百度百科: https://baike.baidu.com/item/.net%20core/20130686?fr=aladdin 个人总结 ...
- 十六、Node.js-fs模块-流
10. fs.createReadStream 从文件流中读取数据 /** * 之前我们学习过读取文件内容的方法readFile():该方法适合读取文件内容比较少的文件,如果遇到数据量庞大的文件,我们 ...