diff --git a/172.factorial-trailing-zeroes.js b/172.factorial-trailing-zeroes.js new file mode 100644 index 000000000..4f9d45205 --- /dev/null +++ b/172.factorial-trailing-zeroes.js @@ -0,0 +1,23 @@ +/* + * @lc app=leetcode id=172 lang=javascript + * + * [172] Factorial Trailing Zeroes + */ +/** + * @param {number} n + * @return {number} + */ +var trailingZeroes = function(n) { + // tag: 数论 + // 只有 2 和 5 相乘才等于 10 + // if (n === 0) return n; + + // return Math.floor(n / 5) + trailingZeroes(Math.floor(n / 5)); + let count = 0; + while(n >= 5) { + count += Math.floor(n / 5); + n = Math.floor(n / 5); + } + return count; +}; + diff --git a/263.ugly-number.js b/263.ugly-number.js new file mode 100644 index 000000000..ff07c1594 --- /dev/null +++ b/263.ugly-number.js @@ -0,0 +1,23 @@ +/* + * @lc app=leetcode id=263 lang=javascript + * + * [263] Ugly Number + */ +/** + * @param {number} num + * @return {boolean} + */ +var isUgly = function(num) { + // TAG: 数论 + if (num <= 0) return false; + if (num === 1) return true; + + const list = [2, 3, 5]; + + if (list.includes(num)) return true; + + for (let i of list) { + if (num % i === 0) return isUgly(Math.floor(num / i)); + } + return false; +}; diff --git a/342.power-of-four.js b/342.power-of-four.js new file mode 100644 index 000000000..849bbd00c --- /dev/null +++ b/342.power-of-four.js @@ -0,0 +1,43 @@ +/* + * @lc app=leetcode id=342 lang=javascript + * + * [342] Power of Four + */ +/** + * @param {number} num + * @return {boolean} + */ +var isPowerOfFour = function(num) { + // tag: 数论 + + // 100 + // 10000 + // 1000000 + + // 发现规律: 4的幂次方的二进制表示 1 的位置都是在奇数位(且不在最低位),其他位置都为0 + + // 10 + // 100 + // 1000 + + // 发现规律: 2的幂次方的特点是最低位之外,其他位置有且仅有一个1 + + // 如果满足: + // 1. 是 2 的幂次方, 就能保证最低位之外,其他位置有且仅有一个1 + // 我们还需要保证 + // 2. 这个1不再偶数位置,一定在奇数位置就行了 + + // 我们可以取一个特殊数字,这个特殊数字,奇数位置都是1,偶数位置都是0,然后和这个特殊数字 + // `求与`, 如果等于本身,那么毫无疑问,这个1不再偶数位置,一定在奇数位置 + // 因为如果在偶数位置,`求与`的结果就是0了 + // 特殊的数字: + + // 01010101010101010101010101010101 + + if (num === 1) return true; + if (num < 4) return false; + + if ((num & (num - 1)) !== 0) return false; + + return (num & 0x55555555) === num; +}; diff --git a/575.distribute-candies.js b/575.distribute-candies.js new file mode 100644 index 000000000..d41326683 --- /dev/null +++ b/575.distribute-candies.js @@ -0,0 +1,14 @@ +/* + * @lc app=leetcode id=575 lang=javascript + * + * [575] Distribute Candies + */ +/** + * @param {number[]} candies + * @return {number} + */ +var distributeCandies = function(candies) { + const count = new Set(candies); + return Math.min(count.size, candies.length >> 1); +}; + diff --git a/README.en.md b/README.en.md index fc4f375e9..77b6c6286 100644 --- a/README.en.md +++ b/README.en.md @@ -201,6 +201,12 @@ Latest updated flashcards (only lists the front page): - The thinkings and related problems of double-pointers problems? - The thinkings and related problems of sliding window problems? - The thinkings and related problems of backtracking? +- The thinkings and related problems of number theory? +- The thinkings and related problems of bit operations? + +> WIP: the translation of the flashcards are on the way. + +> problems added:#2 #3 #11 diff --git a/README.md b/README.md index a796a6a0e..51c43749a 100644 --- a/README.md +++ b/README.md @@ -194,11 +194,15 @@ anki - 文件 - 导入 - 下拉格式选择“打包的 anki集合”,然后 目前已更新卡片一览(仅列举正面): -- 二分法解决问题的关键点是什么,相关问题有哪些 +- 二分法解决问题的关键点是什么,相关问题有哪些? - 如何用栈的特点来简化操作, 涉及到的题目有哪些? - 双指针问题的思路以及相关题目有哪些? - 滑动窗口问题的思路以及相关题目有哪些? - 回溯法解题的思路以及相关题目有哪些? +- 数论解决问题的关键点是什么,相关问题有哪些? +- 位运算解决问题的关键点是什么,相关问题有哪些? + +> 已加入的题目有:#2 #3 #11 ### 计划 diff --git a/backlog/338.counting-bits.js b/backlog/338.counting-bits.js index b3f560eae..92f4ff0ab 100644 --- a/backlog/338.counting-bits.js +++ b/backlog/338.counting-bits.js @@ -44,15 +44,22 @@ * @return {number[]} */ var countBits = function(num) { - // 这是一道位运算的题目 + // tag: bit dp + // Time complexity: O(n) + // Space complexity: O(n) const res = []; res[0] = 0; + // 10000100110101 for (let i = 1; i <= num; i++) { - if ((i & 1) === 0) { // 偶数 - res[i] = res[i >> 1]; // 偶数不影响结果 - } else { // 奇数 - res[i] = res[i - 1] + 1; // 如果是奇数,那就是前面的数字 + 1 + if ((i & 1) === 0) { + // 偶数 + // 偶数最后一位是0,因此右移一位对结果没有影响 + res[i] = res[i >> 1]; + } else { + // 奇数 + // 奇数最后一位是1,i - 1 的 位数 + 1 就是结果 + res[i] = res[i - 1] + 1; } } diff --git a/problems/136.single-number.md b/problems/136.single-number.md index 930d2cdd1..eb6b0649a 100644 --- a/problems/136.single-number.md +++ b/problems/136.single-number.md @@ -32,6 +32,8 @@ Your algorithm should have a linear runtime complexity. Could you implement it w 3. 很多人只是记得异或的性质和规律,但是缺乏对其本质的理解,导致很难想到这种解法(我本人也没想到) +4. bit 运算 + ## 代码 ```js diff --git a/problems/190.reverse-bits.md b/problems/190.reverse-bits.md index 68a4e2666..eb956bd9f 100644 --- a/problems/190.reverse-bits.md +++ b/problems/190.reverse-bits.md @@ -53,6 +53,8 @@ eg : 3. 双"指针" 模型 +4. bit 运算 + ## 代码 diff --git a/problems/191.number-of-1-bits.md b/problems/191.number-of-1-bits.md index 7d034f899..f16b00909 100644 --- a/problems/191.number-of-1-bits.md +++ b/problems/191.number-of-1-bits.md @@ -47,6 +47,8 @@ In Java, the compiler represents the signed integers using 2's complement notati 1. `n & (n - 1)` 可以`消除` n 最后的一个1的原理 简化操作 +2. bit 运算 + ## 代码 diff --git a/problems/201.bitwise-and-of-numbers-range.md b/problems/201.bitwise-and-of-numbers-range.md index 4d6700798..5ad2ea9fc 100644 --- a/problems/201.bitwise-and-of-numbers-range.md +++ b/problems/201.bitwise-and-of-numbers-range.md @@ -61,6 +61,8 @@ Output: 0 - 可以用递归实现, 个人认为比较难想到 +- bit 运算 + 代码: ```js