leetcode每日一题系列-斐波那契数列-「矩阵快速幂」-「动态规划+滚动数组」 - 用rand7实现rand10-「投机取巧」-「概率转换」

481 阅读2分钟

leetcode-470-用 Rand7() 实现 Rand10()

[博客链接]

菜🐔的学习之路

掘金首页

[题目链接]

用rand7实现rand10

斐波那契数列

[github地址]

用rand7实现rand10

斐波那契数列


[用rand7实现rand10]

思路一:投机取巧(不严格求解)

  • 在线OJ真的不太聪明
  • 这种概率题对他来说很难验证所有用例的准确度
  • 所以我们可以通过投机取巧来解决
 public int rand10() {
            int res = 0;
            for(int i = 0; i < 10; i++){
                res += rand7();
            }
            return res % 10 + 1;
        }

  • 时间复杂度O(1)
  • 空间复杂度O(1)

思路二:概率转换

  • rand10 -> rand7的概率是相同的
  • 具体概率求和公式我就不写@jerry_nju
  • 大家可以看一下这个大佬的题解
  • 然后我们就做一个更大的转换为rand49 -> rand7
 public int rand10() {
            int num = (rand7() - 1) * 7 + rand7();
            while (num > 10) {
                num = (rand7() - 1) * 7 + rand7();
            }
            return num;
        }
  • 时间复杂度O(1)
  • 空间复杂度O(1)

思路三:思路二的优化

  • 可以舍弃掉9个数,只取前四十个数
public int rand10() {
            int num = (rand7() - 1) * 7 + rand7();
            while (num > 40) {
                num = (rand7() - 1) * 7 + rand7();
            }
            return 1 + num % 10;
        }
  • 时间复杂度O(1)
  • 空间复杂度O(1)

思路四:思路三的优化

  • 也差不多的思路
  • 代码也是cv过来的理解起来倒是不复杂,不过这道题我确实没有想到
  • 感觉更偏数学,我实在是不太擅长
public int rand10() {
            while (true) {
                int num = (rand7() - 1) * 7 + rand7();
                // 如果在40以内,那就直接返回
                if (num <= 40) return 1 + num % 10;
                // 说明刚才生成的在41-49之间,利用随机数再操作一遍
                num = (num - 40 - 1) * 7 + rand7();
                if (num <= 60) return 1 + num % 10;
                // 说明刚才生成的在61-63之间,利用随机数再操作一遍
                num = (num - 60 - 1) * 7 + rand7();
                if (num <= 20) return 1 + num % 10;

            }
        }
  • 时间复杂度O(1)
  • 空间复杂度O(1)

[斐波那契数列]

思路一:动态规划+滚动数组

  • 斐波那契数列只和前两个数有关,所以定义两个状态即可
  • 有些类似背包问题的维度优化
 public int[] smallestK(int[] arr, int k) {
            int[] f = new int[]{0, 1};
        int mod = (int) 1e9 + 7;

        public int fib(int n) {
            if (n < 2) {
                return f[n];
            }
            for (int i = 2; i <= n; i++) {
                f[i & 1] = (f[0] + f[1]) % mod;
            }
            return f[n & 1] % mod;
        }
        }

  • 时间复杂度O(n)
  • 空间复杂度O(1)

思路二: 矩阵快速幂

  • 忘记了这种题可以用矩阵快速幂了
  • 具体代码可以参照三叶大佬的题解代码
  • 我这里就不cv了
  • 学过现代理解这个简单的二维乘法还是很简单的
  • 时间复杂度O(lgn)
  • 空间复杂度O(1)