2.8 寻找符合条件的数
来源:互联网 发布:淘宝seo是干什么的 编辑:程序博客网 时间:2024/05/21 15:55
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 寻找符合条件的数
- 一个数组中寻找所有三个符合条件的数
- 寻找符合条件的整数
- 1165符合条件的数
- 寻找符合条件的四位数
- 《编程之美》——快速寻找符合条件的两个数
- 编程之美2.8查找符合条件的数
- 《编程之美》 符合条件的数
- 4849:符合条件的数 分数: 3
- 找出符合以下条件的Troitsky数
- 连载5:寻找符合条件的整数(《编程之美》第2.8节)
- 寻找两个满足条件的数
- 快速寻找满足条件的两个数
- 快速寻找满足条件的两个数
- 快速寻找满足条件的两个数
- 快速寻找满足条件的两个数
- 寻找满足条件的两个数
- 寻找满足条件的两个数
- QT显示图片
- leetcode 133: Clone Graph
- Java跨平台开发神器之JNI
- Spring AOP
- LeetCode Regular Expression Matching
- 2.8 寻找符合条件的数
- QQ好友列表数据模型封装
- 8.17总结
- Django+redis 实现登录
- template < typename T >
- HDU 3970 Harmonious Set 容斥欧拉函数
- 大流量高并发性能优化
- Example of MPI_Type_struct
- OC协议protocol详解