Daily Archives: June 24, 2015

Group sort

I saw the original problem from G4G. Given an array of strings with RG & B as characters. Sort the array such that all R comes first, followed by Gs & followed by Bs. Do it in O(n) time complexity. (Paper Code)
For example:
 I/P: G G R B R B B G R B R
 O/P: R R R R G G G B B B B

I developed this problem to a generic problem. Given an array of string, and sequence. Sort the array according to the given sequence.
For example:
String str = “DCBAEECCAAABBAEEE”; String sequence = “ABCDE”;
output should be: AAAAABBBCCCDEEEEE

The basic idea is similar to quick sort by an uncertain pivot: http://allenlipeng47.com/PersonalPage/index/view/95/nkey

Because this algorithm require to compare the sequence order, so we use hashmap to store char and sqeuence mapping. In this way, we can get sequence of a char in O(1) time. And we need to save the number of each element in sequence array.

Below is one step how we operate element ‘A’.

package com.pli.project.algorithm.sort;

import java.util.HashMap;

/**
 * Created by lipeng on 2015/6/23.
 * Original problem is from g4g. http://www.geeksforgeeks.org/microsoft-interview-experience-set-54-for-sde/
 * Developed this problem to more generic one:
 String str = "BCDEAAA"; String sequence = "ABCDE";
 output should be: AAABCDE
 */
public class GroupSort {

    public static void groupSort(char[] str, char[] sequence){
        if(str==null||str.length<2||sequence==null||sequence.length<1||sequence.length > str.length){
            return;
        }
        int[] lenArr = new int[sequence.length];   //stores number of each element in sequence array
        // initilization
        HashMap chrOrder = new HashMap();   //char order
        for(int i = 0; ilength; i++){
            chrOrder.put(sequence[i], i);
            if(str[0]==sequence[i]){
                lenArr[i]++;    //initialize the chr[0]
            }
        }
        for(int i=1;ilength;i++){
            int pos = i;
            boolean found = false;
            for(int j=lenArr.length-1 ;j>0 && pos>0;j--){
                if(chrOrder.get(str[pos])>=chrOrder.get(str[pos-1])){   //compare sequence order
                    lenArr[chrOrder.get(str[pos])]++;
                    found = true;
                    break;
                }
                else{
                    // exchange element with previous one
                    char tmp = str[pos];
                    str[pos] = str[pos - lenArr[j]];
                    str[pos - lenArr[j]] = tmp;
                    pos -= lenArr[j];
                } //if
            } //for j
            if(!found){
                //case could be: BBBCCCCDDDA, when next one is A, in this way, A won't be matched in above if clause
                lenArr[chrOrder.get(str[0])]++;
            }
        } //for i
    }

    public static void main(String[] args) {
        String str = "DCBAEECCAAABBAEEE";
        String sequence = "ABCDE";
        char[] chs = str.toCharArray();
        groupSort(chs, sequence.toCharArray());
        System.out.println(chs);
    }
}