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

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

数组: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用记录下来的起始位置加上记录的最长长度构成

相关推荐