Skip to content
thecscience
THECSICENCE

Learn everything about computer science

  • Home
  • Human values
  • NCERT Solutions
  • HackerRank solutions
    • HackerRank Algorithms problems solutions
    • HackerRank C solutions
    • HackerRank C++ solutions
    • HackerRank Java problems solutions
    • HackerRank Python problems solutions
thecscience
THECSICENCE

Learn everything about computer science

HackerRank Reverse Shuffle Merge Solution

Yashwant Parihar, June 11, 2023August 1, 2024

In this post, we will solve HackerRank Reverse Shuffle Merge Problem Solution. Given a string, A, we define some operations on the string as follows:

a. reverse(A) denotes the string obtained by reversing string A. Example: reverse(“abc”) = “cba”
b. shuffle(4) denotes any string that’s a permutation of string A. Example: shuffle (“god”) [‘god’, ‘gdo’, ‘ogd’, ‘odg’, ‘dgo’, ‘dog’]
c. merge(A1, A2) denotes any string that’s obtained by interspersing the two strings Al & A2, maintaining the order of characters in both. For example, A1 = “abc” & A2 = “def”, one possible result of merge(A1, A2) could be “abcdef”, another could be “abdecf”, another could be “adbecf” and so on.
Given a string s such that s merge (reverse (A), shuffle (A)) for some string A. find the lexicographically smallest A.
For example, s = abab. We can split it into two strings of ab. The reverse is ba and we need to find a string to shuffle in to get abab. The middle two characters match our reverse string, leaving the a and b at the ends. Our shuffle string needs to be ab. Lexicographically ab < ba so our answer is ab.

unction Description

Complete the reverseShuffleMerge function in the editor below. It must return the lexicographically smallest string fitting the criteria.

reverseShuffleMerge has the following parameter(s):

  • s: a string

Input Format

A single line containing the string s.

Output Format

Find and return the string which is the lexicographically smallest valid .

Sample Input 0

eggegg

Sample Output 0

egg

Explanation 0

Split “eggegg” into strings of like character counts: “egg”, “egg”
reverse(“egg”) = “gge”
shuffle(“egg”) can be “egg”
“eggegg” belongs to the merge of (“gge”, “egg”)

The merge is: eggegg.

‘egg’ < ‘gge’

Sample Input 1

abcdefgabcdefg

Sample Output 1

agfedcb
HackerRank Reverse Shuffle Merge Problem Solution
HackerRank Reverse Shuffle Merge Problem Solution

Reverse Shuffle Merge C Solution

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <strings.h>
#include <stdbool.h>

#if 0
#define PRINT(_str...) printf(_str)
#else
#define PRINT(_str...)
#endif

char arr[10001];
char output[10001];

bool isSmallest(int *freq, int idx, bool main) {
    if (!freq[idx]) {
        printf("No instances of %c left in %s\n",
               idx + 'a', main ? "freq" : "temp");
        printf("%s", output);
        exit(-1);
    }
    for (int i = idx - 1; i >=0; i--) {
        if (freq[i]) {
            return false;
        }
    }
    return true;
}

#define PRINT_CHAR(char) do { \
    output[offset] = char; \
    offset++; \
    needed[char - 'a']--; \
} while (0)

