Leetcode 第 380 场周赛 Problem C 价值和小于等于 K 的最大数字(Java + 二分答案 + 规律)

这篇具有很好参考价值的文章主要介绍了Leetcode 第 380 场周赛 Problem C 价值和小于等于 K 的最大数字(Java + 二分答案 + 规律)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目

  • Problem: 100160. 价值和小于等于 K 的最大数字
  • 给你一个整数 k 和一个整数 x 。
  • 令 s 为整数 num 的下标从 1 开始的二进制表示。我们说一个整数 num 的 价值 是满足 i % x == 0 且 s[i] 是 设置位 的 i 的数目。
  • 请你返回 最大 整数 num ,满足从 1 到 num 的所有整数的 价值 和小于等于 k 。
  • 注意:
    • 一个整数二进制表示下 设置位 是值为 1 的数位。
    • 一个整数的二进制表示下标从右到左编号,比方说如果 s == 11100 ,那么 s[4] == 1 且 s[2] == 0 。
    • 1 <= k <= 10 ^ 15
    • 1 <= x <= 8

思路

Java + 二分答案 + 规律

第 1 步:

  • 首先 [1, maxNum] 在确定 x 后显然满足"价值和"单调非递减,因此可以二分最大值 maxNum
  • 其次需要确定 [1, maxNum] 在确定 x 的"价值和"就行

第 2 步:

  • 二分答案确定上下界:
    • k 最小为 1,x 最小为 1 代表每一位均统计,此时结果最小、即下界为 1
    • k 最大为 1e15,x 最大为 8 代表每 8 位统计一次、即每 2^8 个数最少会记录 1 次,此时结果最大,而开始的 [1, 2^8-1] 在 x=8 时不统计,因此上界就是 (k+1)*2^8-1

第 3 步:

  • [1, maxNum] 在 x 下的"价值和"可以找规律,我们先写出 [1, 8] 的二进制:
  • 0001
  • 0010
  • 0011
  • 0100
  • 0101
  • 0110
  • 0111
  • 1000
  • 按题意最后一位往前看(可以多写几位来看):
    • 第 1 位是先零位 0 然后"一位 1 一位 0"的 10 依次循环
    • 第 2 位是先一位 0 然后"两位 1 两位 0"的 10 依次循环
    • 第 3 位是先三位 0 然后"四位 1 四位 0"的 10 依次循环
    • 第 4 位是先七位 0 然后"八位 1 八位 0"的 10 依次循环
  • 如果我们前面加上 0,可以得到第 i 位是 “2^(i-1) 位 0 与 2^(i-1) 位 1” 的 01 依次循环

第 4 步:

  • 对于 [1, maxNum] 先转化为 [0, maxNum] 总共 maxNum+1 个数,
  • 然后循环 long 总共的 63 位 i,当满足 (i % x == 0) 时,记录第 i 位"价值和",
  • 分为前面循环的 1 + 可能有的最后一个不完整的循环 1
  • 前面循环的 1,先除循环再乘完整的 1:(maxNum + 1) / 2^i * 2^(i-1)
  • 可能有的最后一个不完整的循环 1,先减去完整循环再减去开头的 0:max((maxNum + 1) % 2^i - 2^(i-1), 0)

复杂度

时间复杂度:

时间复杂度: O ( 63 ∗ l o g ( k < < x ) ) O(63*log(k<<x)) O(63log(k<<x))

空间复杂度:

空间复杂度: O ( n ) O(n) O(n)文章来源地址https://www.toymoban.com/news/detail-805692.html

Code

