【九度OJ1214】|【剑指offer34】丑数
2013-10-16 00:00
309 查看
题目描述:
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
输入:
输入包括一个整数N(1<=N<=1500)。
输出:
可能有多组测试数据,对于每组数据,
输出第N个丑数。
方法一:(粗糙啊)
咋想的呢!硬生生的解,效率极低最后Runtimeout
方法二
方法三:(参考http://www.cnblogs.com/mingzi/archive/2009/08/04/1538491.html)
2
、
3
或者
5
的结果(
1
除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数。里面的每一个丑数是前面的丑数乘以
2
、
3
或者
5
得到的。在已知一个数组大小的丑数序列时,下一个丑数必然大于已知的最大丑数,并且该丑数是由已知数组里的丑数
乘以
2
、
3
或者
5
的结果。因此我们可以先找到已知数组里的丑数乘以2、3、5得到的第一个大于已知最大丑数的值,然后比较这三个值,最小的那个即为要求得的丑数。
这种算法不需要在非丑数的整数上做任何计算,因此时间复杂度要低很多。
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
输入:
输入包括一个整数N(1<=N<=1500)。
输出:
可能有多组测试数据,对于每组数据,
输出第N个丑数。
方法一:(粗糙啊)
import java.util.Scanner; public class CopyOfMain { public boolean isPrime(int number){ boolean flag = true; for(int i = 2; i <= Math.sqrt(number); i++){ if(number % i == 0){ flag = false; break; } } return flag; } public boolean isUgly(int number){ if(isPrime(number)){ if(number == 2 || number == 3 || number == 5 || number == 1) return true; else{ return false; } } boolean flag = false; for(int i = 2; i < Math.sqrt(number) + 1; i++){ int a = number % i; if(a == 0){ flag = isUgly(i)&&isUgly(number/i); } } return flag; } public void countUgly(int count){ if(count <= 6) System.out.println(count); else{ int j = 6; int number = 7; while(j < count){ if(isUgly(number++)){ j++; } } System.out.println(number-1); } } public static void main(String[] args) { Scanner s = new Scanner(System.in); CopyOfMain m = new CopyOfMain(); m.countUgly(s.nextInt()); } }
咋想的呢!硬生生的解,效率极低最后Runtimeout
方法二
import java.util.Scanner; public class Copy_2_of_Main { public boolean isUgly(int number) { while (number % 2 == 0) number /= 2; while (number % 3 == 0) number /= 3; while (number % 5 == 0) number /= 5; return number == 1; } public void countUgly(int count) { int j = 0; int number = 1; while (j < count) { if (isUgly(number++)) { j++; } } System.out.println(number - 1); } public static void main(String[] args) { // Scanner s = new Scanner(System.in); Copy_2_of_Main m = new Copy_2_of_Main(); // m.countUgly(s.nextInt()); for (int i = 1; i < 20; i++) m.countUgly(i); } }依然是效率问题会额外计算非丑数。
方法三:(参考http://www.cnblogs.com/mingzi/archive/2009/08/04/1538491.html)
import java.util.Scanner; public class Main { public void countUgly(int count) { if(count <= 0)return; int[] array = new int[count]; int pos = 0; array[0] = 1; int i = 0; int j = 0; int k = 0; while (pos < count - 1) { while (array[pos] >= array[i] * 2) i++; while (array[pos] >= array[j] * 3) j++; while (array[pos] >= array[k] * 5) k++; array[++pos] = Min(array[i] * 2, array[j] * 3, array[k] * 5); } System.out.println(array[pos]); } public int Min(int a, int b, int c) { a = Math.min(a, b); return Math.min(a, c); } public static void main(String[] args) { Scanner s = new Scanner(System.in); Main m = new Main(); while(s.hasNext()) m.countUgly(s.nextInt()); } }试图只计算丑数,而不在非丑数的整数上花费时间。根据丑数的定义,丑数应该是另一个丑数乘以
2
、
3
或者
5
的结果(
1
除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数。里面的每一个丑数是前面的丑数乘以
2
、
3
或者
5
得到的。在已知一个数组大小的丑数序列时,下一个丑数必然大于已知的最大丑数,并且该丑数是由已知数组里的丑数
乘以
2
、
3
或者
5
的结果。因此我们可以先找到已知数组里的丑数乘以2、3、5得到的第一个大于已知最大丑数的值,然后比较这三个值,最小的那个即为要求得的丑数。
这种算法不需要在非丑数的整数上做任何计算,因此时间复杂度要低很多。
相关文章推荐
- 剑指Offer - 九度1214 - 丑数
- [剑指offer][面试题34]丑数
- 【剑指Offer面试编程题】题目1388:跳台阶--九度OJ
- 【剑指Offer面试编程题】题目1372:最大子向量和--九度OJ
- 剑指offer34——丑数
- 剑指Offer_面试题34_丑数
- 剑指Offer34 丑数
- 【剑指Offer面试题】 九度OJ1390:矩形覆盖
- 【剑指Offer面试题】 九度OJ1371:最小的K个数
- 【剑指Offer面试题】 九度OJ1504:把数组排成最小的数
- 【剑指Offer面试题】 九度OJ1371:最小的K个数
- 剑指Offer----面试题34:丑数
- 剑指offer 34- 丑数
- 【剑指Offer面试题】 九度OJ1515:打印1到最大的N位数
- 剑指Offer面试题34:丑数 Java实现
- 【剑指Offer面试题】 九度OJ1519:合并两个排序的链表
- 【剑指Offer面试题】 九度OJ1521:二叉树的镜像
- 【剑指Offer面试题】 九度OJ1524:复杂链表的复制
- 【剑指offer】【九度oj】整数中1出现的次数
- 【剑指Offer面试题】 九度OJ1372:最大子向量和(连续子数组的最大和)