当前位置: 首页 > news >正文

数据结构与算法-分裂问题,将数字分成0或1,求l到r之间有多少个1.

// 分裂问题
一个数n,可以分裂成一个数组[n/2, n%2, n/2], 这个数组中哪个数不是1或者0,就继续分裂下去。
比如 n = 5,一开始分裂成[2, 1, 2], [2, 1, 2]这个数组中不是1或者0的数,会继续分裂下去,比如两个2就继续分裂 [2, 1, 2] -> [1, 0, 1, 1, 1, 0, 1],那么我们说,5最后分裂成[1, 0, 1, 1, 1, 0, 1]。每一个数都可以这么分裂,在最终分裂的数组中,假设下标从1开始给定三个数n、l、r,返回n的最终分裂数组里[l,r]范围上有几个1。 n <= 2 ^ 50,n是long类型, r - l <= 50000,l和r是int类型。

importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Map;importjava.util.Set;public class Code_SplitZeroOne{// n=100// n=100, 最终裂变的数组,长度多少? // n=50, 最终裂变的数组,长度多少? // n=25, 最终裂变的数组,长度多少? //..// n=1,.最终裂变的数组,长度多少? // 请都填写到lenMap中去! public static long len(long n, HashMap<Long, Long>lenMap){if(n==0||n==1){lenMap.put(n,1L);return1;}long half=len(n/2,lenMap);long all=(half<<1)+1;lenMap.put(n, all);returnall;}// n=100// n=100, 最终裂变的数组中,一共有几个1 // n=50, 最终裂变的数组,一共有几个1 // n=25, 最终裂变的数组,一共有几个1 //..// n=1,.最终裂变的数组,一共有几个1 // 请都填写到onesMap中去! public static long ones2(long num, HashMap<Long, Long>onesMap){if(num==1||num==0){onesMap.put(num, num);returnnum;}// n>1long half=ones2(num /2, onesMap);long mid=num %2==1?1:0;long all=half *2+ mid;onesMap.put(num, all);returnall;}public static long ones(long n, HashMap<Long, Long>onesMap){if(n==0||n==1){onesMap.put(n,n);returnn;}int mid=(n %2)==1?1:0;long half=ones(n/2,onesMap);long all=(half<<1)+ mid;onesMap.put(n, all);returnall;}public static long nums3(long n, long l, long r){//HashMap<Long, Long>allMap=new HashMap<>();HashMap<Long, Long>lenMap=new HashMap<>();HashMap<Long, Long>oneMap=new HashMap<>();long len=len(n,lenMap);long ones=ones(n,oneMap);returndp2(n,l,r,lenMap,oneMap);}public static long dp2(long n, long l, long r, HashMap<Long,Long>lenMap, HashMap<Long,Long>onesMap){long allLen=lenMap.get(n);if(l<=1&&allLen<=r){returnonesMap.get(n);}long all=0;int mid=(n%2==1)?1:0;long halfLen=(allLen-1)/2;if(l<halfLen+1){all+=dp2(n/2,l,Math.min(r,halfLen),lenMap,onesMap);}if(r>halfLen+1){all+=dp2(n/2,Math.max(l-halfLen-1,1),r-halfLen-1,lenMap,onesMap);}all+=((l>halfLen+1||r<halfLen+1)?0:mid);return all;}//为了测试//彻底生成n的最终分裂数组返回 public static ArrayList<Integer>test(long n){ ArrayList<Integer>arr=new ArrayList<>();process(n,arr);return arr;} public static void process(long n,ArrayList<Integer>arr){ if(n==1||n==0){ arr.add((int)n);} else { process(n/2,arr);arr.add((int)(n%2));process(n /2, arr);}}public static long nums1(long n, long l, long r){if(n==1||n==0){returnn==1?1:0;}long half=size(n /2);long left=l>half ?0:nums1(n /2, l, Math.min(half, r));long mid=(l>half +1||r<half +1)?0:(n&1);long right=r>half +1? nums1(n /2, Math.max(l - half -1,1), r - half -1):0;returnleft + mid + right;}public static long size(long n){if(n==1||n==0){return1;}else{long half=size(n /2);return(half<<1)+1;}}public static void main(String[]args){long num=671;ArrayList<Integer>ans=test(num);int testTime=10000;System.out.println("功能测试开始");for(int i=0;i<testTime;i++){int a=(int)(Math.random()* ans.size())+1;int b=(int)(Math.random()* ans.size())+1;int l=Math.min(a, b);int r=Math.max(a, b);int ans1=0;for(int j=l -1;j<r;j++){if(ans.get(j)==1){ans1++;}}long ans2=nums1(num, l, r);long ans3=nums3(num, l, r);if(ans1!=ans2||ans1!=ans3){System.out.println("出错了!");}}System.out.println("功能测试结束");System.out.println("==============");System.out.println("性能测试开始");num=(2L<<50)+ 22517998136L;long l=30000L;long r=800000200L;long start;long end;start=System.currentTimeMillis();System.out.println("nums1结果 : "+ nums1(num, l, r));end=System.currentTimeMillis();System.out.println("nums1花费时间(毫秒) : "+(end - start));start=System.currentTimeMillis();System.out.println("nums3结果 : "+ nums3(num, l, r));end=System.currentTimeMillis();System.out.println("nums3花费时间(毫秒) : "+(end - start));System.out.println("性能测试结束");System.out.println("==============");System.out.println("单独展示nums2方法强悍程度测试开始");num=(2L<<55)+ 22517998136L;l=30000L;r=6431000002000L;start=System.currentTimeMillis();System.out.println("nums2结果 : "+ nums3(num, l, r));//-1429513860end=System.currentTimeMillis();System.out.println("nums2花费时间(毫秒) : "+(end - start));System.out.println("单独展示nums2方法强悍程度测试结束");}}
http://www.jsqmd.com/news/449080/

相关文章:

  • 轻量级时间选择插件bootstrap-datetimepicker:提升开发效率的全方位解决方案
  • 闭眼入!9个AI论文网站测评:本科生毕业论文写作必备工具推荐
  • picacomic-downloader:打造高效漫画收藏管理新体验
  • 网页资源获取效率低下?猫抓Cat-Catch让你的工作流提速300%的实战指南
  • 解锁3种Cursor Pro技术痛点的创新方案:从原理到实战的深度指南
  • 3月必看!2026年污水处理设备厂家实力推荐,二氧化氯发生器/实验室污水处理设备,污水处理设备供货厂家选哪家 - 品牌推荐师
  • 颠覆式Windows安卓应用安装解决方案:APK Installer全攻略
  • 科研党收藏!当红之选的AI论文网站 —— 千笔·专业论文写作工具
  • AR眼镜菜谱助手:在厨房里飘浮的烹饪指南
  • 在大学的算法竞赛中时间复杂度和空间复杂度的临界点【最大值】
  • 2026高剪切分散机制造厂年度排名,好用的品牌有哪些 - 工业品网
  • 3步掌握轻量级工具G-Helper:释放ROG设备控制潜能
  • TIDAL音乐高效工具:从入门到精通的完整指南
  • 大数据领域数据清洗:提升数据质量和效率的关键
  • 2026年全国好用的有机肥设备制造厂家排名,性价比高的揭晓 - 工业设备
  • 2026必备!8个AI论文工具测评:本科生毕业论文写作与格式规范全攻略
  • 常州中禹激光装备与同行相比怎么样,江苏地区购买费用大概多少钱 - 工业品牌热点
  • 上海2026猫咪绝育指南:专业靠谱专家一览,狗狗绝育/猫咪乳糜胸手术/腹腔镜绝育/狗狗隐睾绝育,猫咪绝育医生推荐排行榜单 - 品牌推荐师
  • 2026年卧式砂磨机生产厂价格对比,选购靠谱厂家 - 工业品网
  • 分析户外亮化灯具生产厂,林德照明产品性价比怎么样? - 工业设备
  • 一文彻底搞懂:Redis 为什么能超高并发、超低延迟?
  • 百联OK卡怎么变现?快速变现技巧详解! - 团团收购物卡回收
  • 解决Ubuntu新用户 Tab 自动补全失效问题
  • 修改文件“创建时间/修改时间/访问时间”方法
  • 用 AR 眼镜打造你的办公助手,使用 Unity 开发到 Rokid 部署全记录
  • 关于 DOM- Document Object Model - 最常见到的节点的类型
  • 说说重庆知名的工业机器人培训机构,哪家口碑好? - myqiye
  • 解读重庆新华无人机维修培训,口碑比较靠谱的有吗? - 工业推荐榜
  • 各类ISO下载
  • 帝国cms为什么信息管理的”信息栏目”列表不变?EmpireCMS