Leetcode 475 -Heaters(二分 or 贪心)

来源:互联网 发布:网络录像机怎么联网 编辑:程序博客网 时间:2024/04/29 15:31

题意

在x轴上给定一堆房子和一些加热器,所有加热器的覆盖半径相同。求最小覆盖半径。

思路

算法1

先排序,然后二分加热器的半径。最后判断是否合法。

时间复杂度O(nlog(INT_MAX))

算法2

先排序,然后O(n)的去扫一遍。

时间复杂度O(nlog(n))

我们对于一个房子x,假设它之前的一个房子的加热器是y。那么x的选择为:y, y + 1, … y + k。我们只需要从里面选出距离x最近的一个即可。并且可以保证:对于下一个房子x + 1,一定不会丢失最优解(因为我们假设x选了y + k,那么x + 1必须从y + k开始选。因为d[x+1]d[x],且d[y+k]d[y]。那么|d[x+1]d[y+k]||d[x+1]d[y]|(画个图很容易看出来)。

代码

//algorithm1class Solution {public:    bool judge(int x, vector<int>& a, vector<int>& b) {        int i = 0, j = 0;        while (i < a.size() && j < b.size()) {            if (abs(a[i] - b[j]) <= x) i++;            else j++;        }        return i == a.size();    }    int findRadius(vector<int>& a, vector<int>& b) {        sort(a.begin(), a.end());        sort(b.begin(), b.end());        int l = 0, r = INT_MAX, m, ans;        while (l <= r) {            m = l + (r - l >> 1);            if (judge(m, a, b)) r = m - 1, ans = m;            else l = m + 1;        }        return ans;    }};//algorithm2class Solution {public:    int findRadius(vector<int>& a, vector<int>& b) {        sort(a.begin(), a.end());        sort(b.begin(), b.end());        b.push_back(-0x3e3e3e3e);        int i = 0, ans = 0;        for (auto x : a) {            while (abs(x - b[i]) >= abs(x - b[i + 1])) i++;            ans = max(ans, abs(x - b[i]));        }        return ans;    }};
0 0