讲两道常考的阶乘算法题 :: labuladong的算法小抄 #1034
Replies: 17 comments 2 replies
-
trailingZeroes(mid)为啥要用两次; |
Beta Was this translation helpful? Give feedback.
-
是我写错了 |
Beta Was this translation helpful? Give feedback.
-
我有几点思考: |
Beta Was this translation helpful? Give feedback.
-
@fkjkkll 👍 |
Beta Was this translation helpful? Give feedback.
-
class Solution:
def preimageSizeFZF(self, k: int) -> int:
def trailing_zeros(n):
res = 0
while n // 5 > 0:
res += n // 5
n = n // 5
return res
# 二分查找 左右边界
def left_bound(target): # target是有多少个满足条件
# 左边界
lo, hi = 0, 10e9
while lo < hi:
mid = lo + (hi - lo) // 2
if trailing_zeros(mid) < target:
lo = mid + 1
elif trailing_zeros(mid) > target:
hi = mid
else:
hi = mid
return lo
def right_bound(target):
# 右边界
lo, hi = 0, 10e9
while lo < hi:
mid = lo + (hi - lo) // 2
if trailing_zeros(mid) < target:
lo = mid + 1
elif trailing_zeros(mid) > target:
hi = mid
else:
lo = mid + 1
return lo - 1
return int(right_bound(k) - left_bound(k) + 1) |
Beta Was this translation helpful? Give feedback.
-
daka |
Beta Was this translation helpful? Give feedback.
-
打卡,感谢楼主! |
Beta Was this translation helpful? Give feedback.
-
谢谢 |
Beta Was this translation helpful? Give feedback.
-
复杂度能这样分析的吗?那所有问题的n都小于某个常数,岂不是所有的复杂度都是常数了 |
Beta Was this translation helpful? Give feedback.
-
@NicholasIssac 比较小的数据可以这样分析,log(LONG_MAX) 最多不超过 64,当然可以认为是常数 |
Beta Was this translation helpful? Give feedback.
-
这个结果只能是5呀。。。超过5个就会多一个0或者少一个0。 |
Beta Was this translation helpful? Give feedback.
-
可以不用搜索右边界的 因为k+1 的左边界是 类似的东西 class Solution {
public int preimageSizeFZF(int k) {
return (int) (left(k+1) - left(k));
// return (int)(right_bound(k) - left(k) + 1);
}
long left(int target) {
long lo = 0, hi = Long.MAX_VALUE;
while( lo < hi) {
long mid = lo + (hi-lo)/2;
if(trailingZeroes(mid) < target) {
lo = mid +1;
} else {
hi = mid;
}
}
return lo;
}
// long right_bound(int target) {
// long lo = 0, hi = Long.MAX_VALUE;
// while (lo < hi) {
// long mid = lo + (hi - lo) / 2;
// if (trailingZeroes(mid) < target) {
// lo = mid + 1;
// } else if (trailingZeroes(mid) > target) {
// hi = mid;
// } else {
// lo = mid + 1;
// }
// }
// return lo - 1;
// }
public long trailingZeroes(long n) {
long res = 0;
for(long d = n; d/5 > 0; d = d/5) {
res += d/5;
}
return res;
}
} |
Beta Was this translation helpful? Give feedback.
-
打卡。 当找到>=k的左边界后left,>=(k+1)的做边界只能是 left 或者left+5. class Solution:
def preimageSizeFZF(self, k: int) -> int:
def zeros(n):
n_0 = 0
while n > 0:
n = n//5
n_0 += n
return n_0
# print(zeros(10000000000)>pow(10,9))
def find_k(left, right, k):
#返回大于等于k的最小值
while left<right:
mid = left + (right-left)//2
n0 = zeros(mid)
if n0>k:
right = mid
elif n0<k:
left = mid + 1
else:
right = mid
return left
left = find_k(0, 10000000000, k)
right = find_k(left, left+5, k+1)
# print(left, right)
return right-left |
Beta Was this translation helpful? Give feedback.
-
为什么这里需要用while(left < right )而不是while(left <= right)? |
Beta Was this translation helpful? Give feedback.
-
二分法lo的初始值设4k就行 |
Beta Was this translation helpful? Give feedback.
-
我们只需要搜索有没有一个数的阶乘的结果的0的个数为k个,如果存在这个数,那么它前面四个肯定也是可以的,返回值要么是0要么是5.
|
Beta Was this translation helpful? Give feedback.
-
"够了吗?我们发现 125 = 5 x 5 x 5,像 125,250 这些 125 的倍数,可以提供 3 个因子 5,那么我们还得再计算出 125! 中有 125 / 125 = 1 个 125 的倍数,它还可以额外再提供一个因子 5。" 这里不太明白,125 / 125 = 1 ,不应该是能提供1*3=3个因子5吗?? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
文章链接点这里:讲两道常考的阶乘算法题
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions