题目描述
4和7是两个幸运数字,我们定义,十进制表示中,每一位只有4和7两个数的正整数都是幸运数字。
前几个幸运数字为:4,7,44,47,74,77,444,447...
现在输入一个数字K,输出第K个幸运数。
输入
第一行一个数字T(T<=1000)表示测试数据的组数。对于每组测试数据,输出一个数K
输出
每组数据输出一行,第K个幸运数。
样例输入
3
5
100
1000000000
样例输出
74
744747
77477744774747744747444444447
解析:
关于"幸运数字4和7"的问题,网上也有不少解决方案,基本上都是用二进制的思想进行处理,但其中使用了“Math.log”或者使用了“循环嵌套”来解决问题,我觉得这都不是太理想,应该避免掉”Math函数“和“循环嵌套”,下面看一下我的解题思路吧:
解题思路:
1、将幸运数字的解空间,当做一个二叉树来处理
2、一个j位长的幸运数字,可以看成是进行了j次选择,每次从4和7中选择一个作为幸运数字的一位,最终组成j+1层的二叉树
3、为了方便计算,我们将选4记为0,将选7记为1
4、求解的过程分两步:
4.1、求解所在的层数(利用二叉树的特性来计算)
4.2、求解是所在的层得几个节点(利用二叉树的性质来计算)
5、将得到的选择转换成4和7,即0->4;1->7
具体实现:
/**
* 思路:
* 1、将幸运数字的解空间,当做一个二叉树来处理
* 2、一个j位长的幸运数字,可以看成是进行了J次选择,每次从4和7中选择一个作为幸运数字的一位,最终组成二叉树
* 3、为了方便计算,我们将选4记为0,将选7记为1
* 4、求解的过程分两步:
* 4.1、求解所在的层数
* 4.2、求解是所在的层得几个节点
* 5、将得到的选择转换成4和7,即0->4;1->7
* @author zhangmeng
* @param n 第n个幸运数
* @return
*/
public static String getLuckNumber(int n){
//1、为方便处理将n装换成二进制的串
String str = Integer.toBinaryString(n);
//2、计算二叉树的层数层数
int level = str.length();
if(!str.contains("0")){
level += 1;
}
//3、设定第n个是所在层的第m个,计算m
int m= n-((1<<(level-1)) -2);
//4、计算对应的二进制
// (1)位数:就是所在层数减一,即level-1
// (2)大小:树的同一层是从0开始记得,以第四层为例 000,001,010,011,100,101,110,111
// 而m是从1,开始记的,所以从零开始计的话,就是第m-1个节点,
// 第m-1个节点的值就是将m-1转成二进制,左面以0填充
String result = Integer.toBinaryString(m-1);
while(result.length()<level-1){
result = "0"+result;
}
//5、将“0”换成“4”,“1”换成“7”,得到最终结果
result = result.replace("0", "4");
result = result.replace("1", "7");
return result;
}