当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度:
Hard

题意:

  1. 求n!末尾有k个0的n有多少个

思路:

  • 因式分解,末尾有0肯定是2*5,不管n是多大,n!分解因式后,2的个数肯定比5的个数多
  • 假设给定n,如何求n!分解因式后有多少个5?每隔5个数贡献一个5因子,每隔25个数有多贡献一个5因子。。。统计能得到结果
  • 这个题的做法是二分一个范围区间,求出n!分解因式后因子5的个数等于k的上下界,相减所得
  • 这个题有个可优化的点,答案要么是0,要么是5,因为每隔5个数肯定会贡献一个5因子。那么我们只需要一个二分,找出是否有一个n,分解因式后有k个5因子,就可以返回5,否则返回0

解法:

  1. class Solution {
  2. private long cal5(long n) {
  3. long ret = 0;
  4. while (n != 0) {
  5. ret += n / 5;
  6. n /= 5;
  7. }
  8. return ret;
  9. }
  10. private long upper(long left, long right, int k) {
  11. while (right - left > 1) {
  12. long mid = (left + right) / 2;
  13. if (cal5(mid) <= k) {
  14. left = mid;
  15. } else {
  16. right = mid;
  17. }
  18. }
  19. if (cal5(left) == k) {
  20. return left;
  21. } else {
  22. return -1;
  23. }
  24. }
  25. private long lower(long left, long right, int k) {
  26. while (right - left > 1) {
  27. long mid = (left + right) / 2;
  28. if (cal5(mid) >= k) {
  29. right = mid;
  30. } else {
  31. left = mid;
  32. }
  33. }
  34. if (cal5(right) == k) {
  35. return right;
  36. } else {
  37. return -1;
  38. }
  39. }
  40. public int preimageSizeFZF(int K) {
  41. long n = upper(1, 6000000000L, K);
  42. if (n == -1) {
  43. return 0;
  44. } else {
  45. long m = lower(-1, n, K);
  46. return (int) (n - m + 1);
  47. }
  48. }
  49. }

该分类下的相关小册推荐: