LeetCode 2239 - Find Closest Number to Zero

The problem gives us an integer array nums, and we need to return the number whose value is closest to 0. The phrase "closest to zero" means we compare numbers using their absolute values. For example: - |-2| = 2 - |5| = 5 Since 2 < 5, the number -2 is closer to zero than 5.

LeetCode Problem 2239

Difficulty: 🟢 Easy
Topics: Array

Solution

Problem Understanding

The problem gives us an integer array nums, and we need to return the number whose value is closest to 0.

The phrase "closest to zero" means we compare numbers using their absolute values. For example:

  • |-2| = 2
  • |5| = 5

Since 2 < 5, the number -2 is closer to zero than 5.

There is also an important tie-breaking rule. If two numbers are equally close to zero, we must return the larger number. For example:

  • -1 and 1 are both distance 1 from zero
  • Since 1 > -1, the correct answer is 1

The input consists of:

  • An integer array nums
  • Array length n where 1 <= n <= 1000
  • Each value is between -10^5 and 10^5

The constraints are small, which means even a straightforward linear scan is efficient enough. We do not need advanced data structures or sorting.

Several edge cases are important:

  • Arrays containing both positive and negative numbers with equal absolute values
  • Arrays containing only negative numbers
  • Arrays containing only positive numbers
  • Arrays containing a single element
  • Arrays containing 0, since zero is automatically the closest possible value

The problem guarantees the array is non-empty, so there will always be at least one valid answer.

Approaches

Brute Force Approach

A brute-force approach would compare every number against every other number to determine which one is closest to zero.

For each element:

  1. Compute its absolute value
  2. Compare it with the absolute values of all other elements
  3. Keep track of the best candidate

This approach works because eventually every pair of numbers is compared, so the closest number can be identified correctly.

However, this method performs unnecessary repeated comparisons. Since we only need the single best answer, we do not need nested loops. A single pass through the array is sufficient.

Key Insight for the Optimal Solution

The important observation is that we only need to maintain the current best answer while scanning the array once.

For each number:

  • If its absolute value is smaller than the current best, update the answer
  • If the absolute values are equal, choose the larger number

Because each element is processed independently, a single linear scan is enough.

This reduces the time complexity from quadratic time to linear time.

Approach Time Complexity Space Complexity Notes
Brute Force O(n²) O(1) Compares each number with every other number
Optimal O(n) O(1) Single pass while tracking the closest number

Algorithm Walkthrough

  1. Initialize the answer with the first element of the array.

We need some starting value for comparison. Since the array is guaranteed to be non-empty, using the first element is safe. 2. Iterate through every number in the array.

For each number, compute its absolute value and compare it with the absolute value of the current best answer. 3. Update the answer if the current number is closer to zero.

If:

abs(current) < abs(answer)

then the current number is strictly better and becomes the new answer. 4. Handle the tie-breaking condition.

If:

abs(current) == abs(answer)

then both numbers are equally close to zero.

In this situation, choose the larger value:

max(current, answer)

This ensures that 1 is chosen over -1. 5. Continue until the array has been fully processed. 6. Return the final answer.

Why it works

The algorithm maintains the invariant that after processing each element, answer stores the best candidate seen so far according to the problem rules.

Whenever we encounter a number that is closer to zero, we update the answer immediately. When two numbers are equally close, we apply the required tie-breaking rule and keep the larger value.

Since every element is processed exactly once, the final answer must be the correct closest number.

Python Solution

from typing import List

class Solution:
    def findClosestNumber(self, nums: List[int]) -> int:
        closest = nums[0]

        for num in nums:
            if abs(num) < abs(closest):
                closest = num
            elif abs(num) == abs(closest):
                closest = max(closest, num)

        return closest

The implementation begins by storing the first array element in closest. This variable always represents the best answer found so far.

The loop processes every number in the array. For each number:

  • If its absolute value is smaller than the current best, it becomes the new closest number.
  • If the absolute values are equal, max() is used to keep the larger value.

Using max() cleanly handles the tie-breaking requirement. For example:

max(-1, 1) == 1

After the loop finishes, closest contains the correct answer and is returned.

Go Solution

