上一篇博客《LeetCode進階944-貪心》,有朋友提出建議944對理解貪心算法並不具備很強的表明性。回顧了下上篇的內容,實際文中博主重點說明的是算法優化的小技巧,題解思路也僅僅只是簡單的統計法,對貪心思想實際幫助確實不大。基於此博主已將上篇博客標題更正爲《LeetCode進階944-算法優化》(除訂閱號因爲微信公衆平臺的限制,標題暫時沒法修改),而本篇將以leetcode1029爲實例,講解貪心算法思想。面試
不知不覺,從開始發算法博客到現在已通過了半月,在這個過程當中其實也遇到過不少困難,也一度想過要放棄,深入體會到沒有任何一件事情是能夠簡簡單單敷衍過去的,特別能體會那些工做之餘還能十年如一日堅持技術文章創做的做者們的不容易。不過儘管辛苦也有不少收穫,好比精益求精,更追求更完美,又好比收穫了不少技術之外的知識,認識了更多的朋友,視野也更加開闊。猶記得第一次投稿成功,第一次文章被大的專欄收錄,第一次有人點贊,第一次有粉絲關注,甚至第一次某平臺粉絲破百的時候心裏的喜悅... 將來,但願本身能把算法博客當成愛好一直寫下去,也但願能這些文章能給有須要的朋友帶來實際的幫助。在後續博文推送過程當中,不排除也有些疏漏或者思惟理解上的誤區,歡迎交流或批評指正。算法
There are 2N people a company is planning to interview. The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1].數組
Return the minimum cost to fly every person to a city such that exactly N people arrive in each city.bash
Example 1:微信
Input: [[10,20],[30,200],[400,50],[30,20]] Output: 110 Explanation: The first person goes to city A for a cost of 10. The second person goes to city A for a cost of 30. The third person goes to city B for a cost of 50. The fourth person goes to city B for a cost of 20.微信公衆平臺
The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city.優化
Note:ui
1 <= costs.length <= 100 It is guaranteed that costs.length is even. 1 <= costs[i][0], costs[i][1] <= 1000編碼
公司安排2N我的參加面試。第i我的坐飛機飛到城市A的費用爲costs[i][0],飛到城市B的費用爲 costs[i][1]。spa
返回安排好每一個人都前往某城市面試的最低費用,A、B城市各有N我的參加。
例:
輸入:[[10,20],[30,200],[400,50],[30,20]] 輸出:110 說明: 第一我的前往 A 市,費用爲 10。 第二我的前往 A 市,費用爲 30。 第三我的前往 B 市,費用爲 50。 第四我的前往B 市,費用爲 20。
總花費最低爲 10 + 30 + 50 + 20 = 110,兩個城市各有一半人在面試。
提示:
1 <= costs.length <= 100 costs.length 爲偶數 1 <= costs[i][0], costs[i][1] <= 1000
須要將2N我的分紅兩組,分別送往A、B城市面試,每一個人去A、B城市的費用已知,要保證總費用最少。凡事涉及最大最小值求和相關的題型,天然不難聯想到貪心算法思想,貪心思想最典型的問題是「揹包問題」,關於貪心思想須要注意的是,必定要確保「貪心」的思路正確即能拿到最優解,實踐過程當中能夠具體進行數值帶入驗證。
根據題意,須要的最優解是花費最少的錢分別安排N我的前往A、B面試,每一個人前往A、B城市的花費有個價格差。能夠這簡單這麼理解咱們能夠統一計算出每一個人前往B城市比前往A城市須要多花的錢(也能夠是前往A城市比前往B城市要多花的錢),而後進行排序,價格差最大的排名第一的人必然只能安排到A城市,這樣能省下的成本費用最大。接着依次日後安排,排第二的人也只能安排到A城市,一直到安排了排第N的人到A城市,剩下的N我的因爲前往B城市比前往A城市花費沒那麼高所有排到B城市。
一、新建一個大小和人數一致的int數組sort,用於保存每一個人前往B城市比前往A城市多花費的費用(注意費用能夠是負數,負數等價理解花費更少);
二、遍歷costs花費數組,將差值記錄在sort數組元素中;
i.計算第i我的前往B和前往A的差值;
ii.差值左移8位;
iii.左移後加上當前在cost數組中的下標位置i;
三、對差值sort數組進行排序;
四、聲明一個int變量min表示最小花費總和,循環遍歷sort數組,遍歷次數只需人數的一半costs.length/2;
i.對於差值排名前N,即sort中最後的N我的,選擇去A城市的花費,根據sort元素存儲的在costs數組中的下標位置從costs數組中獲取去A城市的花費;
ii.對於差值排名後N,即sort中前N我的,選擇去B城市的花費,根據sort元素存儲的在costs數組中的下標位置從costs數組中獲取去B城市的花費;
iii.min累加全部總花費;
複製代碼
public int twoCitySchedCost(int[][] costs) {
int sort[] = new int[costs.length];
for (int i = 0; i < costs.length; ++i) {
sort[i] = ((costs[i][1] - costs[i][0]) << 8) + i;
}
Arrays.sort(sort);
int min = 0;
for (int i = 0; i < sort.length / 2; ++i) {
int index1 = sort[costs.length - 1 - i] & 0xFF;
int index2 = sort[i] & 0xFF;
min = min + costs[index1][0] + costs[index2][1];
}
return min;
}
複製代碼
觀察上面實現代碼會發如今sort數組中存儲前往B和A城市int差價和在costs數組中下標位置時,使用了左移8位再加i的操做,這即是本文的彩蛋,全部彩蛋均會在後續推文中統一說明。
本文重點在與列舉1029實例展現對貪心思想的理解,思路相對簡單易於理解,而且從提交結果能夠看出貪心思想算法的實踐代碼效率已經擊敗了99%的算法,故對另外解法窮舉法便不作詳細說明,讀者能夠考慮本身使用窮舉法進行實現。關於leetcode進階系列博客,後續也會疏理出一篇比較系統的進階大綱,敬請期待^_^