資料結構與演算法 貪心思想經典題總結

2022-07-24 11:42:08 字數 3893 閱讀 2228

leetcode:分發餅乾

題目描述:

假設你是一位很棒的家長,想要給你的孩子們一些小餅乾。但是,每個孩子最多只能給一塊餅乾。對每個孩子 i ,都有乙個胃口值 gi ,這是能讓孩子們滿足胃口的餅乾的最小尺寸;並且每塊餅乾 j ,都有乙個尺寸 sj 。如果 sj >= gi ,我們可以將這個餅乾 j 分配給孩子 i ,這個孩子會得到滿足。你的目標是盡可能滿足越多數量的孩子,並輸出這個最大數值。

注意

你可以假設胃口值為正。

乙個小朋友最多只能擁有一塊餅乾。

示例:

輸入: [1,2,3], [1,1]

輸出: 1

解釋:

你有三個孩子和兩塊小餅乾,3個孩子的胃口值分別是:1,2,3。

雖然你有兩塊小餅乾,由於他們的尺寸都是1,你只能讓胃口值是1的孩子滿足。

所以你應該輸出1。

思想:

經典的貪心思想。

對兩個陣列排序,按順序分配。若小胃口的孩子都滿足不了,則該餅乾拋棄,不可能滿足胃口更大孩子了。

**

class solution 

return i;

}}

題目描述:

給定乙個區間的集合,找到需要移除區間的最小數量,使剩餘區間互不重疊。

注意:可以認為區間的終點總是大於它的起點。

區間 [1,2] 和 [2,3] 的邊界相互「接觸」,但沒有相互重疊。

示例:

輸入: [ [1,2], [2,3], [3,4], [1,3] ]

輸出: 1

解釋: 移除 [1,3] 後,剩下的區間沒有重疊。

思想:

首先對每個區間排序(按照右邊界排序)。假設a區間與b區間相鄰(b在a右邊),若a與b重疊,兩者至少要移除乙個才能滿足要求,這時一定是移除b區間,因為a與b相比,b對後續區間可能的影響更大。

**

class solution 

});int preend=intervals[0][1],res=0;

for(int i=0;ileetcode:用最少數量的箭引爆氣球

題目描述:

在二維空間中有許多球形的氣球。對於每個氣球,提供的輸入是水平方向上,氣球直徑的開始和結束座標。由於它是水平的,所以y座標並不重要,因此只要知道開始和結束的x座標就足夠了。開始座標總是小於結束座標。平面內最多存在104個氣球。

一支弓箭可以沿著x軸從不同點完全垂直地射出。在座標x處射出一支箭,若有乙個氣球的直徑的開始和結束座標為 xstart,xend, 且滿足  xstart ≤ x ≤ xend,則該氣球會被引爆。可以射出的弓箭的數量沒有限制。 弓箭一旦被射出之後,可以無限地前進。我們想找到使得所有氣球全部被引爆,所需的弓箭的最小數量。

示例:輸入:

[[10,16], [2,8], [1,6], [7,12]]

輸出:2

解釋:對於該樣例,我們可以在x = 6(射爆[2,8],[1,6]兩個氣球)和 x = 11(射爆另外兩個氣球)。

思想:

首先這題拿來可以想到,大致做法是,先排序,再遍歷一遍得到結果。

排序有兩種排序方式,按右邊界排序,還是左邊界排序?假設排序後a區間和b區間相鄰。如果按照右邊界,a_right只與b_left的大小關係不清晰;如果按照左邊界排序,a_right與b_left、b_right關係都不清晰。明顯是第一種更好,只需要判斷一次。通過判斷決定a和b是分別射穿,還是一起射穿。這樣,思路就出來了。

**

class solution 

});int res=1,edge=points[0][1];

for(int i=1;iedge)

}return res;

}}

leetcode:根據身高重建佇列

題目描述:

假設有打亂順序的一群人站成乙個佇列。 每個人由乙個整數對(h, k)表示,其中h是這個人的身高,k是排在這個人前面且身高大於或等於h的人數。 編寫乙個演算法來重建這個佇列。