func findClosestNumber(nums []int) int {
    closest := nums[0]

    for _, num := range nums {
        if abs(num) < abs(closest) {
            closest = num
        } else if abs(num) == abs(closest) {
            if num > closest {
                closest = num
            }
        }
    }

    return closest
}

func abs(x int) int {
    if x < 0 {
        return -x
    }
    return x
}

The Go solution follows the same logic as the Python version.

Since Go does not provide a built-in integer abs() function for plain integers, we implement a helper function manually.

The iteration uses Go's range syntax to process each element in the slice.

Because the constraints are small and values fit comfortably within Go's int type, integer overflow is not a concern here.

Worked Examples

Example 1

Input:

nums = [-4, -2, 1, 4, 8]

Initial state:

closest = -4
Current Number abs(Current) abs(closest) Action New closest
-4 4 4 Equal, keep larger -4
-2 2 4 Smaller distance -2
1 1 2 Smaller distance 1
4 4 1 No update 1
8 8 1 No update 1

Final answer:

1

Example 2

Input:

nums = [2, -1, 1]

Initial state:

closest = 2
Current Number abs(Current) abs(closest) Action New closest
2 2 2 Equal, keep larger 2
-1 1 2 Smaller distance -1
1 1 1 Equal distance, larger value wins 1

Final answer:

1

Complexity Analysis

Measure Complexity Explanation
Time O(n) Each element is visited exactly once
Space O(1) Only a few variables are used

The algorithm performs a single linear scan through the array. Each iteration does only constant-time operations such as computing absolute values and comparisons.

No additional data structures proportional to input size are used, so the space complexity remains constant.

Test Cases

from typing import List

class Solution:
    def findClosestNumber(self, nums: List[int]) -> int:
        closest = nums[0]

        for num in nums:
            if abs(num) < abs(closest):
                closest = num
            elif abs(num) == abs(closest):
                closest = max(closest, num)

        return closest

sol = Solution()

assert sol.findClosestNumber([-4, -2, 1, 4, 8]) == 1  # basic mixed array
assert sol.findClosestNumber([2, -1, 1]) == 1  # tie case prefers positive
assert sol.findClosestNumber([-10]) == -10  # single negative element
assert sol.findClosestNumber([7]) == 7  # single positive element
assert sol.findClosestNumber([0]) == 0  # zero itself
assert sol.findClosestNumber([-5, -3, -2]) == -2  # all negative numbers
assert sol.findClosestNumber([5, 3, 2]) == 2  # all positive numbers
assert sol.findClosestNumber([-1, 1]) == 1  # exact tie
assert sol.findClosestNumber([-100000, 100000]) == 100000  # large equal values
assert sol.findClosestNumber([4, -4, 2, -2]) == 2  # multiple tie candidates
assert sol.findClosestNumber([9, -8, 7, -6, 0]) == 0  # zero present
Test Why
[-4, -2, 1, 4, 8] Standard mixed example
[2, -1, 1] Verifies tie-breaking rule
[-10] Single-element negative array
[7] Single-element positive array
[0] Tests zero handling
[-5, -3, -2] All negative values
[5, 3, 2] All positive values
[-1, 1] Exact absolute-value tie
[-100000, 100000] Boundary-value tie
[4, -4, 2, -2] Multiple equal-distance candidates
[9, -8, 7, -6, 0] Confirms zero is always optimal

Edge Cases

Arrays Containing Zero

If the array contains 0, then 0 must be the answer because its distance from zero is exactly zero, which is the smallest possible distance.

A buggy implementation might continue updating the answer incorrectly after finding zero. This implementation handles it correctly because no other number can have a smaller absolute value than 0.

Equal Absolute Values

The tie-breaking rule is the most common source of mistakes. For example:

[-1, 1]

Both numbers are equally close to zero, but the correct answer is 1.

The implementation explicitly checks for equal absolute values and uses the larger number with:

max(closest, num)

This guarantees correct tie resolution.

Single Element Arrays

The array may contain only one value. In that situation, that element must be returned immediately because it is automatically the closest number.

The implementation safely handles this by initializing closest with nums[0]. Since the constraints guarantee the array is non-empty, this is always valid.