Minimize splits to generate monotonous Substrings from given String

Given a string str, the task is to find the minimum numbers of substrings that the given string S can be split into, such that each substring is monotonously increasing or decreasing.

Examples:

Input: str = “abcdcba” 
Output:
Explanation: 
The string can be split into a minimum of 2 monotonous substrings {“abcd”(increasing), “cba”(decreasing)}

Input: str = “aeccdhba” 
Output:
Explanation: 
The generated substrings are {“ae”, “ccdh”, “ba”}

Approach: Follow the steps below to solve the problem:



  • Initialize a variable ongoing = ‘N’ to keep track of order of current sequence.
  • Iterate over the string and for each character, follow the steps below:
  • If ongoing == ‘N’
    • If curr_character < prev_character then update ongoing with D(Non-Increasing).
    • Otherwise, if curr_character > prev_character, then update ongoing with I(Non-Decreasing).
    • Otherwise, update ongoing with N(neither Non-Increasing nor Non-Decreasing).
  • Otherwise, if ongoing == ‘I’:
    • If curr_character > prev_character then update ongoing with I.
    • Otherwise, if curr_character < prev_character then update ongoing with N and increment answer.
    • Otherwise, update ongoing with I.
  • else  do the following steps:
    • If curr_character < prev_character then update ongoing with D.
    • Otherwise, if curr_character > prev_character then update ongoing with N and increment answer.
    • Otherwise, update ongoing with D.
  • Finally, print answer+1 is the required answer.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement
// the above approach
#include<bits/stdc++.h>
using namespace std;
  
// Function to return final result
int minReqSubstring(string s, int n)
{
      
    // Initialize variable to keep
    // track of ongoing sequence
    char ongoing = 'N';
  
    int count = 0, l = s.size();
  
    for(int i = 1; i < l; i++)
    {
  
        // If current sequence is neither
        // increasing nor decreasing
        if (ongoing == 'N')
        {
  
            // If prev char is greater
            if (s[i] < s[i - 1]) 
            {
                ongoing = 'D';
            }
  
            // If prev char is same
            else if (s[i] == s[i - 1])
            {
                ongoing = 'N';
            }
  
            // Otherwise
            else 
            {
                ongoing = 'I';
            }
        }
  
        // If current sequence
        // is Non-Decreasing
        else if (ongoing == 'I')
        {
  
            // If prev char is smaller
            if (s[i] > s[i - 1])
            {
                ongoing = 'I';
            }
  
            // If prev char is same
            else if (s[i] == s[i - 1])
            {
                  
                // Update ongoing
                ongoing = 'I';
            }
  
            // Otherwise
            else
            {
  
                // Update ongoing
                ongoing = 'N';
  
                // Increase count
                count += 1;
            }
        }
  
        // If current sequence
        // is Non-Increasing
        else
        {
              
            // If prev char is greater,
            // then update ongoing with D
            if (s[i] < s[i - 1])
            {
                ongoing = 'D';
            }
  
            // If prev char is equal, then
            // update current with D
            else if (s[i] == s[i - 1])
            {
                ongoing = 'D';
            }
  
            // Otherwise, update ongoing
            // with N and increment count
            else
            {
                ongoing = 'N';
                count += 1;
            }
        }
    }
  
    // Return count+1
    return count + 1;
}
  
// Driver Code
int main()
{
    string S = "aeccdhba";
    int n = S.size();
      
    cout << (minReqSubstring(S, n));
    return 0;
}
  
// This code is contributed by Amit Katiyar

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to implement
// the above approach
import java.util.*;
  
class GFG {
  
