啰嗦的代码:排序子序列

牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列.

输入:

6
1 2 3 2 2 1

如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2

题解:

其实这道题简单明了,思路也比较容易。

a[ i] <a[i+1],即后一个数大于前一个数,则属于非递减序列

a[ i] >a[i+1],即前一个数大于后一个数,则属于非递增序列

a[i]==a[i+1],既可以属于递增序列还可以属于递减序列

代码实现:

#include<iostream>
#include<vector>
using namespace std;


int main()
{
    int n;
    cin>>n;
    vector<int> arr(n);
    for(size_t i=0;i<n;++i)
    {
        cin>>arr[i];
    }
    //输入完成
    
    //处理问题主体
    size_t Index=1;
    bool minflags=false;
    bool greaterflags=false;
    bool equal=false;
    int count=0;
    while(Index<n)
    {
        minflags=false;
        greaterflags=false;
        while(Index<n&&arr[Index-1]<arr[Index])
        {
            ++Index;
            minflags=true;
        }
        //此处设置,是为了遇到一个递减序列加1
        if(minflags)
        {
            count++;
            ++Index;//此处下标加一,是为了防止一个递增序列和递减序列相邻处重复比较
            
        }
        while(Index<n&&arr[Index-1]==arr[Index])
        {
            ++Index;
            equal=true;
        }
             
        while(Index<n&&arr[Index-1]>arr[Index])
        {
            ++Index;
            greaterflags=true;
        }
      //此处设置,是为了遇到一个递增序列加1
        if(greaterflags)
        {
            count++;
            
            ++Index;
        }
     //说实话,设置这么多标志全是为了防止一些特殊情况
     // 2  2   2   2   2 
     //  1 2 1 2 1
        if((Index==n)&&(equal||greaterflags|| minflags))
            count++;
       
            
    }
     cout<<count<<endl;
        return 0;
}

上面的代码,怎么说呢?为了防止一些特殊情况,绞尽脑汁,疯狂设置布尔值;看到大佬的代码,我服气了,自己果然还是只菜鸟。

不废话了,上代码。ε=(´ο`*)))唉!

int main() {    
    int n;    
    cin >> n;
   
 
    vector<int> a;   
    a.resize(n + 1); 
    // 注意这里多给了一个值,是处理越界的情况的比较,同时也处理了一些特殊情况
    // 2  2   2   2   2 
     //  1 2 1 2 1  
    a[n] = 0;//本题的特殊技巧
 
    //读入数组    
    int i = 0;    
    for (i = 0; i < n; ++i){
        cin >> a[i];
    }        
    i = 0;    
    int count = 0;    
    while (i < n)
{       
    // 非递减子序列        
        if (a[i] < a[i + 1])
       {           
            while (i < n && a[i] <= a[i + 1])
             {
                i++;
             }              
            count++;            
            i++;        
        }        
        else if (a[i] == a[i + 1])
       {            
            i++;        
        }
        else 
       {
            // 非递增子序列       
            while (i < n && a[i] >= a[i + 1])
           {
            i++;
            }                
               count++; 
               i++;        
       }    
}

结语:

下面的代码是利用本题的输入(大于0),简化了许多判断的麻烦。

自己在数组开辟时,多定义了一个位置,设为比最小值还小的值,实际要排序的序列中无论是剩余1个还是全部相等,最后一个判断一定进入非增子序列进行加1操作。所以简化了我的代码中的多处判断。

如果对此处感兴趣的伙伴可以去原题网址去看一下。

我的代码中虽然多处判断,但并不局限于题目的输出情况,这样一看,我的代码还是有优势的!

 

你们的 【三连】 是给Qyuan最大的肯定!

↓          ↓           ↓

注:如果本篇博客有任何错误和建议,欢迎伙伴们留言,你快说句话啊!

如果需要练习的小伙伴,可以打开下方链接。

 链接:https://www.nowcoder.com/questionTerminal/2d3f6ddd82da445d804c95db22dcc471

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值