剑指offer_丑数
题目描述
把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。习 惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。
直接分解的话,时间复杂度太大了
1 import java.util.*; 2 public class Solution { 3 ArrayList<Integer> list = new ArrayList<>(); 4 public int GetUglyNumber_Solution(int index) { 5 6 return GetNum(index); 7 } 8 public void fengjie(int j){ 9 //if(isPrime(j)){list.add(j);return;} 10 for(int i=2;i<=Math.sqrt(j);i++){ 11 12 //这个if是找最小公约数 13 if(j%i == 0){ 14 list.add(i); 15 16 //这个if是判断他是不是素数,如果是素数,就将这个数输出,然后就执行break;了 17 if(isPrime(j/i)){ 18 list.add(j/i); 19 } 20 else 21 22 //如果不是素数,就继续分解,找公约数 23 fengjie(j/i); 24 25 break; 26 } 27 } 28 29 } 30 31 public boolean isPrime(int n){ 32 for(int i=2;i<=Math.sqrt(n);i++) 33 { 34 if(n%i == 0) 35 return false; 36 } 37 return true; 38 } 39 40 public int GetNum(int index){ 41 int dp[] = new int[index]; 42 dp[0]=1; 43 int j=1; 44 for(int i=2;i<Integer.MAX_VALUE;i++){ 45 boolean flag = true; 46 if(j==index) break; 47 fengjie(i); 48 if(list.isEmpty()){list.add(i);} 49 for(int a : list){ 50 if(!(a==2||a==3||a==5)) {flag=false;break;} 51 } 52 if(flag){ 53 54 dp[j++]=i; 55 } 56 list.clear(); 57 } 58 System.out.println(Arrays.toString(dp)); 59 return dp[index-1]; 60 } 61 62 public static void main(String[] args) { 63 Solution s = new Solution(); 64 int i = s.GetUglyNumber_Solution(30); 65 System.out.println(i); 66 } 67 }
思路是对的,但是时间空间复杂度太高了,压根运行不出来。
网上看到了别人的思路
1 public int GetUglyNumber_Solution(int N) { 2 if (N <= 6) 3 return N; 4 int i2 = 0, i3 = 0, i5 = 0; 5 int[] dp = new int[N]; 6 dp[0] = 1; 7 for (int i = 1; i < N; i++) { 8 int next2 = dp[i2] * 2, next3 = dp[i3] * 3, next5 = dp[i5] * 5; 9 dp[i] = Math.min(next2, Math.min(next3, next5)); 10 if (dp[i] == next2) 11 i2++; 12 if (dp[i] == next3) 13 i3++; 14 if (dp[i] == next5) 15 i5++; 16 } 17 return dp[N - 1]; 18 }
思路:按顺序把每个丑数放在数组中,求下一个丑数
下一个丑数必定由有数组中的某一个丑数A * 2, B * 3, C * 5 的中的最小值得来。

浙公网安备 33010602011771号