privatebooleanpermute(int d, int n, StringBuilder sb){ if (d == n) { return testPalindromicity(sb); } for (int i = d; i < n; ++i) { swap(sb, d, i); if (permute(d + 1, n, sb)) returntrue; swap(sb, d, i); } returnfalse; }
// swap characters in a StringBuilder privatevoidswap(StringBuilder sb, int i, int j){ char temp = sb.charAt(i); sb.setCharAt(i, sb.charAt(j)); sb.setCharAt(j, temp); }
privatebooleantestPalindromicity(StringBuilder sb){ int n = sb.length(); for (int i = 0; i < n / 2; ++i) { if (sb.charAt(i) != sb.charAt(n - i - 1)) returnfalse; } returntrue; }
Time: $O(N \times N!)$ Space: $O(N)$
Hash Map
We can use hash map based on the fact that odd number of occurrences of a specific character can only occur once at most.
Actually, since there are only 128 ASCII characters, we can use an array of size 128 to store occurrences.
Note: But I think the code is not elegant.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicbooleancanPermutePalindrome(String s){ Map<Character, Integer> map = new HashMap<>(); // count for (char ch : s.toCharArray()) { map.put(ch, map.getOrDefault(ch, 0) + 1); } // check boolean hasMetOdd = false; for (char ch : map.keySet()) { int count = map.get(ch); if (count % 2 != 0) { // meet odd if (hasMetOdd) returnfalse; hasMetOdd = true; } } returntrue; }
A more elegant version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicbooleancanPermutePalindrome(String s){ Map<Character, Integer> map = new HashMap<>(); // count for (char ch : s.toCharArray()) { map.put(ch, map.getOrDefault(ch, 0) + 1); } // check int totalCount = 0; for (char ch : map.keySet()) { int count = map.get(ch); totalCount += (count % 2); // do not add odd count } /* if odd count occurs more than once, totalCount would be > 1 */ return count <= 1; }
Time: $O(N)$ Space: $O(N)$
Hash Set
Idea: Only character with odd number of occurrences will be in the hash set.
1 2 3 4 5 6 7 8 9 10
publicbooleancanPermutePalindrome(String s){ Set<Character> set = new HashSet<>(); // count for (char ch : s.toCharArray()) { if (set.contains(ch)) set.remove(ch); else set.add(ch); } // check return set.size() <= 1; }