Floor and Ceiling in a Sorted Set
Problem
Keep a set of integers. Commands: insert X (prints ok, a repeated value is ignored), floor X (prints the biggest value in the set that is at most X) and ceil X (prints the smallest value in the set that is at least X). Print none if there is no such value.
Constraints
- 1 <= commands <= 10^5
Examples
Input
insert 10 insert 20 floor 15 ceil 15 floor 5
Output
ok ok 10 20 none
Solutions
Java's TreeSet gives floor and ceiling directly. JavaScript has no sorted set, and Python's list needs the bisect module. Knowing the idea (binary search on a sorted structure) lets you do it in any language.
/*
* Problem : Process lines.
* Input : Several lines.
* Output : One answer per command.
* Approach: A sorted set and binary search.
* Time : O(log n) per query (O(n) insert in arrays)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
// Step 1: A TreeSet keeps its values sorted. floor and ceiling find the nearest values in O(log n).
java.util.TreeSet<Long> set = new java.util.TreeSet<>();
String[] output = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
String[] part = lines[i].split(" ");
long value = Long.parseLong(part[1]);
if (part[0].equals("insert")) {
set.add(value);
output[i] = "ok";
} else if (part[0].equals("floor")) {
// Step 2: floor = the biggest value that is at most the query. null means there is none.
Long found = set.floor(value);
output[i] = found == null ? "none" : String.valueOf(found);
} else {
// Step 3: ceiling = the smallest value that is at least the query.
Long found = set.ceiling(value);
output[i] = found == null ? "none" : String.valueOf(found);
}
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (1)
- Which structure gives floor() and ceiling() in Java?