2081 寻找丑数
2015-02-18 11:39
453 查看
把只包含质因子2、3和5的数称作丑数(Ugly Number),例如:2,3,4,5,6,8,9,10,12,15,等,习惯上我们把1当做是第一个丑数。
写一个高效算法,返回第n个丑数。
最普通(也最耗时)的做法是从1开始遍历,然后判断这个数的因式分解中只包含2,3,5,满足则找到了一个,一直找下去,直到第n个被找出!测试了一下,找第1500个丑数耗时40秒!
分析:假设数组ugly
中存放不断产生的丑数,初始只有一个丑数ugly[0]=1,由此出发,下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2, ugly[0]*3, ugly[0]*5, 显然最小的那个数是新的丑数,所以第2个丑数为ugly[1]=2,开始新一轮的竞争,由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,得到ugly[1]*2,ugly[0]*3,ugly[0]*5, 因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],即:ugly[1]*2,
ugly[1]*3, ugly[0]*5, 因子5获胜,得到ugly[3]=5,重复这个过程,直到第n个丑数产生。总之:每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中 胜出的因子就应该加大惩罚!
代码一:遍历法速度极其慢
代码二:网上看的高速的算法,吃力啊。
所幸是写完了,学习的过程吧。
写一个高效算法,返回第n个丑数。
最普通(也最耗时)的做法是从1开始遍历,然后判断这个数的因式分解中只包含2,3,5,满足则找到了一个,一直找下去,直到第n个被找出!测试了一下,找第1500个丑数耗时40秒!
分析:假设数组ugly
中存放不断产生的丑数,初始只有一个丑数ugly[0]=1,由此出发,下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2, ugly[0]*3, ugly[0]*5, 显然最小的那个数是新的丑数,所以第2个丑数为ugly[1]=2,开始新一轮的竞争,由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,得到ugly[1]*2,ugly[0]*3,ugly[0]*5, 因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],即:ugly[1]*2,
ugly[1]*3, ugly[0]*5, 因子5获胜,得到ugly[3]=5,重复这个过程,直到第n个丑数产生。总之:每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中 胜出的因子就应该加大惩罚!
代码一:遍历法速度极其慢
import java.util.*; import java.io.*; /* 效率极低,电脑跑不动啊。 */ public class Main2081{ public static void main(String args[]) throws Exception{ //Scanner sc = new Scanner(System.in); int[] arr = new int[100]; arr[1] = 1; int j=2; for(int i=2;i<=10;i++){ if(ugly(i)){ arr[j] = i; j++; } } for(int temp:arr){ System.out.println(temp); } } //ugly public static boolean ugly(int n){ while(n!=1){ if(n%2==0){ n = n/2; } if(n%3==0){ n = n/3; } if(n%5==0){ n = n/5; } if(n%7==0){ n = n/7; } } if(n==1){ return true; }else{ return false; } } }
代码二:网上看的高速的算法,吃力啊。
import java.util.*; import java.io.*; public class Main2081_2{ public static void main(String args[]) throws Exception{ Scanner sc = new Scanner(System.in); int[] arr = new int[6000]; arr[1] = 1; int x2=1,x3=1,x5=1,x7=1; for(int i=2;i<=5842;i++){ arr[i] = min(min(arr[x2]*2,arr[x3]*3),min(arr[x5]*5,arr[x7]*7)); if(arr[i]==arr[x2]*2) x2++; if(arr[i]==arr[x3]*3) x3++; if(arr[i]==arr[x5]*5) x5++; if(arr[i]==arr[x7]*7) x7++; } int n=1; while(n>0){ n = sc.nextInt(); if(n==0){ break; } System.out.print("The "+n); if((n%100!=11)&&n%10==1){ System.out.print("st"); }else if((n%100!=12)&&n%10==2){ System.out.print("nd"); }else if((n%100!=13)&&n%10==3){ System.out.print("rd"); }else{ System.out.print("th"); } System.out.println(" "+"humble number is "+arr +"."); } } public static int min(int a,int b){ return a<b?a:b; } }
所幸是写完了,学习的过程吧。
相关文章推荐
- 寻找丑数
- HDU 1058 Humble Numbers (动规+寻找丑数问题)
- 微软100题(64)寻找第1500个丑数
- 【转帖】寻找丑数
- 【100题】第六十一题~第六十五题(数组中只出现一次的数、链表公共点、删除字串特定字符、寻找丑数、输出从1到最大的N 位数)
- 寻找丑数
- 寻找丑数及关于程序优化效率的一点说明
- 寻找第k个丑数
- 每日一道算法题-寻找丑数
- Ugly Number 寻找丑数 简单题
- 寻找丑数
- 寻找丑数
- 每日一道算法题-寻找丑数
- 2014华为机试,寻找丑数。
- 寻找丑数
- (剑指offer)丑数 寻找第一个只出现一次的字符
- Ugly Number II 寻找第N个丑数
- 算法题3 寻找丑数&数值逼近
- 寻找丑数(Ugly Number)
- 经典算法题——寻找第1500个丑数