LeetCode刷題:航班預訂統計

2021-02-21 程序IT圈
前言

前幾天,有一哥們發我一個LeetCode題目連結,緊跟著附上了自己的提交記錄,一個2ms,另一個1451ms...

我一看,這題有點意思啊,不同的思路竟然時間差這麼多。搞它。

題目描述

這裡有n個航班,它們分別從1到n進行編號。

我們這兒有一份航班預訂表,表中第i條預訂記錄bookings[i] = [i, j, k]意味著我們在從i到j的每個航班上預訂了k個座位。

請你返回一個長度為n的數組answer,按航班編號順序返回每個航班上預訂的座位數。

示例:

輸入:bookings = [ [1,2,10], [2,3,20], [2,5,25] ], n = 5

輸出:[10,55,45,25,25]

❞O(m*n)解法

根據題意初始化長度為n的answer數組,代表1到n號航班預訂的座位數量,外層遍歷 bookings,內層遍歷bookings[i] = [i, j, k],計算航班號i到j的座位數量,即當前座位數量加k。

public int[] corpFlightBookings(
int[][] bookings, int n) {

int[] answer = new int[n];

// 遍歷整個bookings數組
for (int[] b : bookings) {
// 內層循環把每個航班預訂數加上
for (int i = b[0] - 1;
i <= b[1] - 1; i++) {
answer[i] += b[2];
}
}
return answer;
}

O(n)解法思考

O(m*n)解法中關鍵一點,內層循環我們一直重複的在[i, j]之間加上k,怎麼將這循環變成O(1),成為問題的關鍵!

[i, j]之間加上k,這讓我想到了等差數列,這不就是公差為k的等差數列嗎?然後呢?

分析

設answer[i]表示第i個航班預訂的座位數。定義一個差分數組d[],d[i]表示第i個航班與第i-1個航班預訂座位的差值,即d[i] = answer[i] - answer[i - 1]。

這樣,我們每次遍歷到bookings[i] = [i, j, k],就只需要將d[i]增加k,d[j + 1]減少k即可,因為i到j之間,航班預訂數量是沒有變化的。

最後,計算answer[i] = answer[i - 1] + d[i],返回answer即可。

推演

好吧,這樣說可能有人沒懂,我們按照題目的例子推演一次:

初始航班預訂數量數組 answer = [0,0,0,0,0],差分數組d = [0,0,0,0,0]當遍歷到bookings[0] = [1,2,10]的時候,差分數組第1位加10,第3位減10,變成d = [10,0,-10,0,0]同理,當遍歷到bookings[1] = [2,3,20]的時候,差分數組變成d = [10,20,-10,-20,0]當遍歷到bookings[2] = [2,5,25]的時候,差分數組變成d = [10,45,-10,-20,0],第6位要減25,我們也不需要了最後計算answer數組的值,answer[0] = d[0] = 10,answer[1] = d[1] + answer[0] = 45 + 10 = 55,answer[2] = d[2] + answer[1] = -10 + 55 = 45...最最後發現,只申請一個數組表示d[]和answer[]就可以了,over!代碼
public int[] corpFlightBookings(
int[][] bookings, int n) {

int[] answer = new int[n];

// 遍歷bookings 計算航班i+1 對航班i 變化的預訂數
for (int[] b : bookings) {
// 增加的預訂數
answer[b[0] - 1] += b[2];
// 防止數組越界
if (b[1] < n) {
// 減少的預訂數量
answer[b[1]] -= b[2];
}
}

// 航班i的預訂數等於,i-1的預訂數,加i時刻變化的預定數
for (int i = 1; i < n; i++) {
answer[i] += answer[i - 1];
}
return answer;
}

拼車❝

你以為這就完了嗎?不要太天真。再來看一下這個題,或許會給你帶來新思路。

❞題目描述

假設你是一位順風車司機,車上最初有 capacity 個空座位可以用來載客。由於道路的限制,車 只能 向一個方向行駛(也就是說,不允許掉頭或改變方向,你可以將其想像為一個向量)。

