zoukankan      html  css  js  c++  java
  • 300. Longest Increasing Subsequence (Solution 2)

    package LeetCode_300
    
    /**
     * 300. Longest Increasing Subsequence
     * https://leetcode.com/problems/longest-increasing-subsequence/description/
     * Given an unsorted array of integers, find the length of longest increasing subsequence.
    Example:
    Input: [10,9,2,5,3,7,101,18]
    Output: 4
    Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
    
    Note:
    1. There may be more than one LIS combination, it is only necessary for you to return the length.
    2. Your algorithm should run in O(n2) complexity.
    
    Follow up: Could you improve it to O(n log n) time complexity?
     * */
    class Solution2 {
        /*
        * solution 2: Patience Sorting, Time:O(nlogn), Space:O(n)
        * https://www.cs.princeton.edu/courses/archive/spring13/cos423/lectures/LongestIncreasingSubsequence.pdf
        * */
        fun lengthOfLIS(nums: IntArray): Int {
            val n = nums.size
            if (n == 0) {
                return 0
            }
            val list = ArrayList<Int>()
            for (i in nums.indices) {
                /*
                //method 1:
                Collections.binarySearch:
                * 1. list contains nums[i], return the index of nums[i] in list;
                * 2. list not contains nums[i], return ~index, the index is the first number larger than nums[i],
                * (if key not found, index start from 1);
                * */
                /*var x = Collections.binarySearch(list, nums[i])
                if (x < 0) {
                    x = x.inv()
                }
                if (x == list.size) {
                    list.add(nums[i])
                } else {
                    list.set(x, nums[i])
                }*/
    
                //method 2:
                if (list.isEmpty() || list.get(list.lastIndex) < nums[i]) {
                    list.add(nums[i])
                } else {
                    list.set(findFirstLargeOrEquals(list, nums[i]), nums[i])
                }
            }
            return list.size
        }
    
        private fun findFirstLargeOrEquals(list: ArrayList<Int>, target: Int): Int {
            var left = 0
            var right = list.size - 1
            while (left < right) {
                val mid = left + (right - left) / 2
                if (list.get(mid) < target) {
                    //search in right side
                    left = mid + 1
                } else {
                    right = mid
                }
            }
            return left
        }
    }
  • 相关阅读:
    阅读计划
    第一课 课堂练习总结
    人月神话读后感
    软件工程概论11-软件演化
    【HDU4366】【DFS序+分块】Successor
    【转载】【元胞自动机】生命游戏(时间简史)
    【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L
    【BZOJ3295】【块状链表+树状数组】动态逆序对
    【HDU4391】【块状链表】Paint The Wall
    【POJ2887】【块状链表】Big String
  • 原文地址:https://www.cnblogs.com/johnnyzhao/p/14254663.html
Copyright © 2011-2022 走看看