Find the Floor and Ceiling of a Number in a Sorted Array
Solve this Problemnums sorted in non-decreasing order and an integer target, return [floor, ceil] — the largest value ≤ target and the smallest value ≥ target. Use -1 for either one if it doesn't exist.
Solve it in O(log n) time: as the binary search narrows in on target, every comparison either tightens the floor or the ceiling, so a single pass finds both.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ nums.length ≤ 10⁴ - ◆
0 ≤ nums[i] ≤ 10⁵ (all values non-negative, so -1 unambiguously means "none") - ◆
-10⁵ ≤ target ≤ 10⁵ - ◆
nums is sorted in non-decreasing order (duplicates are allowed)
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public int[] floorCeil(int[] nums, int target) { |
| 3 | int lo = 0, hi = nums.length - 1, floorVal = -1, ceilVal = -1; |
| 4 | while (lo <= hi) { |
| 5 | int mid = lo + (hi - lo) / 2; |
| 6 | if (nums[mid] == target) { |
| 7 | floorVal = nums[mid]; |
| 8 | ceilVal = nums[mid]; |
| 9 | break; |
| 10 | } else if (nums[mid] < target) { |
| 11 | floorVal = nums[mid]; |
| 12 | lo = mid + 1; |
| 13 | } else { |
| 14 | ceilVal = nums[mid]; |
| 15 | hi = mid - 1; |
| 16 | } |
| 17 | } |
| 18 | return new int[]{floorVal, ceilVal}; |
| 19 | } |
| 20 | } |
| 21 |
02-1-1Binary search [0, 2] for target 5, tracking the largest value ≤ target (floor) and smallest value ≥ target (ceil) as we narrow in.
Approach & Solutions
Brute Force — Linear Scan
BruteScan once, left to right. Every value ≤ target is a candidate floor — since the array is sorted, the last one you see is the largest, so just keep overwriting it. The first value ≥ target you encounter is the ceiling — record it once and stop updating it. Correct on any array, but it checks every element instead of jumping straight to the answer.
O(n)O(1)1class Solution {
2 public int[] floorCeil(int[] nums, int target) {
3 int floorVal = -1, ceilVal = -1;
4 for (int i = 0; i < nums.length; i++) {
5 if (nums[i] <= target) floorVal = nums[i];
6 if (nums[i] >= target && ceilVal == -1) ceilVal = nums[i];
7 }
8 return new int[]{floorVal, ceilVal};
9 }
10}Optimal — Binary Search
OptimalBinary search toward target, tracking the best floor and ceil seen so far. Whenever nums[mid] is below target, it's a new floor candidate (closer than any found before) — record it and search right for something even closer. Whenever it's above target, it's a new ceil candidate — record it and search left. An exact match is trivially both.
O(log n)O(1)1class Solution {
2 public int[] floorCeil(int[] nums, int target) {
3 int lo = 0, hi = nums.length - 1, floorVal = -1, ceilVal = -1;
4 while (lo <= hi) {
5 int mid = lo + (hi - lo) / 2;
6 if (nums[mid] == target) {
7 floorVal = nums[mid];
8 ceilVal = nums[mid];
9 break;
10 } else if (nums[mid] < target) {
11 floorVal = nums[mid];
12 lo = mid + 1;
13 } else {
14 ceilVal = nums[mid];
15 hi = mid - 1;
16 }
17 }
18 return new int[]{floorVal, ceilVal};
19 }
20}