• leetcode 1403. Minimum Subsequence in Non-Increasing Order


    Given the array nums, obtain a subsequence of the array whose sum of elements is strictly greater than the sum of the non included elements in such subsequence. 

    If there are multiple solutions, return the subsequence with minimum size and if there still exist multiple solutions, return the subsequence with the maximum total sum of all its elements. A subsequence of an array can be obtained by erasing some (possibly zero) elements from the array. 

    Note that the solution with the given constraints is guaranteed to be unique. Also return the answer sorted in non-increasing order.

     

    Example 1:

    Input: nums = [4,3,10,9,8]
    Output: [10,9] 
    Explanation: The subsequences [10,9] and [10,8] are minimal such that the sum of their elements is strictly greater than the sum of elements not included, however, the subsequence [10,9] has the maximum total sum of its elements. 
    

    Example 2:

    Input: nums = [4,4,7,6,7]
    Output: [7,7,6] 
    Explanation: The subsequence [7,7] has the sum of its elements equal to 14 which is not strictly greater than the sum of elements not included (14 = 4 + 4 + 6). Therefore, the subsequence [7,6,7] is the minimal satisfying the conditions. Note the subsequence has to returned in non-decreasing order.  
    

    Example 3:

    Input: nums = [6]
    Output: [6]
    

     

    Constraints:

    • 1 <= nums.length <= 500
    • 1 <= nums[i] <= 100

    题目意思:

    给你一个数组 nums,请你从中抽取一个子序列,满足该子序列的元素之和 严格 大于未包含在该子序列中的各元素之和。

    如果存在多个解决方案,只需返回 长度最小 的子序列。如果仍然有多个解决方案,则返回 元素之和最大 的子序列。

    与子数组不同的地方在于,「数组的子序列」不强调元素在原数组中的连续性,也就是说,它可以通过从数组中分离一些(也可能不分离)元素得到。

    注意,题目数据保证满足所有约束条件的解决方案是 唯一 的。同时,返回的答案应当按 非递增顺序 排列。

    示例 1:

    输入:nums = [4,3,10,9,8]

    输出:[10,9] 

    解释:子序列 [10,9] 和 [10,8] 是最小的、满足元素之和大于其他各元素之和的子序列。但是 [10,9] 的元素之和最大。 

    示例 2:

    输入:nums = [4,4,7,6,7]

    输出:[7,7,6] 

    解释:子序列 [7,7] 的和为 14 ,不严格大于剩下的其他元素之和(14 = 4 + 4 + 6)。因此,[7,6,7] 是满足题意的最小子序列。注意,元素按非递增顺序返回。  

    示例 3:

    输入:nums = [6]

    输出:[6]

    提示:

    1 <= nums.length <= 500

    1 <= nums[i] <= 100

    思路:找出这样的最小子序列,肯定从数组中最大数开始一个一个提取,直到子序列的和大于剩余在原数组的元素之和。关键在于怎么提取数组中的最大数。可以将排序。

    C++代码

     1 class Solution {
     2 public:
     3     vector<int> minSubsequence(vector<int>& nums) {
     4         vector<int> ans;
     5         int sums = 0;
     6         sort(nums.begin(), nums.end());//将数组按从小到大排序
     7         sums = accumulate(nums.begin(), nums.end(), 0) / 2; //累加数组求和,并取半
     8         int temp = 0;
     9         for (int i = nums.size() - 1; i >= 0; i--) {
    10             //从数组最大数开始遍历,如果之前的累加和已经超过数组和一半,那么当前的nums[i]不用,并且break
    11             if (temp > sums) //细想,只要子序列的和大于一半就要结束,因为子序列的和加上原数组剩余元素和是固定的
    12                 break;
    13             temp += nums[i];
    14             ans.push_back(nums[i]);
    15         }
    16         return ans;
    17     }
    18 };

    优先队列:

     1 class Solution {
     2 public:
     3     vector<int> minSubsequence(vector<int>& nums) {
     4         vector<int> res;
     5         auto sub_sum = 0, half_sum = accumulate(begin(nums), end(nums), 0) / 2;
     6         priority_queue<int> pq(begin(nums), end(nums));
     7         while (sub_sum <= half_sum) {
     8             res.push_back(pq.top());
     9             sub_sum += res.back();
    10             pq.pop();
    11         }
    12         return res;
    13     }
    14 };

    注意:题目限制数值范围为[1,100],所以排序可以用计数排序。

     1 class Solution {
     2 public:
     3     vector<int> minSubsequence(vector<int>& nums) {
     4         vector<int> count(101, 0);
     5         int half_sum = 0;
     6         for (auto num : nums) {
     7             count[num]++;
     8             half_sum += num;
     9         }
    10         half_sum /= 2;
    11         vector<int> res;
    12         int sum = 0;
    13         for (int i = 100; i >= 1 && sum <= half_sum; i--) {
    14             while (count[i] > 0 && sum <= half_sum) {
    15                 sum += i;
    16                 res.push_back(i);
    17                 count[i]--;
    18             }
    19         }
    20         return res;
    21 
    22     }
    23 };

    python3代码

     1 class Solution:
     2     def minSubsequence(self, nums: List[int]) -> List[int]:
     3         half_sum, sums, ans = sum(nums) // 2, 0, []
     4         counter = collections.Counter(nums)
     5         for i in range(100, 0, -1):
     6             while counter[i] > 0 and sums <= half_sum:
     7                 counter[i] -= 1
     8                 sums += i
     9                 ans.append(i)
    10         return ans

    Given the array nums, obtain a subsequence of the array whose sum of elements is strictly greater than the sum of the non included elements in such subsequence. 

    If there are multiple solutions, return the subsequence with minimum size and if there still exist multiple solutions, return the subsequence with the maximum total sum of all its elements. A subsequence of an array can be obtained by erasing some (possibly zero) elements from the array. 

    Note that the solution with the given constraints is guaranteed to be unique. Also return the answer sorted in non-increasing order.

     

    Example 1:

    Input: nums = [4,3,10,9,8]
    Output: [10,9] 
    Explanation: The subsequences [10,9] and [10,8] are minimal such that the sum of their elements is strictly greater than the sum of elements not included, however, the subsequence [10,9] has the maximum total sum of its elements. 
    

    Example 2:

    Input: nums = [4,4,7,6,7]
    Output: [7,7,6] 
    Explanation: The subsequence [7,7] has the sum of its elements equal to 14 which is not strictly greater than the sum of elements not included (14 = 4 + 4 + 6). Therefore, the subsequence [7,6,7] is the minimal satisfying the conditions. Note the subsequence has to returned in non-decreasing order.  
    

    Example 3:

    Input: nums = [6]
    Output: [6]
    

     

    Constraints:

    • 1 <= nums.length <= 500
    • 1 <= nums[i] <= 100
  • 相关阅读:
    【数量技术宅|量化投资策略系列分享】股指期货IF分钟波动率统计策略
    【数量技术宅 | Python爬虫系列分享】实时监控股市重大公告的Python爬虫
    0-1背包问题
    活动选择的贪心算法与动态规划
    图的邻接表、拓扑排序、无权最短路径和加权最短路径
    把二叉树转变为左孩子右兄弟树
    基于接缝裁剪的图像压缩 算法导论
    公司聚会
    二叉堆部分练习
    编辑距离问题
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/12677849.html
Copyright © 2020-2023  润新知