【位运算】【二分查找】【C++算法】100160价值和小于等于 K 的最大数字

简介: 【位运算】【二分查找】【C++算法】100160价值和小于等于 K 的最大数字

LeetCode100160. 价值和小于等于 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 = 9, x = 1

输出:6

解释:数字 1 ,2 ,3 ,4 ,5 和 6 二进制表示分别为 “1” ,“10” ,“11” ,“100” ,“101” 和 “110” 。

由于 x 等于 1 ,每个数字的价值分别为所有设置位的数目。

这些数字的所有设置位数目总数是 9 ,所以前 6 个数字的价值和为 9 。

所以答案为 6 。

示例 2:

输入:k = 7, x = 2

输出:9

解释:由于 x 等于 2 ,我们检查每个数字的偶数位。

2 和 3 在二进制表示下的第二个数位为设置位,所以它们的价值和为 2 。

6 和 7 在二进制表示下的第二个数位为设置位,所以它们的价值和为 2 。

8 和 9 在二进制表示下的第四个数位为设置位但第二个数位不是设置位,所以它们的价值和为 2 。

数字 1 ,4 和 5 在二进制下偶数位都不是设置位,所以它们的价值和为 0 。

10 在二进制表示下的第二个数位和第四个数位都是设置位,所以它的价值为 2 。

前 9 个数字的价值和为 6 。

前 10 个数字的价值和为 8,超过了 k = 7 ,所以答案为 9 。

提示:

1 <= k <= 1015

1 <= x <= 8

二分查找

随着num的增加,价值和单调增加。这是二分查找的基础。寻找最后一个符合条件的nums,用左闭右开空间。

如何求1到num第i位的价值和。 由于0不包括1,所以本问题等效与0到num的价值和。

i==0 0 1 周期长度2
i==1 00 01 10 11… 周期长度4
i==2 000 001 010 011 100 101 110 111… 周期长度8

周期长度 1<

[0,num]共num+1个数。

  • 完整周期数:(num+1)/(1 << i ) 每个周期有半数1
  • 不足一个周期的数有iCnt2= (num+1)%(1<

代码

核心代码

这周的LeetCode C++可能有问题,总溢出,所以加了不少判断。

class Solution {
public:
  long long findMaximumNumber(long long k, int x) {
    long long left = 0, r = 5e17;
    while (r - left > 1)
    {
      const auto mid = left + (r - left) / 2;
      if (Cnt(mid, k,x) <= k)
      {
        left = mid;
      }
      else
      {
        r = mid;
      }
    }
    return left;
  }
  long long Cnt(long long mid,int k,int x )
  {
    long long llCnt = 0;
    for (int ii = x; ii <= 60; ii += x)
    {
      const long long tmp = 1LL << ii;//周期
      const long long cur1 = (mid + 1) / tmp * (tmp / 2); 
      const long long cur2 = max(0LL, (mid + 1) % tmp - tmp / 2);
      if (LLONG_MAX - llCnt < cur1)
      {
        return k + 1;
      }
      llCnt += cur1;
      if (LLONG_MAX - llCnt < cur2)
      {
        return k + 1;
      }
      llCnt += cur2;
    }
    return llCnt;
  }
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
  assert(t1 == t2);
}
template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
  if (v1.size() != v2.size())
  {
    assert(false);
    return;
  }
  for (int i = 0; i < v1.size(); i++)
  {
    Assert(v1[i], v2[i]);
  }
}
int main()
{
  long long k;
  int x;
  {
    Solution sln;
    k = 19, x = 6;
    auto res = sln.findMaximumNumber(k, x);
    Assert(50LL, res);
  }
  {
    Solution sln;
    k = 9, x = 1;
    auto res = sln.findMaximumNumber(k, x);
    Assert(6LL, res);
  }
  {
    Solution sln;
    k = 7, x = 2;
    auto res = sln.findMaximumNumber(k, x);
    Assert(9LL, res);
  }
  {
    Solution sln;
    k = 343883588590415, x = 1;
    auto res = sln.findMaximumNumber(k, x);
    //Assert(9LL, res);
  } 
}


扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。

https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程

https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关文章
|
3月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
94 1
|
1月前
|
存储 算法 C++
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
二分查找的基本思想是:每次比较中间元素与目标元素的大小,如果中间元素等于目标元素,则查找成功;顺序表是线性表的一种存储方式,它用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的元素在物理存储位置上也相邻。第1次比较:查找范围R[0...10],比较元素R[5]:25。第1次比较:查找范围R[0...10],比较元素R[5]:25。第2次比较:查找范围R[0..4],比较元素R[2]:10。第3次比较:查找范围R[3...4],比较元素R[3]:15。,其中是顺序表中元素的个数。
137 68
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
|
1天前
|
存储 监控 算法
员工屏幕监控系统之 C++ 图像差分算法
在现代企业管理中,员工屏幕监控系统至关重要。本文探讨了其中常用的图像差分算法,该算法通过比较相邻两帧图像的像素差异,检测屏幕内容变化,如应用程序切换等。文中提供了C++实现代码,并介绍了其在实时监控、异常行为检测和数据压缩等方面的应用,展示了其实现简单、效率高的特点。
27 15
|
1天前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
22 12
|
1月前
|
负载均衡 算法 安全
探秘:基于 C++ 的局域网电脑控制软件自适应指令分发算法
在现代企业信息化架构中,局域网电脑控制软件如同“指挥官”,通过自适应指令分发算法动态调整指令发送节奏与数据量,确保不同性能的终端设备高效运行。基于C++语言,利用套接字实现稳定连接和线程同步管理,结合实时状态反馈,优化指令分发策略,提升整体管控效率,保障网络稳定,助力数字化办公。
52 19
|
1月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
51 2
|
2月前
|
存储 算法 安全
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
|
1月前
|
存储 算法 安全
基于哈希表的文件共享平台 C++ 算法实现与分析
在数字化时代,文件共享平台不可或缺。本文探讨哈希表在文件共享中的应用,包括原理、优势及C++实现。哈希表通过键值对快速访问文件元数据(如文件名、大小、位置等),查找时间复杂度为O(1),显著提升查找速度和用户体验。代码示例展示了文件上传和搜索功能,实际应用中需解决哈希冲突、动态扩容和线程安全等问题,以优化性能。
|
2月前
|
算法 索引
【算法】——二分查找合集
二分查找基础模版和进阶模版,查找元素位置,搜索插入位置,x的平方根,山脉数组的峰顶索引,寻找峰值,点名
|
2月前
|
算法
【算法】位运算合集
/鸽巢原理优化//位图原理//bitMap&0001000只有非0或者0两个结果//说明当前bitMap位是0,那就添加进去}else{//1:把字符串转化为字符数组// //2:把字符扔到hash表中// //获取hash表中x的value值// }else{// }// }