zoukankan      html  css  js  c++  java
  • 475. Heaters

    题目:

    Winter is coming! Your first job during the contest is to design a standard heater with fixed warm radius to warm all the houses.

    Now, you are given positions of houses and heaters on a horizontal line, find out minimum radius of heaters so that all houses could be covered by those heaters.

    So, your input will be the positions of houses and heaters seperately, and your expected output will be the minimum radius standard of heaters.

    Note:

    1. Numbers of houses and heaters you are given are non-negative and will not exceed 25000.
    2. Positions of houses and heaters you are given are non-negative and will not exceed 10^9.
    3. As long as a house is in the heaters' warm radius range, it can be warmed.
    4. All the heaters follow your radius standard and the warm radius will the same.

    Example 1:

    Input: [1,2,3],[2]
    Output: 1
    Explanation: The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed.
    

    Example 2:

    Input: [1,2,3,4],[1,4]
    Output: 1
    Explanation: The two heater was placed in the position 1 and 4. We need to use radius 1 standard, then all the houses can be warmed.

    链接:https://leetcode.com/problems/heaters/#/description

    3/28/2017

    18ms, beat 96%

    每个房屋只遍历一遍,heater却可能需要在update house之后重新来算。改正的次数太多。最主要的改变是:

    1. radis的初始值,如果第一个house在第一个heater左边则至少大于这个距离;但是如果在heater右边,就跟其他房间/heater计算方法一样

    2. 29行还是需要更新radis的,否则一旦heater前进之后,我们不会根据左边的house来更新radis的。如果左边在下一个heater范围内,一定要在更新heater index之前计算

    3. 26, 29行不要逼着眼更新,一定要选跟当前radis中较大的那个

    4. 注意for循环中没有步进,或者可以改成while loop

     1 public class Solution {
     2     public int findRadius(int[] houses, int[] heaters) {
     3         Arrays.sort(houses);
     4         Arrays.sort(heaters);
     5         int index = 0;
     6         int radis = 0;
     7         if (houses[0] < heaters[0]) radis = heaters[0] - houses[0];
     8         for (int i = 0; i < heaters.length; ) {
     9             // all unvisited houses left to heater[i] should be less than current radis
    10             // some unvisited houses right to heater[i] may also less than current radis
    11             // break when 1. invalid index, 2. houses right to heater[i] larger than current radis
    12             while (index < houses.length && (houses[index] <= heaters[i] || houses[index] - heaters[i] <= radis)) index++;
    13             if (index == houses.length) break;
    14             // have unvisited heaters
    15             // here we meet first house out of range on the right
    16             if (i < heaters.length - 1) {
    17                 // house is right to next heater, we could update radis when processing next heater
    18                 // because this house will still break in while loop
    19                 if (heaters[i + 1] <= houses[index]) {
    20                     i++;
    21                 } else {
    22                     // next heater is right to current house, the house has to be in the range of current heater,
    23                     // need to update radis
    24                     // do not update heater index, we may meet more houses have to be covered by this heater
    25                     if (heaters[i + 1] - houses[index] > houses[index] - heaters[i]) {
    26                         radis = Math.max(houses[index] - heaters[i], radis);
    27                     } else {
    28                         // next heater will cover current house
    29                         radis = Math.max(heaters[i + 1] - houses[index], radis);
    30                         i++;
    31                     }
    32                     // radis determined by current house is done
    33                     index++;
    34                 }
    35             } else {
    36                 // no unvisited heaters, this last house out of range of current radis, update radis
    37                 radis = houses[houses.length - 1] - heaters[i];
    38                 break;
    39             }
    40         }
    41         return radis;
    42     }
    43 }

    还需要看别人的算法

    别人的算法,巧妙的运用了Arrays.binarySearch()方法的返回值,其中第8行运用了负数的反码:(-(insertion point) - 1)。看来Java也是有意用反码,返回的是在数组中可以插入的第几个值,返回的是下标的相反数?

    还有一点,如果本身返回的是正数,那么没有必要来计算,因为result = 0已经足够了。

    第9,10行就是边界问题的考虑。时间复杂度O((m+n)lgn)

     1 public int findRadius(int[] houses, int[] heaters) {
     2     Arrays.sort(heaters);
     3     int result = 0;
     4     
     5     for (int house : houses) {
     6         int index = Arrays.binarySearch(heaters, house);
     7         if (index < 0) {
     8             index = ~index;
     9             int dist1 = index - 1 >= 0 ? house - heaters[index - 1] : Integer.MAX_VALUE;
    10             int dist2 = index < heaters.length ? heaters[index] - house : Integer.MAX_VALUE;
    11             
    12             result = Math.max(result, Math.min(dist1, dist2));
    13         }
    14     }
    15     
    16     return result;
    17 }

    另外一种算法,还是不理解:https://discuss.leetcode.com/topic/71450/simple-java-solution-with-2-pointers

    我猜测的原因是,目的是每个house都被取暖,所以按照house来遍历肯定可以保证都被cover了,而且它只跟左右的来比较

     1 public class Solution {
     2     public int findRadius(int[] houses, int[] heaters) {
     3         Arrays.sort(houses);
     4         Arrays.sort(heaters);
     5         
     6         int i = 0, res = 0;
     7         for (int house : houses) {
     8             while (i < heaters.length - 1 && heaters[i] + heaters[i + 1] <= house * 2) {
     9                 i++;
    10             }
    11             res = Math.max(res, Math.abs(heaters[i] - house));
    12         }
    13         
    14         return res;
    15     }
    16 }

    更多讨论:

    https://discuss.leetcode.com/category/606/heaters

  • 相关阅读:
    认识 Atlassian Datacenter 产品
    [Swift]Array(数组)扩展
    [Swift]二分法的两种方式
    [Swift]LeetCode528. 按权重随机选择 | Random Pick with Weight
    [Swift]LeetCode526. 优美的排列 | Beautiful Arrangement
    [Swift]LeetCode525. 连续数组 | Contiguous Array
    [Swift]LeetCode524. 通过删除字母匹配到字典里最长单词 | Longest Word in Dictionary through Deleting
    [App Store Connect帮助]四、添加 App 图标、App 预览和屏幕快照(6)设置 App 预览海报帧
    [App Store Connect帮助]四、添加 App 图标、App 预览和屏幕快照(5)移除 App 预览或屏幕快照
    [App Store Connect帮助]四、添加 App 图标、App 预览和屏幕快照(4)为其他设备尺寸和本地化内容添加屏幕快照和预览
  • 原文地址:https://www.cnblogs.com/panini/p/6637810.html
Copyright © 2011-2022 走看看