Horje
Minimum number of strictly decreasing subsequences

Given an array arr[] of size N. The task is to split the array into minimum number of strictly decreasing subsequences. Calculate the minimum number of subsequences we can get by splitting.

Examples:

Input: N = 4, arr[] = {3, 5, 1, 2}
Output: 2
Explanation: We can split the array into two subsequences: {3,1} and {5,2}

Both are strictly decreasing subsequence.

Input: N = 3, arr[] = {3,3,3}
Output: 3
Explanation: We can split the array into three subsequences: {3},{3} and {3}

Approach: To solve the problem, follow the below idea:

If we observe carefully, we can see that the Minimum number of decreasing subsequences is equal to the length of longest increasing subsequence where each element from the longest increasing subsequence belongs to a single decreasing subsequence, so it can be found in N*Log(N)

Below is the implementation of the above approach:

C++

#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
class Solution {
public:
    // Function to find the length of the minimum decreasing subsequence.
    int minDecreasingSub(int N, vector<int> arr) {
        // Initialize a vector to store the elements of the decreasing subsequence.
        vector<int> seq;
         
        // Add the first element of the array to the sequence.
        seq.push_back(arr[0]);
 
        // Iterate through the array starting from the second element.
        for (auto i = 1; i < N; i++) {
            // Find the position where the current element should be inserted in the sequence.
            int ind = upper_bound(seq.begin(), seq.end(), arr[i]) - seq.begin();
 
            // If the position is equal to the size of the sequence, push the element to the end.
            if (ind == seq.size())
                seq.push_back(arr[i]);
            // Otherwise, replace the element at the found position with the current element.
            else
                seq[ind] = arr[i];
        }
 
        // Return the size of the sequence as the result.
        return seq.size();
    }
};
 
int main() {
    // Example usage in the main block
    vector<int> arr = {5, 2, 7, 8, 6};
    int N = arr.size();
 
    Solution solution;
    int result = solution.minDecreasingSub(N, arr);
 
    // Display the result.
    cout << "Length of the minimum decreasing subsequence: " << result << endl;
 
    return 0;
}

Java

import java.util.ArrayList;
import java.util.Collections;
 
class Solution {
    // Function to find the length of the minimum decreasing subsequence.
    public int minDecreasingSub(int N, ArrayList<Integer> arr) {
        // Initialize a list to store the elements of the decreasing subsequence.
        ArrayList<Integer> seq = new ArrayList<>();
 
        // Add the first element of the array to the sequence.
        seq.add(arr.get(0));
 
        // Iterate through the array starting from the second element.
        for (int i = 1; i < N; i++) {
            // Find the position where the current element should be inserted in the sequence.
            int ind = Collections.binarySearch(seq, arr.get(i));
 
            // If the position is negative, it means the element is not present.
            // Convert the negative position to the insertion point.
            ind = (ind < 0) ? -ind - 1 : ind;
 
            // If the position is equal to the size of the sequence, add the element to the end.
            if (ind == seq.size())
                seq.add(arr.get(i));
            // Otherwise, replace the element at the found position with the current element.
            else
                seq.set(ind, arr.get(i));
        }
 
        // Return the size of the sequence as the result.
        return seq.size();
    }
 
    public static void main(String[] args) {
        // Example usage in the main block
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(5);
        arr.add(2);
        arr.add(7);
        arr.add(8);
        arr.add(6);
        int N = arr.size();
 
        Solution solution = new Solution();
        int result = solution.minDecreasingSub(N, arr);
 
        // Display the result.
        System.out.println("Length of the minimum decreasing subsequence: " + result);
    }
}

Python

class Solution:
    # Function to find the length of the minimum decreasing subsequence.
    def min_decreasing_sub(self, N, arr):
        # Initialize a list to store the elements of the decreasing subsequence.
        seq = [arr[0]]
 
        # Iterate through the array starting from the second element.
        for i in range(1, N):
            # Find the position where the current element should be inserted in the sequence.
            ind = self.binary_search(seq, arr[i])
 
            # If the position is equal to the size of the sequence, add the element to the end.
            if ind == len(seq):
                seq.append(arr[i])
            # Otherwise, replace the element at the found position with the current element.
            else:
                seq[ind] = arr[i]
 
        # Return the size of the sequence as the result.
        return len(seq)
 
    # Custom binary search function
    def binary_search(self, seq, target):
        low, high = 0, len(seq)
 
        while low < high:
            mid = (low + high) // 2
 
            if seq[mid] < target:
                low = mid + 1
            else:
                high = mid
 
        return low
 