int main() {
    int freq[26];
    bzero(freq, sizeof(freq));
    bzero(output, sizeof(output));
    
    scanf("%s", arr);
    
    int len = 0;
    for (int i = 0; arr[i]; i++, len++) {
        freq[arr[i] - 'a']++;
    }
    
    for (int i = 0; i < 26; i++) {
        if (freq[i] % 2) {
            printf("ERROR - odd count (%d) of %c\n",
                   freq[i], i + 'a');
            return -1;
        }
        freq[i] /= 2;
    }
    
    int needed[26];
    int skipped[26];
    int temp[26];
    
    bzero(temp, sizeof(temp));
    bzero(skipped, sizeof(skipped));
    bcopy(freq, needed, sizeof(freq));
    
    int offset = 0;
    int last_print = len;
    
    for (int i = len - 1; i >= 0; i--) {
        char cur = arr[i];
        int idx = cur - 'a';
        
        PRINT("Checking idx %d - %c\n", i, arr[i]);
        if (needed[idx] == 0) {
            PRINT(" Not needed\n");
            continue;
        }

        if (isSmallest(needed, idx, true)) {
            PRINT(" Adding\n");
            
            PRINT_CHAR(cur);
            last_print = i;
            for (int j = 0; j < 26; j++) {
                skipped[j] += temp[j];
                temp[j] = 0;
            }
            continue;
        }
        
        temp[idx]++;
        if ((skipped[idx] + temp[idx]) <= freq[idx]) {
            PRINT(" Skipping\n");
            continue;
        }
        
        PRINT(" Hit skip limit\n");
        bool added = false;
        for (int j = last_print - 1; j >= i; j--) {
            char tempchar = arr[j];
            int tempidx = tempchar - 'a';
            PRINT(" Reconsidering index %d - %c\n", j, arr[j]);
            if (needed[tempidx] == 0) {
                PRINT("  Not needed\n");
            } else if ((tempchar <= cur) && isSmallest(temp, tempidx, false)) {
                PRINT("  Adding\n");
                PRINT_CHAR(tempchar);
                temp[tempidx]--;
                last_print = j;
                added = true;
                if (tempchar == cur) {
                    i = j;
                    bzero(temp, sizeof(temp));
                    break;
                }
            } else {
                PRINT("  Skipping\n");
                skipped[tempidx]++;
                temp[tempidx]--;
            }
        }
        for (int j = 0; j < 26; j++) {
            if (temp[j]) {
                printf("TEMP NOT RESET PROPERLY - %d=%d\n", j, temp[j]);
                return -1;
            }
        }
        if (!added) {
            PRINT(" Nothing added yet.  Printing last found\n");
            PRINT_CHAR(cur);
            last_print = i;
        }
    }
    if (offset != len / 2) {
        printf("BAD FINAL OFFSET (%d, %d)\n", offset, len);
        return -1;
    }
    printf("%s\n", output);
    return 0;
}

Reverse Shuffle Merge C++ Solution

#include <cmath>
#include <cstdio>
#include <array>
#include <vector>
#include <iterator>
#include <iostream>
#include <algorithm>

template <bool DEBUG = false>
class State {
public:
    typedef std::array<size_t, 26> Counts;
    typedef std::vector<size_t> Needs;

    State(const std::string& str, const std::string& expect = "")
        : source_(str), expect_(expect),
          count_(CountChars(str)),
          need_(Constrain(str, count_)),
          written_({0}), out_() {
        out_.reserve(source_.size() / 2);
    }
    
    void PrintState(auto ch, auto end) const {
        for (auto st = need_.cbegin(); ch != end; ++st, ++ch) {
            std::cout << *ch;
            if (*st != 0) std::cout << ": " << *st;
            std::cout << std::endl;
        }
    }
    
    const std::string& Solve() {
        if (!out_.empty()) return out_;

        auto begin = source_.crbegin();
        auto end = source_.crend();
        for (auto guard = begin; guard != end; ++guard) {
            // find first non-zero constraint
            size_t ix = std::distance(source_.crbegin(), guard);
            if (need(ix) <= written(*guard)) {
                continue;
            }
            // write characters, preferring lower values
            begin = Write(begin, guard + 1, *guard);
            if (DEBUG && out_ > expect_) {
                PrintState(source_.crbegin(), guard + 1);
                return out_;
            }
        }
        
        for (auto ch = begin; ch != end; ++ch) {
            if (written((*ch)) < count(*ch)) {
                out_.push_back(*ch);
                ++written(*ch);
            }
        }

        if (DEBUG && out_.size() != source_.size() / 2) {
            PrintState(source_.crbegin(), source_.crend());
        }
        
        return out_;
    }

private:
    static Counts CountChars(const std::string& str) {
        Counts count = {0};
        for (auto ch = str.cbegin(); ch != str.cend(); ++ch) {
            ++count[*ch - 'a'];
        }
        for (auto it = count.begin(); it != count.cend(); ++it) {
            *it /= 2;
        }
        return count;
    }