這兒有一份行程計劃表 trips[][],其中 trips[i] = [num_passengers, start_location, end_location] 包含了你的第 i 次行程信息:

必須接送的乘客數量;乘客的上車地點;以及乘客的下車地點。這些給出的地點位置是從你的 初始 出發位置向前行駛到這些地點所需的距離(它們一定在你的行駛方向上)。

請你根據給出的行程計劃表和車子的座位數,來判斷你的車是否可以順利完成接送所用乘客的任務(若且唯若你可以在所有給定的行程中接送所有乘客時,返回 true,否則請返回 false)。

示例 1:

輸入:trips = [[2,1,5],[3,3,7]], capacity = 4

輸出:false

示例 2:

輸入:trips = [[2,1,5],[3,3,7]], capacity = 5

輸出:true

提示:

你可以假設乘客會自覺遵守 「先下後上」 的良好素質題目分析

這道題實際上就是問,車的座位數量是否能滿足每個行程i的乘客,即每個乘客都坐上座位,能則返回true,否則返回false。

如果我們能計算出,行程i,要乘車的乘客的數量,然後跟capacity對比一下,就能得到答案了。

很顯然,「要乘車的乘客的數量 = 車上原來乘客的數量 - 下車乘客數量 + 上車乘客數量」

思路

我們可以用數組或者Map記錄,行程i,下車乘客的數量和上車乘客的數量,然後行程開始到結束,計算要乘車的乘客數量,並與capacity比較。

代碼實現Map版
public boolean carPooling(
int[][] trips, int capacity) {
// 使用TreeMap 是為了讓元素根據key排序
TreeMap<Integer, Integer> map =
new TreeMap<>();
for (int[] t : trips) {
int v = map.getOrDefault(t[1], 0) + t[0];
// 上車乘客數量
map.put(t[1], v);
v = map.getOrDefault(t[2], 0) - t[0];
// 下車乘客數量
map.put(t[2], v);
}

int cur = 0;

for (Map.Entry<Integer, Integer> entry
: map.entrySet()) {
Integer value = entry.getValue();
// 當前數量=之前數量+變化的數量
cur += value;

if (cur > capacity) {
return false;
}
}
return true;
}

代碼實現數組版
public boolean carPooling(
int[][] trips, int capacity) {

// 最遠行程 數組長度
int max = 0;
for (int[] t : trips) {
max = Math.max(max, t[2]);
}

// 所有要乘車的乘客數量
int[] passengers = new int[max + 1];
for (int[] t : trips) {
passengers[t[1]] += t[0];
passengers[t[2]] -= t[0];
}

int cur = 0;
for (int passenger : passengers) {
// 當前數量 = 之前數量 + 變化的數量
cur += passenger;
if (cur > capacity) {
return false;
}
}

return true;
}

回頭

「拼車」的代碼與場景感覺好理解一些,因為生活中我們就是這樣,先下後上,能不能坐上座,就看車上原來有多少人,還有下車多少人。

我們再回來來看「航班預訂統計」這題,實際上跟「拼車」是完全一樣的題目。

我看到有人問,計算bookings[i] = [i, j, k]預訂變化數量的時候,為啥是第j + 1的位置要減k,而不是j的位置呢?因為,j - 1的位置,航班預訂座位數量應該加k,而j的位置,航班預訂座位數量也加k,所以j和j - 1之間數量是沒有變化的。但是,j + 1的位置航班數量不再加k了,所以j + 1相對於j位置航班預訂數量是減少k的。

「拼車」這道題,trips[i][j],在j位置,車到站了,乘客就下車了,再坐一站就過站了...

總之,兩道題本質是完全一樣的,只不過略微有些細節不同。

