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.
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:
-1and1are both distance1from zero- Since
1 > -1, the correct answer is1
The input consists of:
- An integer array
nums - Array length
nwhere1 <= n <= 1000 - Each value is between
-10^5and10^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:
- Compute its absolute value
- Compare it with the absolute values of all other elements
- 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
- 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.