    static Needs Constrain(const std::string& str, Counts take) {
        std::vector<size_t> need(str.size());
        auto st = need.rbegin();
        for (auto ch = str.cbegin(); ch != str.cend(); ++ch, ++st) {
            auto& c = take[*ch - 'a'];
            *st = c; if (c != 0) --c;
        }
        return need;
    }

    auto Write(auto begin, auto end, char limit = 'z') {
        for (; begin != end; ++begin) {
            char low = limit + 1;
            for (auto ch = begin; ch != end; ++ch) {
                if (*ch < low && written(*ch) < count(*ch)) {
                    low = *ch;
                    begin = ch;
                }
            }
            if (low == limit + 1) return end;
            out_.push_back(*begin);
            ++written(*begin);
            if (DEBUG && out_ > expect_) return end;
            if (low == limit) return begin + 1;
        }
        return begin;
    }
    
    size_t count(char ch) const {
        return count_[ch - 'a'];
    }
    
    size_t need(size_t ix) const {
        return need_[ix];
    }

    size_t written(char ch) const {
        return written_[ch - 'a'];
    }

    size_t& written(char ch) {
        return written_[ch - 'a'];
    }
    
    const std::string& source_;
    const std::string& expect_;
    const Counts count_;
    const Needs need_;
    Counts written_;
    std::string out_;
};


int main() {
    std::string str;
    std::cin >> str;

    static const bool debug = false;
    
    std::string expect;
    if (debug) std::cin >> expect;

    State<debug> state(str, expect);
    std::string out = state.Solve();
    std::cout << out << std::endl;
    
    return 0;
}

