【算法】——查找:最长连续递增子序列(部分有序)

找出在数组中的最长递增子序列

数组:1,9,2,5,7,3,4,6,8,0

最长递增子序列:3,4,6,8

思路:

遇到大的就移动,如果在某一个位置变小了就计算这一段的长度(双指针)
不停更新最大的length
一个在前线,一个在后面作为游标,最后结束了看一下战线拉了有多长

public class 最长递增子序列 {

    public static void main(String[] args) {
        int []arr = {0,1,0,1,2,3,1,2,0,1,2,3,4,5,1};
        getLargestLen(arr);

    }

    private static void getLargestLen(int[] arr) {
        int begin=0;     // 最长递增子序列长度的开始位
        int maxLen = 1; // 最长递增子序列长度
        int k = 1;  // 递增子序列长度
        for (int end = 1; end < arr.length; end++) {
            if(arr[end]>=arr[end-1]){
                k++;
            } else {
                k=1;
            }
            if (k>=maxLen) {
                maxLen = k;
                begin = end-maxLen+1;
            }
        }
        System.out.print("最长连续递增子序列为:");
        for(int i = begin;i<begin+maxLen;i++)
            System.out.print(arr[i] + "   ");
    }

}

上述代码的主要思想是

因为需要找到连续递增的始末位置,所以需要一个begin来记录需要输入最长连续递增序列的开始位置

以及end来记录需要输入最长连续递增序列的最后位置,又因为不论是否在中间隔断不再递增,end一直需要向后移动,所以可以用end作为循环for(int end=0; end<arr.length; end++);

考虑到如果下一个数不再比上一个数大,那么起始位置应该改变而不是再进行递增,我们首先可以在当变小的时候,把记录的该次的递增序列长度的计数器k变为1(重新开始新的一次记录),当然在k已经变成1的情况下,上一次记录的最长递增序列长度不需要再等于k,而且begin也就是上次保存的位置

通过在循环中不断地让记录的该段连续递增序列的长度k和记录的最长长度进行比较,来更新最长的长度以及更新此刻的起始位置

关于起始位置,是在仍然满足下一个比上一个数大的情况下的话,begin的位置就不会改变,通过思考可以得到一个连续递增序列的起始位置应该是末位置减去记录的该段目前的最长位置+1得到

注意最后输出的时候起始点就是begin,但是末位置不再是end,因为这个是在循环的范围中有效,所以末位置应该hi用记录下来的起始位置加上记录的最长长度构成

原文地址:https://www.cnblogs.com/jessie99/p/12342549.html

时间: 2024-11-10 15:59:22

【算法】——查找:最长连续递增子序列(部分有序)的相关文章

任意区间的最长连续递增子序列,最大连续子序列和

hdu3308 给n个数,有m个操作 U a b 表示将第a个数改成b Q a b 表示询问区间[a,b]的最长连续递增子序列. 区间询问问题且带修改,一般是用线段树来解决 那么要维护 Llen[rt], Lval[rt][2] 表示rt所对应的区间[l,r] 以l开头的最长连续递增子序列的长度, Lval[rt][0]表示子序列的最左边的值,Lval[rt][1]表示子序列最右边的值 Rlen[rt],Rval[rt][2]  表示rt所对应的区间[l,r]以r结尾的最长连续递增子序列的长度,

最长连续递增子序列(部分有序)

题目:(1,9,2,5,7,3,4,6,8,0,)中最长的递增子序列为(3,4,6,8). 代码: public class 最长递增子序列 { public static void main(String[] args) { int []arr = {1,0,2,5,7,3,4,6,8,9,1,2}; getLargestLen(arr); } private static void getLargestLen(int[] arr) { int begin=0; // 最长递增子序列长度的开始

[LintCode] Longest Increasing Continuous Subsequence 最长连续递增子序列

Give an integer array,find the longest increasing continuous subsequence in this array. An increasing continuous subsequence: Can be from right to left or from left to right. Indices of the integers in the subsequence should be continuous. Notice O(n

最长单调递增子序列 POJ 3903 Stock Exchange .

题目传送门 : -------->点这里点这里<---------- 题目大意: 给出一串正整数,个数为N个.1<=N<=100000.求最长单调递增子序列长度. 样例输入: 6 5 2 1 4 5 3 3 1 1 1 4 4 3 2 1 样例输出: 3 1 1 =================================================================== 最长单调递增子序列问题的DP朴素算法复杂度为 O(n^2); 然而题目中的 N 最大有

LeetCode 674. 最长连续递增序列(Longest Continuous Increasing Subsequence) 18

674. 最长连续递增序列 674. Longest Continuous Increasing Subsequence 题目描述 给定一个未经排序的整型数组,找到最长且连续的递增序列. Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). 每日一算法2019/5/21Day 18LeetCode674. Longest Conti

HDURevenge of Segment Tree(第二长的递增子序列)

题目链接 题目大意:这题是求第二长的递增子序列. 解题思路:用n^2的算法来求LIS,但是这里还要记录一下最长的那个序列是否有多种组成方式,如果>= 2, 那么第二长的还是最长的LIS的长度,否则就是LIS - 1: 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1005; int l[maxn], c[maxn

最长单调递增子序列的三种解法

问题描述: 找出由n个数组成的序列的最长单调递增子序列 解法一:转化成LCS问题求解,时间复杂度为O(n*n). 思路:原序列为A,把A按升序排序得到序列B,求出A,B序列的最长公共子序列,即为A的最长单调递增子序列. #include<iostream> #include<algorithm> #include<string> #include<cstdio> using namespace std; //转化成LCS问题,时间复杂度O(n*n) int

最长单调递增子序列问题

题目:设计一个 O( n ^ 2 )复杂度的算法,找出由 n 个数组成的序列的最长单调递增子序列. import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { int n = scanner.nextInt(); int[] nums = new

3.分治法研究-搜索数组中的最长连续递增子集

//分治算法研究 搜索数组中的最长连续递增子集var cc=consolefunction find_max_crossing_lenarray(A,low,mid,high){    var max_left=mid,max_right=mid    var left_sum=1    var sum=0    for(var i=mid;i>low;i--){        sum=A[i]-A[i-1]        if(sum==1){            left_sum++