lc1847 最近的房間

chenfy27發表於2024-03-16

有n個房間,rooms[i]={id[i],size[i]}表示第i個房間編號為id[i],面積為size[i],房間編號唯一。
現有k個查詢query[j]={preferred[j],minsize[j]},表示要求面積至少為minsize[j],且編號跟preferred[j]最接近,如果有多個,選編號小的那個。
1<=n<=1e5; 1<=k<=1e4; 1<=id[i],preferred[i]<=1e7; 1<=size[i],minsize[i]<=1e7

像這種二維偏序查詢問題,一般做法是離線處理,對查詢按第一維排序,按順序加入集合,然後在集合中查詢第二維資訊,這樣把二維降成一維來處理。
對於本題,將查詢按面積從大到小排序,每次查詢前將滿足面積條件的房間加入集合,然後在該集合中尋找編號最接近的元素。

struct node {
    int idx, id, siz, ans;
};
class Solution {
public:
    vector<int> closestRoom(vector<vector<int>>& rooms, vector<vector<int>>& queries) {
        int n = rooms.size();
        int q = queries.size();
        sort(rooms.begin(), rooms.end(), [&](auto &x, auto &y){return x[1]>y[1];});
        vector<node> vn(q);
        for (int i = 0; i < q; i++) {
            vn[i] = {i, queries[i][0], queries[i][1], 0};
        }
        sort(vn.begin(), vn.end(), [&](auto &x, auto &y){return x.siz > y.siz;});

        vector<int> ans(q);
        set<int> st;
        for (int i = 0, j = 0; i < q; i++) {
            while (j < n && rooms[j][1] >= vn[i].siz) {
                st.insert(rooms[j][0]);
                j += 1;
            }
            int best = -1, diff = INT_MAX;
            auto it = st.lower_bound(vn[i].id);
            if (it != st.end() && abs(*it - vn[i].id) < diff) {
                diff = abs(*it - vn[i].id);
                best = *it;
            }
            if (it != st.begin()) {
                --it;
                if (abs(*it - vn[i].id) <= diff) {
                    diff = abs(*it - vn[i].id);
                    best = *it;
                }
            }
            ans[vn[i].idx] = best;
        }
        return ans;
    }
};

相關文章