Reverse Shuffle Merge C Sharp Solution

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
class Solution {
    public static void GetLexicographicallySmallestStr(string str){
        int[] charFrequence ;
        charFrequence=GetCharFrequence(str);
    }
    static void GetString(int []charFrequence,char[] sortStr, string str){
        StringBuilder strB=new StringBuilder();
        int strIndex=0;
        int printedIndex=0;
        str= stringReverseString1(str);
        for(int index=0;index<sortStr.Length;index++){
            for(;strIndex<str.Length;strIndex++){
                if(charFrequence[sortStr[index]-97]==0){
                    break;
                }
                //Console.WriteLine(sortStr[index]+"<"+str[strIndex]);
                if(sortStr[index]<str[strIndex]){
                    //Console.WriteLine(GetFrq(str.Substring(strIndex),str[strIndex])+"<="+charFrequence[str[strIndex]-97]+"frq"+ str[strIndex]);
                    if(GetFrq(str.Substring(strIndex),str[strIndex])<=charFrequence[str[strIndex]-97]){
                        //Console.Write(" charAt["+strIndex+"]="+str[strIndex]+"befr ||");
                        strIndex=checkPreviousCharsFrq(charFrequence,sortStr,index+1,strIndex,str,printedIndex+1);
                        //Console.Write(" ch["+strIndex+"]="+str[strIndex]+" aftr PrChar() ||");
                        if(charFrequence[str[strIndex]-97]!=0){
                            strB.Append(str[strIndex]);
                            printedIndex=strIndex;
                            charFrequence[str[strIndex]-97]--;
                           // Console.Write("o/p"+strB);
                        }
                    }
                }else if(sortStr[index]==str[strIndex]){
                    if(charFrequence[str[strIndex]-97]!=0){
                        strB.Append(str[strIndex]);
                        printedIndex=strIndex;
                        charFrequence[str[strIndex]-97]--;
                        //Console.Write("o/p"+strB);
                    }
                }
            }
        }
        Console.WriteLine(strB);
    }
    public static int checkPreviousCharsFrq(int[] charFrequence,char[] sortStr,int index,int charIndex,string str, int strIndex){
        char toBePrinted;
        char ch=str[charIndex];
        int tempIndex=strIndex;
        //Console.WriteLine("ch["+charIndex+"]="+ch+" in PrChar() ||");
        for(;index<sortStr.Length ;index++){
            //Console.WriteLine(" sortStr["+tempIndex+"]="+sortStr[index]+"<="+ch+" chin");
            if((sortStr[index])<=ch){
                    if(charFrequence[sortStr[index]-97]!=0){
                        toBePrinted=sortStr[index];
                        for(tempIndex=strIndex;(tempIndex<charIndex);tempIndex++){
                            //Console.WriteLine(str[tempIndex]+"--"+tempIndex+"=="+toBePrinted+" at:"+index);
                            if(str[tempIndex]==toBePrinted){
                                return tempIndex;
                            }
                        }
                    }
            }
           
        }
        return tempIndex;
    }
    public static string stringReverseString1 (string str){
        char[] chars = str.ToCharArray();
        char[] result = new char[chars.Length];
        for (int i =0, j = str.Length - 1; i < str.Length; i++, j--){
            result[i] = chars[j];
        }
        return new string(result);
    }
    public static int[] GetCharFrequence(string str){
        int []frq=new int[26];
        int count=0;
        for(int frqIndex=0;frqIndex<26;frqIndex++)
            frq[frqIndex]='0';
        char []temp=RemoveRepetetion(str).ToCharArray();
        Array.Sort(temp);
        for(int index=0;index<temp.Length;index++){
            for(int matchIndex=0;matchIndex<str.Length;matchIndex++){
                if(temp[index]==str[matchIndex]){
                    count++;
                }
            }
            frq[temp[index]-97]=count/2;
            count=0;
        }
        GetString(frq,temp,str);
        return frq;
    }
    static  string RemoveRepetetion(string str){
        string newStr="";
        foreach(char ch in str){
            if(!(IsContainChar(newStr,ch)))
                newStr+=ch;
        }
        return newStr;
    }
    static bool IsContainChar(string str,char character){
        foreach(char ch in str){
            if(ch==character)
                return true;
        }
        return false;
    }
    public static int GetFrq(string str,char ch){
        int frq=0;
        for(int index=0;index<str.Length;index++){
            if(ch==str[index])
                frq++;
        }
        return frq;
    }
    static void Main(String[] args) {
        string str=Console.ReadLine();
        GetLexicographicallySmallestStr(str);
    }
}

Reverse Shuffle Merge Java Solution

import java.io.*;
import java.util.*;
import java.math.*;

public class Solution implements Runnable {
    static BufferedReader in;
    static PrintWriter out;
    static StringTokenizer st;
    static Random rnd;

    private void solve() throws IOException {
        int tests = 1;
        for (int test = 0; test < tests; test++)
            solveOne();
    }

