上升序列问题
Posted 沐枫L
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上升序列问题相关的知识,希望对你有一定的参考价值。
概念
- 递增(非降)序列
如果在序列中,每个数都不小于它前面的一个数,我们就称这个序列为递增序列,或者称为非降序列。例如:1 2 2 3 4
,3 4 5 6 7
都是非降序列。 - 递减(非增)序列
如果在序列中,每个数都不大于它前面的一个数,我们就称这个序列为递减序列,或者称为非增序列。例如:4 3 3 2 1
,7 6 5 4 3
都是非增序列。 - 严格递增序列
如果在序列中,每个数都大于它前面的一个数,我们就称这个序列为严格递增序列。例如:1 2 2 3 4
不是严格递增序列,3 4 5 6 7
为严格递增序列。 - 严格递减序列
如果在序列中,每个数都小于它前面的一个数,我们就称这个序列为严格递减序列。例如:4 3 3 2 1
不是严格递减序列,7 6 5 4 3
为严格递减序列。
上升序列的判断
-
每次判断的操作只比较需要连续的两个数,因此,我们除了用一个变量(例如: x x x)记录刚刚输入的数值以外,还需要用一个变量(例如: l a s t last last)记录上一个输入的数值,将这两个数值进行比较即可。
-
由于我们是从第 2 2 2 个数开始才有 l a s t last last,因此 l a s t last last 一开始的值就是第 1 1 1 个数,我们可以直接将第一个数值输入给 l a s t last last,第 2 2 2 个数输入给 x x x。这样我们可以用
if (x > last)
语句来进行比较。 -
当把第 3 3 3 个数输入给 x x x 时, l a s t last last 应该是第 2 2 2 个数才对,因此,我们需要在将 x x x 变为第 3 3 3 个数之前,先把它的值赋值给 l a s t last last,使其成为第 2 2 2 个数。也就是说,对于每个新输入的 x x x 来说,它之前的数值已经赋值给了 l a s t last last。
对于输入 5 5 5 个数:7 9 5 10 11
i 1 2 3 4 5 x 7 9 5 10 11 last 空 7 9 5 10 从第 2 2 2 列开始,每一列的 x x x 和 l a s t last last 刚好就是一对相邻的数,我们对它们使用
if (x <= last)
语句进行比较即可。 -
如何判断一个序列不是严格上升序列?或者是上升序列?
假如存在某一次判断 x ≤ l a s t x \\le last x≤last,则if (x <= last)
语句为真,立即可以判断该序列不是严格上升序列;
但是,如果对于某一次if (x <= last)
为假,能立即判断它就是严格上升序列吗?显然不能! 正如上面的例子,在第 2 2 2 列里if (x <= last)
就为假,但它绝不是严格上升序列,因为你才刚刚看了前两个数,后面的数很有可能存在if (x <= last)
为真的情况,其实第 3 3 3 列就为真!所以,我们不能用if-else
直接通过某一列就得出“要么为严格上升序列,要么不是严格上升序列”的结论。这种判断以后我们也会经常见到,它的特点就是:只要有一个为真,则输出 NO;必须全部为假,才为 YES。
所以,只有在循环外,当整个循环都没有判断为真的情况时,才能确定这是一个严格上升序列。
#include <iostream>
using namespace std;
int main()
int n, x, last;
//第一个数直接被赋值为last
cin >> n >> last;//省略了last = x
for (int i = 2; i <= n; ++i)
cin >> x;
// 判断不是上升序列的条件
if (x <= last)
cout << "NO";
// 此时整个程序即可结束
return 0;
last = x;
// 整个循环都没有if为真,则输出'YES'
cout << "YES";
最长上升连续子序列 Linkcode
问题:
给定一个整数数组(下标从 0 到 n-1, n 表示整个数组的规模),请找出该数组中的最长上升连续子序列。(最长上升连续子序列可以定义为从右到左或从左到右的序列。)
样例
给定 [5, 4, 2, 1, 3]
, 其最长上升连续子序列(LICS)为 [5, 4, 2, 1]
, 返回 4
.
给定 [5, 1, 2, 3, 4]
, 其最长上升连续子序列(LICS)为 [1, 2, 3, 4]
, 返回 4
.
给定 [1, 1, 1, 1, 1]
, 其最长上升连续子序列(LICS)为 [1]
, 返回 1.
1 public class Solution { 2 /** 3 * @param A an array of Integer 4 * @return an integer 5 */ 6 public static int longestIncreasingContinuousSubsequence(int[] A) { 7 if(A.length==0) 8 return 0; 9 int hz,hj,r,maxz,maxj; 10 hz=hj=0; 11 r=maxz=maxj=1; 12 13 while(r<A.length){ 14 if(A[r]<A[r-1]){ 15 maxz = Math.max(maxz, r-hz); 16 hz = r; 17 }else if(A[r]>A[r-1]){ 18 maxj = Math.max(maxj, r-hj); 19 hj = r; 20 }else{ 21 hz = hj = r; 22 } 23 r++; 24 } 25 maxz = Math.max(maxz, r-hz); 26 maxj = Math.max(maxj, r-hj); 27 return Math.max(maxz, maxj); 28 } 29 }
以上是关于上升序列问题的主要内容,如果未能解决你的问题,请参考以下文章
C语言基础:循环结构(循环类型(while,do...while,for,嵌套循环),循环控制语句(break,continue,goto),无线循环(死循环))