算法学习6(题解)
1.题目
「外观数列」是一个数位字符串序列,由递归公式定义:
- countAndSay(1) = “1”
- countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。
行程长度编码(RLE)
是一种字符串压缩方法,其工作原理是通过将连续相同字符(重复两次或更多次)替换为字符重复次数(运行长度)和字符的串联。例如,要压缩字符串"3322251"
,我们将"33"
用"23"
替换,将"222"
用"32"
替换,将"5"
用"15"
替换并将"1"
用"11"
替换。因此压缩后字符串变为"23321511"
。
给定一个整数n
,返回 外观数列的第n
个元素(1 <= n <= 30)。
2.实例
实例一
输入:n = 4
输出:"1211"
解释:
countAndSay(1) = "1"
countAndSay(2) = "1" 的行程长度编码 = "11"
countAndSay(3) = "11" 的行程长度编码 = "21"
countAndSay(4) = "21" 的行程长度编码 = "1211"
3.代码
鄙人的:
public class Practice10 {
public String countAndSay(int n) {
String a = "1", temp = "";
int count = 1;
for(int i = 1;i < n;i++){
//人为掠过此种情况
if(i == 1){
a = "11";
continue;
}
// 对s1遍历处理获取值
for(int j = 0;j < a.length()-1;j++){
// 设定计数器 计算同一个数字出现的次数 count
if(a.charAt(j) == a.charAt(j+1)){
count++;
//末位数字处理
if(j == a.length()-2){
temp += count+""+a.charAt(j);
break;
}
}else{
// 不符合,记录下
temp += count+""+a.charAt(j);
count = 1;
}
//末位数字处理
if(j == a.length()-2){
temp += 1+""+a.charAt(j+1);
}
}
//归零
a = temp;
temp = "";
count = 1;
}
return a;
}
大佬的:
public String countAndSay(int n) {
// 递归出口
if(n==1){
return "1";
}
// 假设我们获得上一次的结果为 s1 = 112213
String s1 = countAndSay(n - 1);
// 定义结果
StringBuilder result = new StringBuilder();
// 对s1遍历处理获取值
char local = s1.charAt(0);
int count = 0;
for (int i = 0; i < s1.length(); i++) {
// 设定计数器 计算同一个数字出现的次数 count
if(s1.charAt(i) == local){
count++;
}else {
// 不符合,记录下
result.append(count);
result.append(local);
count = 1;
local = s1.charAt(i);
}
}
result.append(count);
result.append(local);
return result.toString();
}
作者:桂继宏
来源:力扣(LeetCode)
4.思路
鄙人的用的迭代,代码十分臃肿; 大佬用的递归——相当于代替了迭代的外层循环,也避免的很多特殊情况。
- 两种方法都是通过
count
计数,直到遇到不同的数字就进行记录,区别在于我是对n
中两两挨着的数字进行比较,所以就出现了数组索引越界的问题:在对s1遍历处理获取值
之前,小于两位的数字需要额外手动处理、在对s1遍历处理获取值
中末位数字也需要分开处理; - 而另一种方法通过依次遍历比较则很好的避免了这些问题,在处理末位数字时也只需要在循环结束后再进行一次赋值;
- 赋值时我用的字符串加减,而第二种用
api
,区别不大。
char local = s1.charAt(0);
int count = 0;
// 对s1遍历处理获取值
for (int i = 0; i < s1.length(); i++) {
if(s1.charAt(i) == local){
count++;
}else {
//result.append(count);
//result.append(local);
count = 1;
local = s1.charAt(i);
}
}
以上题目及实列代码均来自于:力扣(LeetCode)