题目描述
给你一个n(1≤n≤10^5),和一个长度为n的数组,在不同时选位置相邻的两个数的基础上,求该序列的最大子序列和(挑选出的子序列可以为空)。
方法一:动态规划
求解思路
对于本题目要求在不相邻的位置时求解最大子序列的和。这道题目是一个01背包问题,即根据前边计算好的i个节点的结果判断是否选择当前节点,我们假定dp[i]为i位置最大子序列的和,其状态转移方程为: ,其中array[i]表示题目所给的数组在第i位置上的数,根据以上描述即可求解出相应的结果。
解题代码
import java.util.*;
public class Solution {
public long subsequence (int n, int[] array)
{
if (n == 0)
{
return 0;
}
long[] hydp = new long[n]; // 创建一维数组,辅助计算
hydp[0] = Math.max(0,array[0]); // 当序列长度为1时
if (n == 1)
{
return hydp[0];
}
// 序列长度为2
hydp[1] = Math.max(hydp[1],array[1]);
// 对hydp进行遍历
for(int i = 2;i < n;++i)
{
hydp[i] = Math.max(hydp[i-1],hydp[i-2] + array[i]);
}
return hydp[n-1]; // 返回结果
}
}复杂度分析
时间复杂度:使用了一层循环,因此时间复杂度为
空间复杂度:引入dp[n]数组,因此空间复杂度为
方法二:优化方法--动态优化
求解思路
对于本题目的求解,我们参考斐波那契数列的通项公式,在计算第n个值时,发现其结果可以由前两位的结果得出,跟其他位置的值无联系。因此我们对于第一种方法做出优化。
解题代码
import java.util.*;
public class Solution {
public long subsequence (int n, int[] array) {
long i=0,j=0,k=0; // 声明ijk三个变量
for(int x=n-1;x>=0;x--)
{
k=Math.max(i,array[x]+j); // k存储最大值
j=i; // 更新j值
i=k; // 更新i值
}
return k; // 返回结果
}
}复杂度分析
时间复杂度:一层循环,因此时间复杂度为
空间复杂度:引入one,two两个变量,常数级内存空间,因此空间复杂度为

京公网安备 11010502036488号