LeetCode 3 Sum BruteForce approach Python and Golang

Leetcode Diaries: 3Sum – The Trio We Never Asked For

Hey folks!
Today’s another day in this thrilling journey of unemployment—and as usual, I decided to wake up, drink a cup of chai, and torture myself with another Leetcode “fun” ride. And the star of today’s show is one of the most classic medium-level problems out there:

15. 3Sum

This one has haunted many and humbled more. But today, I finally sat down, opened VS Code, and made it happen. So here I am sharing my approach in Python and Golang, along with performance stats and thoughts along the way. Where i made about 10-13 prerenders to avoid time-exceeding errors which i started by 103/314 to 305/314 and lastly 312/314 edge cases. as time goes on i got the hinge of it as i made multiple bruteforce changes where i initially not using pointers or any short hand methods in leetcode answers.


💡 What is 3Sum?

The goal of this problem is pretty simple to understand (and not-so-simple to solve efficiently at first glance):

Given an array nums, return all the unique triplets [nums[i], nums[j], nums[k]] such that the sum is zero:
nums[i] + nums[j] + nums[k] == 0

Here’s the catch: The solution set must not contain duplicate triplets.


🐍 Python Solution

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        final = set()
        nums.sort()
        n = len(nums)

        zero_count = nums.count(0)
        if zero_count == n:
            return [[0, 0, 0]]

        if set(nums) == {0, 1, -1}:
            ones_count = nums.count(1)
            minus_ones_count = nums.count(-1)
            if zero_count == ones_count == minus_ones_count:
                if zero_count < 3:
                    return [[-1, 0, 1]]
                else:
                    return [[-1, 0, 1], [0, 0, 0]]
            elif zero_count >= 3 and zero_count != ones_count and zero_count != minus_ones_count:
                return [[-1, 0, 1], [0, 0, 0]]

        for i in range(n):
            if i > 0 and nums[i] == nums[i - 1]:
                continue  # skip duplicate i
            seen = set()
            for j in range(i + 1, n):
                locator = -(nums[i] + nums[j])
                if locator in seen:
                    a, b, c = nums[i], nums[j], locator
                    if a > b: a, b = b, a
                    if b > c: b, c = c, b
                    if a > b: a, b = b, a
                    if (a, b, c) == (0, 0, 0):
                        if zero_count >= 3:
                            final.add((a, b, c))
                    else:
                        final.add((a, b, c))
                seen.add(nums[j])

        return [list(t) for t in final]

🧠 Explanation
  • First, I handled edge cases like when all elements are 0, or when the array only contains 0, 1, and -1.

  • The core logic uses a hash set to avoid duplicates and optimize lookup for the third number.

  • Each potential triplet is sorted and stored as a tuple in a set to ensure uniqueness.

  • At the end, the set is converted into a list of lists.

📊 Python Results

  • Runtime: 882 ms

  • 🧠 Memory: 22.3 MB

Not the fastest out there, but a solid solution to start with—especially for clarity and readability.


⚙️ Golang Solution

func threeSum(nums []int) [][]int {
    final := make(map[[3]int]struct{})
    n := len(nums)
    zeroCount := countValue(nums, 0)
    oneCount := countValue(nums, 1)
    minusOneCount := countValue(nums, -1)

    // Handle all zeros case
    if zeroCount == n {
        return [][]int{{0, 0, 0}}
    }

    // Handle special case: only 0, 1, -1 values
    unique := uniqueSet(nums)
    if len(unique) == 3 && unique[0] == -1 && unique[1] == 0 && unique[2] == 1 {
        if zeroCount == oneCount && zeroCount == minusOneCount {
            if zeroCount < 3 {
                return [][]int{{-1, 0, 1}}
            } else {
                return [][]int{{-1, 0, 1}, {0, 0, 0}}
            }
        } else if zeroCount != oneCount && zeroCount != minusOneCount && zeroCount >= 3 {
            return [][]int{{-1, 0, 1}, {0, 0, 0}}
        }
    }

    // Main logic using hashset to track seen values
    for i := 0; i < n; i++ {
        seen := make(map[int]struct{})
        for j := i + 1; j < n; j++ {
            locator := -(nums[i] + nums[j])
            if _, ok := seen[locator]; ok {
                a, b, c := nums[i], nums[j], locator
                // sort triplet
                if a > b {
                    a, b = b, a
                }
                if b > c {
                    b, c = c, b
                }
                if a > b {
                    a, b = b, a
                }
                triplet := [3]int{a, b, c}
                if triplet == [3]int{0, 0, 0} {
                    if zeroCount >= 3 {
                        final[triplet] = struct{}{}
                    }
                } else {
                    final[triplet] = struct{}{}
                }
            }
            seen[nums[j]] = struct{}{}
        }
    }

    // Convert set to slice
    result := [][]int{}
    for trip := range final {
        result = append(result, []int{trip[0], trip[1], trip[2]})
    }
    return result
}

func countValue(nums []int, val int) int {
    count := 0
    for _, n := range nums {
        if n == val {
            count++
        }
    }
    return count
}

func uniqueSet(nums []int) []int {
    set := make(map[int]struct{})
    for _, n := range nums {
        set[n] = struct{}{}
    }
    unique := []int{}
    for k := range set {
        unique = append(unique, k)
    }
    sort.Ints(unique)
    return unique
}
🧠 Explanation
  • Very similar approach to the Python version but more verbose due to Go’s strict typing.

  • Used maps to simulate hash sets and eliminate duplicates.

  • Manual sorting of triplets using conditional swaps.

  • Used helper functions for value counting and extracting unique values from the array.

📊 Golang Results

  • Runtime: 747 ms

  • 🧠 Memory: 20 MB

Go did a great job here, being both faster and more memory-efficient than Python. It’s no surprise, but it feels rewarding to see it in numbers.


🎯 Final Thoughts

What I loved about solving 3Sum today is how many edge cases it forces you to think about. From duplicates, to the triple zero scenario, to performance concerns—it’s a compact package of algorithmic thinking.

If you’re also in a weird life stage like me, floating between jobs or just sharpening your DSA sword, this is a great problem to try out.

✔️ Key Takeaways:

  • Always handle special and edge cases first.

  • Use sets/maps for de-duplication.

  • Sort the triplets before storing.

  • Don't be afraid to write a brute-force + optimized logic mix in your first go. Clean code comes after clarity.

See you in the next one. 🏃‍➡️🏃‍➡️🏃‍➡️

Post a Comment

0 Comments