Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions 2_two_pointers/1_valid_palindrome/solution.go
Original file line number Diff line number Diff line change
@@ -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
}
41 changes: 41 additions & 0 deletions 2_two_pointers/1_valid_palindrome/solution_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}
Loading