LeetCode Summary
  • Introduction
  • DP, 动态规划类
    • Best Time to Buy and Sell Stock III 题解
    • Best Time to Buy and Sell Stock 题解
    • Climbing Stairs 题解
    • Decode Ways 题解
    • Distinct Subsequences 题解
    • Edit Distance 题解
    • Interleaving String 题解
    • Longest Palindromic Substring 题解
    • Maximum Product Subarray 题解
    • Maximum Subarray 题解
    • Minimum Path Sum 题解
    • Palindrome Partitioning 题解
    • Palindrome Partitioning II 题解
    • Scramble String 题解
    • Triangle 题解
    • Unique Binary Search Trees 题解
    • Unique Paths II 题解
    • Word Break 题解
    • Word Break II 题解
  • list, 链表相关
    • Add Two Numbers 题解
    • Convert Sorted List to Binary Search Tree 题解
    • Copy List with Random Pointer 题解
    • Insertion Sort List 题解
    • LRU Cache 题解
    • Linked List Cycle 题解
    • Linked List Cycle II 题解
    • Merge Two Sorted Lists 题解
    • Merge k Sorted Lists 题解
    • Partition List 题解
    • Remove Duplicates from Sorted List 题解
    • Remove Duplicates from Sorted List II 题解
    • Remove Nth Node From End of List 题解
    • Reorder List 题解
    • Reverse Linked List II 题解
    • Reverse Nodes in k-Group 题解
    • Rotate List 题解
    • Sort List 题解
    • Swap Nodes in Pairs 题解
  • binary tree, 二叉树相关
    • Balanced Binary Tree 题解
    • Binary Tree Inorder Traversal 题解
    • Binary Tree Level Order Traversal 题解
    • Binary Tree Level Order Traversal II 题解
    • Binary Tree Maximum Path Sum 题解
    • Binary Tree Postorder Traversal 题解
    • Binary Tree Preorder Traversal 题解
    • Binary Tree Zigzag Level Order Traversal 题解
    • Construct Binary Tree from Inorder and Postorder Traversal 题解
    • Construct Binary Tree from Preorder and Inorder Traversal 题解
    • Convert Sorted List to Binary Search Tree 题解
    • Flatten Binary Tree to Linked List 题解
    • Maximum Depth of Binary Tree 题解
    • Minimum Depth of Binary Tree 题解
    • Path Sum 题解
    • Path Sum II 题解
    • Populating Next Right Pointers in Each Node 题解
    • Populating Next Right Pointers in Each Node II 题解
    • Recover Binary Search Tree 题解
    • Same Tree 题解
    • Sum Root to Leaf Numbers 题解
    • Symmetric Tree 题解
    • Unique Binary Search Trees 题解
    • Unique Binary Search Trees II 题解
    • Validate Binary Search Tree 题解
  • sort, 排序相关
    • 3Sum Closest 题解
    • 3Sum 题解
    • 4Sum 题解
    • Insert Interval 题解
    • Longest Consecutive Sequence 题解
    • Merge Intervals 题解
    • Merge Sorted Array 题解
    • Remove Duplicates from Sorted Array 题解
    • Remove Duplicates from Sorted Array II 题解
    • Sort Colors 题解
    • Two Sum 题解
  • search, 搜索相关
    • First Missing Positive 题解
    • Find Minimum in Rotated Sorted Array 题解
    • Find Minimum in Rotated Sorted Array II 题解
    • Median of Two Sorted Arrays 题解
    • Search Insert Position 题解
    • Search a 2D Matrix 题解
    • Search for a Range 题解
    • Search in Rotated Sorted Array 题解
    • Search in Rotated Sorted Array II 题解
    • Single Number 题解
    • Single Number II 题解
  • math, 数学类相关
    • Add Binary 题解
    • Add Two Numbers 题解
    • Divide Two Integers 题解
    • Gray Code 题解
    • Integer to Roman 题解
    • Multiply Strings 题解
    • Palindrome Number 题解
    • Plus One 题解
    • [Pow(x, n) 题解](math/Pow(x,-n).md)
    • Reverse Integer 题解
    • Roman to Integer 题解
    • [Sqrt(x) 题解](math/Sqrt(x).md)
    • [String to Integer (atoi) 题解](math/String-to-Integer-(atoi).md)
    • Valid Number 题解
  • string, 字符串处理相关
    • Anagrams 题解
    • Count and Say 题解
    • Evaluate Reverse Polish Notation 题解
    • [Implement strStr() 题解](string/Implement-strStr().md)
    • Length of Last Word 题解
    • Longest Common Prefix 题解
    • Longest Palindromic Substring 题解
    • Longest Substring Without Repeating Characters 题解
    • Longest Valid Parentheses 题解
    • Minimum Window Substring 题解
    • Regular Expression Matching 题解
    • Reverse Words in a String 题解
    • Simplify Path 题解
    • Text Justification 题解
    • Valid Parentheses 题解
    • Wildcard Matching 题解
    • ZigZag Conversion 题解
  • combination and permutation, 排列组合相关
    • Combinations 题解
    • Combination Sum 题解
    • Combination Sum II 题解
    • Letter Combinations of a Phone Number 题解
    • Next Permutation 题解
    • Palindrome Partitioning 题解
    • Permutation Sequence 题解
    • Permutations 题解
    • Permutations II 题解
    • Subsets 题解
    • Subsets II 题解
    • Unique Paths 题解
  • matrix, 二维数组, 矩阵相关
    • Rotate Image 题解
    • Set Matrix Zeroes 题解
    • Spiral Matrix 题解
    • Spiral Matrix II 题解
    • Maximal Rectangle 题解
  • 回溯, BFS/DFS
    • Clone Graph 题解
    • Generate Parentheses 题解
    • N-Queens 题解
    • N-Queens II 题解
    • Restore IP Addresses 题解
    • Sudoku Solver 题解
    • Surrounded Regions 题解
    • Word Ladder 题解
    • Word Ladder II 题解
    • Word Search 题解
  • greedy, 贪心
    • Best Time to Buy and Sell Stock II 题解
    • Jump Game 题解
    • Jump Game II 题解
  • 其他
    • Candy 题解
    • Container With Most Water 题解
    • Gas Station 题解
    • Gray Code 题解
    • Max Points on a Line 题解
    • [Pascal's Triangle 题解](others/Pascal's-Triangle.md)
    • [Pascal's Triangle II 题解](others/Pascal's-Triangle-II.md)
    • Remove Element 题解
    • Trapping Rain Water 题解
