【題目】
一群孩子做遊戲,現在請你根據遊戲得分來發糖果,要求如下:
1、每個孩子不管得分多少,起碼分到1個糖果
2、任意兩個相鄰的孩子之間,得分較多的孩子必須多拿一些糖果
給定乙個陣列arr代表得分陣列,請返回最少需要多少糖果。
例如:arr = [1,2,2],糖果分配[1,2,1],即可滿足要求且數量最少,所以返回4.
【高階題目】
原題目中的兩個規則不變,再加一條規則:
3、任意兩個相鄰的孩子之間如果得分相同,糖果數必須相同
給定乙個陣列arr代表得分陣列,返回最少需要多少糖果。
例如:arr = [1,2,2],糖果分配[1,2,2],即可滿足要求且數量最少,所以返回5.
【要求】
原文題和高階問題的時間複雜度都為o(n),空間複雜度o(1)。
【基本思路】
原問題。首先引入左坡和右坡的概念,從左到右依次遍歷陣列,值遞增的部分為左坡,遞減的部分為右坡。定義了左坡和右坡後,整個陣列就可以分解成很多對左坡和右坡,挨個計算每對左坡和右坡即可。
假設陣列為[1,4,5,9,3,2],左坡和右坡分別是[1,4,5,9],[9,3,2]。對左坡來說,從左到右糖果的分配為[1,2,3,4],對右坡來說,糖果的分配為[3,2,1],但是兩種分配方式對9這個坡頂的分配是不同的,如何決定?哪個坡更高,就按哪個坡來分配。因為左坡和右坡都是嚴格的遞增和遞減,不存在相同的數值,所以,坡的高度就是各自序列的長度。很明顯左坡的高度大於右坡的高度(4 > 3)。所以坡頂的分配按照左坡來,最終的分配為[1,2,3,4,2,1]。
#python3.5
defcandy1
(arr):
defnextminindex
(arr, start):
for i in range(start, len(arr)-1):
if arr[i+1] >= arr[i]:
return i
return len(arr) - 1
defrightcands
(left, right):
n = right - left + 1
return n * (n+1) // 2
if arr == none
or len(arr) == 0:
return
0 index = nextminindex(arr, 0)
res = rightcands(0, index)
index += 1
lbase = 1
while index != len(arr):
if arr[index] > arr[index-1]:
lbase += 1
res += lbase
index += 1
elif arr[index] < arr[index-1]:
next = nextminindex(arr, index-1)
res += rightcands(index-1, next)
rbase = next - index + 2
res -= rbase if rbase < lbase else lbase
lbase = 1
index = next + 1
else:
res += 1
lbase = 1
index += 1
return res
高階問題。針對新規則,需要對左坡和右坡重新定義。從左到右依次遍歷陣列,值不遞減的部分為左坡,不遞增的部分為右坡。比如,[1,2,2,1],左坡為[1,2,2],右坡為[2,1]。
假設陣列為[0,1,2,3,3,3,2,2,2,2,2,1,1],左坡和右坡,分別是[0,1,2,3,3,3],[3,2,2,2,2,2,1,1]。對左坡來說,從左到右糖果的分配為[1,2,3,4,4,4],對右坡來說,糖果的分配為[3,2,2,2,2,2,1],但是兩種分配方式對[3,3,3]這三個坡頂的分配還是不同的,如何決定?還是根據坡的高度,哪個坡更高,就按哪個坡來分配,因為左坡和右坡不是嚴格的遞增和遞減,可能存在相同的數值,所以,坡的高度不能再通過序列長度來計算(具體做法見如下**) 。很明顯左坡的高度大於右坡的高度(4 > 3)。所以坡頂的分配按照左坡來,最終的分配為[1,2,3,4,4,4,2,2,2,2,2,1,1]。
def
candy2
(arr):
defnextminindex
(arr, start):
for i in range(start, len(arr)-1):
if arr[i] < arr[i+1]:
return i
return len(arr) - 1
defrightcandsandbase
(arr, left, right):
res = 1
base = 1
for i in range(right-1, left-1, -1):
if arr[i] == arr[i+1]:
res += base
else:
base += 1
res += base
return res, base
if arr == none
or len(arr) == 0:
return
0 index = nextminindex(arr, 0)
res, s = rightcandsandbase(arr, 0, index)
index += 1
lbase = 1
same = 1
while index != len(arr):
if arr[index] > arr[index-1]:
lbase += 1
res += lbase
index += 1
elif arr[index] == arr[index-1]:
res += lbase
same += 1
index += 1
else:
next = nextminindex(arr, index-1)
num, rbase = rightcandsandbase(arr, index-1, next)
if rbase < lbase:
res += num - rbase
else:
res += num - rbase + rbase * same - same * lbase
index = next + 1
same = 1
lbase = 1
return res
題目 分糖果
有n個小朋友圍坐成一圈。老師給每個小朋友隨機發偶數個糖果,然後進行下面的遊戲 每個小朋友都把自己的糖果分一半給左手邊的孩子。一輪分糖後,擁有奇數顆糖的孩子由老師補給1個糖果,從而變成偶數。反覆進行這個遊戲,直到所有小朋友的糖果數都相同為止。你的任務是 在已知的初始糖果情形下,老師一共需要補發多少個糖...
分糖果問題
問題描述 有不同分數的小孩排隊,怎麼分糖果使得糖果數最小,且分數高的小孩分到盡可能多的糖果。分析 每個小孩至少可分到乙個糖果,且分數不固定,所以分數高的小孩要盡可能的只比旁邊的兩個人分的糖果多,而分數低的要盡可能的少。解題思路 分別從前後進行掃瞄,讓每個小孩都能分到糖果,保證分數高的盡可能多於兩邊的...
分糖果問題(java)
10個小孩圍成一圈分糖果,老師分給第乙個小孩10塊,第二個小孩2塊,第三個小孩8塊,第四個小孩22塊,第五個小孩16塊,第六個小孩4塊,第七個小孩10塊,第八個小孩6塊,第九個小孩14塊,第十個小孩20塊。然後所有的小孩同時將手中的糖分一半給右邊的小孩 糖塊數為奇數的人可向老師要一塊。問經過幾次後大...