Start learning free

LESSON 218 OF 409 · SORTING

Smallest K Integers in O(n log n) Time Using C++

Practice O(n log n) Read the full explanation

Given an array of positive integers nums, return the smallest k values, in any order you want.

Example:

Input: nums = [5, 9, 3, 6, 2, 1, 3, 2, 7, 5], k = 4
Output: [1, 2, 2, 3]
Explanation: Smallest number is 1, 2nd smallest is 2, 
            3rd smallest is 2, 4th smallest is 3
The result can be in any order, [2, 1, 3, 2] is also a correct answer.

Note:

For this lesson, your algorithm should run in O(n log n) time and use O(1) extra space besides the returned values, when sorting in place (sorting a copy of nums takes O(n) extra space).
(There are faster solutions which we will discuss in future lessons)


STEP 1 OF 2
    Ctrl + Enter to check

    C++ · SORTING

    Smallest K in C++, explained

    Understanding the Problem

    The core challenge of this problem is to find the smallest k integers from an array of positive integers. This problem is significant in various applications such as data analysis, where you might need to find the smallest values in a dataset. A common pitfall is to use a naive approach that doesn't meet the time complexity requirements.

    Approach

    To solve this problem, we can consider the following approaches:

    Naive Approach

    A naive approach would be to sort the entire array and then take the first k elements. This approach is simple but not optimal in terms of space complexity.

    Optimized Approach

    We can use a more efficient approach by leveraging the properties of sorting algorithms. Since we need the smallest k elements, we can sort the array and then select the first k elements. This approach meets the O(n log n) time complexity requirement.

    Algorithm

    Here is a step-by-step breakdown of the optimized algorithm:

    1. Sort the array in ascending order.
    2. Select the first k elements from the sorted array.

    Code Implementation

    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    std::vector<int> smallestKIntegers(std::vector<int>& nums, int k) {
        // Step 1: Sort the array
        std::sort(nums.begin(), nums.end());
        
        // Step 2: Select the first k elements
        std::vector<int> result(nums.begin(), nums.begin() + k);
        
        return result;
    }
    
    int main() {
        std::vector<int> nums = {5, 9, 3, 6, 2, 1, 3, 2, 7, 5};
        int k = 4;
        std::vector<int> result = smallestKIntegers(nums, k);
        
        // Print the result
        for (int num : result) {
            std::cout << num << " ";
        }
        return 0;
    }
    

    Complexity Analysis

    The time complexity of the sorting step is O(n log n), and selecting the first k elements takes O(k) time. Since k is typically much smaller than n, the overall time complexity is dominated by the sorting step, making it O(n log n). The space complexity is O(1) extra space, as we are sorting the array in place and only using a small amount of additional space for the result.

    Edge Cases

    Potential edge cases include:

    • k is greater than the length of the array: This should be handled by returning the entire sorted array.
    • k is zero: This should return an empty array.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Simple cases with small arrays.
    • Cases where k is equal to the length of the array.
    • Cases with duplicate values in the array.
    • Edge cases as discussed above.

    Thinking and Problem-Solving Tips

    When approaching such problems, it's essential to:

    • Understand the problem requirements and constraints.
    • Consider both naive and optimized solutions.
    • Analyze the time and space complexity of your approach.
    • Test your solution with various test cases, including edge cases.

    Conclusion

    In this blog post, we discussed how to find the smallest k integers from an array of positive integers using an efficient approach that meets the O(n log n) time complexity requirement. We provided a detailed explanation of the algorithm, code implementation, complexity analysis, and testing strategies. Understanding and solving such problems is crucial for improving problem-solving skills and preparing for coding interviews.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with C++About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free