📜  最多 K 个连续交换后的字典序最小数组(1)

📅  最后修改于: 2023-12-03 15:10:34.612000             🧑  作者: Mango

最多 K 个连续交换后的字典序最小数组

介绍

在本题中,给定一个长度为 n 的整数数组 nums 和一个整数 k,你可以选取一个任意长度不超过 k 的子区间,然后你可以交换该子区间中任意两个元素的位置。你可以进行多次操作,请问经过最多 k 次交换后,能得到的字典序最小的数组是什么?

本题需要我们注意:

  • 可以进行多次交换操作
  • 交换子区间的长度不能超过 k
  • 交换后的数组字典序最小
解题思路

我们可以用贪心算法来解决本题,其大致的思路如下:

  • 遍历数组 nums,并找到每个数值右侧比它小的最大数值 max_num,如果右侧没有比它小的数,则 max_num = -1
  • 找到 i 位置右侧连续 k 个数中最小值 min_num 及其位置,如果右侧不足 k 个数,则从 i + 1 开始往后最多取 k -(j - i)

接下来,我们交换 i 和 min_num 两个位置的值,并将 k - (min_num - i)赋给 k

这个过程不断重复,直到 k 达到 0 或者遍历结束

最后,我们得到的数组就是字典序最小的数组

具体实现细节可以见代码实现:

class Solution {
public:
    vector<int> findMinArray(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> ret;
        deque<int> q;
        for(int i = 0; i < n; ++i) {
            while(!q.empty() && nums[q.back()] > nums[i]) {
                q.pop_back();
            }
            q.push_back(i);
            if(i >= k && q.front() <= i - k) {
                q.pop_front();
            }
            if(i >= k - 1) {
                ret.push_back(nums[q.front()]);
            }
        }
        sort(ret.begin(), ret.end());
        return ret;
    }
};
总结

本题我们使用了贪心算法来解决,思路清晰,实现简单。然而,贪心算法的解题思路虽好,适用面却有限。我们需要灵活运用各种算法框架和思路来解决不同的问题。