贪心策略3

[Algo] 贪心策略3

1. 最小区间

// 1. 最小区间
// https://leetcode.cn/problems/smallest-range-covering-elements-from-k-lists/
class Node {
public:
    int v; // 值
    int i; // 来自数组i
    int j; // 来自数组i下标j
    Node(int x, int y, int z) : v(x), i(y), j(z) {} 
};
vector<int> smallestRange(vector<vector<int>>& nums) {
    int k = nums.size();
    auto comparator = [](const Node &a, const Node &b) {
        return a.v != b.v ? (a.v < b.v) : (a.i < b.i);
    };
    set<Node, decltype(comparator)> orderedTable(comparator);

    for (int i = 0; i < k; i++) {
        orderedTable.insert(Node(nums[i][0], i, 0));
    }
    int begin, end, len = INT32_MAX;
    while (orderedTable.size() == k) {
        Node min = *orderedTable.begin(), max = *orderedTable.rbegin();
        if (max.v - min.v < len) {
            begin = min.v;
            end = max.v;
            len = max.v - min.v;
        }
        orderedTable.erase(orderedTable.begin());
        if (min.j + 1 < nums[min.i].size()) {
            orderedTable.insert(Node(nums[min.i][min.j + 1], min.i, min.j + 1));
        }
    }
    vector<int> ans = {begin, end};
    return ans;
}

2. 数组的最小偏移量

// 2. 数组的最小偏移量
// https://leetcode.cn/problems/minimize-deviation-in-array/description/
int minimumDeviation(vector<int>& nums) {
    set<int> orderedMap;
    for (auto &num : nums) {
        if (num & 1) orderedMap.insert(2 * num);
        else orderedMap.insert(num);
    }
    int min = *orderedMap.begin(), max = *orderedMap.rbegin(), ans = max - min;
    while (ans > 0 && (max & 1) == 0) {
        orderedMap.erase(max);
        orderedMap.insert(max / 2);
        max = *orderedMap.rbegin();
        min = *orderedMap.begin();
        ans = max - min < ans ? max - min : ans;
    }
    return ans;
}

3. 森林中的兔子

// 3. 森林中的兔子
// https://leetcode.cn/problems/rabbits-in-forest/
int numRabbits(vector<int>& answers) {
    vector<int> arr(1000);
    for (auto &answer : answers) {
        arr[answer]++;
    }
    int ans = 0;
    for (int i = 0; i < 1000; i++) {
        int group = (arr[i] + i) / (i + 1);
        ans += group * (i + 1);
    }
    return ans;
}

4. 使数组相似的最少操作次数

// 4. 使数组相似的最少操作次数
// https://leetcode.cn/problems/minimum-number-of-operations-to-make-arrays-similar/
void partitionAndSortOddEven(vector<int>& nums) {
    if (nums.empty()) return;
    auto it_first_even = partition(nums.begin(), nums.end(), [](int n) {
        return (n & 1);
    });
    sort(nums.begin(), it_first_even);
    sort(it_first_even, nums.end());
}
long long makeSimilar(vector<int>& nums, vector<int>& target) {
    partitionAndSortOddEven(nums);
    partitionAndSortOddEven(target);
    long long diff = 0;
    for (int i = 0; i < nums.size(); i++) {
        diff += abs(nums[i] - target[i]);
    }
    return diff / 4;
}

5. 最低加油次数

// 5. 最低加油次数
// https://leetcode.cn/problems/minimum-number-of-refueling-stops/description/
int minRefuelStops(int target, int startFuel, vector<vector<int>>& stations) {
    if (target <= startFuel) return 0;
    vector<int> lastStation = {target, 0};
    stations.push_back(lastStation);
    int n = stations.size(), totalFuel = startFuel, cnt = 0;
    priority_queue<int, vector<int>, less<int>> maxHeap;
    for (auto &station : stations) {
        int curPos = station[0], curFuel = station[1];
        while (totalFuel < curPos && !maxHeap.empty()) {
            cnt++;
            totalFuel += maxHeap.top();
            maxHeap.pop();
        }
        if (totalFuel < curPos) return -1;
        maxHeap.push(curFuel);
    }
    return cnt;
}
posted @ 2025-06-14 09:02  yaoguyuan  阅读(5)  评论(0)    收藏  举报