• Home
  • About
    • Sybil photo

      Sybil

      Sybil's blog.

    • Learn More
    • Email
    • Github
    • Weibo
  • Posts
    • All Posts
    • All Tags
  • Projects

1103. 分糖果,一元二次方程O(num_people)

18 Mar 2020

预计阅读时间 ~10 分钟

leetcode简单Math

解题思路

由于糖果分配符合 的规律

可以计算出分配糖果的和为

解一元二次方程的正根,可以计算出

所以可以计算出一共分配了 r 到 r+1(边界情况) 轮

算法流程

  1. 先计算前 r 轮的分配

  2. 再遍历模拟单独处理 r+1 轮的分配

复杂度分析

  • 时间复杂度
  • 空间复杂度

代码

class Solution {
    public int[] distributeCandies(int candies, int num_people) {
        int[] ans = new int[num_people];
        // 计算出一共可以分配多少次糖果, 1+2+3+...+n = (n+1)n/2 = candies => n = (-1 + sqrt(1-4*(-2*candies)))/2
        int N = (int)((Math.sqrt(1.0+8.0*candies)-1)/2);
        // 一共可以分配多少轮糖果
        int round = N / num_people;
        // 处理边界数据
        int leftCandies = candies;
        //System.out.println(N + ", round=" + round);

        //先按照可以全部分完的整数分配
        for (int i = 0; i < num_people; ++i) {
            // for (int r = 0; r < round; ++ r) {
            //     ans[i] += (i+1) + r * num_people;
            // }
            ans[i] = (i+1) * round + num_people * round * (round-1)/2;
            leftCandies -= ans[i];
        }

        //最后一轮分配,按照剩余的糖果数分配
        int allotCandies = 1 + round * num_people;
        //System.out.println(leftCandies + ", allot=" + allotCandies);
        for (int i =0; i < num_people; ++i) {
            if (allotCandies <= leftCandies) {
                ans[i] += allotCandies;
                leftCandies -= allotCandies;
                allotCandies++;
            } else {
                ans[i] += leftCandies;
                break;
            }
        }
        return ans;
    }
}


leetcode简单Math Share Tweet +1