[algorithm] How to determine the longest increasing subsequence using dynamic programming?

The O(NLog(N)) Recursive DP Approach To Finding the Longest Increasing Subsequence (LIS)


Explanation

This algorithm involves creating a tree with node format as (a,b).

a represents the next element we are considering appending to the valid subsequence so far.

b represents the starting index of the remaining subarray that the next decision will be made from if a gets appended to the end of the subarray we have so far.

Algorithm

  1. We start with an invalid root (INT_MIN,0), pointing at index zero of the array since subsequence is empty at this point, i.e. b = 0.

  2. Base Case: return 1 if b >= array.length.

  3. Loop through all the elements in the array from the b index to the end of the array, i.e i = b ... array.length-1. i) If an element, array[i] is greater than the current a, it is qualified to be considered as one of the elements to be appended to the subsequence we have so far. ii) Recurse into the node (array[i],b+1), where a is the element we encountered in 2(i) which is qualified to be appended to the subsequence we have so far. And b+1 is the next index of the array to be considered. iii) Return the max length obtained by looping through i = b ... array.length. In a case where a is bigger than any other element from i = b to array.length, return 1.

  4. Compute the level of the tree built as level. Finally, level - 1 is the desired LIS. That is the number of edges in the longest path of the tree.

NB: The memorization part of the algorithm is left out since it's clear from the tree.

Random Example Nodes marked x are fetched from the DB memoized values. enter image description here

Java Implementation

public int lengthOfLIS(int[] nums) {
            return LIS(nums,Integer.MIN_VALUE, 0,new HashMap<>()) -1;
    }
    public int LIS(int[] arr, int value, int nextIndex, Map<String,Integer> memo){
        if(memo.containsKey(value+","+nextIndex))return memo.get(value+","+nextIndex);
        if(nextIndex >= arr.length)return 1;

        int max = Integer.MIN_VALUE;
        for(int i=nextIndex; i<arr.length; i++){
            if(arr[i] > value){
                max = Math.max(max,LIS(arr,arr[i],i+1,memo));
            }
        }
        if(max == Integer.MIN_VALUE)return 1;
        max++;
        memo.put(value+","+nextIndex,max);
        return max;
    }

Examples related to algorithm

How can I tell if an algorithm is efficient? Find the smallest positive integer that does not occur in a given sequence Efficiently getting all divisors of a given number Peak signal detection in realtime timeseries data What is the optimal algorithm for the game 2048? How can I sort a std::map first by value, then by key? Finding square root without using sqrt function? Fastest way to flatten / un-flatten nested JSON objects Mergesort with Python Find common substring between two strings

Examples related to computer-science

HTML5 Canvas background image What exactly does big ? notation represent? Fixed point vs Floating point number What are the differences between a program and an application? What do we mean by Byte array? How to determine the longest increasing subsequence using dynamic programming? What is "entropy and information gain"? What are the differences between NP, NP-Complete and NP-Hard? What is the difference between statically typed and dynamically typed languages? What is “2's Complement”?

Examples related to dynamic-programming

Find common substring between two strings Difference between Divide and Conquer Algo and Dynamic Programming What is the difference between bottom-up and top-down? How to determine the longest increasing subsequence using dynamic programming? What is dynamic programming?

Examples related to memoization

What is the difference between bottom-up and top-down? How to determine the longest increasing subsequence using dynamic programming? What is memoization and how can I use it in Python? Is there a decorator to simply cache function return values?

Examples related to lis

How to determine the longest increasing subsequence using dynamic programming?