Count and Say
首先贴出我第一次accepted的代码:
class Solution {
public String countAndSay(int n) {
String res ="1";//保存上一个值,默认为1
String tVal = "";//循环过程中的临时值,用来累加每个读数
char curVal = res.charAt(0);//当前重复值
int count = 0;//计数当前重复数量
//遍历上一个数,需要一个变量保存重复数,一个变量保存重复值,一个变量保存上一个值,一个变量保存当前值
//每次循环结束都要把当前值赋值给保存上一个值的变量
//重复数+重复值就是上个数字每一位的读数
//遍历上一个值
for(int j=2;j<=n;j++) {
for (int i = 0; i < res.length(); i++) {
//如果当前重复值等于遍历值,个数加一
if (curVal == res.charAt(i)) {
count++;
if (i == res.length() - 1) {
tVal = tVal + count + String.valueOf(curVal);
count = 0;
}
} else {
//如果不等于当前重复值,说明遍历到了一个新值,需要把前一个重复数+重复值赋值给临时变量tVal
tVal = tVal + count + String.valueOf(curVal);
//重置计数器
count = 0;
//保存当前重复数
curVal = res.charAt(i);
//遍历下标减一,让下一轮循环指针指在当前重复数的第一位上
i--;
}
}
//保存当前读数
res = tVal;
tVal = "";
curVal = res.charAt(0);
}
return res;
}
}
简介:首先看这列数字:
第一个数字是1,接下来每个数字是前一个数字的读数(读出来的数),比如第二个数字是第一个数字的读数就是一个1,写作11;第三个数字是第二个数字的读数,读成二个1,写作21...,按照这种规则排列下去。当多个重复数字出现时(比如11122,你不能读作一个1一个1一个1一个2),应该读作三个1,二个2。
思路:
刚开始看到这个题时,因为没有理解好题意(就出现上面的问题),所以耽误了些时间。理解之后就分析解法,重点就放在读数应该怎么去表示,稍微想一下应该就知道规则——每个读数就是这个数字出现的次数加数字本身。
只需要遍历前一个数字,通过变量保存出现的次数和出现的数字,然后通过一个变量拼接每次循环得到次数和数字的值,最终就会得到本次的值,然后通过本次的值继续循环得到下一个值。然后在这个循环外再套一层循环,通过n来控制循环次数得到第n次的结果。
遍历过程会出现一些问题,当遍历到末尾时,会跳出循环,但是这个时候count和curVal还没有拼接到最终结果中,因此在每次循环的后面需要多加一次。
第一次accepted的代码有点凌乱,因为频繁调用String的方法,时间复杂度有点高,后来参考别人的代码,改写为下面的:
class Solution {
public String countAndSay(int n) {
String input ="1";
char[] tVal = input.toCharArray();
char[] res = new char[tVal.length*2];
char curVal;
char count;
int index = 0;
for(int j=2;j<=n;j++) {
count = '1';
index = 0;
tVal = input.toCharArray();
res = new char[tVal.length*2];
curVal = tVal[0];
for (int i = 1; i < tVal.length; i++) {
if (curVal == tVal[i]) {
count++;
} else {
res[index++]=count;
res[index++]=curVal;
count = '1';
curVal = tVal[i];
}
}
res[index++]=count;
res[index++]=curVal;
input = new String(res,0,index);
}
return input;
}
}
这段代码,通过字符数组来代替我之前的String拼接,效率高了很多。