Problem link:
http://oj.leetcode.com/problems/candy/
Suppose we are given an array R[1..N] that are ratings of N children.
Let C[1..N] be a new array where C[i] is the number of candies for i-th child.
From the description, C[i] should meet following requirements:
LEAST. C[i] is at least 1, for i = 1, ..., N
LEFT. C[i] > C[i-1] if R[i] > R[i-1], for i = 2, ..., N
RIGHT. C[i] > C[i+1] if R[i] > R[i+1], for i = 1, ..., N-1
Each C[i] should satisfy these three requirements, excpet that C[1] only needs to meet LEAST and RIGHT and C[N] only needs to meet LEAST and LEFT.
To get the minimum number of candies, we desgin the following algorithm:
- Initialize the array C[1..N] with value of 1
- Scan the array R from left to right, and update C[] to meet LEFT. That is, for each i = 2 to N,
- if R[i] > R[i-1], then C[i] = C[i+1]
- else, keep C[i] = 1
- Now, C[] satisfies LEAST and LEFT. Then scan the array R from right to left, update C[] not only meeting RIGHT but also keeping LEFT satisfied. That is, for each i = N-1 to 1,
- if R[i] > R[i+1], then C[i] = max(C[i], C[i+1]+1)
- else, keep C[i] unchanged
The algorithm computes C[] satisfying LEAST, LEFT, and RIGHT requirements. Since each time we increment C[i] by 1 to meet LEFT or RIGHT, so the total sum of C[] should be minimum (not sure how to prove the correctness, maybe a contradiction method needed). The algorithm can be finished in O(n) time. And the following code is the python solution accepted by oj.leetcode.com.
class Solution:
# @param ratings, a list of integer
# @return an integer
def candy(self, ratings):
# Specail cases
n = len(ratings)
if n < 2:
return n
# First scan, from left to right
# only consider the following LEFT conditions:
# if one's rating is higher than his left neighbor,
# then he should have more candies than his left neighbor
c = [0] * n
c[0] = 1
for p in xrange(1,n):
if ratings[p] > ratings[p-1]:
c[p] = c[p-1] + 1
else:
c[p] = 1
# Second scan, from right to left
# consider both RIGHT and LEFT conditions:
# if c[p]'s rating is higher than his right neighbor,
# then c[p] = max(c[p], c[p+1]+1), otherwise keep c[p] unchagned
for p in xrange(n-2, -1, -1):
if ratings[p] > ratings[p+1]:
c[p] = max(c[p], c[p+1]+1)
# Return the sum
return sum(c)
浙公网安备 33010602011771号