• 最长递增子序列


    
    原数组 arr    [4 2 3 1 5]
    
     LinkedList<Integer> vec ;
    
    i        arr            vec
    0         4  	         4     //直接添加
    1	  2		 2    // 2小于4 替换掉4
    2	  3		 2 3  //直接添加
    3	  1		 1 3  //  1 小于 2  替换。  即  arr[i] 替换掉  vec中  第一个比 arr[i]大的元素。
    4	  5		 1 3 5  
    
    vec 最后的长度即是 LIS 的长度。但vec  不一定是最终的 最大上升子序列,即LIS 
    
    maxLen[] ** 表示以 i 结尾的最长递增子序列长度**。
    
    举个例子 arr [4,2,3,1,5]  对应的  maxLen[] 是 [1,1,2,1,3];
    
    public class S10 {
        public static int[] LIS(int[] arr) {
            //只有一个元素 直接返回
            if (arr.length==1){
                return  arr;
            }
         
            LinkedList<Integer> vec = new LinkedList<>();
            int[] maxLen = new int[arr.length];
            vec.add(arr[0]);
            maxLen[0] = 1;
            //求vec 和 maxLen[]
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] > vec.getLast()) {
                    vec.add(arr[i]);
                    maxLen[i] = vec.size();
                } else if (arr[i] < vec.getLast()) {
                    Iterator<Integer> iterator = vec.iterator();
                    int j = 0;
                    while (iterator.hasNext()) {
                        Integer next = iterator.next();
                        j++;
                        if (next >= arr[i]) {
                            vec.set(j - 1, arr[i]);
                            break;
                        }
                    }
                    maxLen[i] = j;
                } else {
                    maxLen[i] = vec.size();
                }
            }
    		//通过maxLen 和 Vec 计算 最大上升子序列。
            int max = vec.size();
            int[] res = new int[max];
            int k = max - 2;
            boolean f = false;
            int left = 0;
            for (int i = arr.length - 1; i > 0; i--) {
                if (!f && vec.size() == maxLen[i]) {
                    f = true;
                    res[max - 1] = arr[i];
                    left = maxLen[i];
                }
                if (f) {
                    if (left - maxLen[i - 1]==1 && maxLen[i - 1] < max) {
                        max--;
                        res[k] = arr[i - 1];
                        k--;
                        left--;
                    }
                }
    
            }
            return res;
    
        }
    
        public static void main(String[] args) {
            int[] arr = {1,3,8,6,5,2,5};
            int[] lis = LIS(arr);
            for (int i = 0; i < lis.length; i++) {
                System.out.println(lis[i]);
            }
        }
    }
    

  • 相关阅读:
    WPF Popup弹出框箭头自动定位效果
    redis使用3
    linux常用命令
    Redis基础命令使用
    Redis使用笔记1
    jeesite常用注解记录
    Spring@Autowired注解与自动装配
    jeesite中的配置
    jeesite在eclipse中部署
    activiti流程连线与网关以及个人任务、组任务的指定方式
  • 原文地址:https://www.cnblogs.com/paidaxing7090/p/15294012.html
Copyright © 2020-2023  润新知