Minimum operations such that each given segment of String have distinct characters
Given a string S of length N, Q ranges of the form [L, R] in a 2-D array range, and a permutation arr[] containing numbers from 1 to N. In one operation, you can remove the first unremoved character as per the permutation. However, the positions of other characters will not change. Determine the minimum number of operations that follow the below conditions:
- All the characters in each of the Q ranges are distinct. Removed characters are not counted.
- A range with all characters removed is considered to have all distinct characters.
- The sequence of n integers is called a permutation if it contains all integers from 1 to n exactly once.
Note: 1-based indexing is followed.
Examples:
Input: N = 5, Q = 2, S = “aaaaa”, arr[] = {2, 4, 1, 3, 5}, ranges = {{1, 2}, {4, 5}}
Output: 2
Explanation: After the first operation, the string becomes a_aaa
After the second operation, the string becomes a_a_a
Now, in both ranges, all characters are distinct.
Hence, the output is 2.
Input: N = 8, Q = 3, S = “abbabaab”, arr[] = {6, 3, 5, 1, 4, 2, 7, 8}, ranges = {{1, 3}, {4, 7}, {3, 5}}
Output: 5
Explanation: After the first operation, the string becomes abbab_ab
After the second operation, the string becomes ab_ab_ab
After the third operation, the string becomes ab_a_ _ab
After the fourth operation, the string becomes _b_a_ _ab
After the fifth operation, the string becomes _b_ _ _ _ab
Now, in all the ranges, all characters are distinct.
Hence, the output is 5.
Approach: To solve the problem follow the below idea:
One easy way is to traverse the permutation and remove characters serially. At each traversal, we will traverse each query to find whether they all contain unique characters. If the answer comes to be positive then return the number of traversals is the final answer.
Follow the below steps to solve the problem:
- If all the queries have unique characters then return 0.
- Traverse the permutation arr[] from i = 0 to N-1:
- Initialize (arr[i] – 1)th index with ‘_’ in a list temp and call isValid.
- Inside isValid function:
- Traverse the query ranges using iterator j.
- If temp[j] != ‘_’ then push temp[j] in an array (say ss).
- If the length of the set formed by ss is not equal to the length of ss then there are repeating characters so return False.
- Else return True.
- If isValid returns True then return i+1 as the final answer.
- Otherwise, return -1.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
bool IsValid(string S, vector<vector< int >> ranges){
for ( int i = 0; i < ranges.size(); ++i) {
int x = ranges[i][0], y = ranges[i][1];
vector< char > ss;
for ( int j = x - 1; j < y; ++j)
if (S[j] != '_' )
ss.push_back(S[j]);
unordered_set< char > temp;
for ( auto x: ss){
temp.insert(x);
}
if (temp.size() != ss.size())
return false ;
}
return true ;
}
int goodString( int N, int Q, string S, vector< int > arr, vector<vector< int >> ranges){
if (IsValid(S, ranges))
return 0;
for ( int i = 0; i < arr.size(); ++i) {
S[arr[i] - 1] = '_' ;
if (IsValid(S, ranges))
return i + 1;
}
return -1;
}
int main(){
int N = 8;
int Q = 3;
string S = "abbabaab" ;
vector< int > arr = {6, 3, 5, 1, 4, 2, 7, 8};
vector<vector< int >> ranges = {{1, 3}, {4, 7}, {3, 5}};
cout << goodString(N, Q, S, arr, ranges);
return 0;
}
|
Java
import java.io.*;
import java.util.HashSet;
import java.util.stream.Collectors;
class GFG {
public static boolean IsValid( char [] temp,
int [][] ranges)
{
for ( int i = 0 ; i < ranges.length; i++) {
int x = ranges[i][ 0 ];
int y = ranges[i][ 1 ];
StringBuilder ss = new StringBuilder();
for ( int j = x - 1 ; j < y; j++) {
if (temp[j] != '_' ) {
ss.append(temp[j]);
}
}
if (ss.length()
!= new HashSet<Character>(
ss.toString()
.chars()
.mapToObj(c -> ( char )c)
.collect(Collectors.toList()))
.size()) {
return false ;
}
}
return true ;
}
public static int goodString( int N, int Q, String S,
int [] arr, int [][] ranges)
{
char [] temp = S.toCharArray();
if (IsValid(temp, ranges)) {
return 0 ;
}
for ( int i = 0 ; i < arr.length; i++) {
temp[arr[i] - 1 ] = '_' ;
if (IsValid(temp, ranges)) {
return i + 1 ;
}
}
return - 1 ;
}
public static void main(String[] args)
{
int N = 8 ;
int Q = 3 ;
String S = "abbabaab" ;
int [] arr = { 6 , 3 , 5 , 1 , 4 , 2 , 7 , 8 };
int [][] ranges = { { 1 , 3 }, { 4 , 7 }, { 3 , 5 } };
System.out.println(
goodString(N, Q, S, arr, ranges));
}
}
|
Python3
def IsValid(temp, ranges):
for i in range ( len (ranges)):
x, y = ranges[i]
ss = []
for j in range (x - 1 , y):
if temp[j] ! = '_' :
ss.append(temp[j])
if len ( set (ss)) ! = len (ss):
return False
return True
def goodString (N, Q, S, arr, ranges):
temp = list (S)
if IsValid(temp, ranges):
return 0
for i in range ( len (arr)):
temp[arr[i] - 1 ] = '_'
if IsValid(temp, ranges):
return i + 1
return - 1
N = 8
Q = 3
S = "abbabaab"
arr = [ 6 , 3 , 5 , 1 , 4 , 2 , 7 , 8 ]
ranges = [[ 1 , 3 ], [ 4 , 7 ], [ 3 , 5 ]]
print (goodString(N, Q, S, arr, ranges))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static bool IsValid( char [] temp, int [][] ranges)
{
for ( int i = 0; i < ranges.Length; i++) {
int x = ranges[i][0];
int y = ranges[i][1];
var ss = new System.Text.StringBuilder();
for ( int j = x - 1; j < y; j++) {
if (temp[j] != '_' ) {
ss.Append(temp[j]);
}
}
var set = new HashSet< char >(ss.ToString());
if (ss.Length != set .Count) {
return false ;
}
}
return true ;
}
static int GoodString( int N, int Q, string S, int [] arr,
int [][] ranges)
{
char [] temp = S.ToCharArray();
if (IsValid(temp, ranges)) {
return 0;
}
for ( int i = 0; i < arr.Length; i++) {
temp[arr[i] - 1] = '_' ;
if (IsValid(temp, ranges)) {
return i + 1;
}
}
return -1;
}
static public void Main()
{
int N = 8;
int Q = 3;
string S = "abbabaab" ;
int [] arr = { 6, 3, 5, 1, 4, 2, 7, 8 };
int [][] ranges = { new [] { 1, 3 }, new [] { 4, 7 },
new [] { 3, 5 } };
Console.WriteLine(GoodString(N, Q, S, arr, ranges));
}
}
|
Javascript
const IsValid = (temp, ranges) => {
for (let i = 0; i < ranges.length; ++i) {
let x = ranges[i][0], y = ranges[i][1];
let ss = [];
for (let j = x - 1; j < y; ++j)
if (temp[j] != '_' )
ss.push(temp[j]);
if ( new Set(ss).size != ss.length)
return false ;
}
return true ;
}
const goodString = (N, Q, S, arr, ranges) => {
let temp = S.split( "" );
if (IsValid(temp, ranges))
return 0;
for (let i = 0; i < arr.length; ++i) {
temp[arr[i] - 1] = '_' ;
if (IsValid(temp, ranges))
return i + 1;
}
return -1;
}
let N = 8;
let Q = 3;
let S = "abbabaab" ;
let arr = [6, 3, 5, 1, 4, 2, 7, 8];
let ranges = [[1, 3], [4, 7], [3, 5]];
console.log(goodString(N, Q, S, arr, ranges));
|
Time Complexity: O(N * Q * M) where M is the maximum range
Auxiliary Space: O(N)
Last Updated :
08 Feb, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...