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:
?
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%
每個(gè)房屋只遍歷一遍,heater卻可能需要在update house之后重新來(lái)算。改正的次數(shù)太多。最主要的改變是:
1. radis的初始值,如果第一個(gè)house在第一個(gè)heater左邊則至少大于這個(gè)距離;但是如果在heater右邊,就跟其他房間/heater計(jì)算方法一樣
2. 29行還是需要更新radis的,否則一旦heater前進(jìn)之后,我們不會(huì)根據(jù)左邊的house來(lái)更新radis的。如果左邊在下一個(gè)heater范圍內(nèi),一定要在更新heater index之前計(jì)算
3. 26, 29行不要逼著眼更新,一定要選跟當(dāng)前radis中較大的那個(gè)
4. 注意for循環(huán)中沒(méi)有步進(jìn),或者可以改成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 }還需要看別人的算法
別人的算法,巧妙的運(yùn)用了Arrays.binarySearch()方法的返回值,其中第8行運(yùn)用了負(fù)數(shù)的反碼:(-(insertion point) - 1)。看來(lái)Java也是有意用反碼,返回的是在數(shù)組中可以插入的第幾個(gè)值,返回的是下標(biāo)的相反數(shù)?
還有一點(diǎn),如果本身返回的是正數(shù),那么沒(méi)有必要來(lái)計(jì)算,因?yàn)閞esult = 0已經(jīng)足夠了。
第9,10行就是邊界問(wèn)題的考慮。時(shí)間復(fù)雜度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
我猜測(cè)的原因是,目的是每個(gè)house都被取暖,所以按照house來(lái)遍歷肯定可以保證都被cover了,而且它只跟左右的來(lái)比較
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
轉(zhuǎn)載于:https://www.cnblogs.com/panini/p/6637810.html
總結(jié)
以上是生活随笔為你收集整理的475. Heaters的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Linux云自动化运维第六课
- 下一篇: instanceof不是根据构造函数进行