Generating all permutations of a given string

前端 未结 30 1660
我寻月下人不归
我寻月下人不归 2020-11-21 06:35

What is an elegant way to find all the permutations of a string. E.g. permutation for ba, would be ba and ab, but what about longer st

相关标签:
30条回答
  • 2020-11-21 06:57

    This one is without recursion

    public static void permute(String s) {
        if(null==s || s.isEmpty()) {
            return;
        }
    
        // List containing words formed in each iteration 
        List<String> strings = new LinkedList<String>();
        strings.add(String.valueOf(s.charAt(0))); // add the first element to the list
    
         // Temp list that holds the set of strings for 
         //  appending the current character to all position in each word in the original list
        List<String> tempList = new LinkedList<String>(); 
    
        for(int i=1; i< s.length(); i++) {
    
            for(int j=0; j<strings.size(); j++) {
                tempList.addAll(merge(s.charAt(i), strings.get(j)));
                            }
            strings.removeAll(strings);
            strings.addAll(tempList);
    
            tempList.removeAll(tempList);
    
        }
    
        for(int i=0; i<strings.size(); i++) {
            System.out.println(strings.get(i));
        }
    }
    
    /**
     * helper method that appends the given character at each position in the given string 
     * and returns a set of such modified strings 
     * - set removes duplicates if any(in case a character is repeated)
     */
    private static Set<String> merge(Character c,  String s) {
        if(s==null || s.isEmpty()) {
            return null;
        }
    
        int len = s.length();
        StringBuilder sb = new StringBuilder();
        Set<String> list = new HashSet<String>();
    
        for(int i=0; i<= len; i++) {
            sb = new StringBuilder();
            sb.append(s.substring(0, i) + c + s.substring(i, len));
            list.add(sb.toString());
        }
    
        return list;
    }
    
    0 讨论(0)
  • 2020-11-21 06:59
    public static void permutation(String str) { 
        permutation("", str); 
    }
    
    private static void permutation(String prefix, String str) {
        int n = str.length();
        if (n == 0) System.out.println(prefix);
        else {
            for (int i = 0; i < n; i++)
                permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
        }
    }
    

    (via Introduction to Programming in Java)

    0 讨论(0)
  • 2020-11-21 07:00

    Recursion is not necessary, even you can calculate any permutation directly, this solution uses generics to permute any array.

    Here is a good information about this algorihtm.

    For C# developers here is more useful implementation.

    public static void main(String[] args) {
        String word = "12345";
    
        Character[] array = ArrayUtils.toObject(word.toCharArray());
        long[] factorials = Permutation.getFactorials(array.length + 1);
    
        for (long i = 0; i < factorials[array.length]; i++) {
            Character[] permutation = Permutation.<Character>getPermutation(i, array, factorials);
            printPermutation(permutation);
        }
    }
    
    private static void printPermutation(Character[] permutation) {
        for (int i = 0; i < permutation.length; i++) {
            System.out.print(permutation[i]);
        }
        System.out.println();
    }
    

    This algorithm has O(N) time and space complexity to calculate each permutation.

    public class Permutation {
        public static <T> T[] getPermutation(long permutationNumber, T[] array, long[] factorials) {
            int[] sequence = generateSequence(permutationNumber, array.length - 1, factorials);
            T[] permutation = generatePermutation(array, sequence);
    
            return permutation;
        }
    
        public static <T> T[] generatePermutation(T[] array, int[] sequence) {
            T[] clone = array.clone();
    
            for (int i = 0; i < clone.length - 1; i++) {
                swap(clone, i, i + sequence[i]);
            }
    
            return clone;
        }
    
        private static int[] generateSequence(long permutationNumber, int size, long[] factorials) {
            int[] sequence = new int[size];
    
            for (int j = 0; j < sequence.length; j++) {
                long factorial = factorials[sequence.length - j];
                sequence[j] = (int) (permutationNumber / factorial);
                permutationNumber = (int) (permutationNumber % factorial);
            }
    
            return sequence;
        }
    
        private static <T> void swap(T[] array, int i, int j) {
            T t = array[i];
            array[i] = array[j];
            array[j] = t;
        }
    
        public static long[] getFactorials(int length) {
            long[] factorials = new long[length];
            long factor = 1;
    
            for (int i = 0; i < length; i++) {
                factor *= i <= 1 ? 1 : i;
                factorials[i] = factor;
            }
    
            return factorials;
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:01

    Here is my solution that is based on the idea of the book "Cracking the Coding Interview" (P54):

    /**
     * List permutations of a string.
     * 
     * @param s the input string
     * @return  the list of permutations
     */
    public static ArrayList<String> permutation(String s) {
        // The result
        ArrayList<String> res = new ArrayList<String>();
        // If input string's length is 1, return {s}
        if (s.length() == 1) {
            res.add(s);
        } else if (s.length() > 1) {
            int lastIndex = s.length() - 1;
            // Find out the last character
            String last = s.substring(lastIndex);
            // Rest of the string
            String rest = s.substring(0, lastIndex);
            // Perform permutation on the rest string and
            // merge with the last character
            res = merge(permutation(rest), last);
        }
        return res;
    }
    
    /**
     * @param list a result of permutation, e.g. {"ab", "ba"}
     * @param c    the last character
     * @return     a merged new list, e.g. {"cab", "acb" ... }
     */
    public static ArrayList<String> merge(ArrayList<String> list, String c) {
        ArrayList<String> res = new ArrayList<>();
        // Loop through all the string in the list
        for (String s : list) {
            // For each string, insert the last character to all possible positions
            // and add them to the new list
            for (int i = 0; i <= s.length(); ++i) {
                String ps = new StringBuffer(s).insert(i, c).toString();
                res.add(ps);
            }
        }
        return res;
    }
    

    Running output of string "abcd":

    • Step 1: Merge [a] and b: [ba, ab]

    • Step 2: Merge [ba, ab] and c: [cba, bca, bac, cab, acb, abc]

    • Step 3: Merge [cba, bca, bac, cab, acb, abc] and d: [dcba, cdba, cbda, cbad, dbca, bdca, bcda, bcad, dbac, bdac, badc, bacd, dcab, cdab, cadb, cabd, dacb, adcb, acdb, acbd, dabc, adbc, abdc, abcd]

    0 讨论(0)
  • 2020-11-21 07:01

    Here is another simpler method of doing Permutation of a string.

    public class Solution4 {
    public static void main(String[] args) {
        String  a = "Protijayi";
      per(a, 0);
    
    }
    
    static void per(String a  , int start ) {
          //bse case;
        if(a.length() == start) {System.out.println(a);}
        char[] ca = a.toCharArray();
        //swap 
        for (int i = start; i < ca.length; i++) {
            char t = ca[i];
            ca[i] = ca[start];
            ca[start] = t;
            per(new String(ca),start+1);
        }
    
    }//per
    
    }
    
    0 讨论(0)
  • 2020-11-21 07:02

    A java implementation to print all the permutations of a given string considering duplicate characters and prints only unique characters is as follow:

    import java.util.Set;
    import java.util.HashSet;
    
    public class PrintAllPermutations2
    {
        public static void main(String[] args)
        {
            String str = "AAC";
    
        PrintAllPermutations2 permutation = new PrintAllPermutations2();
    
        Set<String> uniqueStrings = new HashSet<>();
    
        permutation.permute("", str, uniqueStrings);
    }
    
    void permute(String prefixString, String s, Set<String> set)
    {
        int n = s.length();
    
        if(n == 0)
        {
            if(!set.contains(prefixString))
            {
                System.out.println(prefixString);
                set.add(prefixString);
            }
        }
        else
        {
            for(int i=0; i<n; i++)
            {
                permute(prefixString + s.charAt(i), s.substring(0,i) + s.substring(i+1,n), set);
            }
        }
    }
    }
    
    0 讨论(0)
提交回复
热议问题