把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路1:既然是只能被2、3和5整除,那么剩余到最后的数只能是1。
思路2:既然没个数都只能被2、3和5整除,那么这个数可以看成是:number = 2^i*3^j*5^p;
先放置几个队列:
L1: 3^i (i >=0)
L2: 3^i * 5^j (j >= 1)
L3: 3^i * 5^j * 7^k (k >= 1)
Step1: 清空三个队列、 分别把 3,5,7 放入三个队列癿首位。 准备一个新队列 L(目前为空)。
Step2: 比较三个队列癿头,找出最小癿那个。把返个元素从队列出队,幵加到 L 癿尾部。
Step3:
如果 Step2 中癿元素是从 L1 中获叏癿,假讴是 3^m,则在 L1 癿尾部加入 3^(m+1),L2 癿尾
部加入 3^m*5,L3 癿尾部加入 3^m*7。
如果 Step2 中癿元素是从 L2 中获叏癿,假讴是 3^m * 5^n,则在 L2 癿尾部加入 3^m * 5^(n+1),
L3 癿尾部加入 3^m * 5^n *7。
如果 Step3 中癿元素是从 L3 中获叏癿,假讴是 3^m * 5^n * 7^p,则在 L3 癿尾部加入 3^m *
5^n * 7^(p+1)。
Step4: L 癿长度到达 N 了向?如果没到达,重复 L2-L4。如果到达,则迕行 L5。
Step5: 叏得 L 癿末尾元素,即为所求。
public int GetUglyNumber_Solution(int index) { int count =0; int i=1; while(count<index){ if(isUgly(i++)){ count++; } } return i-1; } public boolean isUgly(int number){ if(number>=1){ while(number%2==0){ number/=2; } while(number%3==0){ number/=3; } while(number%5==0){ number/=5; } if(number == 1){ return true; }else{ return false; } } return false; }
思路2:
public int GetUglyNumber_Solution(int index) { if(index<=0) return 0; Queue<Integer> stack1 = new LinkedList<>(); Queue<Integer> stack2 = new LinkedList<>(); Queue<Integer> stack3 = new LinkedList<>(); List<Integer> stack = new LinkedList<>(); stack.add(1); stack1.add(2); stack2.add(3); stack3.add(5); while(stack.size()<index){ if(stack1.peek()<stack2.peek()&&stack1.peek()<stack3.peek()){ int data = stack1.poll(); stack.add(data); stack1.add(data*2); stack2.add(data*3); stack3.add(data*5); } else if(stack2.peek()<stack1.peek()&&stack2.peek()<stack3.peek()){ int data = stack2.poll(); stack.add(data); stack2.add(data*3); stack3.add(data*5); } else if(stack3.peek()<stack1.peek()&&stack3.peek()<stack2.peek()){ int data = stack3.poll(); stack.add(data); stack3.add(data*5); } } return stack.get(stack.size()-1); }