Sort a string lexicographically using triple cyclic shifts
Last Updated :
12 Jul, 2025
Given a string consisting of the first N distinct alphabets, the task is to sort the string by using at most N/2 moves. Each move involves the following:
- Select any 3 distinct indices.
- Perform a cyclic shift on the alphabets at these indices.
If it is possible to sort the strings, print the count of required moves. Otherwise, print "Not Possible".
Examples:
Input: str = "cbda"
Output:
possible
1
Explanation:
Selecting the indices 0, 2 and 3 and performing a single circular shift among them, the given string "cbda" is converted to "abcd".
Input: str = "cba"
Output: Not Possible
Approach:
In order to solve the problem, follow the steps below:
- Store the integers denoting correct of characters of the string in a vector .
- Place those elements correctly which can all occupy correct indices in a single cycle.
- Traverse an element of the vector
- If the element is not at its sorted index position, check if two or more numbers can be placed at correct indices in one cycle. If the condition is satisfied, perform the cycle otherwise check if there is a distinct index that does not hold the correct element available. If the condition is satisfied, select this index as the third index of the cycle and perform the cycle. If neither of the above conditions are satisfied, sorting would be impossible. Hence, break out of the loop and print "Not Possible".
- Once a cyclic shift is performed, store the indices involved in the shift.
- If the element is at its sorted position, move to the next index.
- Repeat the above two steps for all vector elements.
- After the traversal is completed, if the entire array is in sorted order, print the shifts required. Else print "Not Possible".
Below is the implementation of the above approach:
C++
// C++ Program for sorting a
// string using cyclic shift
// of three indices
#include <bits/stdc++.h>
using namespace std;
void sortString(vector<int>& arr, int n,
int moves)
{
// Store the indices
// which haven't attained
// its correct position
vector<int> pos;
// Store the indices
// undergoing cyclic shifts
vector<vector<int> > indices;
bool flag = false;
for (int i = 0; i < n; i++) {
// If the element is not at
// it's correct position
if (arr[i] != i) {
// Check if all 3 indices can be
// placed to respective correct
// indices in a single move
if (arr[arr[arr[i]]] == i
&& arr[arr[i]] != i) {
int temp = arr[arr[i]];
indices.push_back({ i, arr[i],
arr[arr[i]] });
swap(arr[i], arr[arr[i]]);
swap(arr[i], arr[temp]);
}
}
// If the i-th index is still
// not present in its correct
// position, store the index
if (arr[i] != i) {
pos.push_back(i);
}
}
for (int i = 0; i < n; i++) {
if (arr[i] != i) {
int pos1 = i, pos2 = arr[i];
int pos3 = arr[arr[i]];
// To check if swapping two indices
// places them in their correct
// position
if (pos3 != pos1) {
indices.push_back({ pos1,
pos2,
pos3 });
swap(arr[pos1], arr[pos2]);
swap(arr[pos1], arr[pos3]);
pos.erase(find(
pos.begin(),
pos.end(), pos2));
pos.erase(find(
pos.begin(),
pos.end(), pos3));
if (arr[pos1] == pos1) {
pos.erase(find(
pos.begin(),
pos.end(),
pos1));
}
}
else {
if (pos3
== *pos.begin()) {
if (*pos.begin()
!= pos.back()) {
auto it
= ++pos.begin();
pos3 = *(it);
if (*it != pos.back()
&& pos3 == pos2) {
pos3 = *(++it);
}
else if (*it == pos.back()
&& pos3 == pos2) {
flag = true;
break;
}
}
else {
flag = true;
break;
}
}
indices.push_back({ pos1, pos2,
pos3 });
swap(arr[pos1], arr[pos2]);
swap(arr[pos1], arr[pos3]);
pos.erase(find(
pos.begin(),
pos.end(),
pos2));
}
}
if (arr[i] != i) {
i--;
}
}
if (flag == true
|| indices.size() > moves) {
cout << "Not Possible" << endl;
}
else {
cout << indices.size() << endl;
// Inorder to see the indices that
// were swapped in rotations,
// uncomment the below code
/*
for (int i = 0; i < indices.size();
i++) {
cout << indices[i][0] << " "
<< indices[i][1] << " "
<< indices[i][2] << endl;
}
*/
}
}
// Driver Code
int main()
{
string s = "adceb";
vector<int> arr;
for (int i = 0; i < s.size(); i++) {
arr.push_back(s[i] - 'a');
}
sortString(arr, s.size(),
floor(s.size() / 2));
}
Java
// Java Program for sorting a
// string using cyclic shift
// of three indices
import java.util.*;
public class Main {
public static void sortString(List<Integer> arr, int n, int moves) {
List<Integer> pos = new ArrayList<>();
// Store the indices which haven't attained its correct position
List<List<Integer>> indices = new ArrayList<>();
// Store the indices undergoing cyclic shifts
boolean flag = false;
for (int i = 0; i < n; i++) {
// If the element is not at
// it's correct position
if (arr.get(i) != i) {
// Check if all 3 indices can be
// placed to respective correct
// indices in a single move
if (arr.get(arr.get(arr.get(i))) == i && arr.get(arr.get(i)) != i) {
int temp = arr.get(arr.get(i));
indices.add(Arrays.asList(i, arr.get(i), arr.get(arr.get(i))));
Collections.swap(arr, i, arr.get(i));
Collections.swap(arr, i, temp);
}
}
// If the i-th index is still
// not present in its correct
// position, store the index
if (arr.get(i) != i) {
pos.add(i);
}
}
for (int i = 0; i < n; i++) {
if (arr.get(i) != i) {
int pos1 = i, pos2 = arr.get(i);
int pos3 = arr.get(arr.get(i));
// To check if swapping two indices
// places them in their correct
// position
if (pos3 != pos1) {
indices.add(Arrays.asList(pos1, pos2, pos3));
Collections.swap(arr, pos1, pos2);
Collections.swap(arr, pos1, pos3);
pos.remove((Integer) pos2);
pos.remove((Integer) pos3);
if (arr.get(pos1) == pos1) {
pos.remove((Integer) pos1);
}
}
else {
if (pos3 == pos.get(0)) {
if (pos.get(0) != pos.get(pos.size() - 1)) {
int index = pos.get(1);
pos3 = index;
if (index != pos.get(pos.size() - 1) && pos3 == pos2) {
pos3 = pos.get(2);
}
else if (index == pos.get(pos.size() - 1) && pos3 == pos2) {
flag = true;
break;
}
}
else {
flag = true;
break;
}
}
indices.add(Arrays.asList(pos1, pos2, pos3));
Collections.swap(arr, pos1, pos2);
Collections.swap(arr, pos1, pos3);
pos.remove((Integer) pos2);
}
}
if (arr.get(i) != i) {
i--;
}
}
if (flag || indices.size() > moves) {
System.out.println("Not Possible");
}
else {
System.out.println(indices.size());
/* In order to see the indices that were swapped in rotations,
* uncomment the below code
for (List<Integer> index : indices) {
System.out.println(index.get(0) + " " + index.get(1) + " " + index.get(2));
}
*/
}
}
//Driver code
public static void main(String[] args) {
String s = "adceb";
List<Integer> arr = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
arr.add(s.charAt(i) - 'a');
}
sortString(arr, s.length(), s.length() / 2);
}
}
// contributed by adityasha4x71
Python3
# Python3 program for sorting a
# string using cyclic shift
# of three indices
import math
def sortString(arr, n, moves):
# Store the indices
# which haven't attained
# its correct position
pos = []
# Store the indices
# undergoing cyclic shifts
indices = []
flag = False
for i in range(n):
# If the element is not at
# it's correct position
if (arr[i] != i):
# Check if all 3 indices can be
# placed to respective correct
# indices in a single move
if (arr[arr[arr[i]]] == i and
arr[arr[i]] != i):
temp = arr[arr[i]]
indices.append([i, arr[i],
arr[arr[i]]])
sw = arr[i]
arr[i] = arr[arr[i]]
arr[sw] = sw
sw = arr[i]
arr[i] = arr[temp]
arr[temp] = sw
# If the i-th index is still
# not present in its correct
# position, store the index
if (arr[i] != i):
pos.append(i)
for i in range(n):
if (arr[i] != i):
pos1 = i
pos2 = arr[i]
pos3 = arr[arr[i]]
# To check if swapping two indices
# places them in their correct
# position
if (pos3 != pos1):
indices.append([pos1, pos2, pos3])
arr[pos1], arr[pos2] = arr[pos2], arr[pos1]
arr[pos1], arr[pos3] = arr[pos3], arr[pos1]
pos.remove(pos2)
if pos3 in pos:
pos.remove(pos3)
if (arr[pos1] == pos1):
pos.remove(pos1)
else:
if (pos3 == pos[0]):
it = 0
if (pos[0] != pos[-1]):
it = it + 1
pos3 = pos[it]
if (pos[it] != pos[-1] and
pos3 == pos2):
it = it + 1
pos3 = pos[it]
elif (pos[it] == pos[-1] and
pos3 == pos2):
flag = True
break
else:
flag = True
break
indices.append([pos1, pos2, pos3])
arr[pos1], arr[pos2] = arr[pos2], arr[pos1]
arr[pos1], arr[pos3] = arr[pos3], arr[pos1]
pos.remove(pos2)
if (arr[i] != i):
i = i - 1
if (flag == True or len(indices) > moves):
print("Not Possible")
else:
# Inorder to see the indices that
# were swapped in rotations,
# uncomment the below code
# for i in range len(indices):
# print (indices[i][0],
# indices[i][1], indices[i][2])
print(len(indices))
# Driver code
s = "adceb"
arr = []
for i in s:
arr.append(ord(i) - ord('a'))
sortString(arr, len(s), math.floor(len(s) / 2))
# This code is contributed by costheta_z
C#
// Python3 program for sorting a
// string using cyclic shift
// of three indices
using System;
class MainClass {
static void SortString(int[] arr, int n, int moves) {
// Store the indices
// which haven't attained
// its correct position
var pos = new System.Collections.Generic.List<int>();
// Store the indices
// undergoing cyclic shifts
var indices = new System.Collections.Generic.List<int[]>();
bool flag = false;
for (int i = 0; i < n; i++) {
// If the element is not at
// it's correct position
if (arr[i] != i) {
// Check if all 3 indices can be
// placed to respective correct
// indices in a single move
if (arr[arr[arr[i]]] == i && arr[arr[i]] != i) {
int temp = arr[arr[i]];
indices.Add(new int[] { i, arr[i], arr[arr[i]] });
int sw = arr[i];
arr[i] = arr[arr[i]];
arr[sw] = sw;
sw = arr[i];
arr[i] = arr[temp];
arr[temp] = sw;
}
// If the i-th index is still
// not present in its correct
// position, store the index
if (arr[i] != i) {
pos.Add(i);
}
}
}
for (int i = 0; i < n; i++) {
if (arr[i] != i) {
int pos1 = i;
int pos2 = arr[i];
int pos3 = arr[arr[i]];
// To check if swapping two indices
// places them in their correct
// position
if (pos3 != pos1) {
indices.Add(new int[] { pos1, pos2, pos3 });
arr[pos1] = arr[pos2];
arr[pos2] = pos1;
arr[pos1] = arr[pos3];
arr[pos3] = pos1;
pos.Remove(pos2);
if (pos.Contains(pos3)) {
pos.Remove(pos3);
}
if (arr[pos1] == pos1) {
pos.Remove(pos1);
}
} else {
if (pos3 == pos[0]) {
int it = 0;
if (pos[0] != pos[pos.Count - 1]) {
it++;
pos3 = pos[it];
if (pos[it] != pos[pos.Count - 1] && pos3 == pos2) {
it++;
pos3 = pos[it];
} else if (pos[it] == pos[pos.Count - 1] && pos3 == pos2) {
flag = true;
break;
}
} else {
flag = true;
break;
}
}
indices.Add(new int[] { pos1, pos2, pos3 });
arr[pos1] = arr[pos2];
arr[pos2] = pos1;
arr[pos1] = arr[pos3];
arr[pos3] = pos1;
pos.Remove(pos2);
}
}
if (arr[i] != i) {
i--;
}
}
if (flag == true || indices.Count > moves) {
Console.WriteLine("Not Possible");
}
// Inorder to see the indices that
// were swapped in rotations,
// uncomment the below code
// for i in range len(indices):
// print (indices[i][0],
// indices[i][1], indices[i][2])
else {
Console.WriteLine(indices.Count);
}
}
// Driver code
public static void Main() {
string s = "adceb";
int[] arr = new int[s.Length];
for (int i = 0; i < s.Length; i++) {
arr[i] = s[i] - 'a';
}
SortString(arr, s.Length, (int)Math.Floor(s.Length / 2.0));
}
}
// This code is contributed by shivhack999
JavaScript
function sortString(arr, n, moves) {
let indices = [];
let flag = false;
for (let i = 0; i < n; i++) {
if (arr[i] !== i) {
if (arr[arr[arr[i]]] === i && arr[arr[i]] !== i) {
let temp = arr[arr[i]];
indices.push([i, arr[i], arr[arr[i]]]);
[arr[i], arr[arr[i]]] = [arr[arr[i]], arr[i]];
[arr[i], arr[temp]] = [arr[temp], arr[i]];
}
}
if (arr[i] !== i) {
pos.push(i);
}
}
for (let i = 0; i < n; i++) {
if (arr[i] !== i) {
let pos1 = i,
pos2 = arr[i];
let pos3 = arr[arr[i]];
if (pos3 !== pos1) {
indices.push([pos1, pos2, pos3]);
[arr[pos1], arr[pos2]] = [arr[pos2], arr[pos1]];
[arr[pos1], arr[pos3]] = [arr[pos3], arr[pos1]];
pos.splice(pos.indexOf(pos2), 1);
pos.splice(pos.indexOf(pos3), 1);
if (arr[pos1] === pos1) {
pos.splice(pos.indexOf(pos1), 1);
}
} else {
if (pos3 === pos[0]) {
if (pos[0] !== pos[pos.length - 1]) {
let it = pos[1];
pos3 = it;
if (it !== pos[pos.length - 1] && pos3 === pos2) {
pos3 = pos[2];
} else if (it === pos[pos.length - 1] && pos3 === pos2) {
flag = true;
break;
}
} else {
flag = true;
break;
}
}
indices.push([pos1, pos2, pos3]);
[arr[pos1], arr[pos2]] = [arr[pos2], arr[pos1]];
[arr[pos1], arr[pos3]] = [arr[pos3], arr[pos1]];
pos.splice(pos.indexOf(pos2), 1);
}
}
if (arr[i] !== i) {
i--;
}
}
if (flag === true || indices.length > moves) {
console.log("Not Possible");
} else {
console.log(indices.length);
}
}
// Driver Code
let s = "adceb";
let arr = [];
for (let i = 0; i < s.length; i++) {
arr.push(s.charCodeAt(i) - 97);
}
sortString(arr, s.length, Math.floor(s.length / 2));
Time Complexity: O(n)
Space Complexity: O(n)
Similar Reads
Sort a string lexicographically by reversing a substring Given a string S consisting of N lowercase characters, the task is to find the starting and the ending indices ( 0-based indexing ) of the substring of the given string S that needed to be reversed to make the string S sorted. If it is not possible to sort the given string S by reversing any substri
12 min read
Lexicographically smallest String by pair swapping Suppose you are given a string Str of length N and a set of Pairs ( i, j such that 0 <= i < j < N, 0 based indexing). Pair âi, jâ means that you can swap the ith and jth characters in the string any number of times. You have to output the lexicographically smallest string that can be produc
11 min read
Lexicographic rank of a string using STL You are given a string, find its rank among all its permutations sorted lexicographically. Examples:Input : str[] = "acb"Output : Rank = 2Input : str[] = "string"Output : Rank = 598Input : str[] = "cba"Output : Rank = 6We have already discussed solutions to find Lexicographic rank of string In this
4 min read
Sort an Array of Strings in Lexicographical order Given an array of strings arr[] of size n, the task is to sort all the strings in lexicographical order. Examples:Input: arr[] = ["banana", "apple", "cherry"]Output: ["apple", "banana", "cherry"]Explanation: All strings are sorted alphabetically. "apple" comes before "banana", and "banana" before "c
11 min read
Lexicographical concatenation of all substrings of a string Given a string, find the concatenation of all substrings in lexicographic order.Examples:Input : s = "abc"Output : aababcbbccThe substrings of s in lexicographic order are "a", "b", "c", "ab", "abc", "bc". Concatenation of substrings is "a"+"ab"+"abc"+"b"+"bc"+"c" = "aababcbbcc".Input : s = "cba"Out
7 min read
K-th lexicographically smallest unique substring of a given string Given a string S. The task is to print the K-th lexicographically the smallest one among the different substrings of s.A substring of s is a string obtained by taking out a non-empty contiguous part in s. For example, if s = ababc, a, bab and ababc are substrings of s, while ac, z, and an empty stri
5 min read