Leetcode 263. Ugly Number & 264. Ugly Number II
2016-05-28 04:18
459 查看
263. Ugly Number
Total Accepted: 58196 TotalSubmissions: 157221 Difficulty: Easy
Write a program to check whether a given number is an ugly number.
Ugly numbers are positive numbers whose prime factors only include
2, 3, 5. For example,
6, 8are ugly while
14is
not ugly since it
includes another prime factor
7.
Note that
1is typically treated
as an ugly number.
思路:
从该数中去除所有的2,3,5之后等于1便是ugly number。然而:
public class Solution { // TLE at 905391974 public boolean isUgly(int num) { if(num<=0) return false; if(num==1) return true; int base = 2; while(num>1){ if(num%base==0){ if(base>5) return false; num/=base; }else{ base++; } } return true; } }
博主看了看例子,应该是因为寻找下一个可以除的base的时间太长了。于是修改了一下:
public class Solution { public boolean isUgly(int num) { if(num<=0) return false; if(num==1) return true; int base = 2; while(num>1){ if(num%base==0){ if(base>5) return false; num/=base; }else{ if(base>5) return false; base++; } } return true; } }
瞬间AC, 3MS.
网上的标准版本是2MS:
public class Solution { public boolean isUgly(int num) { if(num<=0) return false; if(num==1) return true; while(true){ if(num%2==0) num/=2; else if(num%3==0) num/=3; else if(num%5==0) num/=5; else return num==1; } } }
264. Ugly Number II
Total Accepted: 41874 Total Submissions: 136798 Difficulty: MediumWrite a program to find the
n-th ugly number.
Ugly numbers are positive numbers whose prime factors only include
2, 3, 5. For example,
1, 2, 3, 4, 5, 6, 8, 9, 10, 12is the sequence of
the first
10ugly numbers.
Note that
1is typically treated as an ugly
number.
Hint:
1. The naive approach is to call
isUglyfor
every number until you reach the nth one. Most numbers are not ugly.
Try to focus your effort on
generating only the ugly ones.
2. An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
3. The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1,
L2, and L3.
4. Assume you have Uk, the kth ugly
number. Then Uk+1 must be Min(L1 *
2, L2 * 3, L3 *
5).
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating
all test cases.
思路一:
对每个数调用isUgly函数,直到第n个。
思路二:
丑陋数序列可以拆分为下面3个子列表:
(1) 1×2, 2×2, 3×2, 4×2, 5×2, … (2) 1×3, 2×3, 3×3, 4×3, 5×3, … (3) 1×5, 2×5, 3×5, 4×5, 5×5, …
我们可以发现每一个子列表都是丑陋数本身(1, 2, 3, 4, 5, …) 乘以 2, 3, 5
接下来我们使用与归并排序相似的合并方法,从3个子列表中获取丑陋数。每一步我们从中选出最小的一个,然后向后移动一步。
这里有个问题,如果直接用LinkedList<Integer>不会溢出,但是PriorityQueue<Integer>就不行,得用<Long>
public class Solution { // 79 ms public int nthUglyNumber(int n) { long u = 0L; PriorityQueue<Long> q1 = new PriorityQueue<Long>(); PriorityQueue<Long> q2 = new PriorityQueue<Long>(); PriorityQueue<Long> q3 = new PriorityQueue<Long>(); q1.add(1L); q2.add(1L); q3.add(1L); for(int i=0; i<n; i++) { u = Math.min( Math.min(q1.peek(), q2.peek()), q3.peek()); if(q1.peek() == u) q1.poll(); if(q2.peek() == u) q2.poll(); if(q3.peek() == u) q3.poll(); q1.add(u*2); q2.add(u*3); q3.add(u*5); } return (int) u; } }
public class Solution { // 74ms public int nthUglyNumber(int n) { int u = 0; List<Integer> l1 = new LinkedList<Integer>(); List<Integer> l2 = new LinkedList<Integer>(); List<Integer> l3 = new LinkedList<Integer>(); l1.add(1); l2.add(1); l3.add(1); for(int i=0; i<n; i++) { u = Math.min( Math.min(l1.get(0), l2.get(0)), l3.get(0)); if(l1.get(0) == u) l1.remove(0); if(l2.get(0) == u) l2.remove(0); if(l3.get(0) == u) l3.remove(0); l1.add(u*2); l2.add(u*3); l3.add(u*5); } return u; } }
进阶版:
用DP保存第i个Ugly Number,然后用3个指针指向当前的位置。
比如第一个ugly number是1,那么3个指针都指向0位置。判断的时候取res[p1]*2, res[p2]*3和res[p3]*5的最小值。
之后再移动相应指针一位。
一开始都指向1(res[0]),然后min取到的是2,所以p2目前指向res[1] = 2。这样下次对比就是( 2*2, 1*3, 1*5)来对比,结果放入res[2]。
public class Solution { // 10ms public int nthUglyNumber(int n) { if( n == 0 || n == 1) { return n; } int pointer2 = 0; int pointer3 = 0; int pointer5 = 0; int[] result = new int ; result[0] = 1; int i = 1, min =0; while ( i < n ) { min = Math.min(result[pointer2]*2,Math.min(result[pointer3]*3,result[pointer5]*5)); if(min == result[pointer2]*2) { pointer2++; } if(min == result[pointer3]*3) { pointer3++; } if(min == result[pointer5]*5) { pointer5++; } result[i] = min; i++; } return result[n-1]; } }
相关文章推荐
- 微软Word 2007数学插件 Microsoft Math 提供下载
- 关于C# Math 处理奇进偶不进的实现代码
- JavaScript Math 对象常用方法总结
- JavaScript中的Math.SQRT1_2属性使用简介
- JavaScript Math.ceil() 函数使用介绍
- 与Math.pow 相反的函数使用介绍
- JavaScript中使用指数方法Math.exp()的简介
- JavaScript使用Math.Min返回两个数中较小数的方法
- Ajax获取页面被缓存的解决方法
- JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
- JavaScript中Math对象使用说明
- javascript对象之内置对象Math使用方法
- 基于java math API 的详细解释说明
- 简介JavaScript中用于处理正切的Math.tan()方法
- 浅谈JavaScript中的Math.atan()方法的使用
- 基于java中stack与heap的区别,java中的垃圾回收机制的相关介绍
- PHP内置的Math函数效率测试
- 在JavaScript中使用对数Math.log()方法的教程
- JavaScript中用于四舍五入的Math.round()方法讲解
- 简介JavaScript中Math.LOG10E属性的使用