Open In App

Sort a string lexicographically using triple cyclic shifts

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: 

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: 

Below is the implementation of the above approach:
 

// 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 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 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
// 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
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)


Article Tags :