NeetCode Blind75 - Valid Palindrome - Go vs Python
This is my second article on comparing python to go using a coding problem from NeetCode’s Blind75
In this article, we are going to take a look at the NeetCode Blind75 problem Valid Palindrome.
Objective Link to heading
Given a string s, we need to determine if this particular string is a palindrome. This string can have both numbers and letters and anything else can be ignored. Additionally, our solution needs to be case in-sensitive so capital letters are treated the same as lower case letters.
Trick - 2 Pointer Method Link to heading
If you watch NeetCode’s video, the trick here is a two pointer solution. Start with a left pointer at the beginning of the string and a right pointer at the end of the string and have each pointer move inwards and only stop once they cross each other. The pointers represent the index of the string and each step of the way we are checking to see if the characters match while ignoring spaces.
Python Solution Link to heading
My python solution is as follows:
class Solution:
def isPalindrome(self, s: str) -> bool:
# Create two pointers
left, right = 0, len(s)-1
while left < right:
# Move the left pointer until value is an alphabet
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
# We found a letter so we check the lowercase values
if s[left].lower() != s[right].lower():
return False
left += 1
right -= 1
return True
The python code is doing exactly what the trick mentions: creating the 2 pointers, checking to see if the pointers have not crossed, skipping any non-alphanumeric characters, and finally making sure that the characters are either identical or not and returning the appropriate values.
Go Solution Link to heading
Now lets take a look at the Go Solution.
package main
import "unicode"
func isPalindrome(s string) bool {
left, right := 0, len(s)-1
for left < right {
// Move left pointer past non-alphanumeric chars
for left < right && !isAlphanumeric(rune(s[left])) {
left++
}
// Move right pointer past non-alphanumeric chars
for left < right && !isAlphanumeric(rune(s[right])) {
right--
}
// Now compare the characters (case-insensitive)
if unicode.ToLower(rune(s[left])) != unicode.ToLower(rune(s[right])) {
return false
}
left++
right--
}
return true
}
func isAlphanumeric(r rune) bool {
return unicode.IsLetter(r) || unicode.IsDigit(r)
}
This code is similar to the python code above but with a few differences. Let’s break down each of Go’s unique aspects:
Key Differences: Go vs Python Link to heading
1. Unicode Package Import Link to heading
import "unicode"
Go requires explicit imports for character operations. Python’s string methods like .isalnum() and .lower() are built-in, while Go uses the unicode package for ToLower(), IsLetter(), and IsDigit().
2. No While Loops Link to heading
Go doesn’t have while loops - only for loops. What Python writes as:
while left < right:
Go writes as:
for left < right {
3. Rune Casting Required Link to heading
rune(s[left])
Go strings are UTF-8 byte sequences. To work with individual characters, you must cast to rune (Go’s character type). Python handles this automatically.
4. Helper Function for Alphanumeric Checking Link to heading
In the python solution, there is a built-in function called isalnum() that checks if the character is alphanumeric. However, I needed to build out a custom function that checks if the rune (character) is either a digit or a letter.
Key Takeaways Link to heading
Python prioritizes convenience with built-in string methods, while Go emphasizes explicitness and control over Unicode handling. Both solve the same problem, but Go forces you to understand character encoding details that Python abstracts away. However, both methods follow the same principle of utilizing the 2-Pointer method.