这里是题目链接,请点开查看原题
这篇blog的目的和侧重
首先,请你点开我在上面附的题目链接,并且自己独立思考,看能不能想到一个解法,即使暴力一点也没关系。
接下来我必须强调一下这篇博客的内容的侧重,这篇blog将尝试给出这道题目的各种解法,同时分析它们的时间复杂度和空间复杂度。
暴力的解法
好的,如果你刚才想到了一种解法,那么看看你的解法是否是暴力的做法。算法是这样的:
1.申请一个队列Queue
2.将第一个丑数加入到队列,那么现在Queue中是1
我用 (Q --> 1)表示
3.(Q <-- 1) : 将1出队
(Q --> 2 3 5):将2,3,5进队
4.(Q <-- 2 ) and (Q --> 3 5 2*2 2*3 2*5 )
5.(Q <-- 3 ) and (Q --> 5 4 6 10 3*2 3*3 3×5)
6.(Q <-- 4 ) and (Q --> 5 6 10 6 9 15)
在上面我列出的第 6 步中我们可以发现,要出队的元素是 4 ,但是4的位置不一定在队首,所以每次都得Math.min(Q1, Q2, ... , Qn)
ok, 空间复杂度就是队列的长度,也就是队列中最多有多少个元素,由于每 1 次出队的同时, 会有 3 个新元素入队, 所以每次的净增长是 2 个元素,那么第 n 次出队时, 队列中element --> 2n
package 第k个数;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
public int GetUglyNumber_Solution (int index) {
if (index == 0 ) {
return 0 ;
}
if (1 == index) {
return 1 ;
}
Queue<Integer> q2 = new LinkedList<Integer>();
Queue<Integer> q3 = new LinkedList<Integer>();
Queue<Integer> q5 = new LinkedList<Integer>();
q2.add(2 );
q3.add(3 );
q5.add(5 );
int cur = 2 , minVal = 0 ;
int q2Val, q3Val, q5Val;
while (cur != (index + 1 )) {
q2Val = q2.peek();
q3Val = q3.peek();
q5Val = q5.peek();
minVal = Math.min(q2Val, Math.min(q3Val, q5Val));
if (minVal == q2Val) {
q2.poll();
q2.add(minVal * 2 );
q3.add(minVal * 3 );
q5.add(minVal * 5 );
cur++;
continue ;
}
if (minVal == q3Val) {
q3.poll();
q3.add(minVal * 3 );
q5.add(minVal * 5 );
cur++;
continue ;
}
if (minVal == q5Val) {
q5.poll();
q5.add(minVal * 5 );
cur++;
continue ;
}
}
return minVal;
}
public static void main (String[] args) {
System.out.println(new Solution().GetUglyNumber_Solution(2 ));
}
}