HackerRank Suffix Rotation Problem Solution Yashwant Parihar, August 6, 2023August 1, 2024 In this post, we will solve HackerRank Suffix Rotation Problem Solution. Megan is playing a string game with the following rules: It starts with a string, 8. During each turn, she performs the following move:o Choose an index in s. The chosen index must be strictly greater than any index chosen in a prior move. Perform one or more circular rotations (in either direction) of the suffix starting at the chosen index. For example, let’s say s = abcdefjghi. During our move, we choose to do three right rotations of the suffix starting at index 6: Note that this counts as one move. The goal of the game is to convert & into the lexicographically smallest possible string in as few moves as possible. In other words, we want the characters to be in alphabetical order. Megan plays this game g times, starting with a new string s each time. For each game, find the minimum number of moves necessary to convert & into the lexicographically smallest string and print that number on a new line.Input FormatThe first line contains an integer, g, denoting the number of games. Each of the g subsequent lines contains a single string denoting the initial value of string sfor a game. Output Format For each game, print an integer on a new line denoting the minimum number of moves required to convert into the lexicographically smallest string possible. Sample Input 0 3 abcdefghij acab baba Sample Output 0 0 1 2 Explanation 0We play the following g = 3 games; In the first game, abcdefghij is already as lexicographically small as possible (each sequential letter is in alphabetical order). Because we don’t need to perform any moves, we print 0 on a new line. In the second game, we rotate the suffix starting at index 1. so acab becomes aabc.Because the string is lexicographically smallest after one move, we print 1 on a new line. In the third game, we perform the following moves: Rotate the suffix starting at index 0 (i.e… the entire string), so baba becomes abab. Rotate the suffix starting at index 1. so abab becomes aabbBecause the string is lexicographically smallest after two moves, we print 2 on a newline. HackerRank Suffix Rotation Problem Solution Suffix Rotation C Solution #include<stdio.h> #include<string.h> #include<stdbool.h> #define FOR(a,b,c) for(int a=(b),_for=(c);a<_for;++a) #define M 1000 #define Z 26 char c[M+5]; int n, P[M+5], A[M+5], B[M+5], C[Z+5], D[M+5], E[M+5]; int min(int a, int b) { return a < b ? a : b; } int n; int p[M+5]; char c[M+5]; int cnt[Z+5]; int dp[M+5]; int nju[M+5]; int nx[M+5]; int isti[M+5]; void solve(){ scanf ("%s",c); n=strlen(c); FOR(i,0,n) p[i]=Z-1-(c[i]-'a'); FOR(i,0,Z) cnt[i]=0; FOR(i,0,n) cnt[p[i]]++; FOR(i,0,n) dp[i]=0; FOR(i,0,n) nju[i]=0; FOR(i,0,n) nx[i]=0; FOR(i,0,n) isti[i]=0; FOR(cl,0,Z){ if (!cnt[cl]) continue; FOR(i,0,n) dp[i]=nju[i]; memset(nju,-1,n*sizeof(int)); memset(isti,0,n*sizeof(int)); int last=-1,prvi=-1,sum=0,b1=n,b2=n; FOR(i,0,n) if (p[i]<=cl){ if (last>=0){ nx[last]=i; if (p[last]!=p[i] && p[i]==cl) isti[i]=1,sum++; } else prvi=i; last=i; } nx[last]=prvi; if (p[last]!=p[prvi] && p[prvi]==cl) isti[prvi]=1,sum++; int pb1=-1; FOR(i,0,n) if (p[i]==cl && p[nx[i]]!=cl){ b2=min(b2,dp[nx[i]]); if (b2<b1) { int temp = b1; b1 = b2; b2 = temp; pb1=i; } } sum+=b1-1; if (pb1==-1) sum=-1; bool flag=0; FOR(i,0,n){ if (p[i]>cl) continue; if (p[i]<cl || !isti[i]){ nju[i]=sum+1; continue; } if (b1==b2 || b2==n){ nju[i]=sum; continue; } nju[i]=sum; flag=1; } if (flag){ for (int i=pb1;i>=0 && flag;--i){ if (isti[i]) nju[i]++,flag=0; } for (int i=n-1;i>=0 && flag;--i){ if (isti[i]) nju[i]++,flag=0; } } } printf ("%d\n",nju[0]); } int main(){ int znj; scanf ("%d",&znj); while(znj--) solve(); return 0; } Suffix Rotation C++ Solution #include <bits/stdc++.h> using namespace std; #define N 1010 #define inf 1010 int t; char s[N]; map <string, int> mp; int solve(char *s) { // puts(s); int len = strlen(s); if (!len) return 0; if (mp.count(s)) return mp[s]; char c = *min_element(s, s + len); if (s[0] == c) return mp[s] = solve(s + 1); int rlt = 0; char ss[N]; int runs = 0; bool vis[N]; for (int i = 0; i < len; i ++) if (s[i] != c) { ss[runs] = s[i]; int prv = i ? i - 1 : len - 1; vis[runs++] = s[prv] == c; if (i < len - 1 && s[i+1] == c) rlt ++; } ss[runs] = 0; len = runs; c = *min_element(ss, ss + len); bool start_c = 0; for (int i = 0; i < len; i ++) { if (vis[i] && ss[i] == c) { start_c = 1; break; } } int mn = inf; char sss[N]; for (int i = 0; i < len; i ++) if (vis[i]) { if (start_c && ss[i] != c) continue; for (int j = 0; j < len; j ++) sss[j] = ss[(j+i)%len]; sss[len] = 0; mn = min(mn, solve(sss)); } return mp[s] = rlt + mn; } int main() { // freopen("s.in", "r", stdin); // freopen("s.out", "w", stdout); scanf("%d", &t); while (t --) { scanf("%s", s); printf("%d\n", solve(s)); } return 0; } Suffix Rotation C Sharp Solution using System.Collections.Generic; using System.Linq; using System; class Solution { static void Main(string[] args) { int q = Convert.ToInt32(Console.ReadLine()); //DateTime start = DateTime.Now; for (int qItr = 0; qItr < q; qItr++) { string s = Console.ReadLine(); Console.WriteLine(new MinEdits().GetMinEdits(s)); } //Console.Error.WriteLine(DateTime.Now - start); } } public class MinEdits { public int GetMinEdits(string str) { _charsinOrder = str.OrderBy(x => x).Distinct().ToArray(); return GetMinEdits(str, 0, 0); } public int GetMinEdits(string str, int cost, int min) { if (_cache.TryGetValue(str, out var costCache)) return costCache; var s = str.ToCharArray(); var somethingToDo = false; char minc = _charsinOrder[min]; s = DeRepete(s, minc, out somethingToDo); while (!somethingToDo && s.Length>1) { min++; minc = _charsinOrder[min]; s = DeRepete(s, minc, out somethingToDo); } int costOut = 0; if (somethingToDo) { costOut = Remap(s, min, cost); } if (costOut == 0 && cost < bestSoFar) bestSoFar = cost; //if(str.Length < 500) _cache.Add(str, costOut); return costOut; } private int bestSoFar = int.MaxValue; private Dictionary<string, int> _cache = new Dictionary<string, int>(); private char[] _charsinOrder; public char[] AsSpan(char[] s, int start, int length) { var result = new char[length]; for (int i = 0; i < length; i++) { result[i] = s[start + i]; } return result; } public int Remap(char[] s, int min , int cost) { char mapon = _charsinOrder[min]; List<char[]> segments = new List<char[]>(); int start = 0; char[] startSeg = null; for (var i = 0; i < s.Length; i++) { if (s[i] == mapon) { if (start == 0) startSeg = AsSpan(s, start, i - start).ToArray(); else segments.Add(AsSpan(s, start, i - start)); start = i + 1; } } var lengthLast = s.Length - start + startSeg.Length; if (lengthLast > 0) { char[] last = new char[lengthLast]; Array.Copy(s, start, last, 0, s.Length - start); Array.Copy(startSeg, 0, last, s.Length - start, startSeg.Length); segments.Add(last); } int totalLength = segments.Sum(x => x.Length); List<char[]> testStrings = new List<char[]>(segments.Count); for (var j = 0; j < segments.Count; j++) { char[] test = new char[totalLength]; Array.Copy(segments[j], 0, test, 0, segments[j].Length); int copied = segments[j].Length; for (var i = 1; i < segments.Count; i++) { int copyindex = (j + i) % segments.Count; Array.Copy(segments[copyindex], 0, test, copied, segments[copyindex].Length); //test += segments[]; copied += segments[copyindex].Length; } testStrings.Add(test); } if ((min + 1 >= _charsinOrder.Length)) { } bool opt = testStrings.Any(x => x[0] == _charsinOrder[min + 1]); int lowestScore = int.MaxValue; foreach (var test in testStrings) { if (!opt || test[0] == _charsinOrder[min + 1]) { var testScore = GetMinEdits(new string(test), cost + segments.Count, min + 1); if (lowestScore > testScore) lowestScore = testScore; } } return lowestScore + segments.Count; } private char[] DeRepete(char[] s, char min, out bool somethingToDo) { somethingToDo = false; List<char> res = new List<char>(s.Length); if (s[0] != min) res.Add(s[0]); for (int i = 1; i < s.Length; i++) { if (s[i] != s[i - 1]) { res.Add(s[i]); somethingToDo = somethingToDo || s[i] == min; } } if (res.Count <= 1) somethingToDo = false; return res.ToArray(); } } Suffix Rotation Java Solution import java.io.*; import java.util.*; public class Solution { static int copy(List<Character> sorg, char[] dest, int startSorg, int endSorg, int startDest) { for (int j = startSorg; j < endSorg; j++) { dest[startDest++] = sorg.get(j); } return startDest; } static int copy(char[] sorg, char[] dest, int startSorg, int endSorg, int startDest) { for (int j = startSorg; j < endSorg; j++) { dest[startDest++] = sorg[j]; } return startDest; } static char[] create(List<Character> sorg, int startSorg, int endSorg) { char[] dest = new char[endSorg - startSorg]; copy(sorg, dest, startSorg, endSorg, 0); return dest; } static int solve(char[] s) { int res = 0; char prev1 = 0; List<Character> t = new ArrayList<>(); char a = s[0]; for (char c : s) { if (c != prev1) { t.add(c); } prev1 = c; if (a > c) { a = c; } } if (t.size() > 0 && t.get(0) == a) { if (t.size() == 1) { return 0; } return solve(create(t, 1, t.size())); } List<char[]> parts = new ArrayList<>(); int prev = -1; res = 0; for (int i = 0; i < t.size(); i++) { if (t.get(i) != a) { continue; } parts.add(create(t, prev + 1, i)); res++; prev = i; } char[] v = new char[t.size() - (prev + 1) + parts.get(0).length]; int start = copy(t, v, prev + 1, t.size(), 0); copy(parts.get(0), v, 0, parts.get(0).length, start); parts.set(0, v); int bi = -1; int bq = 0; for (int i = 0; i < parts.size(); i++) { char b = parts.get(i)[0]; int h = i > 0 ? i - 1 : parts.size() - 1; char z = parts.get(h)[parts.get(h).length - 1]; char c = 0; int ii = i; int jj = 0; while (true) { jj++; if (jj == parts.get(ii).length) { ii = (ii + 1) % parts.size(); jj = 0; } if (ii == i && jj == 0) { break; } if (parts.get(ii)[jj] != b) { c = parts.get(ii)[jj]; break; } } if (c == 0) { c = b; } int q = (((int) b) * 1024) + ((z != b ? 0 : 1) * 256) - ((int) c); if (bi == -1 || q < bq) { bq = q; bi = i; } } StringBuilder sb = new StringBuilder(); for (int i = bi; i < parts.size(); i++) { sb.append(parts.get(i)); } for (int i = 0; i < bi; i++) { sb.append(parts.get(i)); } if (sb.length() == 0) { return res; } return res + solve(sb.toString().toCharArray()); } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); int q = Integer.parseInt(st.nextToken()); for (int qItr = 0; qItr < q; qItr++) { String s = br.readLine(); System.out.println(solve(s.toCharArray())); } br.close(); } } Suffix Rotation Python Solution #!/bin/python3 import sys def bestlastrotation(s,groups,letters,memos): if len(letters) < 3: return groups[0] mn = letters[0] mn2 = letters[1] mn3 = letters[2] lens = len(s) groups2 = [] for g in groups: i = g while s[i] == mn: i = (i + 1) % lens if s[i] == mn2 and s[g-1] != mn2: groups2.append([g,i]) if len(groups2) == 0: return groups[0] if len(groups2) == 1: return groups2[0][0] for gg in groups2: j = gg[1] while s[j] == mn2 or s[j] == mn: j = (j + 1) % lens if s[j] != mn3: return gg[0] else: gg.append(j) if len(letters) < 4: return groups2[0][0] groupset = set(x[0] for x in groups2) ans = 0 best = lens for g in groupset: s2 = (s[g:]+s[:g]).replace(mn,'') result = min_rotations(s2,memos) if best > result: best = result ans = g return ans def min_rotations(s,memos): if s in memos: return memos[s] letters = sorted(set(s)) mn = min(letters) ans = 0 while mn != max(letters): i = 0 while s[i] == mn: i += 1 if i > 0: s = s[i:] groups = [] for i in range(len(s)): if s[i] == mn and s[i-1] != mn: groups.append(i) ans += len(groups) if len(groups) == 1: g = groups[0] s = s[g:] + s[:g] if len(groups) > 1: g = bestlastrotation(s,groups,letters,memos) s = s[g:] + s[:g] s = s.replace(mn,'') letters = letters[1:] mn = min(letters) memos[s] = ans return ans q = int(input().strip()) for a0 in range(q): s = input().strip() # your code goes here print(min_rotations(s,dict())) c C# C++ HackerRank Solutions java python CcppCSharpHackerrank Solutionsjavapython