Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1708. Largest Subarray Length K - Leetcode Solution

Problem Description

You are given an array of integers nums and an integer k. Your task is to find the subarray of length k that has the largest lexicographical order. Return this subarray as a new array.

Key constraints:

  • The subarray must be exactly length k.
  • You must return the first such subarray if there are multiple with the same maximum lexicographical order.
  • Elements must be contiguous in the original array.

Lexicographical order means the subarray that would appear last if all possible subarrays of length k were sorted like words in a dictionary.

Thought Process

At first glance, you might consider checking every possible subarray of length k and comparing them to find the largest. However, this would be inefficient, especially for large arrays.

Instead, we realize that for each position in nums where a subarray of length k can start, we can compare the subarray starting at that position to the current largest found so far. Because subarrays are contiguous, and we want the one with the largest lexicographical order, we can take advantage of direct comparison between slices.

The key insight is that comparing two arrays lexicographically is similar to comparing words: you look at the first index where they differ, and the one with the larger value at that position is greater. Therefore, we can keep a variable to store the current "best" subarray and update it as we scan through nums.

Solution Approach

We can solve this problem efficiently by scanning through all possible starting indices for subarrays of length k and keeping track of the largest one found so far.

  1. Initialize: Set a variable (e.g., max_subarray) to store the current largest subarray found. You can start by taking the first subarray of length k.
  2. Iterate: For each possible starting index i from 0 to len(nums) - k:
    • Extract the subarray nums[i:i+k].
    • Compare it to max_subarray using lexicographical comparison. In most languages, comparing arrays directly works as expected.
    • If the current subarray is larger, update max_subarray to this subarray.
  3. Return: After iterating, return max_subarray.

This approach is efficient because:

  • We only need to check n - k + 1 subarrays.
  • Each comparison of two subarrays is at most k steps.
  • We avoid unnecessary storage or sorting of all subarrays.

Example Walkthrough

Input: nums = [1, 4, 5, 2, 3], k = 3

All possible subarrays of length 3:

  • [1, 4, 5]
  • [4, 5, 2]
  • [5, 2, 3]
Step-by-step:
  1. Start with max_subarray = [1, 4, 5].
  2. Compare with [4, 5, 2]: since 4 > 1, update max_subarray to [4, 5, 2].
  3. Compare with [5, 2, 3]: since 5 > 4, update max_subarray to [5, 2, 3].

Result: The largest subarray of length 3 is [5, 2, 3].

Code Implementation

class Solution:
    def largestSubarray(self, nums, k):
        max_subarray = nums[:k]
        for i in range(1, len(nums) - k + 1):
            current = nums[i:i+k]
            if current > max_subarray:
                max_subarray = current
        return max_subarray
        
class Solution {
public:
    vector<int> largestSubarray(vector<int>& nums, int k) {
        vector<int> max_subarray(nums.begin(), nums.begin() + k);
        for (int i = 1; i <= nums.size() - k; ++i) {
            vector<int> current(nums.begin() + i, nums.begin() + i + k);
            if (current > max_subarray) {
                max_subarray = current;
            }
        }
        return max_subarray;
    }
};
        
class Solution {
    public int[] largestSubarray(int[] nums, int k) {
        int n = nums.length;
        int start = 0;
        for (int i = 1; i <= n - k; ++i) {
            for (int j = 0; j < k; ++j) {
                if (nums[i + j] > nums[start + j]) {
                    start = i;
                    break;
                } else if (nums[i + j] < nums[start + j]) {
                    break;
                }
            }
        }
        int[] res = new int[k];
        System.arraycopy(nums, start, res, 0, k);
        return res;
    }
}
        
var largestSubarray = function(nums, k) {
    let maxSubarray = nums.slice(0, k);
    for (let i = 1; i <= nums.length - k; i++) {
        let current = nums.slice(i, i + k);
        for (let j = 0; j < k; j++) {
            if (current[j] > maxSubarray[j]) {
                maxSubarray = current;
                break;
            } else if (current[j] < maxSubarray[j]) {
                break;
            }
        }
    }
    return maxSubarray;
};
        

Time and Space Complexity

Brute-force approach:

  • Generate all possible subarrays of length k (there are n - k + 1 of them).
  • Sorting all subarrays would take O((n-k+1) \cdot k \log(n-k+1)) time and O((n-k+1) \cdot k) space.
Optimized approach (as above):
  • We scan through n - k + 1 starting positions.
  • For each, we compare at most k elements.
  • Total time complexity: O((n - k + 1) \cdot k).
  • Space complexity: O(k) for the result.

This is efficient enough for typical constraints in coding interviews and LeetCode problems.

Summary

To solve the "Largest Subarray Length K" problem, we scan through all possible subarrays of length k and keep track of the one with the largest lexicographical order. The key insight is that comparing arrays lexicographically is efficient and can be done as we iterate, without storing all subarrays. This yields a clean and efficient solution that works well for both small and large inputs.