Minimize splits to generate monotonous Substrings from given String
Last Updated :
19 May, 2021
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: 2
Explanation:
The string can be split into a minimum of 2 monotonous substrings {"abcd"(increasing), "cba"(decreasing)}
Input: str = "aeccdhba"
Output: 3
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++
// 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
Java
// 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));
}
}
Python3
# 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
C#
// 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
JavaScript
<script>
// javascript program for the
// above approach
// Function to return final result
function minReqSubstring(s, n)
{
// Initialize variable to keep
// track of ongoing sequence
let ongoing = 'N';
let count = 0, l = s.length;
for (let 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
let S = "aeccdhba";
let n = S.length;
document.write(
minReqSubstring(S, n));
// This code is contributed by target_2.
</script>
Time Complexity: O(N)
Auxiliary Space: O(1)
Similar Reads
Minimize partitions in given string to get another string Given two strings A and B, print the minimum number of slices required in A to get another string B. In case, if it is not possible to get B from A, then print "-1". Examples : Input: A = "geeksforgeeks", B = "ksgek"Output: 5Explanation: g | ee | ks | forge | ek | s : minimum 5 slices are required t
15+ min read
Print all Substrings of length n possible from the given String Given a string str and an integer N, the task is to print all possible sub-strings of length N. Examples: Input: str = âgeeksforgeeksâ, N = 3Output: gee eek eks ksf sfo for org rge gee eek eksExplanations: All possible sub-strings of length 3 are âgeeâ, âeekâ, âeksâ, âksfâ, âsfoâ, âforâ, âorgâ, ârge
8 min read
Find the Longest Non-Prefix-Suffix Substring in the Given String Given a string s of length n. The task is to determine the longest substring t such that t is neither the prefix nor the suffix of string s, and that substring must appear as both prefix and suffix of the string s. If no such string exists, print -1. Example: Input: s = "fixprefixsuffix"Output: fix
7 min read
Minimum splits in a binary string such that every substring is a power of 4 or 6. Given a string S composed of 0 and 1. Find the minimum splits such that the substring is a binary representation of the power of 4 or 6 with no leading zeros. Print -1 if no such partitioning is possible. Examples: Input: 100110110 Output: 3 The string can be split into a minimum of three substrings
11 min read
Smallest substring occurring only once in a given string Given a string S consisting of N lowercase alphabets, the task is to find the length of the smallest substring in S whose occurrence is exactly 1. Examples: Input: S = "abaaba"Output: 2Explanation: The smallest substring in the string S, whose occurrence is exactly 1 is "aa" . Length of this substri
6 min read