1. 程式人生 > 其它 >LeetCode2266. 統計打字方案數-----動態規劃

LeetCode2266. 統計打字方案數-----動態規劃

題目表述

Alice 在給 Bob 用手機打字。數字到字母的 對應 如下圖所示。

為了打出一個字母,Alice需要按對應字母 i 次,i 是該字母在這個按鍵上所處的位置。

  • 比方說,為了按出字母 's' ,Alice 需要按 '7' 四次。類似的, Alice 需要按 '5' 兩次得到字母  'k' 。
  • 注意,數字 '0' 和 '1' 不對映到任何字母,所以 Alice 不 使用它們。

但是,由於傳輸的錯誤,Bob 沒有收到 Alice 打字的字母資訊,反而收到了 按鍵的字串資訊 。

  • 比方說,Alice 發出的資訊為 "bob" ,Bob 將收到字串 "2266622" 。

給你一個字串 pressedKeys ,表示 Bob 收到的字串,請你返回 Alice 總共可能發出多少種文字資訊 。

由於答案可能很大,將它對10^9 + 7取餘後返回

動態規劃

記字串為 s=pressedKeyss,狀態轉移過程如下:

  1. 若s[i] != s[i - 1], 則s[i] 本身自成一體, 易得dp[i] = dp[i-1];

  2. 若s[i] == s[i - 1] != s[i-2],則

    • 情況一:s[i]本身可自成一種方案,對應資訊種類為dp[i−1] 種;
    • 情況二:s[i] 和 s[i−1] 成一種組合,對應資訊種類為dp[i−2] 種(應判斷 dp[i-2]是存在的方可);

    綜合起來有dp[i] = dp[i-1] + dp[i-2]

  3. 若s[i] == s[i - 1] == s[i-2],則

    • 情況一:s[i]本身可自成一種方案,對應資訊種類為dp[i−1] 種;
    • 情況二:s[i] 和 s[i−1] 成一種組合,對應資訊種類為dp[i−2] 種;
    • 也可以 s[i],s[i−1] 和 s[i-2] 成一種組合,對應資訊種類為dp[i−3] 種(應判斷dp[i−3] 是存在的方可);

    綜合起來有dp[i] = dp[i-1] + dp[i-2] + dp[i-3]

  4. 對於字元7,9而言,最多可以對應四種字元,因此最長的有效連續字元數目為4.因此綜合起來則有
    dp[i] = dp[i-1] + dp[i-2] + dp[i-3] + dp[i-4]

參考連結

class Solution {
    public int countTexts(String pressedKeys) {
        int mod = (int) 1e9 + 7;
        long[] dp = new long[pressedKeys.length()];
        dp[0] = 1;
        for(int i = 1; i < pressedKeys.length();i++){
            dp[i] = dp[i-1];
            if(pressedKeys.charAt(i) == pressedKeys.charAt(i-1)){
                dp[i] += i>=2 ? dp[i-2] : 1;
                if(i >= 2 && pressedKeys.charAt(i) == pressedKeys.charAt(i-2)){
                    dp[i] += i>=3 ? dp[i-3] : 1;
                    if((pressedKeys.charAt(i) == '7' || pressedKeys.charAt(i)  == '9') && i >= 3 && pressedKeys.charAt(i) == pressedKeys.charAt(i-3) ){
                        dp[i] += i>=4 ? dp[i-4] : 1;
                    }
                }
            }

            dp[i] %= mod;
        }
        return (int)dp[pressedKeys.length()-1];
    }
}