题目:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路:
摘自牛客评论——一个丑数的因子只有2,3,5,那么丑数p=2^x*3^y*5^z,即一个丑数一定是由另一个丑数乘以2或者乘以3或者乘以5而得。那么维护三个队列,分别是乘以2,乘以3和乘以5的队列,1乘以2,3,5得到丑数2,3,5,2,3,5再乘以2,3,5又得到4,6,10,6,9,15,10,15,25,这并不是有序的,因此,需要这样做:
丑数数组中:1
乘以2队列:|2
乘以3队列:|3
乘以5队列:|5
"|"代表队首位置,每次比较队首的元素,小的出队加入丑数数组中
丑数数组中:1,2
乘以2队列:2,|4
乘以3队列:|3,6
乘以5队列:|5,10
丑数数组中:1,2,3
乘以2队列:2,|4,6
乘以3队列:3,|6,9
乘以5队列:|5,10,15
丑数数组中:1,2,3,4
乘以2队列:2,4,|6,10
乘以3队列:3,|6,9,15
乘以5队列:|5,|10,15,25
丑数数组中:1,2,3,4,5,6
乘以2队列:2,4,6,|10,12
乘以3队列:3,6,|9,15,18
乘以5队列:5,|10,15,25,30
Java
package nowcoder;
import java.util.ArrayList;
public class S33_UglyNumber {
public int uglyNumber(int index){
if (index < 7) return index;
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(1); //将1加入丑数数组中
int p2 = 0, p3 = 0, p5 = 0;
while (arr.size() < index) {
int v2 = arr.get(p2) * 2;
int v3 = arr.get(p3) * 3;
int v5 = arr.get(p5) * 5;
int min = Math.min(v2, Math.min(v3, v5));
arr.add(min);
if (v2 == min) p2++;
if (v3 == min) p3++;
if (v5 == min) p5++;
}
return arr.get(arr.size()-1);
}
public static void main(String[] args){
S33_UglyNumber s33 = new S33_UglyNumber();
System.out.println(s33.uglyNumber(100));
}
}
Python
class UglyNumber:
def UglyNumber(self, index):
arr = [1]
if index < 7:
return index
p2, p3, p5 = 0, 0, 0
while len(arr) < index:
v2 = arr[p2] * 2
v3 = arr[p3] * 3
v5 = arr[p5] * 5
mini = min(v2, v3, v5)
arr.append(mini)
if v2 == mini: p2 += 1
if v3 == mini: p3 += 1
if v5 == mini: p5 += 1
return arr[-1]
if __name__ == '__main__':
test = UglyNumber()
print(test.UglyNumber(100))
结果
1536