其他題目 分糖果問題

2021-08-10 05:30:26 字數 3469 閱讀 9894

【題目】

一群孩子做遊戲,現在請你根據遊戲得分來發糖果,要求如下:

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塊。然後所有的小孩同時將手中的糖分一半給右邊的小孩 糖塊數為奇數的人可向老師要一塊。問經過幾次後大...