* 我們把只包含因子 2,3,和 5 的稱為醜數。求按從小到大的順序的第 1500個醜數。例如 6、8 都是醜數,但 14 不是,因為它包含因子 7.習慣上我們把 1當做第一個醜數 *
該段程式中包含常規方法和最優方法。本篇部落格的貢獻在於用java實現 劍指offer面試題34:醜數。
相關講解在此不再贅述(和劍指offer面試題34演算法思想相同)。
重點是:應用空間來換取時間,效率提升一萬倍。
常規方法:挨個判斷每個數是否為醜數。
藉助輔助空間的方法:使用數組來儲存,快速讀取。
public class JZ34_UglyNumber { public static void main(String[] args) { long begin = System.currentTimeMillis(); // 這段代碼放在程式執行前 //常規方法執行時間超過10秒 //System.out.println(getOneUglyNumber(1500)); //藉助輔助空間來提交效率,執行時間1毫秒,效率提升1萬倍。 System.out.println(getResult(1500)); long end = System.currentTimeMillis() - begin; // 這段代碼放在程式執行後 System.out.println("耗時:" + end + "毫秒"); } public static boolean isUglyNumber(long num){ if( index < 1){ return 0; } while( num % 2 ==0 ) num /= 2; while( num % 3 ==0 ) num /= 3; while( num % 5 ==0 ) num /= 5; return num == 1? true:false; } public static long getOneUglyNumber(int index){ long i = 0; long ci = 0; while ( ci < index ){ i++; if( isUglyNumber(i)){ ci++; } } return i; } public static long getResult(int index){ if( index < 1){ return 0; } long[] array = new long[index]; array[0] = 1; int nextIndex = 1; long tar2 = 1; long tar3 = 1; long tar5 = 1; int t2i = 0,t3i=0,t5i=0; //儲存上一次最小的比最大值大的醜數的下標,用於下一次尋找醜數時候用,避免了重複的計算與比較 while( nextIndex < index ){ for ( int i = t2i; i<= nextIndex; i++){ if( array[i]*2 > array[nextIndex-1]){ tar2 = array[i]*2; t2i = i; break; } } for ( int i = t3i; i<= nextIndex; i++){ if( array[i]*3 > array[nextIndex-1]){ tar3 = array[i]*3; t3i = i; break; } } for ( int i = t5i; i<= nextIndex; i++){ if( array[i]*5 > array[nextIndex-1]){ tar5 = array[i]*5; t5i = i; break; } } array[nextIndex++] = getMinFromThree(tar2,tar3,tar5); } return array[index-1]; } public static long getMinFromThree(long a,long b,long c){ return Math.min(Math.min(a, b), c); }}