给你一个数组,其长度为 n ,在其中选出一个子序列,子序列中任意两个数不能有相邻的下标(子序列可以为空),求该序列的最大子序列和。
本题中子序列指在数组中任意挑选若干个数组成的数组。
数据范围:
,数组中所有数的值满足
进阶:空间复杂度
, 时间复杂度
3,[1,2,3]
4
有[],[1],[2],[3],[1,3] 4种选取方式其中[1,3]选取最优,答案为4
4,[4,2,3,5]
9
其中[4,5]的选取方案是在满足不同时选取相邻位置的数的情况下是最优的答案
1,[-1]
0
选择子序列为空最优
5,[3,2,3,4,5]
11
其中选择[3,3,5]的方案是最优的答案
输入的值在int范围内
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算 * @param n int整型 数组的长度 * @param array int整型一维数组 长度为n的数组 * @return long长整型 */ public long subsequence (int n, int[] array) { // write code here\ long[] dp = new long[n]; dp[0] = array[0]; if(n < 2){ return dp[0] > 0 ? dp[0] : 0; } dp[1] = Math.max(dp[0],array[1]); for(int i = 2 ; i < n ; i++){ dp[i] = Math.max(dp[i-1],dp[i-2]+array[i]); } return dp[n-1] > 0 ? dp[n-1] : 0; } }
public long subsequence (int n, int[] array) { long[] resArr = new long[n + 2]; resArr[0] = resArr[1] = 0; for (int i = 2; i < n + 2; i++) { long elem1 = resArr[i - 1]; long elem2 = resArr[i - 2] + array[i - 2]; resArr[i] = (elem1 > elem2) ? elem1 : elem2; } return resArr[n + 1]; }
public long subsequence (int n, int[] array) { // write code here long choosen = array[0]; long notChoosen = 0; for(int i=1;i<array.length;i++){ long temp = Math.max(choosen,notChoosen); choosen = notChoosen+array[i]; notChoosen = temp; } return Math.max(choosen,notChoosen); }
// 动态规划 优化一下空间复杂度 public class Solution { public long subsequence (int n, int[] array) { if (n == 1) return Math.max(0, array[0]); long pre = 0, now = array[0], tmp = 0; for (int i = 1; i < n; i++) { tmp = now; now = Math.max(pre + array[i], now); if (now < 0) now = 0; pre = tmp; } return now; } }
import java.util.*;
public class Solution {
// 动态规划解决不相邻最大子序列和
public long subsequence (int n, int[] array) {
if (array.length == 0) {
return 0;
}
if (array.length == 1) {
return array[0];
}
int[] dp = new int[n];
// 为遍历作初始化准备
dp[0] = array[0];
if (array[0] < array[1]) {
dp[1] = array[1];
} else {
dp[1] = array[0];
}
// 思路: 如果第i项为负数,直接取前一项的值;
// 如果前i-2项子序列大小 + array[i] 大于 前i-1项子序列大小 ,就取前者,否则就取后者
// 最后dp数组最后一个元素就是最大值了
for (int i = 2; i < array.length; i++) {
if (array[i] < 0) {
dp[i] = dp[i - 1];
} else {
dp[i] = Math.max(dp[i - 2] + array[i], dp[i - 1]);
}
}
return dp[n - 1];
}
}
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 计算 * @param n int整型 数组的长度 * @param array int整型一维数组 长度为n的数组 * @return long长整型 */ public long subsequence (int n, int[] array) { // write code here if (array == null || n == 0) { return 0; } int f = 0, s = 0, res = 0; for (int a : array) { if (a < 0) { res = s; } else { res = Math.max(f + a, s); } // 滚动 f = s; s = res; } return res; } }
public long subsequence (int n, int[] array) { long dp[]=new long[n]; dp[0]=array[0]; if(n==1)return dp[0]; dp[1]=Math.max(array[0],array[1]); if(n==2)return dp[1]; for(int i=2;i<n;i++){ //不相邻的话,取i-1就不能要i元素,要i元素就可以加上i-2的最大值 dp[i]=Math.max(dp[i-1],dp[i-2]+array[i]); } return dp[n-1]; }