相關焦點

  • 航班預訂 ——如何預訂嬰兒記錄
    嬰兒票的預訂與成人有怎樣的不同?如旅客要求再加一張嬰兒票,那我們該怎樣操作?今天我們就分享一下為一位嬰兒旅客預訂一張國內航空公司的國內航班記錄案例。首先,嬰兒旅客與成人旅客最大的不同是嬰兒一般是不佔座的,並且嬰兒通常是免收機場建設稅和燃油稅的,嬰兒必須要和成人在同一個記錄裡,不能如成人旅客一樣單獨預訂。
  • [LeetCode] 871. Minimum Number of Refueling Stops 最少的加油站個數
    <stations[stations.length-1][0]<target這道題說有一輛小車,需要向東行駛 target 的距離,路上有許多加油站,每個加油站有兩個信息,一個是距離起點的距離,另一個是可以加的油量,問我們到達 target 位置最少需要加的油量。
  • 高中數學:概率統計應用題
    概率統計是研究隨機現象的數學分支。概率應用題的文字敘述長,數量關係分散,且背景新穎而難以把握。
  • 每日一題:力扣85-最大矩形
    ❞力扣85-最大矩形一、原題題目1.1 題目  給定一個僅包含 0 和 1 、大小為 rows x cols 的二維二進位矩陣,找出只包含 1 的最大矩形,並返回其面積。示例5:輸入: matrix = [["0","0"]]輸出: 0提示:來源:力扣(LeetCode)連結:https://leetcode-cn.com
  • 年底假期多 亞航機票預訂火爆
    世界日報訊  泰亞洲航空公司董事長訕迪素透露,年底長假即將到來之際,提前預訂機票情況火爆,估計12月載客率可達
  • 捷星航空預訂流程詳解
    捷星航空提供三類票價:商務艙(J 和D 艙)、經濟艙MAX(Y 和V 艙)和經濟艙(H、K、L、M、N、O、Q、R、S、T艙)。價格均為單程點到點的價格,這樣可為遊客提供最大的靈活性。示例:SSR OTHS 1E JQ CONFONBR I6S13M票價的有效期需根據JQ 的保留時限,具體詳情可根據運價規則條款。每個預訂 (PNR)僅允許使用一張信用卡。信用卡和BSP 支付方式不能同時使用。對於多位乘客的聯合購票,如果每位乘客希望用自己的信用卡進行支付,則必須創建獨立預訂。
  • 今天出一道統計題~~附「舉例說明認知失調」參考答案
    第四題今天出一道統計計算題~~附「舉例說明認知失調」參考答案
  • 中日之間最新航班信息,出來了!我刷了一下機票價格……
    由於新冠肺炎疫情的影響,現在來往中日兩國的航班並不多。一個星期大致就10來個航班。這與疫情前的航班數量相比,完全沒法比較。
  • 每日一題:Excel根據打卡記錄統計考勤結果!(一)
    如下圖:是每個員工的打卡記錄,現在要統計員工的出勤情況。我問:原來怎麼統計的?回答:目視,手工一個一個核對!我真的無語了,Excel有很多很多的功能可以簡化這項工作。這個問題完全解決比較複雜,我會分幾次逐步完善解決方案,今天算一個初步方案。我們複製一份數據到另外一張表,並把日期與時間用分列拆分成兩列,並調整日期格式。
  • 澳航開啟國際航班預訂,聯邦政府回應:只有滿足這一條件,才會重開國際邊境
    7News1月5日報導,澳航開啟2021年7月國際航班的預訂服務,對於此事
  • 刷題第14天:完成2題+略微幻滅
    但是也不後悔刷題這麼久,編程基礎還是鞏固了很多。筆試還是要做的,漲漲見識,看看能做對多少。至於能不能通過,就順其自然吧。對於工作,我現在覺得只要做好份內的事,按時拿到工資就行了。以前狂熱追求的職業發展什麼的,已經不考慮了。沒那個機會了。昨天另外一個前同事幫我內推了她公司,今天反饋說公司要求90後。。。
  • 視頻課:概率與統計解答題
    音樂響起公眾微信號《高中數學研習室》是我市名校名師名師風(筆名)創建的一個服務高中數學教與學的平臺,平臺主要內容有名師親授視頻課,專門為學生打造,主要有兩個板塊:熱門內容專題講座(每一講20分鐘左右)+典型習題一題精講
  • Google:深析遊客移動端搜索和預訂行為
    研究所覆蓋的一個特定的旅遊業領域是航班(包含在目的地內使用的附加細節)。  研究目的是為了說明旅遊行程的搜索、預訂及旅途中其他時刻對行動裝置的使用及遊客的在線行為的增加。  以下是品橙盤點出的在客戶使用手機預訂休閒遊航班方面的主要發現:85%的用戶擁有智慧型手機,其中66%的用戶用智慧型手機訪問網絡的頻率與用臺式機時一樣;89%的用戶在線搜索產品,其中56%的用戶在行動裝置上搜索;80%的用戶會在線預訂,但只有9%會在手機上預訂;13%的用戶會利用行動裝置進行研究,隨後在線下預訂。
  • 英語情景對話:預訂往返飛機票
    中國東方航空,早上好,有什麼能為您服務嗎?B:I would like the round-way ticket to Shanghai on December 10th.  我想預訂十二月十日飛往上海的往返飛機票。A:Lady, let me check.
  • 中國-美國直飛航線統計,小夥伴們再也不用為了選航班而發愁了~~~
    使用小貼士:1.中國大陸及香港、臺北到美國城市及夏威夷的航線統計。
  • 4k+住萬豪,來衝繩刷籤,家庭旅行也要品位十足
    飛行時間不遠,交通非常方便;一年四季氣候都很溫和舒適,還有美到極致的海灘;城市不大,不會迷路,國際通可以完成的一站式購物也非常輕鬆;還能刷日本三年多次籤證……親子遊衝繩 圖/窮遊er Sally小妞如果是親子遊,最重要的就是選一家好酒店。不僅酒店的設施更好可以讓旅程更享受,有時候偷懶不願出門,酒店自身就是一個很好的遊樂園。
  • 美聯航UA857突然取消航班!乘客欲哭無淚!
    11月22日的UA857舊金山SFO飛上海的航班突然被取消了,昨天下午相信很多乘客已收到航空公司通知,但有些乘客已經提前趕往舊金山,而有些乘客剛完成核酸採樣,突然收到航班被取消的通知真是很無奈,但能怎麼樣?據悉取消原因為不可預測的運營問題。
  • 新航發布新加坡和香港的航班計劃.
    在一份媒體聲明中,新加坡航空公司(SIA)已發布了兩個城市之間ATB航班的時間表。在新航集團內部,新航將運營飛往香港的ATB航班,而酷航將運營非ATB的航班。從新加坡SIA起飛的ATB首飛航班SQ890,將於11月22日起飛。(圖片來源網絡)新航還發布了11月25日至12月4日的ATB航班時間表。從12月7日起,新航將每日運營ATB往返香港的航班。
  • 澳航開放7月中澳航班預訂!僅400刀起,真的假的?政府已回應
    澳航開放國際航班預訂,前往上海、香港、新加坡等地的多條國際航線重回人們視野中。這兩天,澳航Qantas搞了一大動作:重新開始售賣國際航線機票!現在世界疫情形勢如此嚴峻,澳航膽子這麼大?是的!出於對疫苗已經開始使用的信心,澳航真的開始賣票了!
  • 通過雅高中文網站預訂的亞太區酒店實現53%年度預訂收入增長,中國區同比猛增93%
    統計顯示,在2014年7月至2015年6月期間,亞太區酒店直接通過該網站進行預訂而獲得的收入同比增長53%,而其中中國區酒店的預訂收入更增加了93%。早在2005年,雅高集團就成為首家推出中文預訂的國際酒店集團。然而直到2014年推出為使用中文的消費者度身定製的升級版中文網站,其預訂業務才迎來了顯著的增長,例如,從全球範圍來看,雅高酒店的預訂收入提高了37%。