明天过年,祝各位朋友新春快乐,大吉大利.
题目: 设计一个算法,找出只含素因子2 ,3 ,5的第 n 小的数。
思路: 题目拿到手,最容易想到的就是暴力破解法,即对从1开始的每个整数都进行判断,如果该数一直除2直至不能整除再一直除3直至不能整除,再一直除5直至不能整除,最后所得结果是1的话,则这个数就是一个丑数,一直循环到找到第n个丑数,即为所求.
int m=0; //m统计是第几个丑数 int num=0; //num为从1开始的自然数列 while(n != m){ //n是所求的第n个丑数 num++; int num1 = num; while(num1/2 == (float)num1/2){ num1 = num1/2; } while(num1/3 == (float)num1/3){ num1 = num1/3; } while(num1/5 == (float)num1/5){ num1 = num1/5; } if(num1 == 1){ m++; } } return num;
但这段代码效率不高,并没有能通过lintcode的检测.
改进: 由于丑数是只含2,3,5因子的数,所以一个丑数必然与比它小的丑数有联系,即可以由在它之前的丑数生成.从最小的丑数开始,每个丑数对2,3,5的乘积都是一个丑数,因此只用拿"潜在的"未比较过的3个丑数进行比较,取最小的那个,填入数组,即可得一个纯丑数的数列,效率得到了明显的提升.
int[] arr = new int[n]; int n2 = 0; int n3 = 0; int n5 = 0; arr[0] = 1; for(int i=1;i<n;i++){ int ugly = Math.min(Math.min(arr[n2]*2,arr[n3]*3),arr[n5]*5); arr[i] = ugly; if(arr[i] == arr[n2]*2){ n2++; } if(arr[i] == arr[n3]*3){ n3++; } if(arr[i] == arr[n5]*5){ n5++; } } return arr[n-1];成功通过检测.