C++實(shí)現(xiàn)LeetCode(135.分糖果問題)
[LeetCode] 135.Candy 分糖果問題
There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
- Each child must have at least one candy.
- Children with a higher rating get more candies than their neighbors.
What is the minimum candies you must give?
這道題看起來很難,其實(shí)解法并沒有那么復(fù)雜,當(dāng)然我也是看了別人的解法才做出來的,先來看看兩遍遍歷的解法,首先初始化每個(gè)人一個(gè)糖果,然后這個(gè)算法需要遍歷兩遍,第一遍從左向右遍歷,如果右邊的小盆友的等級(jí)高,等加一個(gè)糖果,這樣保證了一個(gè)方向上高等級(jí)的糖果多。然后再從右向左遍歷一遍,如果相鄰兩個(gè)左邊的等級(jí)高,而左邊的糖果又少的話,則左邊糖果數(shù)為右邊糖果數(shù)加一。最后再把所有小盆友的糖果數(shù)都加起來返回即可。代碼如下:
解法一:
class Solution {
public:
int candy(vector<int>& ratings) {
int res = 0, n = ratings.size();
vector<int> nums(n, 1);
for (int i = 0; i < n - 1; ++i) {
if (ratings[i + 1] > ratings[i]) nums[i + 1] = nums[i] + 1;
}
for (int i = n - 1; i > 0; --i) {
if (ratings[i - 1] > ratings[i]) nums[i - 1] = max(nums[i - 1], nums[i] + 1);
}
for (int num : nums) res += num;
return res;
}
};
下面來看一次遍歷的方法,相比于遍歷兩次的思路簡單明了,這種只遍歷一次的解法就稍有些復(fù)雜了。首先我們給第一個(gè)同學(xué)一個(gè)糖果,那么對(duì)于接下來的一個(gè)同學(xué)就有三種情況:
1. 接下來的同學(xué)的rating等于前一個(gè)同學(xué),那么給接下來的同學(xué)一個(gè)糖果就行。
2. 接下來的同學(xué)的rating大于前一個(gè)同學(xué),那么給接下來的同學(xué)的糖果數(shù)要比前一個(gè)同學(xué)糖果數(shù)加1。
3.接下來的同學(xué)的rating小于前一個(gè)同學(xué),那么我們此時(shí)不知道應(yīng)該給這個(gè)同學(xué)多少個(gè)糖果,需要看后面的情況。
對(duì)于第三種情況,我們不確定要給幾個(gè),因?yàn)橐侵唤o1個(gè)的話,那么有可能接下來還有rating更小的同學(xué),總不能一個(gè)都不給吧。也不能直接給前一個(gè)同學(xué)的糖果數(shù)減1,有可能給多了,因?yàn)槿绻竺嬖贈(zèng)]人了的話,其實(shí)只要給一個(gè)就行了。還有就是,如果后面好幾個(gè)rating越來越小的同學(xué),那么前一個(gè)同學(xué)的糖果數(shù)可能還得追加,以保證最后面的同學(xué)至少能有1個(gè)糖果。來一個(gè)例子吧,四個(gè)同學(xué),他們的rating如下:
1 3 2 1
先給第一個(gè)rating為1的同學(xué)一個(gè)糖果,然后從第二個(gè)同學(xué)開始遍歷,第二個(gè)同學(xué)rating為3,比1大,所以多給一個(gè)糖果,第二個(gè)同學(xué)得到兩個(gè)糖果。下面第三個(gè)同學(xué),他的rating為2,比前一個(gè)同學(xué)的rating小,如果我們此時(shí)給1個(gè)糖果的話,那么rating更小的第四個(gè)同學(xué)就得不到糖果了,所以我們要給第四個(gè)同學(xué)1個(gè)糖果,而給第三個(gè)同學(xué)2個(gè)糖果,此時(shí)要給第二個(gè)同學(xué)追加1個(gè)糖果,使其能夠比第三個(gè)同學(xué)的糖果數(shù)多至少一個(gè)。那么我們就需要統(tǒng)計(jì)出多有個(gè)連著的同學(xué)的rating變小,用變量cnt來記錄,找出了最后一個(gè)減小的同學(xué),那么就可以往前推,每往前一個(gè)加一個(gè)糖果,這就是個(gè)等差數(shù)列,我們可以直接利用求和公式算出這些rating減小的同學(xué)的糖果之和。然后我們還要看第一個(gè)開始減小的同學(xué)的前一個(gè)同學(xué)需不需要追加糖果,只要比較cnt和pre的大小,pre是之前同學(xué)得到的最大糖果數(shù),二者做差加1就是需要追加的糖果數(shù),加到結(jié)果res中即可,參見代碼如下:
解法二:
class Solution {
public:
int candy(vector<int>& ratings) {
if (ratings.empty()) return 0;
int res = 1, pre = 1, cnt = 0;
for (int i = 1; i < ratings.size(); ++i) {
if (ratings[i] >= ratings[i - 1]) {
if (cnt > 0) {
res += cnt * (cnt + 1) / 2;
if (cnt >= pre) res += cnt - pre + 1;
cnt = 0;
pre = 1;
}
pre = (ratings[i] == ratings[i - 1]) ? 1 : pre + 1;
res += pre;
} else {
++cnt;
}
}
if (cnt > 0) {
res += cnt * (cnt + 1) / 2;
if (cnt >= pre) res += cnt - pre + 1;
}
return res;
}
};
參考資料:
https://discuss.leetcode.com/topic/5243/a-simple-solution
https://discuss.leetcode.com/topic/8208/one-pass-constant-space-java-solution
到此這篇關(guān)于C++實(shí)現(xiàn)LeetCode(135.分糖果問題)的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)分糖果問題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++實(shí)現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞)
- C++實(shí)現(xiàn)LeetCode(150.計(jì)算逆波蘭表達(dá)式)
- C++實(shí)現(xiàn)LeetCode(149.共線點(diǎn)個(gè)數(shù))
- C++實(shí)現(xiàn)LeetCode(148.鏈表排序)
- C++實(shí)現(xiàn)LeetCode(147.鏈表插入排序)
- C++實(shí)現(xiàn)LeetCode(146.近最少使用頁面置換緩存器)
- C++實(shí)現(xiàn)LeetCode(140.拆分詞句之二)
- C++實(shí)現(xiàn)LeetCode(152.求最大子數(shù)組乘積)
相關(guān)文章
基于C中一個(gè)行壓縮圖的簡單實(shí)現(xiàn)代碼
首先簡單說一下什么是行壓縮圖,其實(shí)嚴(yán)格意義上應(yīng)該是行壓縮矩陣2013-05-05
C++?Opencv實(shí)現(xiàn)錄制九宮格視頻
這篇文章主要為大家介紹了如何利用C++和OpenCV庫實(shí)現(xiàn)錄制九宮格視頻,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定幫助,感興趣的可以了解一下2022-05-05
openCV中meanshift算法查找目標(biāo)的實(shí)現(xiàn)
本文主要介紹了openCV中meanshift算法查找目標(biāo)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
c++ std::sort使用自定義的比較函數(shù)排序方式
文章介紹了使用std::sort對(duì)容器內(nèi)元素進(jìn)行排序的基本方法,包括自定義排序函數(shù)和在類中調(diào)用自定義成員函數(shù)進(jìn)行排序的方法,文章還指出了在傳遞成員函數(shù)指針時(shí)可能會(huì)遇到的錯(cuò)誤,并提供了使用Lambda表達(dá)式的解決辦法2025-02-02
c++ 數(shù)據(jù)結(jié)構(gòu)map的使用詳解
這篇文章主要介紹了c++ 數(shù)據(jù)結(jié)構(gòu)map的使用詳解,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下2021-04-04
C語言數(shù)據(jù)結(jié)構(gòu)之順序表和單鏈表
在數(shù)據(jù)結(jié)構(gòu)中,線性表是入門級(jí)數(shù)據(jù)結(jié)構(gòu),線性表又分為順序表和鏈表,這篇文章主要給大家介紹了關(guān)于C語言數(shù)據(jù)結(jié)構(gòu)之順序表和單鏈表的相關(guān)資料,需要的朋友可以參考下2021-06-06

