Java解leetcode,助力面试之中等10道题(六)
第300题 最长递增子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1:
输入 | 输出 |
---|---|
nums = [10,9,2,5,3,7,101,18] | 4 |
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:
输入 | 输出 |
---|---|
nums = [0,1,0,3,2,3] | 4 |
示例 3:
输入 | 输出 |
---|---|
nums = [7,7,7,7,7,7,7] | 1 |
解题思路
每一个数都与前面的数进行比较,如果后一数大于前面的数,则判断当前最大上升长度与当前数的最大上升长度加1谁大,然后更新最大值。
代码
// 最长递增子序列:动态规划
class Solution {
public int lengthOfLIS(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[] dp = new int[nums.length];//设dp为当前数组的最大上升子序列长度
dp[0] = 1;
int maxans = 1;
for (int i = 1; i < nums.length; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
//判断后一个数是否大于前一个数,如果大于,则比较遍历到的数的最大上升长度与当前数的上升长度加1的最大值
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
maxans = Math.max(maxans, dp[i]);
}
return maxans;
}
}
时间复杂度为O( n 2 n^2 n2),n为数组长度
空间复杂度为O(n)
第309题 最佳买卖股票时机含冷冻期
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
示例 1:
输入 | 输出 |
---|---|
[1,2,3,0,2] | 3 |
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
解题思路
本题使用动态规划求解,先找一个最小买入值,然后用一个值存储买入与当前值的和,最后用一个值存储更新后的最大卖出收益,不断递归计算,遍历整个数组
代码
// 最佳买卖股票时机含冷冻期:动态规划
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0) {
return 0;
}
int n = prices.length;
int f0 = -prices[0];//买入值
int f1 = 0;
int f2 = 0;
for (int i = 1; i < n; ++i) {
int newf0 = Math.max(f0, f2 - prices[i]);//挑选最小买入值
int newf1 = f0 + prices[i];//买入值与当前值的和
int newf2 = Math.max(f1, f2);//更新最大卖出值
f0 = newf0;//取最小买入值
f1 = newf1;//更新买入与当前值的和
f2 = newf2;//传递卖出值
}
return Math.max(f1, f2);
}
}
时间复杂度为O(n),n为数组长度
空间复杂度为O(1)
第318题 最大单词长度乘积
给定一个字符串数组 words,找到 length(word[i]) * length(word[j]) 的最大值,并且这两个单词不含有公共字母。你可以认为每个单词只包含小写字母。如果不存在这样的两个单词,返回 0
示例 1:
输入 | 输出 |
---|---|
[“abcw”,“baz”,“foo”,“bar”,“xtfn”,“abcdef”] | 16 |
解释: 这两个单词为 “abcw”, “xtfn”。
示例 2:
输入 | 输出 |
---|