3Sum - Leetcode Solution


đź’ˇOptimal Solution: HashMap

  1. Convert to Negative Values: Since heapq provides a min heap (where the smallest element is at the root), we negate all elements in nums by iterating through the array and setting nums[i] = -nums[i]. This effectively simulates a max heap, where the largest original value corresponds to the smallest (most negative) value in the heap.
  2. Heapify the Array: We call heapq.heapify(nums) to rearrange the array into a min heap based on the negated values. This operation ensures that the smallest negated value (corresponding to the largest original value) is at the root.
  3. Pop k-1 Elements: To find the kth largest element, we remove the smallest negated value (largest original value) from the heap k-1 times using heapq.heappop(nums). Each pop operation removes the root and re-heapifies the remaining elements, bringing the next smallest negated value to the root.
  4. Extract the Kth Largest: After k-1 pops, the root of the heap is the kth smallest negated value (kth largest original value). We pop this element with heapq.heappop(nums) and return its negation (i.e., -heapq.heappop(nums)) to obtain the original positive value.

Code Solution (HashMap)


                

                

                

                

đź’ˇOptimal Solution: Two Pointers

  • Initialize Min Heap: We create an empty list min_heap to serve as a min heap, which will store at most k elements. The heap will maintain the smallest element at the root.
  • Process Each Element: We iterate through each number num in nums:
    • If the heap has fewer than k elements, we push num onto the heap using heapq.heappush(min_heap, num). This builds the initial set of k candidates.
    • If the heap already has k elements, we use heapq.heappushpop(min_heap, num). This operation pushes num onto the heap and immediately pops the smallest element, ensuring the heap maintains exactly k elements. If num is larger than the smallest element in the heap, it replaces it; otherwise, num is discarded.
  • Extract Result: After processing all elements, the heap contains the k largest elements, with the smallest of these (the kth largest) at the root. We return min_heap[0], the root of the heap.

Code Solution (Two Pointers)

[
                

                

                

                

Detailed Explanation

Understanding the Problem: Valid Palindrome

The “Valid Palindrome” problem asks us to determine whether a given string is a palindrome. A palindrome reads the same forward and backward. However, we must ignore case differences and non-alphanumeric characters (like spaces, punctuation, etc.).

For example:

  • "A man, a plan, a canal: Panama" → Output: true
  • "race a car" → Output: false
The goal is to clean the string and then check if the cleaned version is equal to its reverse.

Why This Problem Matters

This problem is a great test of string manipulation and two-pointer techniques. It also has practical applications in input validation, text normalization, and pattern recognition systems.

Optimal Approach: Two Pointers with Character Checks

Instead of cleaning the entire string upfront, we can use two pointers to scan from both ends and compare only valid characters. This approach is both time- and space-efficient, avoiding the need to create a new cleaned string.

Steps:

  1. Initialize two pointers:
    • left = 0 (start of string)
    • right = s.length - 1 (end of string)
  2. While left < right:
    • If s[left] is not alphanumeric, move left forward.
    • If s[right] is not alphanumeric, move right backward.
    • Compare the lowercase of both characters:
      • If they don't match, return false.
      • If they match, continue inward: increment left, decrement right.
  3. If the loop completes without mismatch, return true.

Example Walkthrough

Input: "A man, a plan, a canal: Panama"
Cleaned version: "amanaplanacanalpanama"
After two-pointer scan, all characters match → return true.

Time and Space Complexity

Time Complexity: O(n), where n is the length of the string. Each character is visited at most once.
Space Complexity: O(1), since we're not using extra memory beyond the two pointers.

Edge Cases to Consider

  • Empty string → considered a palindrome → return true
  • String with only non-alphanumeric characters → return true
  • Mixed case letters → should be treated as equal
  • Symbols, punctuation, and whitespace are ignored

Conclusion

The “Valid Palindrome” problem is an excellent example of how to handle real-world messy input efficiently. It reinforces essential techniques like input sanitization, case-insensitive comparison, and space-efficient scanning with two pointers. Mastering this approach is useful in a wide variety of scenarios, including data preprocessing and text validation tasks.

Get Personalized Support at AlgoMap Bootcamp đź’ˇ