题目:把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
代码1的结果只能通过百分之46,原因就在于对丑数的判断不完整,如果i=7,7不是丑数,但会被判定为丑数。
class Solution {
public:
int GetUglyNumber_Solution(int index) {
int count = 0;
int i = 0;
while(count<index){
i++;
if(IsUglyNumber(i))
count += 1;
}
return i;
}
private:
bool IsUglyNumber(int i){
bool isNumber = true;
if(i == 1) return isNumber;
for(int j=2;j<i;j++){
if(j!= 2 && j!=3 && j!=5){
if(i%j == 0)
isNumber = false;
}
}
return isNumber;
}
};
修改判断丑数的函数IsUglyNumber(int i),然后重新运行。仍然报错,报错:运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。但在VS中调试通过。
代码2:
class Solution {
public:
bool isUgly(int number) {
while (number % 2 == 0)
number /= 2;
while (number % 3 == 0)
number /= 3;
while (number % 5 == 0)
number /= 5;
return (number == 1) ? true : false;
}
int GetUglyNumber_Solution(int index) {
if (index <= 0) return 0;
int number = 0;
int count = 0;
while (count < index) {
number++;
if (isUgly(number))
count++;
}
return number;
}
};
针对上述问题要想办法改进。创建一个数组,里面的数字都是排好序的丑数,每个丑数都是前面的丑数乘以2、3和5。这种思路的关键在于怎样确保数组里面的丑数是排好序的。我们可以通过t2、t3和t5来记录丑数的位置,每次生成新的丑数都去更新t2、t3和t5。
class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index < 7) return index;
vector<int> result(index);
result[0] = 1;
int t2 = 0;
int t3 = 0;
int t5 = 0;
for(int i=1;i<index;i++){
result[i]=min(result[t2]*2,min(result[t3]*3,result[t5]*5));
if(result[i] == result[t2]*2) t2++;
if(result[i] == result[t3]*3) t3++;
if(result[i] == result[t5]*5) t5++;
}
return result[index - 1];
}
};