Skip to content

Commit

Permalink
feat(strings): is palindrome permutation
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianLusina committed Dec 24, 2024
1 parent cfae34b commit f4c8333
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,29 @@ package com.kotlinground.strings.anagram
* Checks to see if s is an anagram of t.
*/
fun isAnagram(s: String, t: String): Boolean {
// first normalize the strings by removing white spaces which might result in uneven lengths if s1 and s2 are
// anagrams of each other
val s1 = s.replace(" ", "").lowercase()
val s2 = t.replace(" ", "").lowercase()

if (s1.length != s2.length) {
return false
}

// This map is used to keep track of the character count in the strings to check if the strings are anagrams
// of each other, the character count must be equal in both strings. This enables the algorithm to keep track of
// this count.
val map = mutableMapOf<Char, Int>()

// Loop through each character in the first string to count the number of characters and store them in the map
// this is linear, so, O(n) where n is the number of characters in the string as the loop has to iterate over each
// character
for (char in s1) {
map[char] = map[char]?.plus(1) ?: 1
}

// Loops through each character in the second string checking for the existence of that character in the already
// populated map. If a character, exists, the count is decremented, if not, the count is incremented. This
// will be used to show the discrepancy in character count between the two strings
for (char in s2) {
if (map.containsKey(char)) {
map[char] = map[char]?.minus(1) ?: 1
Expand All @@ -25,6 +35,10 @@ fun isAnagram(s: String, t: String): Boolean {
}
}

// Finally, check each key in the map. If a given key's count is not equal to 0, then the algorithm exits
// early as it's not possible to have a character count of more than 0 for strings that are anagrams, since the above
// loop should have reduced the character count to 0. This shows a discrepancy, meaning there is an extra character
// in a string that is not in another string
for ((_, count) in map) {
if (count != 0) {
return false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.kotlinground.strings.palindromes

/**
* Checks if a given string is a palindrome permutation
* @param someString [String] string to check for palindrome property
* @return [Boolean] True if a palindrome, false otherwise
*/
fun isPalindromePermutation(someString: String): Boolean {
val normalizedString = someString.replace(" ", "").lowercase()
val charCount = mutableMapOf<Char, Int>()

for (char in normalizedString) {
if (charCount.containsKey(char)) {
charCount[char] = charCount[char]!! + 1
} else {
charCount[char] = 1
}
}

var oddCount = 0
for (count in charCount.values) {
val isEven = count % 2 != 0
if (isEven && oddCount == 0) {
oddCount++
} else if (isEven && oddCount != 0) {
return false
}
}
return true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.kotlinground.strings.palindromes

import kotlin.test.Test
import kotlin.test.assertTrue

class IsPalindromePermutationTest {
@Test
fun `should return true for 'Tact Coa'`() {
val s = "Tact Coa"
val actual = isPalindromePermutation(s)
assertTrue(actual)
}

@Test
fun `should return true for 'This is not a palindrome permutation'`() {
val s = "This is not a palindrome permutation"
val actual = isPalindromePermutation(s)
assertTrue(actual)
}

@Test
fun `should return true for 'taco cat'`() {
val s = "taco cat"
val actual = isPalindromePermutation(s)
assertTrue(actual)
}
}

0 comments on commit f4c8333

Please sign in to comment.