38. 外观数列
题目描述查看:https://leetcode-cn.com/problems/count-and-say/
题目的意思是新字符串是根据上一轮字符串按规则读取生成的。
读取的规则是数字一样的数有几个,把数字的个数、数字写进新字符串。
-
思路
分析题目可知,新字符串跟上一轮的字符串有关,要想求这一轮的字符串,必须先知道上一轮的字符串是啥,天然是个递归问题,可以使用动态规划来解。
设dp[i]为第i-1项的字符串,dp[i+1] 的值为遍历dp[i],并根据规则生成字符串。
-
边界条件
遍历字符串生成新字符串的过程,使用2个变量count和pre,count统计相似字符的个数,pre指向前一个字符。
for循环结束以后,最后的字符还没有写到builder中,循环结束后写。
1 StringBuilder builder = new StringBuilder(); 2 char[] str = dp[i-1].toCharArray(); 3 int count = 1; 4 char pre = str[0]; 5 for (int j = 1; j < str.length; j++) { 6 if(str[j] == pre)count++; 7 else{ 8 builder.append(count).append(pre); 9 count = 1; 10 pre = str[j]; 11 } 12 } 13 builder.append(count).append(pre); 14 dp[i] = builder.toString();
-
代码
1 public static String countAndSay(int n) { 2 String[] dp = new String[n]; 3 dp[0] = "1"; 4 for (int i = 1; i < n; i++) { 5 StringBuilder builder = new StringBuilder(); 6 char[] str = dp[i-1].toCharArray(); 7 int count = 1; 8 char pre = str[0]; 9 for (int j = 1; j < str.length; j++) { 10 if(str[j] == pre)count++; 11 else{ 12 builder.append(count).append(pre); 13 count = 1; 14 pre = str[j]; 15 } 16 } 17 builder.append(count).append(pre); 18 dp[i] = builder.toString(); 19 } 20 return dp[n-1]; 21 }
-
递归实现
方法作用,计算第n个外观数列。
参数,第几个外观数列。
结束条件,n==1时,返回"1";
1 public static String countAndSay(int n) { 2 if(n == 1)return "1"; 3 StringBuilder builder = new StringBuilder(); 4 char[] str = countAndSay(n-1).toCharArray(); 5 int count = 1; 6 char pre = str[0]; 7 for (int j = 1; j < str.length; j++) { 8 if(str[j] == pre)count++; 9 else{ 10 builder.append(count).append(pre); 11 count = 1; 12 pre = str[j]; 13 } 14 } 15 builder.append(count).append(pre); 16 return builder.toString(); 17 }