提交 cd5790db 编写于 作者: L liu13

20190116

上级 a5a28faa
......@@ -4,6 +4,7 @@ package code;
* 题意:股票买卖1次,最大利润
* 难度:Easy
* 分类:Arryas, Dynamic Programming
* Tips:lc122
*/
public class lc121 {
public int maxProfit(int[] prices) {
......
package code;
/*
* 122. Best Time to Buy and Sell Stock II
* 题意:买卖股票最大利润,可以买多次
* 难度:Easy
* 分类:Array, Greedy
* 思路:计算 prices[i] 与 prices[i-1] 的差值,把正数全加起来就行了
* Tips:lc121, lc309
*/
public class lc122 {
public int maxProfit(int[] prices) {
if(prices.length<1) return 0;
int res = 0;
for (int i = 1; i < prices.length ; i++) {
if(prices[i]-prices[i-1]>0)
res += prices[i]-prices[i-1];
}
return res;
}
}
package code;
/*
* 287. Find the Duplicate Number
* 题意:n+1个数属于[1~n],找出重复的那个数
* 难度:Medium
* 分类:Array, Two Pointers, Binary Search
* 思路:如果nums[i]不在对应位置,则和对应位置交换。如果对应位置上也为该数,说明这个数就是重复的数字。这个方法改变了数组。是错误的。
* 另一种方法,把问题转换成有环链表,找环的起始节点。O(n) O(1) lc142
* 二分查找,每次看一边数字的个数, O(nlog(n)) O(1)
* Tips:剑指offer原题
*/
public class lc287 {
public int findDuplicate(int[] nums) { //该方法修改了数组,是错误的,没看清题意
for (int i = 0; i < nums.length ; i++) {
if(nums[i]!=i+1){
int temp = nums[nums[i]-1];
if(temp==nums[i])
return temp;
nums[nums[i]-1] = nums[i];
nums[i] = temp;
i--;
}
}
return -1;
}
public int findDuplicate2(int[] nums) {
int slow = nums[0];
int fast = nums[nums[0]];
while(slow!=fast){
slow = nums[slow];
fast = nums[nums[fast]];
}
fast = 0; // fast是0,不是nums[0]
while(slow!=fast){
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
}
package code;
/*
* 300. Longest Increasing Subsequence
* 题意:最长递增子数组,不一定是连续的
* 难度:Medium
* 分类:Binary Search, Dynamic Programming
* 思路:基本的思路是dp[i]记录以nums[i]结尾的最长长度,每次遍历 dp[i] 得到dp[i+1],复杂度为O(n^2)。最优的解法是O(nlgn),dp[i]是递增的数组,每次插入时二分查找是lgn。
* Tips:经典题目,记一下
*/
import java.util.Arrays;
public class lc300 {
public int lengthOfLIS(int[] nums) {
if(nums.length<2)
return nums.length;
int[] dp = new int[nums.length]; //dp[i] 存储以nums[i]结尾的最大长度
Arrays.fill(dp,1);
int res = 1;
for (int i = 1; i < nums.length ; i++) {
for (int j = 0; j < i ; j++) {
if(nums[i]>nums[j]){
dp[i] = Math.max(dp[j]+1, dp[i]);
}
}
res = Math.max(res, dp[i]);
}
return res;
}
public int lengthOfLIS2(int[] nums) {
if(nums.length<2)
return nums.length;
int size = 0; //size指dp中递增的长度。 dp[0~i] 表示了长度为 i+1 的递增子数组,且最后一个值是最小值
int[] dp = new int[nums.length]; //dp存储递增的数组,之后更新这个数组。如果x>最后一个值,则插入到末尾,否则更新对应位置上的值为该值。
for (int i = 0; i < nums.length ; i++) {
int left = 0;
int right = size;
while(left!=right){ //得到要插入的位置
int mid = (left+right)/2;
if(dp[mid]<nums[i])
left = mid+1;
else
right = mid;
}
dp[left] = nums[i];
if(left==size) size++;
}
return size;
}
}
package code;
/*
* 309. Best Time to Buy and Sell Stock with Cooldown
* 题意:最佳时间买卖股票,有冷却期,如果前一天卖了,下一天就不能买
* 难度:Medium
* 分类:Dynamic Programming
* 思路:状态DP,自己不会写。要分两种状态,手中有股票时最大收益,手中没股票时最大收益(包括冷冻期)。
* buy[i] = max( buy[i-1], sell[i-2]-price[i] )
* sell[i] = max( sell[i-1], buy[i-1]+price[i] )
* 空间压缩以后时间是O(n),空间是O(1)
* Tips:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/discuss/75931/Easiest-JAVA-solution-with-explanations
* lc122
*/
public class lc309 {
public int maxProfit(int[] prices) {
if(prices.length==0) return 0;
int b1 = -prices[0];
int s2=0, s1=0;
int b = 0, s = 0;
for (int i = 0; i < prices.length ; i++) {
b = Math.max(b1, s2-prices[i]);
s = Math.max(s1, b1+prices[i]);
s2 = s1;
s1 = s;
b1 = b;
}
return Math.max(s,b);
}
}
......@@ -5,19 +5,20 @@ package code;
* 难度:Hard
* 分类:Divide and Conquer, Dynamic Programming
* 思路:假设第n个气球是最后一个被踩爆,则从第n个气球开始,数组可以分为无前后相关性的两块
* Tips:太难了,弃疗了,不会写。直接粘答案。
* 首尾补1,最小区间为3个数,maxCoins[1,4],则需遍历2,3两种情况, 1,4指的是边界
* maxCoins[0][n - 1] = maxCoins[0][i - 1] + maxCoins[i + 1][n - 1] + nums[left] * nums[i] * nums[right]
* left是左边界,right是右边界,不一定是相邻的
* Tips:太难了,弃疗了,不会写。直接粘答案。区间dp。
*/
public class lc312 {
public static void main(String[] args) {
System.out.println(maxCoins(new int[]{3,1,5,8}));
System.out.println(maxCoins2(new int[]{3,1,5,8}));
}
public static int maxCoins(int[] iNums) {
int[] nums = new int[iNums.length + 2];
int n = 1;
for (int x : iNums) if (x > 0) nums[n++] = x;
nums[0] = nums[n++] = 1;
int[][] memo = new int[n][n];
int res = burst(memo, nums, 0, n - 1);
return res;
......@@ -34,4 +35,23 @@ public class lc312 {
return ans;
}
public static int maxCoins2(int[] iNums) {
int[] nums = new int[iNums.length + 2];
int n = 1;
for (int x : iNums) if (x > 0) nums[n++] = x;
nums[0] = nums[n++] = 1;
int[][] dp = new int[n][n];
for (int k = 2; k < n; ++k)
for (int left = 0; left < n - k; ++left) {
int right = left + k;
for (int i = left + 1; i < right; ++i)
dp[left][right] = Math.max(dp[left][right],
nums[left] * nums[i] * nums[right] + dp[left][i] + dp[i][right]);
}
return dp[0][n - 1];
}
}
......@@ -51,7 +51,7 @@ public class lc437 {
if (root == null)
return 0;
if (root.val == sum)
return 1 + dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);
return 1 + dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);//不要直接返回1,因为可能后边节点,或节点和为0
return dfs(root.left, sum - root.val) + dfs(root.right, sum - root.val);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册