N
cars are going to the same destination along a one lane road. The destination is target
miles away.html
Each car i
has a constant speed speed[i]
(in miles per hour), and initial position position[i]
miles towards the target along the road.git
A car can never pass another car ahead of it, but it can catch up to it, and drive bumper to bumper at the same speed.github
The distance between these two cars is ignored - they are assumed to have the same position.ide
A car fleet is some non-empty set of cars driving at the same position and same speed. Note that a single car is also a car fleet.code
If a car catches up to a car fleet right at the destination point, it will still be considered as one car fleet. How many car fleets will arrive at the destination?htm
Example 1:blog
Input: target = 12, position = [10,8,0,5,3], speed = [2,4,1,1,3] Output: 3 Explanation: The cars starting at 10 and 8 become a fleet, meeting each other at 12. The car starting at 0 doesn't catch up to any other car, so it is a fleet by itself. The cars starting at 5 and 3 become a fleet, meeting each other at 6. Note that no other cars meet these fleets before the destination, so the answer is 3.\ Note:
0 <= N <= 10 ^ 4
0 < target <= 10 ^ 6
0 < speed[i] <= 10 ^ 6
0 <= position[i] < target
這道題說是路上有一系列的車,車在不一樣的位置,且分別有着不一樣的速度,但行駛的方向都相同。若是後方的車在到達終點以前追上前面的車了,那麼它就會如癡漢般尾隨在其後,且速度降至和前面的車相同,能夠看做是一個車隊,固然,單獨的一輛車也能夠看做是一個車隊,問咱們共有多少個車隊到達終點。這道題是小學時候的應用題的感受,什麼狗追人啊,人追狗啊之類的。這道題的正確解法的思路其實不太容易想,由於咱們很容易把注意力都集中到每輛車,去計算其每一個時刻所在的位置,以及跟前面的車相遇的位置,這其實把這道題想複雜了,其實並不須要知道車的相遇位置,只關心是否能組成車隊一同通過終點線,那麼如何才能知道是否能一塊兒過線呢,最簡單的方法就是看時間,假如車B在車A的後面,而車B到終點線的時間小於等於車A,那麼就知道車A和B必定會組成車隊一塊兒過線。這樣的話,就能夠從離終點最近的一輛車開始,先算出其撞線的時間,而後再一次遍歷身後的車,若後面的車撞線的時間小於等於前面的車的時間,則會組成車隊。反之,若大於前面的車的時間,則說明沒法追上前面的車,因而本身會造成一個新的車隊,且是車頭,則結果 res 自增1便可。隊列
思路有了,就能夠具體實現了,使用一個 TreeMap 來創建小車位置和其到達終點時間之間的映射,這裏的時間使用 double 型,經過終點位置減去當前位置,併除以速度來得到。咱們但願能從 position 大的小車開始處理,而 TreeMap 是把小的數字排在前面,這裏使用了個小 trick,就是映射的時候使用的是 position 的負數,這樣就能先處理原來 position 大的車,從而統計出正確的車隊數量,參見代碼以下:leetcode
解法一:get
class Solution { public: int carFleet(int target, vector<int>& position, vector<int>& speed) { int res = 0; double cur = 0; map<int, double> pos2time; for (int i = 0; i < position.size(); ++i) { pos2time[-position[i]] = (double)(target - position[i]) / speed[i]; } for (auto a : pos2time) { if (a.second <= cur) continue; cur = a.second; ++res; } return res; } };
咱們也可使用優先隊列來作,因爲其是按照從大到小的順序自動排列的,因此不用使用上面的小 trick。還有一點和上面的不一樣的是,並無在開始就計算過線時間,而是直接存的是速度,由於存整型確定比存 double 型的要節省空間。在以後處理的時候,再取出位置和速度計算時間,而後再進行跟上面相同的操做便可,參見代碼以下:
解法二:
class Solution { public: int carFleet(int target, vector<int>& position, vector<int>& speed) { int res = 0; double cur = 0; priority_queue<pair<int, int>> q; for (int i = 0; i < position.size(); ++i) { q.push({position[i], speed[i]}); } while (!q.empty()) { auto t = q.top(); q.pop(); double timeNeeded = (double)(target - t.first) / t.second; if (timeNeeded <= cur) continue; cur = timeNeeded; ++res; } return res; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/853
參考資料:
https://leetcode.com/problems/car-fleet/
https://leetcode.com/problems/car-fleet/discuss/180287/Java-Priority-Queue-Explained
https://leetcode.com/problems/car-fleet/discuss/139850/C%2B%2BJavaPython-Straight-Forward