{x}
blog image

Find the Kth Largest Integer in the Array

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 the kth 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.

 

Example 1:

Input: nums = ["3","6","7","10"], k = 4
Output: "3"
Explanation:
The numbers in nums sorted in non-decreasing order are ["3","6","7","10"].
The 4th largest integer in nums is "3".

Example 2:

Input: nums = ["2","21","12","1"], k = 3
Output: "2"
Explanation:
The numbers in nums sorted in non-decreasing order are ["1","2","12","21"].
The 3rd largest integer in nums is "2".

Example 3:

Input: nums = ["0","0"], k = 2
Output: "0"
Explanation:
The numbers in nums sorted in non-decreasing order are ["0","0"].
The 2nd largest integer in nums is "0".

 

Constraints:

  • 1 <= k <= nums.length <= 104
  • 1 <= nums[i].length <= 100
  • nums[i] consists of only digits.
  • nums[i] will not have any leading zeros.

Solution Explanation for Finding the Kth Largest Integer

This problem requires finding the k-th largest integer within an array of strings representing integers. The solution approaches leverage sorting or a selection algorithm like quickselect for efficiency.

Approach 1: Sorting

This is a straightforward approach. We sort the input array nums in descending order based on the numerical values represented by the strings. Once sorted, the k-th largest integer is simply the element at index k-1 (since indexing starts from 0).

Time Complexity: O(n log n), dominated by the sorting algorithm. n is the length of the nums array.

Space Complexity: O(log n) or O(n) depending on the sorting algorithm used. In-place sorting algorithms like quicksort have logarithmic space complexity, while merge sort might use linear space in the worst case.

Approach 2: Quickselect (or similar selection algorithm)

Quickselect is an algorithm that finds the k-th smallest or k-th largest element in an unordered array in average linear time. It's a randomized algorithm, meaning its performance can vary slightly from run to run, but on average, it performs much faster than sorting for this specific task.

The algorithm works by repeatedly partitioning the array around a pivot element. The goal is to find a position such that all elements before this position are greater than or equal to the k-th largest element, and all elements after this position are less than it. If the pivot's index is k-1, we've found our answer. Otherwise, we recursively apply the algorithm to the appropriate subarray.

Time Complexity: Average case: O(n), Worst case: O(n^2). The average-case linear time is significantly faster than sorting, especially for large arrays. The worst-case quadratic complexity can occur if the pivots are consistently chosen poorly, but this is rare in practice.

Space Complexity: O(log n) due to the recursive calls in the average case (this is the space used by the call stack). In the worst case, it can become O(n), though this is unlikely.

Code Examples

The following code examples demonstrate the two approaches in different programming languages.

Python (Sorting)

from heapq import nlargest
 
class Solution:
    def kthLargestNumber(self, nums: List[str], k: int) -> str:
        return nlargest(k, nums, key=lambda x: int(x))[-1]  #using heapq for efficiency
 

This version uses the nlargest function from the heapq module which provides a more efficient way to find the k largest elements than a full sort. It still has a time complexity of O(n log k) which is better than O(n log n) when k << n.

Java (Sorting)

import java.util.Arrays;
import java.util.Comparator;
 
class Solution {
    public String kthLargestNumber(String[] nums, int k) {
        Arrays.sort(nums, (a, b) -> Integer.compare(Integer.parseInt(b), Integer.parseInt(a))); // Sort in descending order
        return nums[k - 1];
    }
}

C++ (Quickselect)

#include <algorithm>
#include <string>
#include <vector>
 
using namespace std;
 
class Solution {
public:
    string kthLargestNumber(vector<string>& nums, int k) {
        nth_element(nums.begin(), nums.begin() + k - 1, nums.end(), [](const string& a, const string& b) {
            return stoll(a) > stoll(b); // Compare as long longs to avoid integer overflow
        });
        return nums[k - 1];
    }
};

This C++ solution utilizes nth_element, a standard library function that implements a quickselect-like algorithm.

Go (Sorting)

import (
	"sort"
	"strconv"
)
 
func kthLargestNumber(nums []string, k int) string {
	sort.Slice(nums, func(i, j int) bool {
		num1, _ := strconv.Atoi(nums[i])
		num2, _ := strconv.Atoi(nums[j])
		return num1 > num2
	})
	return nums[k-1]
}

Choosing between sorting and quickselect depends on the specific constraints of the problem and the anticipated size of the input. For smaller arrays, sorting might be simpler and sufficiently fast. For very large arrays, quickselect is generally preferable due to its average-case linear time complexity. The code examples above provide efficient implementations of both approaches.