zoukankan      html  css  js  c++  java
  • 编程之美2.16 求数组中最长递增子序列

     编程之美2.16 最长递增子序列:

    写一个时间复杂度尽可能低的程序,求一个一维数组(N个元素)中的最长递增子序列的长度。例如:在序列1,-1,2,-3,4,-5,6-7中,其最长的递增子序列为1,2,4,6

    分析:利用动态规划分析。用A[i]来更新maxLen和MaxV:,从A[0]~A[i-1]可能存在多个存在多个子问题的最优解,所以需要将他他们合并为一个。

    1. 当A[i]>MaxV[maxLen](即子问题最优解的最小值)时,maxLen++ && MaxV[maxLen] = a[i]

      A[i]>MaxV[maxLen]时,A[i]必然比MaxV[0]-MaxV[maxLen]中所有的值都大,因此,比如不会更新这些已有的长度的尾部最小值
    2. 当A[j]<A[i]<A[j+1]时,即存在一个更小的局部问题最优解,所以需要更新这个最优解。更新长度为j+1的记录,即:MaxV[j+1] =A[i]

       1).对于MaxV[0]-MaxV[j]的不用说了,A[i]比他们都大,他们都不会更新了,

       2).对于MaxV[j+1],刚好可以更新其值为A[i],

       3).对于MaxV[j+2]-MaxV[MaxLen]的元素由于递增子序列的后无效性,也不需要更新。对于长度相同的最长递增子序列, 我们可以将他们分到同一组中(合并为一组),并只记录它们最大元素的最小值MaxV[长度值], 如: (1,3, 4, 6) 和(-4, -2, -1, 8), 可以合并为(-4, -2, -1,6)

    就是这样了,分析好对于每个A[i],如何更新maxLen和MaxV就ok了。

            // 用二分法查找是否存在 MaxV[k]<array[i]<MaxV[k+1]
            public static int BinarySearch(int[] array, int maxLength, int target)
            {   
                int left = 0;
                int right = maxLength - 1;
                int middle = 0;
    
                while (left <= right)
                {
                    middle = (left + right) / 2;
    
                    if (array[middle] == target)
                    {
                        return middle;
                    }
                    else if (array[middle] < target)
                    {
                        left = middle + 1;
                    }
                    else
                    {
                        right = middle - 1;
                    }
                }
    
                return array[middle] > target ? middle : middle + 1;
            }
    
            // 编程之美2.16 最长递增子序列  
            public static int GetMaxLength(int[] array)
            {
                int maxLen = 1;
                int[] MaxV = new int[array.Length];
                MaxV[0] = array[0];
    
                for (int i = 1; i < array.Length; i++)
                {
                    if (array[i] > MaxV[maxLen - 1])
                    {
                        maxLen++;
                        MaxV[maxLen-1] = array[i];
                    }
                    else  //if last_min[k]<array[i]<last_min[k+1]
                    {
                        int pos = BinarySearch(MaxV,maxLen, array[i]);
    
                        if (pos >= 0) //存在 MaxV[k]<array[i]<MaxV[k+1],更新 MaxV[k+1]
                        {
                            MaxV[pos] = array[i];
                        }
                    }
                }
    
                return maxLen;
            }
  • 相关阅读:
    使用Flex Bison 和LLVM编写自己的编译器[zz]
    应用开发框架讨论应用配置wxFileConfig
    交流电220V是从何而来的
    电压、电流、电阻的概念
    电路返回端,接地,大地,等势体,静电场,回路,电能
    泛型实现List(List<T>)排序
    javascript注册功能
    层(div或table)的左右滚动
    javascript正则表达式检验
    JavaScript通用类库(ZT)
  • 原文地址:https://www.cnblogs.com/Jessy/p/3482496.html
Copyright © 2011-2022 走看看