注意:總人數少於1100人。

示例:

輸入:

[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]

輸出:[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

思想:

貪心演算法很重要乙個特性:無後效性,即某個狀態以後的過程不會影響以前的狀態,只與當前狀態有關。

於是可以想到,先按身高由高到低排序,再依次插入list中,剛好滿足貪心的無後效性。每一次插入時,item[1]值剛好是插入序號,這個位置是對當前人來說,最優的決策,即區域性最優。然後可以導致全域性最優。

**

class solution 

});listres = new linkedlist<>();

for(int item : people)

return res.toarray(people);

}}

leetcode:買賣**的最佳時機2

題目描述:

給定乙個陣列,它的第 i 個元素是一支給定**第 i 天的**。

設計乙個演算法來計算你所能獲取的最大利潤。你可以盡可能地完成更多的交易(多次買賣一支**)。

注意:你不能同時參與多筆交易(你必須在再次購買前**掉之前的**)。

示例:

輸入: [7,1,5,3,6,4]

輸出: 7

解釋: 在第 2 天(**** = 1)的時候**,在第 3 天(**** = 5)的時候賣出, 這筆交易所能獲得利潤 = 5-1 = 4 。

隨後,在第 4 天(**** = 3)的時候**,在第 5 天(**** = 6)的時候賣出, 這筆交易所能獲得利潤 = 6-3 = 3 。

思想:

買賣**的最佳時機是使用dp思想,而本題是公升級版,使用貪心思想。

首先要抓住本題特點:每一天都進行買賣不影響結果,即d - a = (d - c) + (c - b) + (b - a)

然後,每一天都進行最大經濟效益的買賣,即將前一天的賣出再立即**今天的(收益為當天與前一天的差價),或者前一天不買今天才來**(今天收益0)。這樣每一天的最大收益加起來就是總收益。典型的區域性最優累加得到全域性最優。

**

class solution else

nums[i-1] = nums[i];

}return cnt<2;

}}

leetcode:劃分字母區間

題目描述:

字串 s 由小寫字母組成。我們要把這個字串劃分為盡可能多的片段,同乙個字母只會出現在其中的乙個片段。返回乙個表示每個字串片段的長度的列表。

注意:s的長度在[1, 500]之間。

s只包含小寫字母'a'到'z'。

示例:

輸入: s = "ababcbacadefegdehijhklij"

輸出: [9,7,8]

解釋:劃分結果為 "ababcbaca", "defegde", "hijhklij"。

每個字母最多出現在乙個片段中。

像 "ababcbacadefegde", "hijhklij" 的劃分是錯誤的,因為劃分的片段數較少。

思想:

沒感覺這題有什麼貪心思想。網上說,針對每乙個區間,lastindex能更新就更新,這屬於貪心思想。感覺有點牽強。

**

class solution 

return target*res;

}

方法二:

public int cutrope(int target) 

}return dp[target];

}

資料結構與演算法 演算法思想 貪心演算法

貪心演算法 回溯演算法 分治演算法 動態規劃 四種基本的演算法思想 貪心演算法,分治演算法,回溯演算法,動態規劃,他們不是具體演算法,常用來指導我們設計具體的演算法和編碼等。霍夫曼編碼 huffman coding prim和kruskal最小生成數演算法,dijkstra單源最短路徑演算法。假設我...

資料結構與演算法 排序經典題總結

leetcode 陣列中的第k個最大元素 題目描述 在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。示例 輸入 3,2,3,1,2,4,5,5,6 和 k 4 輸出 4思想 方法一 優先佇列 可直接使用priorityque...

資料結構與演算法 總入口

土地開墾中。我的個人blog 線性結構 排序演算法 樹結構1 樹結構2 雜湊表圖結構 陣列篇氣泡排序 二叉樹建立與遍歷 樹的插入原理 雜湊函式設計 樹的遍歷 佇列與棧 快速排序 二叉樹節點查詢與刪除節點樹 b樹和b 樹原理 雜湊衝突 鍊錶篇插入排序 順序儲存的二叉樹遍歷 查詢演算法 希爾排序 線索二...