第几个幸运数(算法入门题目004)

题目

到x星球旅行的游客都被发给一个整数,作为游客编号。
x星的国王有个怪癖,他只喜欢数字 3, 5 和 7 。
国王规定,游客的编号如果只含有因子:3 , 5, 7, 就可以获得一份奖品。

我们来看前10个幸运数字是:
3 5 7 9 15 21 25 27 35 45
因而第11个幸运数字是:49

小明领到了一个幸运数字 59084709587505。
他去领奖的时候,被要求准确地说出这是第几个幸运数字,否则领不到奖品。
请你帮小明计算一下,59084709587505是第几个幸运数字。

分析

我们先来看当数字较小的时候采用的可靠的笨办法。
从小到大搜索整数,当它只含有 因子3, 5, 7, 就把它记录在数组中。
判断是否只含有因子 3 5 7,只要不断的地除以3 5 7, 看看最后剩下的是不是 1 即可。
用这个办法对付上面那个大数,一般电脑肯定不行。

更高效的算法:
我们可不可以设法去生成那个幸运数的数列呢?、
有没有注意到,数列中的每个数都是数列前边的数乘以3, 5 或 7 得到的。
因而,只把开始 3 个位置添上3, 5, 7, 后边的就都可以算出来啦!
难度在于:应该把前边哪个位置上的数乘以多少,放入到后边的哪个位置呢?
注意会有重复噢。比如 3 x 5, 5 x 3

可能会有很多实现的手段。
比如方案一:
用一个指针,从 3 开始,往后扫。
对扫过的每一个数,分别乘以 3 5 7,得到的 3 个数插入到队列中合适位置。
实际上是二分法进行的经典的插入排序。
虽然说,尾巴上的一些数的序号可能不靠谱,但指针扫过的那些肯定是靠谱的。

还有更好的方案二:
分别用三个指针,对指针指向的数字分别进行乘3, 乘5, 乘7 的操作。
3 个乘积 pk 一下,谁最小,这个数就填入到队尾。
产生这个数的指针向前移动。

代码

先上个笨的

//problem004
import java.util.*;
public class A
{
   
	static List<Integer> f(int num){
   
		List<Integer> lst = new ArrayList<Integer>();
		
		for(int i=3; lst.size()<num; i++){
   
			int n = i;
			while(n%3==0) n /= 3;
			while(n%5==0) n /= 5;
			while(n%7==0) n /= 7;
			
			if(n==1) lst.add(i);
		}
		
		return lst;
	}
	
	public static void main(String[] args){
   
		System
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值