|
| 1 | +from typing import List, Union, Collection, Mapping, Optional |
| 2 | +from abc import ABC, abstractmethod |
| 3 | + |
| 4 | +class Solution: |
| 5 | + def candy(self, ratings: List[int]) -> int: |
| 6 | + """ |
| 7 | + Distribute candies to children based on ratings. |
| 8 | + |
| 9 | + Rules: |
| 10 | + 1. Each child gets at least 1 candy |
| 11 | + 2. Children with higher rating than neighbors get more candies |
| 12 | + |
| 13 | + Strategy: Two-pass greedy |
| 14 | + - Left-to-right: Ensure each child has more candies than left neighbor if rating is higher |
| 15 | + - Right-to-left: Ensure each child has more candies than right neighbor if rating is higher |
| 16 | + - Take maximum from both passes to satisfy both neighbors |
| 17 | + |
| 18 | + Time: O(n), Space: O(n) |
| 19 | + """ |
| 20 | + |
| 21 | + n = len(ratings) |
| 22 | + if n == 0: |
| 23 | + return 0 |
| 24 | + |
| 25 | + # Initialize all children with 1 candy |
| 26 | + candies = [1] * n |
| 27 | + |
| 28 | + # Left-to-right pass: Compare with left neighbor |
| 29 | + # If current child has higher rating than left neighbor, |
| 30 | + # give them one more candy than left neighbor |
| 31 | + for i in range(1, n): |
| 32 | + if ratings[i] > ratings[i - 1]: |
| 33 | + candies[i] = candies[i - 1] + 1 |
| 34 | + |
| 35 | + # Right-to-left pass: Compare with right neighbor |
| 36 | + # If current child has higher rating than right neighbor, |
| 37 | + # ensure they have more candies (take max of current and right+1) |
| 38 | + for i in range(n - 2, -1, -1): |
| 39 | + if ratings[i] > ratings[i + 1]: |
| 40 | + candies[i] = max(candies[i], candies[i + 1] + 1) |
| 41 | + |
| 42 | + # Return total candies needed |
| 43 | + return sum(candies) |
| 44 | + |
| 45 | + |
| 46 | +""" |
| 47 | +Example walkthrough for ratings = [1, 0, 2]: |
| 48 | +
|
| 49 | +Initial: candies = [1, 1, 1] |
| 50 | +
|
| 51 | +Left-to-right pass: |
| 52 | +i=1: ratings[1]=0 < ratings[0]=1 → no change → candies = [1, 1, 1] |
| 53 | +i=2: ratings[2]=2 > ratings[1]=0 → candies[2] = candies[1] + 1 = 2 → candies = [1, 1, 2] |
| 54 | +
|
| 55 | +Right-to-left pass: |
| 56 | +i=1: ratings[1]=0 < ratings[2]=2 → no change → candies = [1, 1, 2] |
| 57 | +i=0: ratings[0]=1 > ratings[1]=0 → candies[0] = max(1, 1+1) = 2 → candies = [2, 1, 2] |
| 58 | +
|
| 59 | +Total: 2 + 1 + 2 = 5 |
| 60 | +
|
| 61 | +
|
| 62 | +Example walkthrough for ratings = [1, 2, 2]: |
| 63 | +
|
| 64 | +Initial: candies = [1, 1, 1] |
| 65 | +
|
| 66 | +Left-to-right pass: |
| 67 | +i=1: ratings[1]=2 > ratings[0]=1 → candies[1] = 1 + 1 = 2 → candies = [1, 2, 1] |
| 68 | +i=2: ratings[2]=2 = ratings[1]=2 → no change → candies = [1, 2, 1] |
| 69 | +
|
| 70 | +Right-to-left pass: |
| 71 | +i=1: ratings[1]=2 = ratings[2]=2 → no change → candies = [1, 2, 1] |
| 72 | +i=0: ratings[0]=1 < ratings[1]=2 → no change → candies = [1, 2, 1] |
| 73 | +
|
| 74 | +Total: 1 + 2 + 1 = 4 |
| 75 | +
|
| 76 | +
|
| 77 | +Example walkthrough for ratings = [1, 3, 2, 2, 1]: |
| 78 | +
|
| 79 | +Initial: candies = [1, 1, 1, 1, 1] |
| 80 | +
|
| 81 | +Left-to-right: |
| 82 | +i=1: 3 > 1 → candies[1] = 2 → [1, 2, 1, 1, 1] |
| 83 | +i=2: 2 < 3 → no change → [1, 2, 1, 1, 1] |
| 84 | +i=3: 2 = 2 → no change → [1, 2, 1, 1, 1] |
| 85 | +i=4: 1 < 2 → no change → [1, 2, 1, 1, 1] |
| 86 | +
|
| 87 | +Right-to-left: |
| 88 | +i=3: 2 > 1 → candies[3] = max(1, 2) = 2 → [1, 2, 1, 2, 1] |
| 89 | +i=2: 2 = 2 → no change → [1, 2, 1, 2, 1] |
| 90 | +i=1: 3 > 2 → candies[1] = max(2, 2) = 2 → [1, 2, 1, 2, 1] |
| 91 | +i=0: 1 < 3 → no change → [1, 2, 1, 2, 1] |
| 92 | +
|
| 93 | +Total: 1 + 2 + 1 + 2 + 1 = 7 |
| 94 | +""" |
0 commit comments