2.8 找出整除n的只有0, 1的数
来源:互联网 发布:华为mac地址在哪里 编辑:程序博客网 时间:2024/06/05 18:59
1. 前言
本文的一些图片, 资料 截取自编程之美
2. 问题描述
3. 问题分析
这个问题主要 给定一个n, 然后寻找最小的能够整除n, 的并且只含有0, 1 的十进制数
解法一 : 穷举 0, 1, 10, 11, 100, 101, 110, 111, …
解法二 : 缓存<余数, 除以n余数为键的最小的整数>, 使用一个num计数, num从1开始, 每次迭代num*10, 遍历缓存表[遍历所有缓存余数], 如果num + entry.key能够被n整除, 那么则说明num + entry.key即为所求, 否则 判断num + entry.key 对应的余数不存在于缓存表, 则将<余数, num + entry.key> 添加到缓存表中, 所以缓存表中保存的就是 余数和余数对应的最小的能够被n整除的数字
这个思路减少了一些余数相同的数, 的重复计算 [比如 n为3, num为100, 假设之后的数为1, 10 [拼凑出101, 110], 因为1, 10 除以3 都余1 并且100除以3余数固定 , 所以这两个计算实际上是重复的, 而这里的思路, 就减少了这种重复的计算 ]
但是第二种思路的优势, 确实是挺难的, 吧备选的数字(们), 限制在了最多为n个
比如n为13, 而现在num跑到了1000000, 这样1000000, 之后的备选数字有2^6 64个, 而第二种思路, 将备选数字限制到了最多12个
编程之美分析原图 :
4. 代码
/** * file name : Test14ModNGotOnly01.java * created at : 9:21:48 AM May 23, 2015 * created by 970655147 */package com.hx.test03;import com.hx.util.Log;public class Test15ModNGotOnly01 { // 获取能够整除n 并且只包含01的整数 public static void main(String []args) { long start = System.currentTimeMillis(); Random ran = new Random(); int n = ran.nextInt(500);// int n = 111; Log.log(n); findModGotOnly0101(n); Log.enter(); findModGotOnly0102(n); Log.horizon(); long spent = System.currentTimeMillis() - start; Log.log("spent : " + spent + " ms..."); } // 穷举 1, 10, 11, 100, ... public static void findModGotOnly0101(int n) { int i = 1; boolean isFound = false; while(!isFound) { int num = Integer.valueOf(Integer.toBinaryString(i ++ )); if((num % n) == 0 ) { isFound = true; Log.log(num); break; } if(num > (Integer.MAX_VALUE >> 1) ) { Log.log("specified number not find..."); break; } } } // num : 1 -> 10 -> 100 -> ... // 先检查modValues中的对象 // 在检查num能否被n整除 // modValues存放于n计算<取得的模[除了0], 最小的值> // 比如 n为3 则1 -> 1, 2 -> 11 // tmp用于存放本次计算中可以加入modValues中的entry[因为 如果直接在循环中加入modValues的话 会打乱计算] // 比如 如果num为100 如果计算得到了一个(1111 -> 3)可以加入modValues // 如果直接加入的话 下一次循环计算的时候 会将这个1111也一并计算了 导致计算的不准确[1000 + 1111 = 2111]] // 所以先将可存储的entry 存入tmp中 循环结束 加入到modValues中 public static void findModGotOnly0102(int n) { Map<Integer, Integer> modValues = new HashMap<Integer, Integer>(n - 1); Map<Integer, Integer> tmp = new HashMap<Integer, Integer>( (n >> 1) ); int i = 1; int num = i; boolean isFound = false; while(!isFound) { int modVal = num % n; tmp.clear(); for(Map.Entry<Integer, Integer> entry : modValues.entrySet() ) { int mayBeRes = entry.getKey() + modVal; int modVal02 = mayBeRes % n; if(modVal02 == 0) { isFound = true; Log.log(num + entry.getValue() ); break; } else { if(!modValues.containsKey(modVal02) ) { tmp.put(modVal02, num + entry.getValue()); } } } modValues.putAll(tmp); if(modVal == 0) { isFound = true; Log.log(num); } else { if(!modValues.containsKey(modVal) ) { modValues.put(modVal, num); } } // 如果快要越界了还没有找到 则视为找不到了 if(!isFound && (num > (Integer.MAX_VALUE >> 1)) ) { Log.log("specified number not find..."); break; } num *= 10; } }}
5. 运行结果
6. 总结
穷举的想法当然不是很难想到
第二种思路是非常巧妙的, 再再一次证明了数学与算法的紧密联系
注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!
0 0
- 2.8 找出整除n的只有0, 1的数
- 广搜搜法找出只有1和0组成的n的最小倍数问题
- 丑数,即只有2,3,5因子的整数,找出第n 个丑数
- 一连串1组成的数被n整除问题
- 找出最小的能被1-20中每个数整除的数。
- 题目5:找出最小的能被1-20中每个数整除的数。
- 找出100-201之间的素数,除了1和它本身不能被整除的数
- poj 2356 Find a multiple 【抽屉原理应用】【在n个数组成的数列中找出若干个连续数使它们之和能被n整除】
- 欧拉工程第5题 找出最小的能被1-20中每个数整除的数
- 找出1至n之间同构数的个数---转载
- 找出1至n之间同构数的个数
- 找出1到n缺失的那个数
- 找出1到n所有数的因数
- 找出N之内的所有完数
- 找出N之内的所有完数
- 找出N内的所有完数
- 找出N之内的所有完数
- 找出数组前N大的数
- linux 安装git
- 最小生成树普利姆算法c语言实现__Prim
- 老罗安卓教程 在TextView文本中实现走马灯效果
- [leetcode] 224.Basic Calculator
- R语言_数据结构
- 2.8 找出整除n的只有0, 1的数
- sqlite 3 使用交叉编译
- Python解析XML的minidom
- iOS AppsFlyer的使用注意事项
- 关于ElasticSearch
- Android软件安全与逆向分析笔记(2)
- Linux 网卡驱动学习(八)(基于 MAC 地址转发数据)
- 高并发事务处理方案 秒杀的分析
- CGContextRef用法