Open In App

Minimum operations such that each given segment of String have distinct characters

Improve
Improve
Like Article
Like
Save
Share
Report

 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++




// C++ program for the above approach:
#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;
}
 
// driver's code
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;
}
 
// This code is contributed by Nidhi goel.


Java




// Java program for the above approach:
 
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));
  }
}
 
// This code is contributed by lokesh.


Python3




# Python program for the above approach:
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
 
# driver's code
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#




// C# program for the above approach:
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()
  {
 
    // Code
    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));
  }
}
 
// This code is contributed by lokeshmvs21.


Javascript




// JavaScript program for the above approach:
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;
}
 
// driver's code
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));
 
// This code is contributed by rakeshsahni.


Output

5

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
Previous
Next
Share your thoughts in the comments
Similar Reads