牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为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