1-9 最长连续递增子序列 (20 分)

给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。

输入格式:

输入第1行给出正整数n(≤10
​5
​​ );第2行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出第一次出现的最长连续递增子序列,数字之间用空格分隔,序列结尾不能有多余空格。

输入样例:

15
1 9 2 5 7 3 4 6 8 0 11 15 17 17 10

输出样例:

3 4 6 8

我的分析

先记录一下第一个序列的位置,比如:1 9 2 5 7 3 4 6 8 0 11 15 17 17 10中,我先记下位置pos = k ;(此时k=0,所以第一个序列位置为0)。并设置序列长度为1(len=1;),然后再看从数字1开始的这个序列最长能到哪里,用for(;a[k]<a[k+1];k++)中的a[k]<a[k+1]来判断。
若后面的数字大于当前数字,则满足递增,同时len++;序列长度加一。例如:1<9 , len:1->2。9>2,不满足递增,则以第一个数字1为首的最大序列找到。
将全局变量mpos和mlen,分别赋值为pos和len,表示当前最长的序列的下标和长度。
之后从第2个数字开始,继续循环。每次要和全局变量mpos和mlen比较,修改mpos和mlen。
最后得到的是最后出现的最长的序列,但不一定是第一个,所以要在找一次,寻找递增数列len==mlen的。
因为做的事情和之前一样,所以就又在原来的函数中添加了一个判断。

 if(flag&&len==mlen2)
         {
             mpos=pos;
         }

用了mlen2来保存最大长度。还用了一个标志变量flag,以确保第一次调用的时候不会执行这部分。

我的代码(20分的放心用,虽然这代码可能不咋地)
#include <stdio.h>
#define N 100000
int mlen;
int mlen2;
int flag=0;
int mpos;
void find(int *a,int n);
int main ()
{
    int i,n;
    int * a;
    scanf("%d",&n);
    a=(int *)malloc(sizeof(int)*n);
    for(i=0;i<n;i++)
    {
        scanf("%d",a+i);
    }
    find(a,n);
    //printf("%d %d\n",mpos,mlen); 测试用的
    mlen2=mlen;
    find(a,n);
    for(i=mpos;i<mpos+mlen2-1;i++)
    {
        printf("%d ",a[i]);
    }
    printf("%d",a[i]);
 return 0;
}
 void find(int *a,int n)
 {
     int i,k,sum,pos,max=0,len;
     for(i=0;i<n-1;i++)
     {
         k=i;
         pos=k;
         len=1;
         for(;a[k]<a[k+1];k++)
         {
           len++;
         }
         if(flag&&len==mlen2)
         {
             mpos=pos;
         }
         if(mlen<len)
         {
             mlen=len;
             mpos=pos;
         }
     }

 }
要是看不懂我写的,就别看了,我也隐隐觉得这想法和代码都有点渣。我再去看看别人的想法,实践后再来更新。
——————————更新 ———————————
下面的这段代码和我的想法一样,不过他是在函数中直接找到了并能输出第一个出现的。(他是靠同时记录了序列的起始位置完成的,我的没有记录结尾下标,就只能再调用一次了。)

来源https://blog.csdn.net/qq_36913610/article/details/82319910

#include <stdio.h>
#define MAXSIZE 100000
typedef struct Node{
    int Data[MAXSIZE];
    int size;
}Node, *List; /*传递结构指针效率高*/
List Read(List L);
void PrintSeq(List L);

int main(void){
    Node node;
    List L = &node;
    L = Read(L);
    PrintSeq(L);

    return 0;
}

List Read(List L){
    int n, i;
    scanf("%d", &n);
    L->size = n;
    for(i=0; i<n; i++){
        scanf("%d", &L->Data[i]);
    }

    return L;
}

void PrintSeq(List L){
    int maxL, maxR, maxLen, l, r, len;
    int i;
    if(L->size==0)
        return;
    else{
        maxL=maxR=0;
        maxLen = 1;
    }
    l=r=0;
    len = 1;
    for(i=1; i<L->size; i++){
        if(L->Data[i]>L->Data[i-1]){
            r++;
            len++;
        }
        else{ /*遇到非增长点更新*/
            if(len>maxLen){
                maxL = l;
                maxR = r;
                maxLen = len;
            }
            l=r=i;
            len = 1;
        }
    }
    if(len>maxLen){ /*遍历结束后再次判断以防遗漏*/
        maxL = l;
        maxR = r;
        maxLen = len;
    }

    for(i=maxL; i<=maxR; i++){
        if(i==maxL)
            printf("%d", L->Data[i]);
        else
            printf(" %d", L->Data[i]);
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值