最长连续递增子列

在这里插入图片描述

#include <stdio.h>
int main()
{
    int i,N;
    scanf("%d",&N);
    int Data[N];
    for(i=0;i<N;i++)
        scanf("%d",&Data[i]);
    int Max=1, front=0,rear=0;//保留最终的结果
    int head=0,tail=0,temp_max=0,last=0;//临时存放结果
    //这里要注意每次更新i的值是怎样的
    for(i=0;i<N;i=tail)
    {
    	//初始化临时存放的最大值
        //temp_max=1;
        temp_max = 0;
        //如果位置真不是没有抵达数组的最后
        while(tail<N)
        {
        	//tail = last +1;
        	//判断后一个值是否大于前一个值,
            //if(Data[tail]>Data[last] && tail < N)
            if(Data[tail]>Data[last])
            {
            //如果是,就满足递增序列要求,更新临时最大值,last与tail都后移一位
                temp_max++;
                last = tail;
                tail++;
            }
            else
            {//否则就不满足递增条件,跳出循环,同时将last向前移一位(因为跳出的时候last指向的是大的那个数字,如果不后移,会陷入死循环,tail得不到更新。
            	last++;
            	break;
			}
                
        }
        //退出while循环意味着找完了一个递增序列,这时比较这个递增序列是否为当前的最长序列,如果是就更新最长序列的信息
        if(temp_max>Max)
        {
            front = head;
            rear = tail--;
            Max = temp_max;
        }
        //将头指针初始化和尾指针指向同一位置,开启下一个循环。
        head = tail;
        
    }
    
    printf("%d",Data[front]);
    int t = front+1;
    for(t;t<front+Max;t++)
        printf(" %d",Data[t]);
    return 0;
}

**这个程序还可以进一步优化,last和rear的值如何更新需要在深入思考,同时如果使用链表存放数据对于头尾的更新更容易理解一点(个人推测)
**
本题要求是输出最长连续递增子列,思考思路:第一反应是和输出最大和相似因此可以考虑在线处理,这样的话时间复杂度就是线性的,只需要扫描一遍就可以得到最终结果,如果对于长度相同的结果则只保留第一个子列
那按照这个思路,按照题目要求最终要输出最长子列,那就要求我们需要直到最长子列的信息,需要哪些信息才能输出呢?
首先对于输入用什么方式存放才合理呢?这里个人认为链表与数组均可,只是保存最长子列的方法有所差异,思想是相同的,同时链表会消耗更多的内存,所以这里使用数组实现。
思路1:用一个数组存放最长子列,优点:好想,第一反应就是这样,缺点。更新比较麻烦很难在线更新,同时空间开销比较大,
思路2:通过记录最长子列的起点与终点,优点:只需要两个整形的空间就可以输出最长子列,同时不用额外开辟空间。节省内存;
思路3:通过记录头结点与最大值同样可以实现
回到题目:
首先看一下递增序列有什么特点:
设一个队列:a1,a2……an
如果从ai->aj都是递增的,到aj+1就失去了递增的特点,那么可以推出 ak(k属于i到j任意数字)到aj与aj+1组成的序列都不是递增序列,exp:在这里插入图片描述

在遍历完一个递增序列后,将这个递增序列的最大值temp_max与当前序列最大值Max比较,如果比当前的最大值大就更新最大值,然后从当前序列最后继续进行遍历。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
动态规划最长递增子序列问题描述的是在一个已知序列中,取出若干元素组成一个新的序列,要求新序列中的元素顺序保持不变且递增,找出最长的这样的子序列。为了解决这个问题,可以采用动态规划的思路。 首先,定义一个dp数组,dp[i]表示以第i个元素作为末尾的最长递增子序列的长度。那么,我们要求的最长递增子序列的长度就是dp数组中的最大值。 接下来,我们需要确定dp数组的递推关系。可以采用以下的递推公式: dp[i] = max(dp[j] + 1),其中j < i且nums[j] < nums[i]。 这个递推公式的意思是,以第i个元素作为末尾的最长递增子序列的长度,等于在前面的元素中找到一个小于nums[i]的元素,使得以该元素作为末尾的最长递增子序列的长度加上1,得到的结果最大。也就是说,我们要找到一个在i之前的位置j,使得dp[j]最大,并且nums[j] < nums[i]。 通过计算dp数组中的每个元素,最后得到的dp数组中的最大值即为最长递增子序列的长度。 总结起来,动态规划最长递增子序列的思路是:先定义dp数组的含义,然后确定dp数组的递推关系,最后计算dp数组中的最大值即为最长递增子序列的长度。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [动态规划——最长递增子序列](https://blog.csdn.net/qq_36935691/article/details/113924931)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [动态规划系列之「最长递增子序列」](https://blog.csdn.net/weixin_44471490/article/details/109030232)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值