leetcode 135. Candy 分糖果 + 很經典的貪心演算法
阿新 • • 發佈:2019-02-13
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?
典型的貪心演算法題本身可以用貪心法來做,我們用candy[n]表示每個孩子的糖果數,遍歷過程中,如果孩子i+1的rate大於孩子i 的rate,那麼當前最好的選擇自然是:給孩子i+1的糖果數=給孩子i的糖果數+1如果孩子i+1的rate小於等於孩子i 的rate咋整?這個時候就不大好辦了,因為我們不知道當前最好的選擇是給孩子i+1多少糖果。
程式碼如下:
import java.util.Arrays;
/*
* 典型的貪心演算法
* 題本身可以用貪心法來做,我們用candy[n]表示每個孩子的糖果數,遍歷過程中,
* 如果孩子i+1的rate大於孩子i 的rate,那麼當前最好的選擇自然是:給孩子i+1的糖果數=給孩子i的糖果數+1
* 如果孩子i+1的rate小於等於孩子i 的rate咋整?這個時候就不大好辦了,
* 因為我們不知道當前最好的選擇是給孩子i+1多少糖果。
* 解決方法是:暫時不處理這種情況。等陣列遍歷完了,我們再一次從尾到頭遍歷陣列,
* 這回逆過來貪心,就可以處理之前略過的孩子。
* 最後累加candy[n]即得到最小糖果數。
* */
public class Solution
{
public int candy(int[] ratings)
{
if(ratings==null || ratings.length<=0)
return 0;
int []num = new int[ratings.length];
Arrays.fill(num, 1);
for(int i=1;i<ratings.length;i++)
{
if(ratings[i]>ratings[i-1 ])
num[i]=num[i-1]+1;
}
for(int i=ratings.length-2;i>=0;i--)
{
if(ratings[i]>ratings[i+1] && num[i] < num[i+1]+1)
num[i]=num[i+1]+1;
}
int sum=0;
for(int i=0;i<num.length;i++)
sum+=num[i];
return sum;
}
}
下面是C++的做法,這道題是的典型的貪心演算法的一個簡單應用,需要好好學習
注意反向遍歷的時候注意dp的比較
程式碼如下:
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
using namespace std;
class Solution
{
public:
int candy(vector<int>& r)
{
int n = r.size();
vector<int> dp(n, 1);
for (int i = 1; i < n; i++)
{
if (r[i] > r[i - 1])
dp[i] = dp[i - 1] + 1;
}
for (int i = n - 2; i >= 0; i--)
{
if (r[i] > r[i + 1] && dp[i] < dp[i + 1]+1)
dp[i] = dp[i + 1] + 1;
}
return accumulate(dp.begin(), dp.end(), 0);
}
};