You are given an array of strings nums and an integer k. Each string in nums represents an integer without leading zeros.
Return the string that represents thekth _largest integer in _nums.
Note : Duplicate numbers should be counted distinctly. For example, if nums is ["1","2","2"], "2" is the first largest integer, "2" is the second-largest integer, and "1" is the third-largest integer.
Input: nums =["3","6","7","10"], k =4Output: "3"Explanation:
The numbers in nums sorted in non-decreasing order are ["3","6","7","10"].The 4th largest integer in nums is"3".
Input: nums =["2","21","12","1"], k =3Output: "2"Explanation:
The numbers in nums sorted in non-decreasing order are ["1","2","12","21"].The 3rd largest integer in nums is"2".
Input: nums =["0","0"], k =2Output: "0"Explanation:
The numbers in nums sorted in non-decreasing order are ["0","0"].The 2nd largest integer in nums is"0".
Since the numbers are represented as strings and can be very large, we cannot convert them to integers directly. To compare two numbers as strings, compare their lengths first; if equal, compare lexicographically. Sorting the array with this custom comparator allows us to find the k-th largest easily.
We need to custom our comparator since the default comparator is string comparator which compares by lexicographically order, it means for example: “123” < “14”.
Rather than sorting the entire array, we can maintain a min heap of size k to efficiently keep track of the k largest numbers. This way, the smallest element in the heap is always the k-th largest overall, and we avoid unnecessary sorting of all elements.
public String kthLargestNumber(String[] nums, int k) {
PriorityQueue<String> minHeap =new PriorityQueue<>((o1, o2) -> {
if (o1.length() == o2.length()) { // If the same length then compare by their stringreturn o1.compareTo(o2);
}
return Integer.compare(o1.length(), o2.length()); // Compare by their length });
for (String num : nums) {
minHeap.offer(num);
if (minHeap.size() > k) {
minHeap.poll(); // pop the minimum value in the heap }
}
return minHeap.poll();
}
⏰ Time complexity: O(n * m * log k), where n is the number of strings, m is the average string length, and k is the heap size. Each insertion and removal in the heap takes O(log k), and string comparison takes O(m).
🧺 Space complexity: O(k * m), as the heap stores up to k strings, each of length up to m.
By using a max heap, we can efficiently extract the k-th largest number by repeatedly removing the largest elements. This approach leverages the heap property to always access the largest element in constant time.
⏰ Time complexity: O(n * m + k * log n), where n is the number of strings, m is the average string length. Building the heap takes O(n * m), and each removal takes O(log n).
🧺 Space complexity: O(n * m), as the heap stores all n strings, each of length up to m.
Quickselect is an efficient selection algorithm to find the k-th largest element without fully sorting the array. It partitions the array around a pivot, narrowing down the search space to the relevant part.
⏰ Time complexity: O(n * m) on average, where n is the number of strings and m is the average string length. Partitioning and comparisons are linear in n, and each comparison is O(m).
🧺 Space complexity: O(1) additional space, as partitioning is done in-place.