Permutations excluding repeated characters

前端 未结 5 1210
無奈伤痛
無奈伤痛 2021-02-06 01:43

I\'m working on a Free Code Camp problem - http://www.freecodecamp.com/challenges/bonfire-no-repeats-please

The problem description is as follows -

<
5条回答
  •  感动是毒
    2021-02-06 02:28

    Thanks Lurai for great suggestion. It took a while and is a bit lengthy but here's my solution (it passes all test cases at FreeCodeCamp after converting to JavaScript of course) - apologies for crappy variables names (learning how to be a bad programmer too ;)) :D

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    
    public class PermAlone {
    
        public static int permAlone(String str) {
            int length = str.length();
            int total = 0;
            int invalid = 0;
            int overlap = 0;
            ArrayList vals = new ArrayList<>();
            Map chars = new HashMap<>();
    
            // obtain individual characters and their frequencies from the string
            for (int i = 0; i < length; i++) {
                char key = str.charAt(i);
                if (!chars.containsKey(key)) {
                    chars.put(key, 1);
                }
                else {
                    chars.put(key, chars.get(key) + 1);
                }
            }
    
            // if one character repeated set total to 0
            if (chars.size() == 1 && length > 1) {
                total = 0;
            }
            // otherwise calculate total, invalid permutations and overlap
            else {
                // calculate total
                total = factorial(length);
    
                // calculate invalid permutations
                for (char key : chars.keySet()) {
                    int len = 0;
                    int lenPerm = 0;
                    int charPerm = 0;
                    int val = chars.get(key);
                    int check = 1;
                    // if val > 0 there will be more invalid permutations to  calculate
                    if (val > 1) {
                        check = val;
                        vals.add(val); 
                    }
                    while (check > 1) {
                        len = length - check + 1; 
                        lenPerm = factorial(len);
                        charPerm = factorial(check);
                        invalid = lenPerm * charPerm;
                        total -= invalid; 
                        check--; 
                    }   
                }
    
                // calculate overlaps
                if (vals.size() > 1) {
                    overlap = factorial(chars.size());
                    for (int val : vals) {
                        overlap *= factorial(val);
                    }
                }
    
                total += overlap;
            }
            return total;
        }
    
        // helper function to calculate factorials - not recursive as I was running out of memory on the platform :?
        private static int factorial(int num) {
            int result = 1;
            if (num == 0 || num == 1) {
                result = num;
            }
            else {
                for (int i = 2; i <= num; i++) {
                    result *= i;
                }
            }
            return result;
        }
    
        public static void main(String[] args) {
            System.out.printf("For %s: %d\n\n", "aab", permAlone("aab")); //   expected 2
            System.out.printf("For %s: %d\n\n", "aaa", permAlone("aaa")); // expected 0
            System.out.printf("For %s: %d\n\n", "aabb", permAlone("aabb")); // expected 8
            System.out.printf("For %s: %d\n\n", "abcdefa", permAlone("abcdefa")); // expected 3600
            System.out.printf("For %s: %d\n\n", "abfdefa", permAlone("abfdefa")); // expected 2640
            System.out.printf("For %s: %d\n\n", "zzzzzzzz", permAlone("zzzzzzzz")); // expected 0
            System.out.printf("For %s: %d\n\n", "a", permAlone("a")); // expected 1
            System.out.printf("For %s: %d\n\n", "aaab", permAlone("aaab")); // expected 0
            System.out.printf("For %s: %d\n\n", "aaabb", permAlone("aaabb")); // expected 12
            System.out.printf("For %s: %d\n\n", "abbc", permAlone("abbc")); //expected 12
        }
    } 
    

提交回复
热议问题