Skip to content

Commit 41605bc

Browse files
committed
Added palindrome permutation
1 parent 0bf8de1 commit 41605bc

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.ctci.arraysandstrings;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* @author rampatra
8+
* @since 21/11/2018
9+
*/
10+
public class PalindromePermutation {
11+
12+
/**
13+
* This method exploits the fact that a palindrome will contain at most
14+
* one character with odd counts. All other characters should be of even
15+
* counts.
16+
*
17+
* @param str input string
18+
* @return {@code true} if {@code str} is a permutation of a palindrome
19+
*/
20+
private static boolean isPermutationOfPalindrome(String str) {
21+
Map<Character, Integer> charCounts = new HashMap<>();
22+
Integer freq;
23+
int oddCounts = 0; // keep count of odds so that we don't have to loop through the hashmap the second time
24+
for (int i = 0; i < str.length(); i++) {
25+
char c = str.charAt(i);
26+
if (c != 32) {
27+
freq = charCounts.get(c) == null ? 0 : charCounts.get(c);
28+
if ((freq + 1) % 2 == 1) {
29+
oddCounts++;
30+
} else {
31+
oddCounts--;
32+
}
33+
charCounts.put(c, freq + 1);
34+
}
35+
}
36+
return oddCounts <= 1;
37+
}
38+
39+
40+
/**
41+
* This approach sets a bit in a number based on the character in the string and
42+
* then un-sets the bit if it sees the character again. Finally, checks if the
43+
* bitVector has at most one bit set only.
44+
*
45+
* @param str input string
46+
* @return {@code true} if {@code str} is a permutation of a palindrome
47+
*/
48+
private static boolean isPermutationOfPalindromeViaBits(String str) {
49+
int bitVector = 0;
50+
int index;
51+
52+
for (int i = 0; i < str.length(); i++) {
53+
index = getIndex(str.charAt(i));
54+
if (index != -1) {
55+
bitVector = toggleBitAt(bitVector, index);
56+
}
57+
}
58+
return (bitVector & (bitVector - 1)) == 0;
59+
}
60+
61+
/**
62+
* Calculates the index to set the bit according to the character {@code c}.
63+
*
64+
* @param c
65+
* @return the index to set the bit as per the character {@code c}
66+
*/
67+
private static int getIndex(char c) {
68+
char a = 'a';
69+
char z = 'z';
70+
71+
// assuming string contains only lowercase characters
72+
if (c < a || c > z) {
73+
return -1;
74+
}
75+
76+
return c - a;
77+
}
78+
79+
/**
80+
* Toggles the bit at index {@code index} in {@code bitVector}.
81+
*
82+
* @param bitVector
83+
* @param index
84+
* @return the resulting {@code bitVector} after toggling the bit
85+
*/
86+
private static int toggleBitAt(int bitVector, int index) {
87+
return bitVector ^ (1 << index);
88+
}
89+
90+
public static void main(String[] args) {
91+
System.out.println(isPermutationOfPalindrome("tactc oapapa"));
92+
System.out.println(isPermutationOfPalindrome("maam"));
93+
System.out.println(isPermutationOfPalindrome("maa m"));
94+
System.out.println(isPermutationOfPalindrome("rammmar"));
95+
System.out.println(isPermutationOfPalindrome("rammmara"));
96+
System.out.println("---------");
97+
System.out.println(isPermutationOfPalindromeViaBits("tactc oapapa"));
98+
System.out.println(isPermutationOfPalindromeViaBits("maam"));
99+
System.out.println(isPermutationOfPalindromeViaBits("maa m"));
100+
System.out.println(isPermutationOfPalindromeViaBits("rammmar"));
101+
System.out.println(isPermutationOfPalindromeViaBits("rammmara"));
102+
}
103+
}

0 commit comments

Comments
 (0)