都只用创建一个一维的动态规划数组,然后求相应的最值。
class Solution {
public int maxSubArray(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
dp[0] = nums[0];
int ans = dp[0];
for(int i = 1; i < len; i++) {
dp[i] = Math.max(nums[i],dp[i-1] + nums[i]);
ans = Math.max(ans,dp[i]);
}
return ans;
}
}
class Solution {
public int lengthOfLIS(int[] nums) {
int len = nums.length;
if(len < 2) return len;
int[] dp = new int[len];//以i为结尾的最长递增子序列的长度
int ans = 0;
Arrays.fill(dp, 1);
for(int i = 0; i < len; i++) {
for(int j = 0; j < i; j++) {
if(nums[j] < nums[i]) {//如果这个数小于这段的数,那么有递增子序列
if(dp[j] >= dp[i]) {
dp[i] = dp[j] + 1;
}
}
ans = Math.max(dp[i], ans);
}
}
return ans;
}
}
二分查找法
class Solution {
public int lengthOfLIS(int[] nums) {
int ans = 0;
int len = nums.length;
int[] dp = new int[len];
for(int i = 0; i < len; i++) {
int sit = Arrays.binarySearch(dp,0,ans,nums[i]);//找到比nums[i]大的元素的位置
sit = sit < 0 ? - sit - 1:sit;
dp[sit] = nums[i];//替换第一个比他大的位置
if(sit == ans) {//如果正好比子序列中所有的数都大,那么最长递增子序列长度增一
ans++;
}
}
return ans;
}
}
class Solution {
public int findNumberOfLIS(int[] nums) {
int len = nums.length;
if(len < 2) return len;
int[] lengths = new int[len];//递增子序列的几种情况
int[] dp = new int[len];//每种递增子序列的个数
Arrays.fill(dp,1);
for(int i = 0; i < len; i++) {
for(int j = 0; j < i; j++) {
if(nums[j] < nums[i]) {
if(lengths[j] >= lengths[i]) {
lengths[i] = lengths[j] + 1;
dp[i] = dp[j];
}else if(lengths[j] + 1 == lengths[i]) {
dp[i] += dp[j];
}
}
}
}
int lengest = 0, ans = 0;
for(int length : lengths) {
lengest = Math.max(lengest,length);
}
for(int i = 0; i < len; i++) {
if(lengths[i] == lengest) {
ans += dp[i];
}
}
return ans;
}
}
class Solution {
public int longestSubsequence(int[] arr, int difference) {
int ans = 1;
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = 0; i < arr.length; i++) {
int temp = map.getOrDefault(arr[i]-difference, 0) + 1;//表示之前出现过等差子序列
map.put(arr[i], temp);//新的长度
ans = Math.max(ans, temp);
}
return ans;
}
}