Given an array of random numbers, find the longest monotonically increasing subsequence (LIS) in the array. If you want to understand the O(NlogN) approach, it’s explained very clearly here.
In this post, a simple and time-saving implementation of O(NlogN) approach using stl is discussed. Below is the code for LIS O(NlogN):
Implementation:
C++
// C++ implementation // to find LIS #include<iostream> #include<algorithm> #include<set> using namespace std;
// Return length of LIS in arr[] of size N int lis( int arr[], int N)
{ int i;
set< int > s;
set< int >::iterator k;
for (i=0; i<N; i++)
{
// Check if the element was actually inserted
// An element in set is not inserted if it is
// already present. Please see
if (s.insert(arr[i]).second)
{
// Find the position of inserted element in iterator k
k = s.find(arr[i]);
k++; // Find the next greater element in set
// If the new element is not inserted at the end, then
// remove the greater element next to it (This is tricky)
if (k!=s.end()) s.erase(k);
}
}
// Note that set s may not contain actual LIS, but its size gives
// us the length of LIS
return s.size();
} int main()
{ int arr[] = {8, 9, 12, 10, 11};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << lis(arr, n)<< endl;
} |
Java
// Java implementation // to find LIS import java.util.*;
import java.util.Set;
class GFG {
// Return length of LIS in arr[] of size N
public static int lis( int [] arr, int N)
{
Set<Integer> s = new HashSet<>();
Iterator<Integer> k;
for ( int i = 0 ; i < N; i++)
{
// Check if the element was actually inserted
// An element in set is not inserted if it is
// already present. Please see
if (s.add(arr[i]))
{
// Find the position of inserted element in
// iterator k
k = s.iterator();
// Find the next greater element in set
while (k.hasNext() && k.next() < arr[i]);
// If the new element is not inserted at the
// end, then remove the greater element next
// to it (This is tricky)
if (k.hasNext())
s.remove(k.next());
}
}
// Note that set s may not contain actual LIS, but
// its size gives us the length of LIS
return s.size();
}
public static void main(String[] args)
{
int [] arr = { 8 , 9 , 12 , 10 , 11 };
int n = arr.length;
System.out.println(lis(arr, n));
}
} // This Code is Contributed by Prasad Kandekar(prasad264) |
Python3
# python implementation to find LIS # Return length of LIS in arr[] of size N def lis(arr):
s = set ()
for i in range ( len (arr)):
# Check if the element was actually inserted
# An element in set is not inserted if it is
# already present
if arr[i] not in s:
s.add(arr[i])
# Find the position of inserted element
# Find the next greater element in set
next_greater = [x for x in s if x > arr[i]]
# If the new element is not inserted at the end, then
# remove the greater element next to it (This is tricky)
if next_greater:
s.remove( min (next_greater))
# Note that set s may not contain actual LIS, but its size gives
# us the length of LIS
return len (s)
arr = [ 8 , 9 , 12 , 10 , 11 ]
print (lis(arr))
# This Code is Contributed by Prasad Kandekar(prasad264) |
C#
// C# implementation // to find LIS using System;
using System.Collections.Generic;
class GFG {
// Return length of LIS in arr[] of size N
public static int lis( int [] arr, int N)
{
SortedSet< int > s = new SortedSet< int >();
SortedSet< int >.Enumerator k;
for ( int i = 0; i < N; i++)
{
// Check if the element was actually inserted
// An element in set is not inserted if it is
// already present. Please see
if (s.Add(arr[i]))
{
// Find the position of inserted element in
// iterator k
k = s.GetEnumerator();
// Find the next greater element in set
while (k.MoveNext() && k.Current < arr[i]) ;
// If the new element is not inserted at the
// end, then remove the greater element next
// to it (This is tricky)
if (k.MoveNext())
s.Remove(k.Current);
}
}
// Note that set s may not contain actual LIS, but
// its size gives us the length of LIS
return s.Count;
}
public static void Main(String[] args)
{
int [] arr = { 8, 9, 12, 10, 11 };
int n = arr.Length;
Console.WriteLine(lis(arr, n));
}
} |
Javascript
// JavaScript implementation to find LIS // Return length of LIS in arr[] of size N function lis(arr) {
var s = new Set();
for ( var i = 0; i < arr.length; i++) {
// Check if the element was actually inserted
// An element in set is not inserted if it is
// already present
if (!s.has(arr[i])) {
s.add(arr[i]);
// Find the position of inserted element
// Find the next greater element in set
var nextGreater = Array.from(s).filter(x => x > arr[i]);
// If the new element is not inserted at the end, then
// remove the greater element next to it (This is tricky)
if (nextGreater.length > 0) {
s. delete (Math.min(...nextGreater));
}
}
}
// Note that set s may not contain actual LIS, but its size gives
// us the length of LIS
return s.size;
} var arr = [8, 9, 12, 10, 11];
console.log(lis(arr)); // This Code is Contributed by Prasad Kandekar(prasad264) |
Output
4
Time Complexity: O(N log N)
Auxiliary Space: O(N)