Reverse given range of String for M queries
Last Updated :
01 Feb, 2023
Given a string S of length N and an array of queries A[] of size M, the task is to find the final string after performing M operations on the string. In each operation reverse a segment of the string S from position (A[i] to N-A[i]+1).
Examples:
Input: N = 6, S = "abcdef", M = 3, A = {1, 2, 3}
Output: "fbdcea"
Explanation: After the first operation, the string will be "fedcba".
After the second operation it will be "fbcdea".
After the third operation the final string will be "fbdcea".
Input: N = 2, S = "jc", M = 5, A = {1, 1, 1, 1, 1}
Output: "cj"
Naive Approach:
A simple solution is to update the string after each operation by reversing it for the given range as defined by the query.
Below is the implementation of the naive approach:
C++
// C++ program to find the string after
// M reversals on query ranges
#include <bits/stdc++.h>
using namespace std;
// Function for reversing string according
// to each query
void reverseForAll(string& S, int N, vector<int>& A, int M)
{
for (int i = 0; i < M; i++) {
int start = A[i] - 1;
int end = N - A[i] + 1;
reverse(S.begin() + start, S.begin() + end);
}
}
// Driver Code
int main()
{
int N = 6;
string S = "abcdef";
int M = 3;
vector<int> A = { 1, 2, 3 };
// Function call
reverseForAll(S, N, A, M);
cout << S;
return 0;
}
Java
// Java program to find the string after M reversals on
// query ranges
import java.io.*;
class GFG {
// Function for reversing string according
// to each query
public static String reverseForAll(String S, int N,
int A[], int M)
{
String tmp = "";
for (int j = 0; j < M; j++) {
int start = A[j] - 1;
int end = N - A[j] + 1;
tmp = "";
// reverse(S.begin() + start, S.begin() + end);
// string tmp="";
for (int i = 0; i < start; i++)
tmp += S.charAt(i);
for (int i = end - 1; i >= start; i--)
tmp += S.charAt(i);
for (int i = end; i < S.length(); i++)
tmp += S.charAt(i);
S = tmp;
}
return tmp;
}
// Driver Code
public static void main(String[] args)
{
int N = 6;
String S = "abcdef";
int M = 3;
int A[] = { 1, 2, 3 };
// Function call
String ans = reverseForAll(S, N, A, M);
System.out.println(ans);
}
}
// This code is contributed by Akshay
// Tripathi(akshaytripathi19410)
Python3
# Python program to find the string after
# M reversals on query ranges
# Function for reversing string according
# to each query
def reverseForAll( S, N, A, M):
for i in range(0,M):
start = A[i] - 1;
end = N - A[i] + 1;
S = S[:start] + "".join(reversed(S[start:end])) + S[end:];
return S;
# Driver Code
N = 6;
S = "abcdef";
M = 3;
A = [ 1, 2, 3 ];
# Function call
S=reverseForAll(S, N, A, M);
print(S);
C#
using System;
using System.Collections.Generic;
class GFG {
// Function for reversing string according
// to each query
static string reverseForAll(string S, int N, List<int> A, int M)
{
string tmp="";
for (int j = 0; j < M; j++) {
int start = A[j] - 1;
int end = N - A[j] + 1;
tmp="";
//reverse(S.begin() + start, S.begin() + end);
//string tmp="";
for(int i=0; i<start; i++)
tmp+=S[i];
for(int i=end-1; i>=start; i--)
tmp+=S[i];
for(int i=end; i<S.Length; i++)
tmp+=S[i];
S=tmp;
}
return tmp;
}
// Driver Code
public static void Main()
{
int N = 6;
string S = "abcdef";
int M = 3;
List<int> A = new List<int>();
A.Add(1);
A.Add(2);
A.Add(3);
// Function call
string ans=reverseForAll(S, N, A, M);
Console.Write(ans);
}
}
// This code is contributed by ratiagarwal.
JavaScript
// Javascript program to find the string after
// M reversals on query ranges
// Function for reversing string according
// to each query
function reverseForAll(S, N, A, M)
{
for (let i = 0; i < M; i++) {
let start = A[i] - 1;
let end = N - A[i] + 1;
let sub = S.substring(start, end);
sub = sub.split("").reverse().join("");
S = S.substring(0, start) + sub + S.substring(end);
}
document.write(S);
}
// Driver Code
let N = 6;
let S = "abcdef";
let M = 3;
let A = [ 1, 2, 3 ];
// Function call
reverseForAll(S, N, A, M);
Time Complexity: O(M*N)
Auxiliary Space: O(1)
Efficient Approach: Please check out the Difference Array | Range update query in O(1) article before reading this approach.
Observations:
Notice that when the same section of a string is reversed twice it gains back its original state.
As in the example:
For example multiple queries of reversal on the given input
Consider (1-based Indexing) that:
- The first reversal is to be applied to the range [1, 6].
- The second reversal is to be applied to the range [2, 5].
- The third reversal is to be applied to the range [3, 4].
It can be observed that:
- reversal is applied on 1 and 6 indices one time.
- reversal is applied on 2 and 5 indices two times.
- reversal is applied on 3 and 4 indices three times.
In the final string, characters on indices 2 and 5 remained unchanged while indices 1, 3, 4, and 6 are reversed. So, the indices on which reversal is to be applied an even number of times do not take part in the final reversal of string while those with odd no. of reversal queries take part in reversal.
So, the idea of the efficient approach to solve this problem is:
Count for each index, how many queries include this number, if the index is included in even number of queries, it would not be reversed, otherwise if the index is included in odd number of queries it would be reversed.
Follow the steps to solve this problem:
- Take a count array initialized to 0 with a length equal to the length of the string. This will count how many reversal queries include the corresponding index.
- For each query, increment all the values in the range where reversal should be done.
- This increment can be done in O(1) using the concept mentioned in the Difference Array | Range update query in O(1) article.
- Take an empty string and traverse the count array.
- Count array is traversed and for the indices with even value, characters at those indices from the original string are added to the answer string, otherwise, characters from the reversed string are added.
Below is the implementation of the efficient approach:
C++
// C++ program to find the string after
// M reversals on query ranges
#include <bits/stdc++.h>
using namespace std;
// Increments the value at first index and
// decrements at next of last index
void updateRange(vector<int>& count, int i, int j)
{
count[i]++;
// Check index out of bound
if (j + 1 < count.size())
count[j + 1]--;
}
// Prefix sum to finalise count value
// at each index
void finaliseCountArray(vector<int>& count)
{
for (int i = 0; i < count.size(); i++)
count[i] += count[i - 1];
}
// Function for reversing string according
// to each query
string reverseForAll(string S, int N, vector<int>& A, int M)
{
vector<int> count(N, 0);
// Traversal of query array
for (int i = 0; i < M; i++) {
int start = A[i] <= (N + 1) / 2 ? A[i] - 1 : N - A[i];
int end = A[i] <= (N + 1) / 2 ? N - A[i] : A[i] - 1;
// Increment the value of all indices
// between both indices
updateRange(count, start, end);
}
// Finalising count array using prefix sum
finaliseCountArray(count);
// Storing the characters at indices with
// odd no. of reversal queries in reverse
// manner, this stores the required indices
// to string temp as well as temp is
// reversed at the same time
string temp;
for (int i = count.size() - 1; i >= 0; i--) {
if (count[i] % 2 != 0)
temp.push_back(S[i]);
}
// Storing the new characters in
// original string
int i = 0, j = 0;
for (i = 0; i < count.size(); i++) {
// For characters with odd reversal
// queries character is taken from
// string temp
if (count[i] % 2 != 0)
S[i] = temp[j++];
// If count is even then there is no
// need to update characters as those
// characters do not take part
// in reversal
}
// Return final string
return S;
}
// Driver Code
int main()
{
int N = 6;
string S = "abcdef";
int M = 3;
vector<int> A = { 1, 2, 3 };
// Function call
cout << reverseForAll(S, N, A, M);
return 0;
}
Java
/*package whatever //do not write package name here */
// Java program to find the string after
// M reversals on query ranges
import java.io.*;
class GFG {
// Increments the value at first index and
// decrements at next of last index
static void updateRange(int[] count, int i, int j)
{
count[i]++;
// Check index out of bound
if (j + 1 < count.length)
count[j + 1]--;
}
// Prefix sum to finalise count value
// at each index
static void finaliseCountArray(int[] count)
{
for (int i = 1; i < count.length; i++)
count[i] += count[i - 1];
}
// Function for reversing string according
// to each query
static String reverseForAll(String S, int N,int[] A, int M){
int[] count = new int[N];
char str[] = S.toCharArray();
// Traversal of query array
for (int i = 0; i < M; i++) {
int start = A[i] <= (N + 1) / 2 ? A[i] - 1 : N - A[i];
int end = A[i] <= (N + 1) / 2 ? N - A[i] : A[i] - 1;
// Increment the value of all indices
// between both indices
updateRange(count, start, end);
}
// Finalising count array using prefix sum
finaliseCountArray(count);
// Storing the characters at indices with
// odd no. of reversal queries in reverse
// manner, this stores the required indices
// to string temp as well as temp is
// reversed at the same time
String temp = "";
for (int i = count.length - 1; i >= 0; i--) {
if (count[i] % 2 != 0)
temp += S.charAt(i);
}
// Storing the new characters in
// original string
int j = 0;
for (int i = 0; i < count.length; i++) {
// For characters with odd reversal
// queries character is taken from
// string temp
if (count[i] % 2 != 0)
str[i] = temp.charAt(j++);
// If count is even then there is no
// need to update characters as those
// characters do not take part
// in reversal
}
// Return final string
return new String(str);
}
public static void main (String[] args) {
int N = 6;
String S = "abcdef";
int M = 3;
int[] A = { 1, 2, 3 };
System.out.println(reverseForAll(S, N, A, M));
}
}
// This code is contributed by aadityapburujwale
Python3
class GFG :
# Increments the value at first index and
# decrements at next of last index
@staticmethod
def updateRange( count, i, j) :
count[i] += 1
# Check index out of bound
if (j + 1 < len(count)) :
count[j + 1] -= 1
# Prefix sum to finalise count value
# at each index
@staticmethod
def finaliseCountArray( count) :
i = 1
while (i < len(count)) :
count[i] += count[i - 1]
i += 1
# Function for reversing string according
# to each query
@staticmethod
def reverseForAll( S, N, A, M) :
count = [0] * (N)
str = list(S)
# Traversal of query array
i = 0
while (i < M) :
start = A[i] - 1 if A[i] <= int((N + 1) / 2) else N - A[i]
end = N - A[i] if A[i] <= int((N + 1) / 2) else A[i] - 1
# Increment the value of all indices
# between both indices
GFG.updateRange(count, start, end)
i += 1
# Finalising count array using prefix sum
GFG.finaliseCountArray(count)
# Storing the characters at indices with
# odd no. of reversal queries in reverse
# manner, this stores the required indices
# to string temp as well as temp is
# reversed at the same time
temp = ""
i = len(count) - 1
while (i >= 0) :
if (count[i] % 2 != 0) :
temp += S[i]
i -= 1
# Storing the new characters in
# original string
j = 0
i = 0
while (i < len(count)) :
# For characters with odd reversal
# queries character is taken from
# string temp
if (count[i] % 2 != 0) :
j = j + 1
str[i] = temp[j-1]
i += 1
# Return final string
return ''.join(str)
@staticmethod
def main( args) :
N = 6
S = "abcdef"
M = 3
A = [1, 2, 3]
print(GFG.reverseForAll(S, N, A, M))
if __name__=="__main__":
GFG.main([])
# This code is contributed by aadityaburujwale.
C#
// Include namespace system
// C# program to find the string after
// M reversals on query ranges
using System;
public class GFG
{
// Increments the value at first index and
// decrements at next of last index
public static void updateRange(int[] count, int i, int j)
{
count[i]++;
// Check index out of bound
if (j + 1 < count.Length)
{
count[j + 1]--;
}
}
// Prefix sum to finalise count value
// at each index
public static void finaliseCountArray(int[] count)
{
for (int i = 1; i < count.Length; i++)
{
count[i] += count[i - 1];
}
}
// Function for reversing string according
// to each query
public static String reverseForAll(String S, int N, int[] A, int M)
{
int[] count = new int[N];
char[] str = S.ToCharArray();
// Traversal of query array
for (int i = 0; i < M; i++)
{
var start = A[i] <= (int)((N + 1) / 2) ? A[i] - 1 : N - A[i];
var end = A[i] <= (int)((N + 1) / 2) ? N - A[i] : A[i] - 1;
// Increment the value of all indices
// between both indices
GFG.updateRange(count, start, end);
}
// Finalising count array using prefix sum
GFG.finaliseCountArray(count);
// Storing the characters at indices with
// odd no. of reversal queries in reverse
// manner, this stores the required indices
// to string temp as well as temp is
// reversed at the same time
var temp = "";
for (int i = count.Length - 1; i >= 0; i--)
{
if (count[i] % 2 != 0)
{
temp += S[i];
}
}
// Storing the new characters in
// original string
var j = 0;
for (int i = 0; i < count.Length; i++)
{
// For characters with odd reversal
// queries character is taken from
// string temp
if (count[i] % 2 != 0)
{
str[i] = temp[j++];
}
}
// Return final string
return new String(str);
}
public static void Main(String[] args)
{
var N = 6;
var S = "abcdef";
var M = 3;
int[] A = {1, 2, 3};
Console.WriteLine(GFG.reverseForAll(S, N, A, M));
}
}
// This code is contributed by aadityapburujwale
JavaScript
// Function for updating the count array
function updateRange(count, i, j) {
count[i] += 1;
if (j + 1 < count.length) {
count[j + 1] -= 1;
}
}
// Function for finalizing the count array
function finalizeCountArray(count) {
for (let i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
}
// Function for reversing the string according to each query
function reverseForAll(S, N, A, M) {
let count = new Array(N).fill(0);
let str = S.split('');
// Traversal of query array
for (let i = 0; i < M; i++) {
let start = A[i] <= Math.ceil((N + 1) / 2) ? A[i] - 1 : N - A[i];
let end = A[i] <= Math.ceil((N + 1) / 2) ? N - A[i] : A[i] - 1;
// Increment the value of all indices between both indices
updateRange(count, start, end);
}
// Finalizing count array using prefix sum
finalizeCountArray(count);
// Storing the characters at indices with odd no. of reversal queries in reverse manner
// this stores the required indices to string temp as well as temp is reversed at the same time
let temp = "";
for (let i = count.length - 1; i >= 0; i--) {
if (count[i] % 2 !== 0) {
temp += S[i];
}
}
// Storing the new characters in original string
let j = 0;
for (let i = 0; i < count.length; i++) {
// For characters with odd reversal queries character is taken from string temp
if (count[i] % 2 !== 0) {
j++;
str[i] = temp[j - 1];
}
}
// Return final string
return str.join('');
}
let N = 6;
let S = "abcdef";
let M = 3;
let A = [1, 2, 3];
document.write(reverseForAll(S, N, A, M));
//This code is contributed by ik_9
Time Complexity: O(M+N)
Auxiliary Space: O(N)
Similar Reads
Reverse the given string in the range [L, R] Given a string str, and two integers L and R, the task is to reverse the string in the range [L, R] i.e. str[L...R].Examples: Input: str = "geeksforgeeks", L = 5, R = 7 Output: geeksrofgeeks Reverse the characters in the range str[5...7] = "geeksforgeeks" and the new string will be "geeksrofgeeks" I
4 min read
Queries for counts of array values in a given range Given an unsorted array of integers and a set of m queries, where each query consists of two integers x and y, the task is to determine the number of elements in the array that lie within the range [x, y] (inclusive) for each query.Examples: Input: arr = [1, 3, 4, 9, 10, 3], queries = [[1, 4], [9, 1
15+ min read
Queries for Nth smallest character for a given range in a string Given a string str which consists of only lowercase letters and an array arr[][] that represents range queries on the given string str where each query contains 3 integers, {L, R, N} such that for each query we have to output the Nth smallest character in the given range [L, R] as specified in the q
14 min read
Queries to flip characters of a binary string in given range Given a binary string, str and a 2D array Q[][] representing queries of the form {L, R}. In each query, toggle all the characters of the binary strings present in the indices [L, R]. The task is to print the binary string by performing all the queries. Examples: Input: str = "101010", Q[][] = { {0,
8 min read
Array range queries for searching an element Given an array of N elements and Q queries of the form L R X. For each query, you have to output if the element X exists in the array between the indices L and R(included). Prerequisite : Mo's Algorithms Examples : Input : N = 5 arr = [1, 1, 5, 4, 5] Q = 3 1 3 2 2 5 1 3 5 5 Output : No Yes Yes Expla
15+ min read
Perform range sum queries on string as per given condition Given a string S with lowercase alphabets only and Q queries where each query contains a pair {L, R}. For each query {L, R}, there exists a substring S[L, R], the task is to find the value of the product of the frequency of each character in substring with their position in alphabetical order. Note:
7 min read
Maximum count of 0s between two 1s in given range for Q queries | Set - 2 Given a binary string S of size N, and a 2D array Q[][] of queries consisting of M pairs of the form {L, R}, the task for each query is to find the maximum number of 0s lying between two 1s in the range [L, R].Examples: Input: S = â1001010â, Q[][] = {{0, 4}, {0, 5}}Output: 2 3Explanation: The Querie
8 min read
Count of Perfect Numbers in given range for Q queries Given an array arr[] consisting of N pairs, where each pair represents a query of the form {L, R}, the task is to find the count of perfect numbers in the given range for each query. Examples: Input: arr[][] = {{1, 10}, {10, 20}, {20, 30}}Output: 1 1 1Explanation: Query(1, 10): Perfect numbers in th
9 min read
Array range queries over range queries Given an array of size n and a give set of commands of size m. The commands are enumerated from 1 to m. These commands can be of the following two types of commands: Type 1 [l r (1 <= l <= r <= n)] : Increase all elements of the array by one, whose indices belongs to the range [l, r]. In th
15+ min read
Maximum count of 0s between two 1s in given range for Q queries Given a binary string S of size N, and a 2D array Q[][] of queries consisting of M pairs of the form {L, R}, the task for each query is to find the maximum number of 0s lying between two 1s in the range [L, R]. Examples: Input: S = "1001010", Q[][] = {{0, 4}, {0, 5}}Output: 2 3Explanation: The Queri
10 min read