Powered by GitBook
On this page
  • 每次找最低点,再往回确定糖数量
  • 从左到右从右到左双向遍历
  • 备忘录法

Was this helpful?

  1. 其他

Candy 题解

Previous其他NextContainer With Most Water 题解

Last updated 5 years ago

Was this helpful?

题目来源:

>

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?

解题思路:

解析:注意理解题意 [3,2,2,3,1] 糖数量: 2,1,1,2,1; [4,2,3,4,1] 结果是 2,1,2,3,1.

每次找最低点,再往回确定糖数量

遍历一两遍即可,每次找下一次最低点,最低点的糖数量为1,再从最低的遍历到当前点得到结果。下面代码用了一个数组保存了每个child的结果,实际上只需用几个变量记录即可。 按照这个思路写了下面的比较戳的代码。

    //nextLowest and max index
    int nextLowest(vector<int> &ratings, int startIndex)
    {
        if(startIndex == ratings.size() - 1) return startIndex;
        while(ratings[startIndex] >= ratings[startIndex+1])
        {
            startIndex++;
            if(startIndex == ratings.size() - 1)
                return startIndex;
        }
        return startIndex;
    }

    //use two other variables to store candies[index-1] candies[index+1]
    //can change the space complexity to O(1)
    int candy(vector<int> &ratings)
    {
        size_t len = ratings.size();
        if(len <= 1) return (int)len;
        int curIndex = 0;
        int nextLow = nextLowest(ratings, curIndex);
        int sum = 0;
        vector<int> candies(len);
        while(curIndex < len)
        {
            if(curIndex == nextLow)
            {
                if(curIndex == 0)
                    candies[curIndex] = 1;
                else
                    candies[curIndex] = candies[curIndex-1] + 1;
                sum += candies[curIndex];
            }else
            {
                int index = nextLow;
                while(index-1 >= curIndex)
                {
                    if(ratings[index-1] == ratings[index])
                    {
                        if(index+1 <= nextLow && ratings[index] > ratings[index+1])
                            candies[index] = candies[index+1] + 1;
                        else
                            candies[index] = 1;
                        sum += candies[index];
                    }else // ratings[index-1] > ratings[index]
                    {
                        if(index == nextLow || (index+1 <= nextLow && ratings[index] == ratings[index+1]))
                            candies[index] = 1;
                        else
                            candies[index] = candies[index+1] + 1;
                        sum += candies[index];
                    }
                    --index;
                    if(index == curIndex)
                    {
                        //4 2 3 [4] 1
                        if(ratings[index] > ratings[index+1] && (index-1 >= 0 && ratings[index] > ratings[index-1]) )
                            candies[index] = std::max(candies[index+1], candies[index-1]) + 1;
                        else if(ratings[index] > ratings[index+1])
                            candies[index] = candies[index+1] + 1;
                        else if(ratings[index] > ratings[index-1])
                            candies[index] = candies[index-1] + 1; //1 [2] 2
                        else
                            candies[index] = 1;
                        sum += candies[index];
                        break;
                    }
                }
            }
            curIndex = nextLow+1;
            nextLow = nextLowest(ratings, curIndex);
        }
        return sum;
    }

