2389. Longest Subsequence With Limited Sum

  • Hardness: \(\color{green}\textsf{Easy}\)
  • Ralated Topics: ArrayBinary SearchGreedySortingPrefix Sum

一、題目

You are given an integer array nums of length n, and an integer array queries of length m.
Return an array answer of length m where answer[i] is the maximum size of a subsequence that you can take from nums such that the sum of its elements is less than or equal to queries[i].
A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.

Example 1:

  • Input: nums = [4,5,2,1], queries = [3,10,21]
  • Output: [2,3,4]
  • Explanation: We answer the queries as follows:
  • The subsequence [2,1] has a sum less than or equal to 3. It can be proven that 2 is the maximum size of such a subsequence, so answer[0] = 2.
  • The subsequence [4,5,1] has a sum less than or equal to 10. It can be proven that 3 is the maximum size of such a subsequence, so answer[1] = 3.
  • The subsequence [4,5,2,1] has a sum less than or equal to 21. It can be proven that 4 is the maximum size of such a subsequence, so answer[2] = 4.

Example 2:

  • Input: nums = [2,3,4,5], queries = [1]
  • Output: [0]
  • Explanation: The empty subsequence is the only subsequence that has a sum less than or equal to 1, so answer[0] = 0.

Constraints:

  • n == nums.length
  • m == queries.length
  • 1 <= n, m <= 1000
  • 1 <= nums[i], queries[i] <= 10^6

二、分析

  • 根據 greedy 的思維出發,子序列中的數字愈小,組成目標數字的數值個數愈多的可能性愈大,換句話說,當我們將陣列 sort 過後,前 n 個數字所組成的數字,即代表組成該數字最多的個數為 n
  • 由於我們要求的是前 n 個數字的和,故我們可以算出 prefix sum,再利用 binary search 去找到 target 所落在的位置。
  • 舉例來說,nums = [4,5,2,1],經排序後為 nums = [1,2,4,5],求得 prefixSum = [1,3,7,12],再利用 upper_bound 可求得解。
    prefixSum = [1,3,7,12]
    target = [0,1,2,3,4,5,6,7,8,9,10,11,12]
                ^   ^       ^           ^
    answer = [0,1,1,2,2,2,2,3,3,3,3, 3, 4 ]
    

三、解題

  • Time complexity: \(O((m+n)\log n)\)
    排序:\(O(n\log n)\)
    m 次 Binary Search:\(O(m\times\log n)\)
  • Space complexity: \(O(n)\)
vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
    sort(nums.begin(), nums.end()); // 排序
    vector<int> acc;
    vector<int> res;
    for (int x : nums) {            // 求 prefix sum
        if (acc.empty())
            acc.push_back(x);
        else
            acc.push_back(acc.back() + x);
    }
    for (const auto& q : queries) { // 用 binary search 求解
        res.push_back(distance(acc.begin(), upper_bound(acc.begin(), acc.end(), q)));
    }
    return res;
}

回目錄 Catalog