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.