剑指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 的中的最小值得来。
posted @ 2019-09-08 13:13  chyblogs  阅读(125)  评论(0)    收藏  举报