From e038d33370655ea944b0207325ee0704c30e27da Mon Sep 17 00:00:00 2001 From: AC_Oier Date: Tue, 22 Nov 2022 11:28:38 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8feat:=20add=20878=20*=20808?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "Index/\344\272\214\345\210\206.md" | 1 + ...71\346\226\245\345\216\237\347\220\206.md" | 1 + "Index/\346\225\260\345\255\246.md" | 1 + ...10\345\233\260\351\232\276\357\274\211.md" | 1 - ...10\344\270\255\347\255\211\357\274\211.md" | 2 +- ...10\345\233\260\351\232\276\357\274\211.md" | 152 ++++++++++++++++++ 6 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 "LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" diff --git "a/Index/\344\272\214\345\210\206.md" "b/Index/\344\272\214\345\210\206.md" index 55ff58b2..1edd4c79 100644 --- "a/Index/\344\272\214\345\210\206.md" +++ "b/Index/\344\272\214\345\210\206.md" @@ -47,6 +47,7 @@ | [793. 阶乘函数后 K 个零](https://leetcode.cn/problems/preimage-size-of-factorial-zeroes-function/) | [LeetCode 题解链接](https://leetcode.cn/problems/preimage-size-of-factorial-zeroes-function/solution/by-ac_oier-pk9g/) | 困难 | 🤩🤩🤩🤩 | | [852. 山脉数组的峰顶索引](https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/solution/gong-shui-san-xie-er-fen-san-fen-cha-zhi-5gfv/) | 简单 | 🤩🤩🤩🤩🤩 | | [875. 爱吃香蕉的珂珂](https://leetcode.cn/problems/koko-eating-bananas/) | [LeetCode 题解链接](https://leetcode.cn/problems/koko-eating-bananas/solution/by-ac_oier-4z7i/) | 中等 | 🤩🤩🤩🤩 | +| [878. 第 N 个神奇数字](https://leetcode.cn/problems/nth-magical-number/) | [LeetCode 题解链接](https://leetcode.cn/problems/nth-magical-number/solution/by-ac_oier-ln3b/) | 困难 | 🤩🤩🤩🤩🤩 | | [911. 在线选举](https://leetcode-cn.com/problems/online-election/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/online-election/solution/gong-shui-san-xie-er-fen-yun-yong-ti-by-5y3hi/) | 中等 | 🤩🤩🤩🤩🤩 | | [926. 将字符串翻转到单调递增](https://leetcode.cn/problems/flip-string-to-monotone-increasing/) | [LeetCode 题解链接](https://leetcode.cn/problems/flip-string-to-monotone-increasing/solution/by-ac_oier-h0we/) | 中等 | 🤩🤩🤩 | | [981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/time-based-key-value-store/solution/gong-shui-san-xie-yi-ti-shuang-jie-ha-xi-h5et/) | 中等 | 🤩🤩🤩🤩 | diff --git "a/Index/\345\256\271\346\226\245\345\216\237\347\220\206.md" "b/Index/\345\256\271\346\226\245\345\216\237\347\220\206.md" index 20b4e10a..fd3d4571 100644 --- "a/Index/\345\256\271\346\226\245\345\216\237\347\220\206.md" +++ "b/Index/\345\256\271\346\226\245\345\216\237\347\220\206.md" @@ -19,6 +19,7 @@ | [724. 寻找数组的中心下标](https://leetcode-cn.com/problems/find-pivot-index/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-pivot-index/solution/shi-yong-shao-bing-ji-qiao-liang-bian-qi-vkju/) | 简单 | 🤩🤩🤩🤩🤩 | | [793. 阶乘函数后 K 个零](https://leetcode.cn/problems/preimage-size-of-factorial-zeroes-function/) | [LeetCode 题解链接](https://leetcode.cn/problems/preimage-size-of-factorial-zeroes-function/solution/by-ac_oier-pk9g/) | 困难 | 🤩🤩🤩🤩 | | [825. 适龄的朋友](https://leetcode-cn.com/problems/friends-of-appropriate-ages/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/friends-of-appropriate-ages/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-maa8/) | 中等 | 🤩🤩🤩🤩 | +| [878. 第 N 个神奇数字](https://leetcode.cn/problems/nth-magical-number/) | [LeetCode 题解链接](https://leetcode.cn/problems/nth-magical-number/solution/by-ac_oier-ln3b/) | 困难 | 🤩🤩🤩🤩🤩 | | [926. 将字符串翻转到单调递增](https://leetcode.cn/problems/flip-string-to-monotone-increasing/) | [LeetCode 题解链接](https://leetcode.cn/problems/flip-string-to-monotone-increasing/solution/by-ac_oier-h0we/) | 中等 | 🤩🤩🤩🤩 | | [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/binary-subarrays-with-sum/solution/gong-shui-san-xie-yi-ti-shuang-jie-qian-hfoc0/) | 中等 | 🤩🤩🤩 | | [1004. 最大连续1的个数 III](https://leetcode-cn.com/problems/max-consecutive-ones-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/max-consecutive-ones-iii/solution/san-chong-jie-fa-cong-dong-tai-gui-hua-d-gxks/) | 中等 | 🤩🤩🤩 | diff --git "a/Index/\346\225\260\345\255\246.md" "b/Index/\346\225\260\345\255\246.md" index 1d64ef07..208ed817 100644 --- "a/Index/\346\225\260\345\255\246.md" +++ "b/Index/\346\225\260\345\255\246.md" @@ -56,6 +56,7 @@ | [828. 统计子串中的唯一字符](https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/) | [LeetCode 题解链接](https://leetcode.cn/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/by-ac_oier-922k/) | 困难 | 🤩🤩🤩🤩 | | [829. 连续整数求和](https://leetcode.cn/problems/consecutive-numbers-sum/) | [LeetCode 题解链接](https://leetcode.cn/problems/consecutive-numbers-sum/solution/by-ac_oier-220q/) | 困难 | 🤩🤩🤩🤩 | | [869. 重新排序得到 2 的幂](https://leetcode-cn.com/problems/reordered-power-of-2/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reordered-power-of-2/solution/gong-shui-san-xie-yi-ti-shuang-jie-dfs-c-3s1e/) | 中等 | 🤩🤩🤩🤩 | +| [878. 第 N 个神奇数字](https://leetcode.cn/problems/nth-magical-number/) | [LeetCode 题解链接](https://leetcode.cn/problems/nth-magical-number/solution/by-ac_oier-ln3b/) | 困难 | 🤩🤩🤩🤩 | | [879. 盈利计划](https://leetcode-cn.com/problems/profitable-schemes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/profitable-schemes/solution/gong-shui-san-xie-te-shu-duo-wei-fei-yon-7su9/) | 困难 | 🤩🤩🤩🤩🤩 | | [891. 子序列宽度之和](https://leetcode.cn/problems/sum-of-subsequence-widths/) | [LeetCode 题解链接](https://leetcode.cn/problems/sum-of-subsequence-widths/solution/by-ac_oier-6tyk/) | 困难 | 🤩🤩🤩🤩 | | [907. 子数组的最小值之和](https://leetcode.cn/problems/sum-of-subarray-minimums/) | [LeetCode 题解链接](https://leetcode.cn/problems/sum-of-subarray-minimums/solution/by-ac_oier-h9cd/) | 中等 | 🤩🤩🤩 | diff --git "a/LeetCode/471-480/472. \350\277\236\346\216\245\350\257\215\357\274\210\345\233\260\351\232\276\357\274\211.md" "b/LeetCode/471-480/472. \350\277\236\346\216\245\350\257\215\357\274\210\345\233\260\351\232\276\357\274\211.md" index 51d1afff..a914dafa 100644 --- "a/LeetCode/471-480/472. \350\277\236\346\216\245\350\257\215\357\274\210\345\233\260\351\232\276\357\274\211.md" +++ "b/LeetCode/471-480/472. \350\277\236\346\216\245\350\257\215\357\274\210\345\233\260\351\232\276\357\274\211.md" @@ -118,4 +118,3 @@ class Solution { 为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 - diff --git "a/LeetCode/801-810/808. \345\210\206\346\261\244\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/801-810/808. \345\210\206\346\261\244\357\274\210\344\270\255\347\255\211\357\274\211.md" index 401b0c88..f880590a 100644 --- "a/LeetCode/801-810/808. \345\210\206\346\261\244\357\274\210\344\270\255\347\255\211\357\274\211.md" +++ "b/LeetCode/801-810/808. \345\210\206\346\261\244\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -2,7 +2,7 @@ 这是 LeetCode 上的 **[808. 分汤](https://leetcode.cn/problems/soup-servings/solution/by-ac_oier-3n1h/)** ,难度为 **中等**。 -Tag : 「数学」、「动态规划」 +Tag : 「数学」、「动态规划」、「线性 DP」 diff --git "a/LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" "b/LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" new file mode 100644 index 00000000..204f9ead --- /dev/null +++ "b/LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" @@ -0,0 +1,152 @@ +### 题目描述 + +这是 LeetCode 上的 **[878. 第 N 个神奇数字](https://leetcode.cn/problems/nth-magical-number/solution/by-ac_oier-ln3b/)** ,难度为 **困难**。 + +Tag : 「数学」、「容斥原理」、「二分」、「gcd」、「lcm」 + + + +一个正整数如果能被 `a` 或 `b` 整除,那么它是神奇的。 + +给定三个整数 `n` , `a` , `b` ,返回第 `n` 个神奇的数字。因为答案可能很大,所以返回答案 对 $10^9 + 7$ 取模 后的值。 + +示例 1: +``` +输入:n = 1, a = 2, b = 3 + +输出:2 +``` +示例 2: +``` +输入:n = 4, a = 2, b = 3 + +输出:6 +``` + +提示: +* $1 <= n <= 10^9$ +* $2 <= a, b <= 4 \times 10^4$ + +--- + +### 数学 + +#### 提示一 : 从题面分析常见做法,从常见做法复杂度出发考虑其他做法 + +若不看数据范围,只看题面,容易想到的做法是「多路归并」:起始使用两个指针指向 `[a, 2a, 3a, ... ]` 和 `[b, 2b, 3b, ...]` 的开头,不断比较两指针所指向的数值大小,从而决定将谁后移,并不断更新顺位计数。 + +该做法常见,但其复杂度为 $O(n)$,对于本题 $n = 1e9$ 来说并不可行。 + +确定线性复杂度的做法不可行后,我们考虑是否存在对数复杂度的做法。 + +#### 提示二 : 如何考虑常见的对数复杂度做法,如何定义二段性 + +题目要我们求第 $n$ 个符合要求的数,假设我们想要通过「二分」来找该数值,那么我们需要分析其是否存在「二段性」。 + +假设在所有「能够被 `a` 或 `b` 整除的数」形成的数轴上,我们要找的分割点是 `k`,我们期望通过「二分」来找到 `k` 值,那么需要定义某种性质,使得 `k` 左边的数均满足该性质,`k` 右边的数均不满足该性质。 + +不难想到可根据题意来设定该性质:小于 `k` 的任意数字 `x` 满足在 $[0, x]$ 范围数的个数不足 `k` 个,而大于等于 `k` 的任意数字 `x` 则不满足该性质。 + +#### 提示三 : 如何实现高效的 `check` 函数 + +当确定使用「二分」来做时,剩下问题转化为:**如何快速得知某个 $[0, n]$ 中满足要求的数的个数。** + +容易联想到「容斥原理」:**能被 `a` 或 `b` 整除的数的个数 = 能够被 `a` 整除的数的个数 + 能够被 `b` 整除的数的个数 - 既能被 `a` 又能被 `b` 整除的数的个数**。 + +$$ +\left \lfloor \frac{n}{a} \right \rfloor + \left \lfloor \frac{n}{b} \right \rfloor - \left \lfloor \frac{n}{c} \right \rfloor +$$ + +其中 `c` 为 `a` 和 `b` 的最小公倍数。 + +求解最小公倍数 `lcm` 需要实现最大公约数 `gcd`,两者模板分别为: + +```Java [] +int gcd(int a, int b) { + return b == 0 ? a : gcd(b, a % b); +} +int lcm(int a, int b) { + return a * b / gcd(a, b); +} +``` + +#### 提示四 : 如何确定值域 + +一个合格的值域只需要确定答案在值域范围即可,因此我们可以直接定值域大小为 $1e20$。 + +或是根据 `a` 和 `b` 的取值来大致确定:假设两者中的较大值为 $m$,此时第 $n$ 个符合要求的数最大不会超过 $n \times m$,因此也可以设定值域大小为 $[0, 40000n]$。 + +Java 代码: +```Java +class Solution { + int n, a, b, c; + int gcd(int a, int b) { + return b == 0 ? a : gcd(b, a % b); + } + public int nthMagicalNumber(int _n, int _a, int _b) { + n = _n; a = _a; b = _b; c = a * b / gcd(a, b); + long l = 0, r = (long)1e20; + while (l < r) { + long mid = l + r >> 1; + if (check(mid) >= n) r = mid; + else l = mid + 1; + } + return (int)(r % 1000000007); + } + long check(long x) { + return x / a + x / b - x / c; + } +} +``` +TypeScript 代码: +```TypeScript +function nthMagicalNumber(n: number, a: number, b: number): number { + function gcd(a: number, b: number): number { + return b == 0 ? a : gcd(b, a % b) + } + function check(x: number): number { + return Math.floor(x / a) + Math.floor(x / b) - Math.floor(x / c) + } + const c = Math.floor(a * b / gcd(a, b)) + let l = 0, r = 1e19 + while (l < r) { + const mid = Math.floor((l + r) / 2) + if (check(mid) >= n) r = mid + else l = mid + 1 + } + return r % 1000000007 +} +``` +Python3 代码: +```Python +class Solution: + def nthMagicalNumber(self, n: int, a: int, b: int) -> int: + def gcd(a, b): + return a if b == 0 else gcd(b, a % b) + def check(x): + return x // a + x // b - x // c + c = a * b // gcd(a, b) + l, r = 0, 1e20 + while l < r: + mid = (l + r) // 2 + if check(mid) >= n: + r = mid + else: + l = mid + 1 + return int(r % 1000000007) +``` +* 时间复杂度:$O(\log{N})$,其中 $N = 1e20$ 为值域大小 +* 空间复杂度:$O(1)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.878` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 + From 93169b2cc85cc36501521f9b1e2b51435ca5353d Mon Sep 17 00:00:00 2001 From: AC_Oier Date: Wed, 23 Nov 2022 11:18:04 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8feat:=20add=20878=E3=80=811742?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\345\223\210\345\270\214\350\241\250.md" | 1 + "Index/\346\250\241\346\213\237.md" | 1 + ...10\347\256\200\345\215\225\357\274\211.md" | 119 ++++++++++++++++++ ...10\345\233\260\351\232\276\357\274\211.md" | 10 +- 4 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 "LeetCode/1741-1750/1742. \347\233\222\345\255\220\344\270\255\345\260\217\347\220\203\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217\357\274\210\347\256\200\345\215\225\357\274\211.md" diff --git "a/Index/\345\223\210\345\270\214\350\241\250.md" "b/Index/\345\223\210\345\270\214\350\241\250.md" index 47a0f4ce..8b5b0c47 100644 --- "a/Index/\345\223\210\345\270\214\350\241\250.md" +++ "b/Index/\345\223\210\345\270\214\350\241\250.md" @@ -81,6 +81,7 @@ | [1640. 能否连接形成数组](https://leetcode.cn/problems/check-array-formation-through-concatenation/) | [LeetCode 题解链接](https://leetcode.cn/problems/check-array-formation-through-concatenation/solution/by-ac_oier-3jqf/) | 简单 | 🤩🤩🤩🤩🤩 | | [1700. 无法吃午餐的学生数量](https://leetcode.cn/problems/number-of-students-unable-to-eat-lunch/) | [LeetCode 题解链接](https://leetcode.cn/problems/number-of-students-unable-to-eat-lunch/solution/by-ac_oier-rvc3/) | 简单 | 🤩🤩🤩🤩🤩 | | [1711. 大餐计数](https://leetcode-cn.com/problems/count-good-meals/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-good-meals/solution/gong-shui-san-xie-xiang-jie-san-chong-gu-nn4f/) | 中等 | 🤩🤩🤩 | +| [1742. 盒子中小球的最大数量](https://leetcode.cn/problems/maximum-number-of-balls-in-a-box/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-number-of-balls-in-a-box/solution/by-ac_oier-3mxf/) | 简单 | 🤩🤩🤩 | | [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/solution/gong-shui-san-xie-yi-ti-shuang-jie-dan-x-elpx/) | 中等 | 🤩🤩🤩🤩 | | [1748. 唯一元素的和](https://leetcode-cn.com/problems/sum-of-unique-elements/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-unique-elements/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-atnd/) | 简单 | 🤩🤩🤩🤩 | | [1838. 最高频元素的频数](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/solution/gong-shui-san-xie-cong-mei-ju-dao-pai-xu-kxnk/) | 中等 | 🤩🤩🤩 | diff --git "a/Index/\346\250\241\346\213\237.md" "b/Index/\346\250\241\346\213\237.md" index a967f7f2..5b99074e 100644 --- "a/Index/\346\250\241\346\213\237.md" +++ "b/Index/\346\250\241\346\213\237.md" @@ -206,6 +206,7 @@ | [1732. 找到最高海拔](https://leetcode.cn/problems/find-the-highest-altitude/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-the-highest-altitude/solution/by-ac_oier-a0j8/) | 简单 | 🤩🤩🤩🤩 | | [1736. 替换隐藏数字得到的最晚时间](https://leetcode-cn.com/problems/latest-time-by-replacing-hidden-digits/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/latest-time-by-replacing-hidden-digits/solution/gong-shui-san-xie-ti-huan-yin-cang-shu-z-2l1h/) | 简单 | 🤩🤩🤩🤩 | | [1737. 满足三条件之一需改变的最少字符数](https://leetcode.cn/problems/change-minimum-characters-to-satisfy-one-of-three-conditions/) | [LeetCode 题解链接](https://leetcode.cn/problems/change-minimum-characters-to-satisfy-one-of-three-conditions/solution/by-ac_oier-vs5u/) | 中等 | 🤩🤩🤩🤩 | +| [1742. 盒子中小球的最大数量](https://leetcode.cn/problems/maximum-number-of-balls-in-a-box/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-number-of-balls-in-a-box/solution/by-ac_oier-3mxf/) | 简单 | 🤩🤩🤩 | | [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/solution/gong-shui-san-xie-yi-ti-shuang-jie-dan-x-elpx/) | 中等 | 🤩🤩🤩🤩 | | [1748. 唯一元素的和](https://leetcode-cn.com/problems/sum-of-unique-elements/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-unique-elements/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-atnd/) | 简单 | 🤩🤩🤩🤩 | | [1763. 最长的美好子字符串](https://leetcode-cn.com/problems/longest-nice-substring/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-nice-substring/solution/cong-shu-ju-fan-wei-xuan-ze-he-gua-suan-n3y2a/) | 简单 | 🤩🤩🤩 | diff --git "a/LeetCode/1741-1750/1742. \347\233\222\345\255\220\344\270\255\345\260\217\347\220\203\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217\357\274\210\347\256\200\345\215\225\357\274\211.md" "b/LeetCode/1741-1750/1742. \347\233\222\345\255\220\344\270\255\345\260\217\347\220\203\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217\357\274\210\347\256\200\345\215\225\357\274\211.md" new file mode 100644 index 00000000..51ab5b46 --- /dev/null +++ "b/LeetCode/1741-1750/1742. \347\233\222\345\255\220\344\270\255\345\260\217\347\220\203\347\232\204\346\234\200\345\244\247\346\225\260\351\207\217\357\274\210\347\256\200\345\215\225\357\274\211.md" @@ -0,0 +1,119 @@ +### 题目描述 + +这是 LeetCode 上的 **[1742. 盒子中小球的最大数量](https://leetcode.cn/problems/maximum-number-of-balls-in-a-box/solution/by-ac_oier-3mxf/)** ,难度为 **简单**。 + +Tag : 「哈希表」、「模拟」 + + + +你在一家生产小球的玩具厂工作,有 `n` 个小球,编号从 `lowLimit` 开始,到 `highLimit` 结束(包括 `lowLimit` 和 `highLimit` ,即 `n == highLimit - lowLimit + 1`)。另有无限数量的盒子,编号从 `1` 到 `infinity` 。 + +你的工作是将每个小球放入盒子中,其中盒子的编号应当等于小球编号上每位数字的和。例如,编号 `321` 的小球应当放入编号 `3 + 2 + 1 = 6` 的盒子,而编号 `10` 的小球应当放入编号 `1 + 0 = 1` 的盒子。 + +给你两个整数 `lowLimit` 和 `highLimit` ,返回放有最多小球的盒子中的小球数量。如果有多个盒子都满足放有最多小球,只需返回其中任一盒子的小球数量。 + +示例 1: +``` +输入:lowLimit = 1, highLimit = 10 +输出:2 + +解释: +盒子编号:1 2 3 4 5 6 7 8 9 10 11 ... +小球数量:2 1 1 1 1 1 1 1 1 0 0 ... +编号 1 的盒子放有最多小球,小球数量为 2 。 +``` +示例 2: +``` +输入:lowLimit = 5, highLimit = 15 + +输出:2 + +解释: +盒子编号:1 2 3 4 5 6 7 8 9 10 11 ... +小球数量:1 1 1 1 2 2 1 1 1 0 0 ... +编号 5 和 6 的盒子放有最多小球,每个盒子中的小球数量都是 2 。 +``` +示例 3: +``` +输入:lowLimit = 19, highLimit = 28 + +输出:2 + +解释: +盒子编号:1 2 3 4 5 6 7 8 9 10 11 12 ... +小球数量:0 1 1 1 1 1 1 1 1 2 0 0 ... +编号 10 的盒子放有最多小球,小球数量为 2 。 +``` + +提示: +* $1 <= lowLimit <= highLimit <= 10^5$ + +--- + +### 模拟 + +数据范围 $n = 1e5$,因此最大盒子编号 `99999 = 5 * 9 = 45`,我们可以用一个大小为 $50$ 的数组 `cnts` 来统计每个编号盒子中小球的数量,$cnts[idx] = x$ 含义为编号为 $idx$ 的盒子有 $x$ 个小球。 + +Java 代码: +```Java +class Solution { + public int countBalls(int l, int r) { + int ans = 0; + int[] cnts = new int[50]; + for (int i = l; i <= r; i++) { + int j = i, cur = 0; + while (j != 0) { + cur += j % 10; j /= 10; + } + if (++cnts[cur] > ans) ans = cnts[cur]; + } + return ans; + } +} +``` +TypeScript 代码: +```TypeScript +function countBalls(l: number, r: number): number { + let ans = 0 + const cnts = new Array(50).fill(0) + for (let i = l; i <= r; i++) { + let j = i, cur = 0 + while (j != 0) { + cur += j % 10 + j = Math.floor(j / 10) + } + if (++cnts[cur] > ans) ans = cnts[cur] + } + return ans +} +``` +Python 代码: +```Python +class Solution: + def countBalls(self, l: int, r: int) -> int: + ans = 0 + cnts = [0] * 50 + for i in range(l, r + 1): + j, cur = i, 0 + while j != 0: + j, cur = j // 10, cur + j % 10 + cnts[cur] += 1 + if cnts[cur] > ans: + ans = cnts[cur] + return ans +``` +* 时间复杂度:$O(n\log{r})$ +* 空间复杂度:$O(C)$,其中 $C = 50$ 为最大盒子编号 + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.1742` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 + diff --git "a/LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" "b/LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" index 204f9ead..0c1db92c 100644 --- "a/LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" +++ "b/LeetCode/871-880/878. \347\254\254 N \344\270\252\347\245\236\345\245\207\346\225\260\345\255\227\357\274\210\345\233\260\351\232\276\357\274\211.md" @@ -72,7 +72,7 @@ int lcm(int a, int b) { #### 提示四 : 如何确定值域 -一个合格的值域只需要确定答案在值域范围即可,因此我们可以直接定值域大小为 $1e20$。 +一个合格的值域只需要确定答案在值域范围即可,因此我们可以直接定值域大小为 $1e18$。 或是根据 `a` 和 `b` 的取值来大致确定:假设两者中的较大值为 $m$,此时第 $n$ 个符合要求的数最大不会超过 $n \times m$,因此也可以设定值域大小为 $[0, 40000n]$。 @@ -85,7 +85,7 @@ class Solution { } public int nthMagicalNumber(int _n, int _a, int _b) { n = _n; a = _a; b = _b; c = a * b / gcd(a, b); - long l = 0, r = (long)1e20; + long l = 0, r = (long)1e18; while (l < r) { long mid = l + r >> 1; if (check(mid) >= n) r = mid; @@ -108,7 +108,7 @@ function nthMagicalNumber(n: number, a: number, b: number): number { return Math.floor(x / a) + Math.floor(x / b) - Math.floor(x / c) } const c = Math.floor(a * b / gcd(a, b)) - let l = 0, r = 1e19 + let l = 0, r = 1e18 while (l < r) { const mid = Math.floor((l + r) / 2) if (check(mid) >= n) r = mid @@ -126,7 +126,7 @@ class Solution: def check(x): return x // a + x // b - x // c c = a * b // gcd(a, b) - l, r = 0, 1e20 + l, r = 0, 1e18 while l < r: mid = (l + r) // 2 if check(mid) >= n: @@ -135,7 +135,7 @@ class Solution: l = mid + 1 return int(r % 1000000007) ``` -* 时间复杂度:$O(\log{N})$,其中 $N = 1e20$ 为值域大小 +* 时间复杂度:$O(\log{N})$,其中 $N = 1e18$ 为值域大小 * 空间复杂度:$O(1)$ ---