1. 摆动序列
算法思路
删除坡度上的节点,不包括端点,成为摆动序列,达到局部最优;
整个序列有最多的局部峰值,从而达到最长摆动序列,达到全局最优,
注意点
1.上下坡中有平坡情况:删除前面平坡的点,留下最后一个端点,将prediff=0也算上;
2. 数组首尾两端,开始prediff等于0,首部将被算入摆动,且令result初始值为1,尾部自动算入摆动序列;
3. 单调坡中有平坡,只需要在摆动变化的时候更新prediff,就不会因为平坡发生变化,而造成误判。
代码
class Solution {
public int wiggleMaxLength ( int [ ] nums) {
if ( nums. length <= 1 ) return nums. length;
int curdiff = 0 ;
int prediff = 0 ;
int result = 1 ;
for ( int i = 0 ; i< nums. length- 1 ; i++ ) {
curdiff = nums[ i+ 1 ] - nums[ i] ;
if ( prediff<= 0 && curdiff > 0 || prediff>= 0 && curdiff< 0 ) {
result++ ;
prediff = curdiff;
}
}
return result;
}
}
2. 最大子序和
算法思路
1. 选取一个正数为起始点,才能让后面的数变大;
2. 选取最大和的情况为终止点。
注意点
1. 令result的初始值为Integer.MIN_VALUE而不是0,因为最大值可能是负数;
2. 不是遇到负数就直接重新开始累加,而是累加后为负数才开始重新累加。
代码
class Solution {
public int maxSubArray ( int [ ] nums) {
int result = Integer . MIN_VALUE ;
int count = 0 ;
for ( int i= 0 ; i< nums. length; i++ ) {
count += nums[ i] ;
if ( count < 0 ) count = 0 ;
result = Math . max ( result, count) ;
}
return result;
}
}
3. 买卖股票的最佳时机 II
算法思路
1. 计算出每天的利润序列 prices[i] -prices[i-1];
2. 挑出利润序列中大于0的进行累加,即可得到最大利润。
注意点
第一天没有利润,所以 i 从1开始遍历。
代码
class Solution {
public int maxProfit ( int [ ] prices) {
int result = 0 ;
for ( int i = 1 ; i< prices. length; i++ ) {
result += Math . max ( prices[ i] - prices[ i- 1 ] , 0 ) ;
}
return result;
}
}
4. 跳跃游戏
算法思路
寻找最大的覆盖范围,若最大覆盖范围能覆盖到终点下标,则返回true。
注意点
i 只能在覆盖范围内移动; 覆盖范围要不断更新取最大。
代码
class Solution {
public boolean canJump ( int [ ] nums) {
if ( nums. length == 1 ) return true ;
int coverage = 0 ;
for ( int i = 0 ; i<= coverage; i++ ) {
coverage = Math . max ( i + nums[ i] , coverage) ;
if ( coverage >= nums. length- 1 ) return true ;
}
return false ;
}
}