    private void solveOne() throws IOException {
        String s = nextToken();
        s = reverseString(s);
        final int alphaSize = 26;
        int[] count = new int[alphaSize];
        for (int i = 0; i < s.length(); i++)
            ++count[s.charAt(i) - 'a'];
        int needLength = 0;
        for (int i = 0; i < alphaSize; i++) {
            if (count[i] % 2 != 0)
                throw new AssertionError();
            count[i] /= 2;
            needLength += count[i];
        }
        StringBuilder result = new StringBuilder();
        int[][] counts = new int[s.length()][alphaSize];
        for (int i = s.length() - 1; i >= 0; i--) {
            for (int j = 0; j < alphaSize; j++)
                counts[i][j] = (i + 1 == s.length() ? 0 : counts[i + 1][j]);
            counts[i][s.charAt(i) - 'a']++;
        }
        int leftPointer = 0;
        for (int it = 0; it < needLength; it++) {
            int resultIndex = -1;
            for (int i = leftPointer; i < s.length(); i++) {
                // out.println(it + " " + i + " " + resultIndex);
                if (count[s.charAt(i) - 'a'] > 0) {
                    if (resultIndex == -1
                            || s.charAt(i) < s.charAt(resultIndex)) {
                        if (isOk(count, counts[i]))
                            resultIndex = i;
                    }
                }
            }
            result.append(s.charAt(resultIndex));
            --count[s.charAt(resultIndex) - 'a'];
            leftPointer = resultIndex + 1;
            // out.println(resultIndex + " " + result);
            // out.flush();
        }
        out.println(result);
    }

    private boolean isOk(int[] a, int[] b) {
        for (int i = 0; i < a.length; i++)
            if (a[i] > b[i])
                return false;

        return true;
    }

    private String reverseString(String s) {
        return new StringBuilder(s).reverse().toString();
    }

    public static void main(String[] args) {
        new Solution().run();
    }

    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);

            rnd = new Random();

            solve();

            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    private String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            String line = in.readLine();

            if (line == null)
                return null;

            st = new StringTokenizer(line);
        }

        return st.nextToken();
    }

    private int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    private long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    private double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }
}
                    

Reverse Shuffle Merge JavaScript Solution

'use strict';

const fs = require('fs');

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.replace(/\s*$/, '')
        .split('\n')
        .map(str => str.replace(/\s*$/, ''));

    main();
});

function readLine() {
    return inputString[currentLine++];
}

// Complete the reverseShuffleMerge function below.
const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
function reverseShuffleMerge(s) {
    var { dict, skipDict } = buildDictionary(s);
    var charList = [];
    s.split('').reverse().forEach((c) => {
        if (charList.length === 0) {
            charList.push(c);
            dict[c]--;
        } else {
            if (dict[c] == 0) {
                skipDict[c]--;
            } else {
                while (charList.length > 0) {
                    let last = charList[charList.length - 1];
                    if (c < last && skipDict[last] > 0) {
                        skipDict[last]--;
                        dict[last]++;
                        charList.length--;
                    } else {
                        break;
                    }
                }
                charList.push(c);
                dict[c]--;
            }
        }
    });
    return charList.join('');
}

function buildDictionary(s) {
    let dict = {};
    for (let i = 0; i < s.length; i++) {
        let char = s.charAt(i)
        if (dict[char] == undefined) {
            dict[char] = 0.5;
        } else {
            dict[char] += 0.5;
        }
    }
    return { dict, skipDict: { ...dict } }
}
function main() {
    const ws = fs.createWriteStream(process.env.OUTPUT_PATH);

    const s = readLine();

    let result = reverseShuffleMerge(s);

    ws.write(result + "\n");

    ws.end();
}

Reverse Shuffle Merge Python Solution

from collections import Counter

original = s = input()
counter = Counter(s)
for k in counter:
    counter[k] //= 2
word = ""
while len(word) < len(original) // 2:
    for c in sorted(counter.keys()):
        i = s.rfind(c)
        left = Counter(s[:i + 1])
        if all(k in left and left[k] >= counter[k] for k in counter):
            word += c
            s = s[:i]
            counter[c] -= 1
            if counter[c] == 0:
                del counter[c]
            break
print(word)
c C# C++ HackerRank Solutions java javascript python CcppCSharpHackerrank Solutionsjavajavascriptpython

Post navigation

Previous post
Next post
  • HackerRank Dynamic Array Problem Solution
  • HackerRank 2D Array – DS Problem Solution
  • Hackerrank Array – DS Problem Solution
  • Von Neumann and Harvard Machine Architecture
  • Development of Computers
©2025 THECSICENCE | WordPress Theme by SuperbThemes