Sort a string lexicographically using triple cyclic shifts

• Difficulty Level : Medium
• Last Updated : 21 Mar, 2023

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

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 ``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 > 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));``}`

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`

Java

 `// Java Program for sorting a``// string using cyclic shift``// of three indices``import` `java.util.*;` `public` `class` `Main {``    ` `    ``public` `static` `void` `sortString(List arr, ``int` `n, ``int` `moves) {``        ``List pos = ``new` `ArrayList<>();``        ``// Store the indices which haven't attained its correct position``        ``List> 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 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 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`

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));`

Output

`1`

Time Complexity: O(n)

Space Complexity: O(n)

My Personal Notes arrow_drop_up