    // Function to return final result
    static int minReqSubstring(String s, int n)
    {
  
        // Initialize variable to keep
        // track of ongoing sequence
        char ongoing = 'N';
  
        int count = 0, l = s.length();
  
        for (int i = 1; i < l; i++) {
  
            // If current sequence is neither
            // increasing nor decreasing
            if (ongoing == 'N') {
  
                // If prev char is greater
                if (s.charAt(i) < s.charAt(i - 1)) {
                    ongoing = 'D';
                }
  
                // If prev char is same
                else if (s.charAt(i) == s.charAt(i - 1)) {
                    ongoing = 'N';
                }
  
                // Otherwise
                else {
                    ongoing = 'I';
                }
            }
  
            // If current sequence
            // is Non-Decreasing
            else if (ongoing == 'I') {
  
                // If prev char is smaller
                if (s.charAt(i) > s.charAt(i - 1)) {
                    ongoing = 'I';
                }
  
                // If prev char is same
                else if (s.charAt(i) == s.charAt(i - 1)) {
  
                    // Update ongoing
                    ongoing = 'I';
                }
  
                // Otherwise
                else {
  
                    // Update ongoing
                    ongoing = 'N';
  
                    // Increase count
                    count += 1;
                }
            }
  
            // If current sequence
            // is Non-Increasing
            else {
  
                // If prev char is greater,
                // then update ongoing with D
                if (s.charAt(i) < s.charAt(i - 1)) {
                    ongoing = 'D';
                }
  
                // If prev char is equal, then
                // update current with D
                else if (s.charAt(i) == s.charAt(i - 1)) {
                    ongoing = 'D';
                }
  
                // Otherwise, update ongoing
                // with N and increment count
                else {
                    ongoing = 'N';
                    count += 1;
                }
            }
        }
  
        // Return count+1
        return count + 1;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String S = "aeccdhba";
        int n = S.length();
        System.out.print(
            minReqSubstring(S, n));
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement 
# the above approach 
  
# Function to return final result 
def minReqSubstring(s, n):
      
    # Initialize variable to keep 
    # track of ongoing sequence 
    ongoing = 'N'
    count, l = 0, len(s)
      
    for i in range(1, l):
          
        # If current sequence is neither 
        # increasing nor decreasing 
        if ongoing == 'N':
              
            # If prev char is greater 
            if s[i] < s[i - 1]:
                ongoing = 'D'
                  
            # If prev char is same
            elif s[i] == s[i - 1]:
                ongoing = 'N'
                  
            # Otherwise 
            else:
                ongoing = 'I'
                  
        # If current sequence 
        # is Non-Decreasing 
        elif ongoing == 'I':
              
            # If prev char is smaller
            if s[i] > s[i - 1]:
                ongoing = 'I'
                  
            # If prev char is same 
            elif s[i] == s[i - 1]:
                  
                # Update ongoing
                ongoing = 'I'
              
            # Otherwise
            else:
                  
                # Update ongoing 
                ongoing = 'N'
                  
                # Increase count
                count += 1
              
        # If current sequence 
        # is Non-Increasing 
        else:
              
            # If prev char is greater, 
            # then update ongoing with D
            if s[i] < s[i - 1]:
                ongoing = 'D'
                  
            # If prev char is equal, then 
            # update current with D 
            elif s[i] == s[i - 1]:
                ongoing = 'D'
                  
            # Otherwise, update ongoing 
            # with N and increment count 
            else:
                ongoing = 'N'
                count += 1
                  
    # Return count + 1 
    return count + 1
  
# Driver code
S = "aeccdhba"
n = len(S)
  
print(minReqSubstring(S, n))
  
# This code is contributed by Stuti Pathak

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# Program to implement
// the above approach
using System;
class GFG{
  
  // Function to return readonly result
  static int minReqSubstring(String s, int n)
  {
  
    // Initialize variable to keep
    // track of ongoing sequence
    char ongoing = 'N';
  
    int count = 0, l = s.Length;
  
    for (int i = 1; i < l; i++) 
    {
  
      // If current sequence is neither
      // increasing nor decreasing
      if (ongoing == 'N')
      {
  
        // If prev char is greater
        if (s[i] < s[i - 1])
        {
          ongoing = 'D';
        }
  
        // If prev char is same
        else if (s[i] == s[i - 1]) 
        {
          ongoing = 'N';
        }
  
        // Otherwise
        else
        {
          ongoing = 'I';
        }
      }
  
      // If current sequence
      // is Non-Decreasing
      else if (ongoing == 'I'
      {
  
        // If prev char is smaller
        if (s[i] > s[i - 1]) 
        {
          ongoing = 'I';
        }
  
        // If prev char is same
        else if (s[i] == s[i - 1])
        {
  
          // Update ongoing
          ongoing = 'I';
        }
  
        // Otherwise
        else 
        {
  
          // Update ongoing
          ongoing = 'N';
  
          // Increase count
          count += 1;
        }
      }
  
      // If current sequence
      // is Non-Increasing
      else 
      {
  
        // If prev char is greater,
        // then update ongoing with D
        if (s[i] < s[i - 1]) 
        {
          ongoing = 'D';
        }
  
        // If prev char is equal, then
        // update current with D
        else if (s[i] == s[i - 1]) 
        {
          ongoing = 'D';
        }
  
        // Otherwise, update ongoing
        // with N and increment count
        else 
        {
          ongoing = 'N';
          count += 1;
        }
      }
    }
  
    // Return count+1
    return count + 1;
  }
  
  // Driver Code
  public static void Main(String[] args)
  {
    String S = "aeccdhba";
    int n = S.Length;
    Console.Write(minReqSubstring(S, n));
  }
}
  
// This code is contributed by Rohit_ranjan

chevron_right


Output: 

3

Time Complexity: O(N) 
Auxiliary Space: O(1)
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

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.