报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
1 被读作 "one 1" ("一个一") , 即 11。
11 被读作 "two 1s" ("两个一"), 即 21。
21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。
给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串。
举例分析:给定1112222112计数得 3个1,4个2,2个1,1个2 1112222112-->31422112。我们想到利用递归的方式求解第n个数对应的输出,主要需要解决的问题在于具体计数部分
我用两种方法对该题进行coding:递归(countAndSay0,countAndSay1)和队列(countAndSay2)
import java.util.LinkedList;
class Solution {
/*
* 执行用时 :3 ms, 在所有 Java 提交中击败了91.67%的用户
* 内存消耗 :34.1 MB, 在所有 Java 提交中击败了91.59%的用户
*/
public static String countAndSay0(int n) {
if(n==1) return "1";
String fir="11";
char[] ch=fir.toCharArray();
int count=1;
int n1=0;
while(n>2) {
StringBuffer sb=new StringBuffer();
for(int i=1;i<ch.length;i++) {
n1=ch[i];
if(n1==ch[i-1])
count++;
else {
sb.append(count).append(ch[i-1]);
count=1;
}
if(i==ch.length-1)
sb.append(count).append(ch[i]);
}
count=1;
ch=sb.toString().toCharArray();
n--;
}
return String.valueOf(ch);
}
/*
* 递归思路:简单明了
* 执行用时 :6 ms, 在所有 Java 提交中击败了61.91%的用户
* 内存消耗 :35.8 MB, 在所有 Java 提交中击败了79.84%的用户
*/
public static String countAndSay1(int n) {
//System.out.print("countAndSay: ");
//System.out.println(n);
if (n==1) return "1";
return bs(countAndSay1(n-1));
}
private static String bs (String s) {
StringBuffer lis=new StringBuffer(s);
lis.append('0');//末尾补0,不漏掉最后一次计数
//System.out.print("bs:");
//System.out.print("input "+lis+" ");
StringBuffer lis1=new StringBuffer();
int re=0;
int i=0;
while(i<lis.length()-1) {
if(lis.charAt(i)!=lis.charAt(i+1))
{
lis1.append(String.valueOf(i+1-re));
lis1.append(lis.charAt(i));
re=i+1;
}
i+=1;
}
//System.out.println("output "+lis1);
return String.valueOf(lis1);
}
/*
* 利用队列,压第一个元素,再取出对比,进行尾插法
* 执行用时 :8 ms, 在所有 Java 提交中击败了49.60%的用户
* 内存消耗 :35.9 MB, 在所有 Java 提交中击败了78.05%的用户
*/
public static String countAndSay2(int n)
{
if (n==1) return "1";
LinkedList<Integer> queue=new LinkedList<>();
//计数
int count=0;
//标记
int temp;
queue.addLast(1);
for (int i=0;i<n-1;i++) {
temp=queue.getFirst();
int len=queue.size();
for(int j=0;j<len;j++) {
//取出一个元素
Integer poll=queue.poll();
if(poll!=temp) {
queue.addLast(count);
queue.addLast(temp);
temp=poll;
count=1;
}
else
count++;
}
queue.addLast(count);
queue.addLast(temp);
count=0;
}
StringBuilder sb=new StringBuilder();
for(Integer integer:queue)
sb.append(integer);
return sb.toString();
}
public static void main(String[] args) {
System.out.println(countAndSay1(5));
}
}