标签:如何 boolean static i++ ++ 就会 数组 记录 code
方法一:暴力法
代码如下:
判断是否是丑数 public static boolean isUgly(int n){ while(n!=1){ if(n%2 == 0){ n /= 2; }else if(n%3 == 0){ n /= 3; }else if(n%5 == 0){ n /= 5; }else{ break; } } return n==1; } public static int getUglyNumber(int n){ if(n == 0) return 0; int count = 0; for(int i = 1;i<Integer.MAX_VALUE;i++){ if(isUgly(i)) count++; if(count == n) return i; } return 0; }
方法二:思路:
三指针法。只计算丑数,而不计算非丑数。丑数=丑数*(2/3/5),所以创建数组保存有序的丑数。
关键在于如何在计算丑数的过程中保持数组有序。当前的丑数必然是之前某一个丑数*因子的结果,
但是不需要每个数都要乘一遍2、3、5。要获得的丑数必然是大于现在已有的,
在计算得出丑数中选择一个最小的放入数组中,来保持数组的有序,因为新放入的丑数是根据之前的丑数计算得到的,
所以必然是有序的。为了每次新得到的三个丑数都是比已有丑数大,且最小,所以要记录各个因子下次计算要使用的已有丑数在什么位置,
否则就会出现跳数,比如已有{1,2,3,4},我们知道下一个丑数应该是5,但是如果因子5没有选择第一个丑数1来相乘,就会漏掉5这个丑数。
代码实现如下:
public static int getUglyNumber(int n) { if(n == 0) return 0; //定义三个指针,分别指向质因子2,3,5 int a = 0; int b = 0; int c = 0; int[] arr = new int[n]; arr[0] = 1; for(int i = 1;i<n;i++){ int r = arr[a]*2; int s = arr[b]*3; int t = arr[c]*5; int sign = Math.min(r,Math.min(s,t)); //将最小的丑数放入结果集中,用于下一次计算 arr[i] = sign; //找出对应此次计算最小丑数的因子,并移动指针指向下一次计算丑数对应的老丑数下标 if(sign%2==0){ a++; } if(sign%3==0){ b++; } if(sign%5==0){ c++; } } return arr[n-1]; }
标签:如何 boolean static i++ ++ 就会 数组 记录 code
原文地址:https://www.cnblogs.com/du001011/p/10720987.html