返回
C/C++ 1403:拨开迷雾,探索非递增顺序的最小子序列
后端
2024-01-20 15:09:47
题目
给你一个整数数组 nums
,请你找出并返回一个非递增顺序的最小子序列,该子序列包含 nums
的所有元素。
示例 1:
输入:nums = [4,3,10,9,8]
输出:[10,9,8,4,3]
示例 2:
输入:nums = [4,4,7,6,7]
输出:[7,7,6,4,4]
示例 3:
输入:nums = [1,3,2]
输出:[3,2,1]
提示:
1 <= nums.length <= 2000
1 <= nums[i] <= 1000
题目整理
- 输入:整数数组
nums
- 输出:一个非递增顺序的最小子序列,该子序列包含
nums
的所有元素
题目的解题思路
-
贪心算法:
- 使用贪心算法,从左到右遍历数组,维护一个栈。
- 如果栈为空,或者栈顶元素不大于当前元素,则将当前元素压入栈中。
- 否则,弹出栈顶元素,继续遍历数组。
- 最后,栈中剩下的元素就是非递增顺序的最小子序列。
-
动态规划:
- 定义状态
dp[i]
为前i
个元素的非递增顺序的最小子序列的长度。 - 则有状态转移方程:
dp[i] = max(dp[j] + 1) for j < i and nums[j] >= nums[i]
- 最终答案为
max(dp[i])
。
- 定义状态
具体的实现和代码
贪心算法
class Solution {
public:
vector<int> minSubsequence(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int> res;
int sum = 0;
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
}
int currSum = 0;
for (int i = nums.size() - 1; i >= 0; i--) {
currSum += nums[i];
res.push_back(nums[i]);
if (currSum > sum - currSum) {
break;
}
}
return res;
}
};
动态规划
class Solution {
public:
vector<int> minSubsequence(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n + 1, 0);
for (int i = 1; i <= n; i++) {
dp[i] = nums[i - 1];
for (int j = 0; j < i; j++) {
if (nums[j] <= nums[i - 1]) {
dp[i] = max(dp[i], dp[j] + nums[i - 1]);
}
}
}
int maxLen = *max_element(dp.begin(), dp.end());
vector<int> res;
for (int i = n; i >= 1; i--) {
if (dp[i] == maxLen) {
res.push_back(nums[i - 1]);
maxLen -= nums[i - 1];
}
}
return res;
}
};
结语
通过对 1403. 非递增顺序的最小子序列 这道题目的详细解析,我们不仅掌握了它的解题思路和具体实现,还领略了算法世界中的魅力。希望这篇文章能对您有所帮助,也期待您继续关注我的创作,共同探索算法世界中的奥秘。