From 64859732326ae326d1078bf09f11da3c22b6a69b Mon Sep 17 00:00:00 2001 From: javy99 Date: Sat, 7 Jun 2025 15:35:17 +0200 Subject: [PATCH] implement valid palindrome problem --- 2_two_pointers/1_valid_palindrome/solution.go | 49 +++++++++++++++++++ .../1_valid_palindrome/solution_test.go | 41 ++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 2_two_pointers/1_valid_palindrome/solution.go create mode 100644 2_two_pointers/1_valid_palindrome/solution_test.go diff --git a/2_two_pointers/1_valid_palindrome/solution.go b/2_two_pointers/1_valid_palindrome/solution.go new file mode 100644 index 0000000..c657176 --- /dev/null +++ b/2_two_pointers/1_valid_palindrome/solution.go @@ -0,0 +1,49 @@ +package validpalindrome + +// Time complexity: O(n) +// Space complexity: O(n) +func IsPalindromeReverseString(s string) bool { + clean := make([]rune, 0, len(s)) + for _, r := range s { + if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') { + clean = append(clean, r) + } else if r >= 'A' && r <= 'Z' { + clean = append(clean, r+32) + } + } + n := len(clean) + for i := 0; i < n/2; i++ { + if clean[i] != clean[n-1-i] { + return false + } + } + return true +} + +// Time complexity: O(n) +// Space complexity: O(1) +func IsPalindromeTwoPointers(s string) bool { + left, right := 0, len(s)-1 + for left < right { + for left < right && !((s[left] >= 'a' && s[left] <= 'z') || (s[left] >= 'A' && s[left] <= 'Z') || (s[left] >= '0' && s[left] <= '9')) { + left++ + } + for left < right && !((s[right] >= 'a' && s[right] <= 'z') || (s[right] >= 'A' && s[right] <= 'Z') || (s[right] >= '0' && s[right] <= '9')) { + right-- + } + l := s[left] + r := s[right] + if l >= 'A' && l <= 'Z' { + l += 32 + } + if r >= 'A' && r <= 'Z' { + r += 32 + } + if l != r { + return false + } + left++ + right-- + } + return true +} diff --git a/2_two_pointers/1_valid_palindrome/solution_test.go b/2_two_pointers/1_valid_palindrome/solution_test.go new file mode 100644 index 0000000..85f0fb7 --- /dev/null +++ b/2_two_pointers/1_valid_palindrome/solution_test.go @@ -0,0 +1,41 @@ +package validpalindrome + +import "testing" + +func TestIsPalindrome(t *testing.T) { + cases := []struct { + name string + fn func(string) bool + s string + expected bool + }{ + // IsPalindromeReverseString + {"Reverse String - Palindrome with spaces/punctuations", IsPalindromeReverseString, "Was it a car or a cat I saw?", true}, + {"Reverse String - Not a palindrome", IsPalindromeReverseString, "tab a cat", false}, + {"Reverse String - Single character", IsPalindromeReverseString, "a", true}, + {"Reverse String - Empty string", IsPalindromeReverseString, "", true}, + {"Reverse String - Mixed case palindrome", IsPalindromeReverseString, "Able was I ere I saw Elba", true}, + {"Reverse String - Only non-alphanumeric", IsPalindromeReverseString, "!!!", true}, + {"Reverse String - Palindrome with numbers", IsPalindromeReverseString, "12321", true}, + {"Reverse String - Not palindrome with numbers", IsPalindromeReverseString, "12345", false}, + + // IsPalindromeTwoPointers + {"Two Pointers - Palindrome with spaces/punctuations", IsPalindromeTwoPointers, "Was it a car or a cat I saw?", true}, + {"Two Pointers - Not a palindrome", IsPalindromeTwoPointers, "tab a cat", false}, + {"Two Pointers - Single character", IsPalindromeTwoPointers, "a", true}, + {"Two Pointers - Empty string", IsPalindromeTwoPointers, "", true}, + {"Two Pointers - Mixed case palindrome", IsPalindromeTwoPointers, "Able was I ere I saw Elba", true}, + {"Two Pointers - Only non-alphanumeric", IsPalindromeTwoPointers, "!!!", true}, + {"Two Pointers - Palindrome with numbers", IsPalindromeTwoPointers, "12321", true}, + {"Two Pointers - Not palindrome with numbers", IsPalindromeTwoPointers, "12345", false}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + got := c.fn(c.s) + if got != c.expected { + t.Errorf("%s failed: expected %v, got %v", c.name, c.expected, got) + } + }) + } +}