The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 111221, ...
1
is read off as "one 1"
or 11
.
11
is read off as "two 1s"
or 21
.
21
is read off as "one 2
, then one 1"
or 1211
.
Given an integer n, generate the nth sequence.
Note: The sequence of integers will be represented as a string.
1.思路:题目中所有的结果都是递推得到,则首先想到两种方法:队列,递归。
我使用了前者实现。因为不知道数字的规模,如果贸然使用递归可能会造成overstack
首先,在安排队列的时候,若当前这一组进入队列,则必须要等改组最后一个数字出来之后,下一组才能进队,但是下一组的每一个数字不是在这一组全都出队之后才形成的,而是当前这一组出某一部分数字就能产生下一组的某一部分数字,而当前组出完之后,下一组一定已经形成。所以,考虑之后使用两组队列。当前队列出兑完毕,则下一组队列也入队完毕。直接对下一组队列进行操作,而下下组又放到当前的空队列,轮换使用,以此类推。
其次,数字的产生是有规律的。如果有连续的几个数字,那么要一次提出来,比如111221这个数,3个1首先从队1出队,得到31入队2;然后2个2出队1,得到22入队2;最后出1个1,得到11入队2。则得到结果312211。
注意:开始的1需要预先存入队列。则得到的结果11是从n=2开始算起。所以,若n=1为参数时,直接返回“1”即可,这是边界条件。
2.AC代码:
public String countAndSay(int n) {
Queue<Integer> queue = new LinkedList<Integer>();
Queue<Integer> queue1= new LinkedList<Integer>();
if(n==1)
return "1";
queue.offer(1);
for(int i=2;i<=n;i++){
while(!queue.isEmpty()){
int num = 1;
int a = queue.poll();
while(!queue.isEmpty()){
int b = queue.peek();
if(b==a){
queue.poll();
num++;
}
else{
break;
}
}
queue1.offer(num);
queue1.offer(a);
}
Queue c = queue1;
queue1 = queue;
queue = c;
}
StringBuilder stringBuilder = new StringBuilder();
while(!queue.isEmpty()){
int a = queue.poll();
stringBuilder.append(a);
}
return stringBuilder.toString();
}