# Longest subsequence having greater corner values

Given an array **arr[]** containing a random permutation of first **N** natural numbers, the task is to find the longest sub-sequence having the property that the first and the last elements are greater than all the other sub-sequence elements.

**Examples:**

Input:arr[] = {3, 1, 5, 2, 4}

Output:4

The sub-sequence is {3, 1, 2, 4}. The corner elements of this subsequence are greater than all other elements.

Input:arr[] = {1, 2, 3, 4, 5}

Output:2

We cannot make a subsequence of size greater than 2.

**Approach:** If we fix the leftmost and the rightmost elements of a sub-sequence, we are interested in counting how many elements between them have a smaller value than both. A straight forward implementation of this idea has a complexity of O(N^{3}).

In order to reduce the complexity, we approach the problem differently. Instead of fixing the ends of the sub-sequence, we fix the elements in between. The idea is that for a given X (1 ≤ X ≤ N), we want to find two elements greater or equal to X, that have between them as many elements as possible less than X. For a fixed X it’s optimal to choose the leftmost and rightmost elements ≤ X. Now we have a better O(N^{2}) solution.

As X increases, the leftmost element can only increase, while the rightmost one can only decrease. We can use a pointer for each of them to get an amortised complexity of O(N).

Below is the implementation of the above approach:

`// Java implementation of the approach ` `class` `GFG { ` ` ` ` ` `static` `int` `MAXN = (` `int` `)1e5 + ` `5` `; ` ` ` ` ` `// Function to return the length of the ` ` ` `// longest required sub-sequence ` ` ` `static` `int` `longestSubSeq(` `int` `n, ` `int` `[] arr) ` ` ` `{ ` ` ` `int` `max_length = ` `0` `; ` ` ` ` ` `// Create a position array to find ` ` ` `// where an element is present ` ` ` `int` `[] pos = ` `new` `int` `[MAXN]; ` ` ` ` ` `for` `(` `int` `i = ` `0` `; i < n; i++) ` ` ` `pos[arr[i] - ` `1` `] = i; ` ` ` ` ` `int` `left = n, right = ` `0` `; ` ` ` ` ` `for` `(` `int` `i = n - ` `1` `, num = ` `1` `; i >= ` `0` `; ` ` ` `i -= ` `1` `, num += ` `1` `) { ` ` ` ` ` `// Store the minimum position ` ` ` `// to the left ` ` ` `left = Math.min(left, pos[i]); ` ` ` ` ` `// Store the maximum position to ` ` ` `// the right ` ` ` `right = Math.max(right, pos[i]); ` ` ` ` ` `// Recompute current maximum ` ` ` `max_length = Math.max(max_length, ` ` ` `right - left - num + ` `3` `); ` ` ` `} ` ` ` ` ` `// Edge case when there is a single ` ` ` `// element in the sequence ` ` ` `if` `(n == ` `1` `) ` ` ` `max_length = ` `1` `; ` ` ` ` ` `return` `max_length; ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `public` `static` `void` `main(String[] args) ` ` ` `{ ` ` ` `int` `arr[] = { ` `1` `, ` `2` `, ` `3` `, ` `4` `, ` `5` `}; ` ` ` `int` `n = arr.length; ` ` ` `System.out.println(longestSubSeq(n, arr)); ` ` ` `} ` `} ` |

*chevron_right*

*filter_none*

**Output:**

2

## Recommended Posts:

- Counting values greater than equal to x after increments
- Python | Check if all the values in a list that are greater than a given value
- Replace two consecutive equal values with one greater
- Replace repeating elements with greater that greatest values
- Longest subsequence with no 0 after 1
- Longest Zig-Zag Subsequence
- Longest Consecutive Subsequence
- Longest Repeating Subsequence
- Longest Bitonic Subsequence in O(n log n)
- Longest Uncommon Subsequence
- Longest subsequence whose average is less than K
- Longest Bitonic Subsequence | DP-15
- Longest Increasing Odd Even Subsequence
- Longest Common Subsequence | DP-4
- Longest Palindromic Subsequence | DP-12

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.