字符串解碼問題

字符串解碼問題

作者:Grey

原文地址:

博客園:字符串解碼問題

CSDN:字符串解碼問題

題目描述

給定一個經過編碼的字符串,返回它解碼後的字符串。

編碼規則爲: k[encoded_string],表示其中方括號內部的 encoded_string 正好重複 k 次。注意 k 保證爲正整數。

你可以認爲輸入字符串總是有效的;輸入字符串中沒有額外的空格,且輸入的方括號總是符合格式要求的。

此外,你可以認爲原始數據不包含數字,所有的數字只表示重複的次數 k ,例如不會出現像 3a 或 2[4] 的輸入。

示例 1:

輸入:s = "3[a]2[bc]"
輸出:"aaabcbc"
示例 2:

輸入:s = "3[a2[c]]"
輸出:"accaccacc"
示例 3:

輸入:s = "2[abc]3[cd]ef"
輸出:"abcabccdcdcdef"
示例 4:

輸入:s = "abc3[cd]xyz"
輸出:"abccdcdcdxyz"

題目鏈接見:LeetCode 394. Decode String

主要思路

定義遞歸函數

String[] p(char[] str, int n, int from)

遞歸含義表示,str 字符串從 from 開始一直到結尾或者右邊括號生成的信息返回,返回值是一個長度爲 2 的數組,例如

2[abc]3[cd]ef

這個字符串,遞歸函數在執行過程中,遇到第一個右括號的時候,就會結算出兩個信息,

第一個信息:之前處理過的字符串是什麼;

第二個信息:處理到了哪個位置。

所以,在經歷第一次遞歸過程後,返回

String[] res

其中

res[0] = "abcabc"; // 第一次遇到],進行結算生成的字符串
res[1] = "5" // 處理到了第五個位置,即第一個]出現的位置

繼續遞歸

res[0] = "abcabccdcdcd"; // 第二次遇到],進行結算生成的字符串,注:這裏要拼接上上一次遞歸的"abcabc"
res[1] = "10" // 處理到了第十個位置,即第二個]出現的位置

繼續,後續沒有]了,所以一直到字符串最後,得到最終的結果

res[0] = "abcabccdcdcdef"; // 處理到了終止位置,結算之前拼接的字符串和最後遺留字符串拼接的最終結果
res[1] = "12"; // 處理到了終止位置

完整代碼如下

class Solution {
  
  public static String decodeString(String s) {
    char[] str = s.toCharArray();
    int len = str.length;
    return p(str, len, 0)[0];
  }

  private static String[] p(char[] str, int n, int from) {
    StringBuilder sb = new StringBuilder();
    int pre = 0;
    int i = from;
    while (i != n && str[i] != ']') {
      if (Character.isLowerCase(str[i]) || Character.isUpperCase(str[i])) {
        // 字母
        sb.append(str[i++]);
      } else if (Character.isDigit(str[i])) {
        // 數字
        pre = pre * 10 + Integer.parseInt(String.valueOf(str[i++]));
      } else if ('[' == str[i]) {
        // 左括號
        String[] bra = p(str, n, i + 1);
        sb.append(build(pre, bra[0]));
        pre = 0;
        i = Integer.parseInt(bra[1]) + 1;
      }
    }
    return new String[] {sb.toString(), String.valueOf(i)};
  }

  private static String build(int pre, String s) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < pre; i++) {
      sb.append(s);
    }
    return sb.toString();
  }

}

代碼說明

主要看p函數的while循環部分,其中i != n && str[i] != ']'就是控制每次遞歸只處理除了結尾位置和]位置的其他位置,遇到結尾或者]直接返回一次結算結果。

while中的三個分支也比較直白,對於字母的話,直接append就可以,對於數字,要處理一個簡單的邊界條件,即數字不一定是單個整數,可能是多位數,比如334[abc],對於[,就可以結算這個[匹配的右括號之間的內容:

        // 得到與其匹配的右括號之間的內容
        String[] bra = p(str, n, i + 1);
        sb.append(build(pre, bra[0]));
        pre = 0;
        // 去下一個位置匹配
        i = Integer.parseInt(bra[1]) + 1;

更多

算法和數據結構筆記

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章