# Example usage
arr = [5, 2, 7, 8, 6]
N = len(arr)
 
solution = Solution()
result = solution.min_decreasing_sub(N, arr)
 
# Display the result.
print("Length of the minimum decreasing subsequence:", result)

C#

using System;
 
class Solution {
    // Function to find the length of the minimum decreasing
    // subsequence.
    public int MinDecreasingSub(int N, int[] arr)
    {
        // Initialize a list to store the elements of the
        // decreasing subsequence.
        int[] seq = new int[] { arr[0] };
 
        // Iterate through the array starting from the
        // second element.
        for (int i = 1; i < N; i++) {
            // Find the position where the current element
            // should be inserted in the sequence.
            int ind = BinarySearch(seq, arr[i]);
 
            // If the position is equal to the size of the
            // sequence, add the element to the end.
            if (ind == seq.Length) {
                Array.Resize(ref seq, seq.Length + 1);
                seq[ind] = arr[i];
            }
            // Otherwise, replace the element at the found
            // position with the current element.
            else {
                seq[ind] = arr[i];
            }
        }
 
        // Return the size of the sequence as the result.
        return seq.Length;
    }
 
    // Custom binary search function
    private int BinarySearch(int[] seq, int target)
    {
        int low = 0, high = seq.Length;
 
        while (low < high) {
            int mid = (low + high) / 2;
 
            if (seq[mid] < target) {
                low = mid + 1;
            }
            else {
                high = mid;
            }
        }
 
        return low;
    }
}
 
class Program {
    static void Main()
    {
        int[] arr = { 5, 2, 7, 8, 6 };
        int N = arr.Length;
 
        Solution solution = new Solution();
        int result = solution.MinDecreasingSub(N, arr);
 
        // Display the result.
        Console.WriteLine(
            "Length of the minimum decreasing subsequence: "
            + result);
    }
}
 
// This code is contributed by shivamgupta0987654321

Javascript

class Solution {
    // Function to find the length of the minimum decreasing subsequence.
    minDecreasingSub(N, arr) {
        // Initialize a sequence array to store the elements of the decreasing subsequence.
        let seq = [];
         
        // Add the first element of the array to the sequence.
        seq.push(arr[0]);
 
        // Iterate through the array starting from the second element.
        for (let i = 1; i < N; i++) {
            // Find the position where the current element should be inserted in the sequence.
            let ind = this.upperBound(seq, arr[i]);
 
            // If the position is equal to the size of the sequence, push the element to the end.
            if (ind === seq.length)
                seq.push(arr[i]);
            // Otherwise, replace the element at the found position with the current element.
            else
                seq[ind] = arr[i];
        }
 
        // Return the size of the sequence as the result.
        return seq.length;
    }
 
    // Helper function to find the upper bound of an element in the sequence.
    upperBound(seq, target) {
        let left = 0;
        let right = seq.length;
 
        while (left < right) {
            let mid = Math.floor((left + right) / 2);
 
            if (seq[mid] <= target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
 
        return left;
    }
}
 
// Example usage in the main block
let arr = [5, 2, 7, 8, 6];
let N = arr.length;
 
let solution = new Solution();
let result = solution.minDecreasingSub(N, arr);
 
// Display the result.
console.log("Length of the minimum decreasing subsequence: " + result);

Output

Length of the minimum decreasing subsequence: 3



Time Complexity: O(N log N), where N is the length of array arr[].
Auxiliary Space: O(N)




Reffered: https://www.geeksforgeeks.org


DSA

Related
Find maximum frequency of any point across all ranges Find maximum frequency of any point across all ranges
Does jump search need to be sorted? Does jump search need to be sorted?
In which case pigeonhole sort is best? In which case pigeonhole sort is best?
What size of arrays is Shell Sort good? What size of arrays is Shell Sort good?
What is the stupidest sorting algorithm? (Worst Sorting Algorithm) What is the stupidest sorting algorithm? (Worst Sorting Algorithm)

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
12