class Solution {
    /**
     * Java + 二分答案 + 规律:
     *
     * 第 1 步:
     * 首先 [1, maxNum] 在确定 x 后显然满足"价值和"单调非递减,因此可以二分最大值 maxNum,
     * 其次需要确定 [1, maxNum] 在确定 x 的"价值和"就行
     *
     * 第 2 步:
     * 二分答案确定上下界:
     *     * k 最小为 1,x 最小为 1 代表每一位均统计,此时结果最小、即下界为 1
     *     * k 最大为 1e15,x 最大为 8 代表每 8 位统计一次、即每 2^8 个数最少会记录 1 次,此时结果最大,而开始的 [1, 2^8-1] 在 x=8 时不统计,因此上界就是 (k+1)*2^8-1
     *
     * 第 3 步:
     * [1, maxNum] 在 x 下的"价值和"可以找规律,我们先写出 [1, 8] 的二进制:
     * 0001
     * 0010
     * 0011
     * 0100
     * 0101
     * 0110
     * 0111
     * 1000
     * 按题意最后一位往前看(可以多写几位来看):
     *     * 第 1 位是先零位 0 然后"一位 1 一位 0"的 10 依次循环
     *     * 第 2 位是先一位 0 然后"两位 1 两位 0"的 10 依次循环
     *     * 第 3 位是先三位 0 然后"四位 1 四位 0"的 10 依次循环
     *     * 第 4 位是先七位 0 然后"八位 1 八位 0"的 10 依次循环
     * 如果我们前面加上 0,可以得到第 i 位是 "2^(i-1) 位 0 与 2^(i-1) 位 1" 的 01 依次循环,
     *
     * 第 4 步:
     * 对于 [1, maxNum] 先转化为 [0, maxNum] 总共 maxNum+1 个数,
     * 然后循环 long 总共的 63 位 i,当满足 (i % x == 0) 时,记录第 i 位"价值和",
     * 分为前面循环的 1 + 可能有的最后一个不完整的循环 1
     * 前面循环的 1,先除循环再乘完整的 1:(maxNum + 1) / 2^i * 2^(i-1)
     * 可能有的最后一个不完整的循环 1,先减去完整循环再减去开头的 0:max((maxNum + 1) % 2^i - 2^(i-1), 0)
     * 时间复杂度:O(63*log(k<<x)),空间复杂度:O(1)
     *
     */
    public long findMaximumNumber(long k, int x) {
        // 二分答案,确定上下界
        long left = 1;
        long right = (k + 1) << x - 1;

        long res = 1;
        while (left <= right) {
            // 避免加法溢出
            long mid = ((right - left) >> 1) + left;
            // 获取 [1, mid] 在 x 下的"价值和"
            long count = getCount(mid, x);
            if (count <= k) {
                res = mid;
                left = mid + 1;

            } else {
                right = mid - 1;
            }
        }

        return res;
    }

    /**
     * 获取 [1, maxNum] 在 x 下的"价值和"
     */
    private long getCount(long maxNum, int x) {
        long res = 0;
        // long 的最大值有 63 位
        for (int i = 1; i <= 63; i++) {
            if (i % x == 0) {
                // 获取每个循环之和
                res += (maxNum + 1) / (1L << i) * (1L << i - 1);
                // 获取可能有的最后一个不完整的循环
                res += Math.max((maxNum + 1) % (1L << i) - (1L << i - 1), 0);
            }
        }

        return res;
    }
}