从左到右从右到左双向遍历

> 1. From left to right, to make all candies satisfy the condition if ratings[i] > ratings[i - 1] then candies[i] > candies[i - 1], just ignore the right neighbor as this moment. We can assume leftCandies[i] is a solution which is satisfied. 2. From right to left, almost like step 1, get a solution rightCandies[i] which just satisfy the condition if ratings[i] > ratings[i + 1] then candies[i] > candies[i + 1] 3. For now, we have leftCandies[i] and rightCandies[i], so how can we satisfy the real condition in the problem? Just make candies[i] equals the maximum betweenleftCanides[i] and rightCandies[i]

即把整个过程分为两个步骤,第一步从左到右,只要右边的ratings大于自己,右边的糖数量就=自己+1, (先不管左边大于右边的情况),这一步完成之后有条件,ratings[i] > ratings[i - 1] && candies[i] > candies[i - 1] 然后再从右往左,一样的思路,使得ratings[i] > ratings[i + 1] && candies[i] > candies[i + 1]。 最后candies再取两个中的max,这样就同时满足这两个条件。问题解决。

    int candy2(vector<int> &ratings)
    {
        int n = ratings.size();
        if(n <= 1) return n;
        vector<int> candies(n, 1);
        //left to right
        for(int i = 1; i < n; i++)
        {
            if(ratings[i] > ratings[i-1])
                candies[i] = candies[i-1]+1;
            else
                candies[i] = 1;
        }
        int total = candies[n-1];
        for(int i = n-2; i >= 0; i--)
        {
            if(ratings[i] > ratings[i+1])
                candies[i] = std::max(candies[i+1]+1, candies[i]);
            total += candies[i];
        }
        return total;
    }

备忘录法

    int f(vector<int> &ratings, vector<int> &cache, int index){
        if(cache[index] == 0)//has not been calculated before
        {
            cache[index] = 1;
            if(index+1 < ratings.size() && ratings[index] > ratings[index+1])
                cache[index] = std::max(cache[index], f(ratings, cache, index+1)+1);
            if(index-1 >= 0 && ratings[index] > ratings[index-1])
                cache[index] = std::max(cache[index], f(ratings, cache, index-1)+1);
        }
        return cache[index];}
    int candy3(vector<int> &ratings){
        int n = ratings.size();
        if(n <= 1) return n;
        int total = 0;
        vector<int> cache(n, 0);
        for(int i = 0; i < n; i++)
            total += f(ratings, cache, i);
        return total;
    }

从看到的答案,短小精悍的代码。思路也很清晰。

这个方法参考了。即用递归的方式使得分得candy数量同时满足以上两个条件。

Candy
discuss
leetcode-cpp