Every day a Leetcode
题目来源:2826. 将三个组排序
解法1:贪心 + 二分查找
最长递增子序列的变种题。
利用 Leetcode300. 最长递增子序列 的方法,求出数组 nums 的最长递增子序列 g,最后答案为 nums.size() - g.size()。
代码:
// 最长递增子序列,贪心 + 二分查找class Solution
{
public:int minimumOperations(vector<int> &nums){// 特判if (nums.empty())return 0;int n = nums.size();vector<int> g; // 最长递增子序列for (int i = 0; i < n; i++){int j = upper_bound(g.begin(), g.end(), nums[i]) - g.begin();if (j == g.size())g.push_back(nums[i]);elseg[j] = nums[i];}return n - g.size();}
};
结果:
复杂度分析:
时间复杂度:O(nlogn),其中 n 是数组 nums 的元素个数。
空间复杂度:O(n),其中 n 是数组 nums 的元素个数。
解法2:状态机 DP
代码:
class Solution
{
public:int minimumOperations(vector<int> &nums){// 特判if (nums.empty())return 0;int n = nums.size();// dp[i+1][j]: 考虑 nums[0] 到 nums[i],且 nums[i] 变成 j 的最小修改次数vector<vector<int>> dp(n + 1, vector<int>(4, 0));// 状态转移for (int i = 0; i < n; i++)for (int j = 1; j <= 3; j++){dp[i + 1][j] = INT_MAX;for (int k = 1; k <= j; k++)dp[i + 1][j] = min(dp[i + 1][j], dp[i][k]);dp[i + 1][j] += nums[i] != j;}return *min_element(dp[n].begin() + 1, dp[n].end());}
};
结果:
复杂度分析:
时间复杂度:O(n),其中 n 是数组 nums 的元素个数。
空间复杂度:O(n),其中 n 是数组 nums 的元素个数。