到了这里,关于Leetcode 第 380 场周赛 Problem C 价值和小于等于 K 的最大数字(Java + 二分答案 + 规律)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【LeetCode周赛】LeetCode第370场周赛

    一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 = i, j = n - 1 且 i != j 的所有 i, j :如果 grid[i][j] == 1,那么 i 队比 j 队 强 ;否则,j 队比 i 队 强 。 在这场比赛中,如果不存在某支强于 a 队的队伍,则认为

    2024年02月05日
    浏览(48)
  • [LeetCode周赛复盘] 第 348场周赛20230604

    这场可惜了。 T1 模拟。 T2 模拟。 T3 倒序计算。 T4 同时限制上下界的数位DP。 6462. 最小化字符串长度 1. 题目描述 2. 思路分析 题意仔细想一下就会发现,其实会将每个字符仅留1个。 3. 代码实现 6424. 半有序排列 1. 题目描述 2. 思路分析 由于只能相邻交换来移动,因此每次只能

    2024年02月08日
    浏览(38)
  • [LeetCode周赛复盘] 第 359 场周赛20230820

    T1 模拟。 T2 数学贪心。 T3 dp。 T4 分组+滑窗。 2828. 判别首字母缩略词 1. 题目描述 2. 思路分析 按题意模拟即可。 3. 代码实现 2829. k-avoiding 数组的最小总和 1. 题目描述 2. 思路分析 贪心 1~k-1中,选了1就不能选k-1;选了2就不能选k-2… 因此可以选1~k//2 剩余的从k开始向上选。 可以

    2024年02月11日
    浏览(34)
  • [LeetCode周赛复盘] 第 353 场周赛20230709

    感觉有奖品大家都来了。 T1 数学。 T2 dp。 T3 dp。 T4 差分/BIT RUPQ。 6451. 找出最大的可达成数字 1. 题目描述 2. 思路分析 为了使x num在t步内相同,需要相向而行,每步最大缩短距离是2,那么t步距离是2t。 3. 代码实现 6899. 达到末尾下标所需的最大跳跃次数 1. 题目描述 2. 思路分

    2024年02月15日
    浏览(31)
  • LeetCode第354场周赛

    给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 对 nums 中的元素 nums[i] 而言,如果 n 能够被 i 整除,即 n % i == 0 ,则认为 num[i] 是一个 特殊元素 。 返回 nums 中所有 特殊元素 的 平方和 。 直接模拟就好了 给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。 在一

    2024年02月16日
    浏览(57)
  • leetcode 第360场周赛

    好久没参加leetcode周赛了,比赛时间都从两小时变成了一个半小时。这次周赛由两道签到题和两道中等难度题组成,严格来说最后一道的难度也可以视为hard,但是只要想到正确的思路,编码还是比较容易的。 比赛链接:leetcode 第 360 场周赛 题目描述 给你一个长度为 n 的字符串

    2024年02月11日
    浏览(36)
  • LeetCode第343场周赛

    2023.4.30LeetCode第343场周赛 根据题意模拟 使用哈希表记录每个数出现的位置,再用m+n个集合记录每一行和每一列被涂满的格子数,若某行或某列全部被涂满则返回答案 BFS 首先将距离大于两点的曼哈顿距离的特殊路径去掉 每个点考虑经过每个特殊路径到达,分成两段,一段是当

    2024年02月02日
    浏览(40)
  • LeetCode第347场周赛

    2023.5.28LeetCode第347场周赛 从最后一位开始遍历,为0则跳过 暴力模拟 对于每个 s[i] != s[i - 1] ,要使其相等 有两种选择,翻转前 i 个,或者翻转后 n - i 个,选择代价最小的方案 动态规划 从小到大枚举所有值,每个值一定是从更小的数转移而来 定义动态规划数组f, f[i][j] 表示

    2024年02月06日
    浏览(72)
  • leetcode第 357/358 场周赛

    可能别人有更好的解法,我这写法是不断往线段树中插入数值,每次先插入nums[i-x],然后搜索(1到i)中的最大值和(i到max)中的最小值去更新ans。 看了看别人题解,直接用set写是真的牛。自己还是见识短浅了。 暴力乱搞,考虑两种极端情况,一种无脑选profit大的,一种优先选

    2024年02月12日
    浏览(39)
  • leetcode第354场周赛补题

    6889. 特殊元素平方和 - 力扣(LeetCode) 思路:模拟 6929. 数组的最大美丽值 - 力扣(LeetCode) 思路:排序+双指针 6927. 合法分割的最小下标 - 力扣(LeetCode) 思路:哈希+枚举 6924. 最长合法子字符串的长度 - 力扣(LeetCode) 思路:哈希+双指针

    2024年02月16日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包