PAT (Basic Level) 1040. 有幾個PAT

題目

字符串APPAPT中包含了兩個單詞“PAT”,其中第一個PAT是第2位(P),第4位(A),第6位(T);第二個PAT是第3位(P),第4位(A),第6位(T)。
現給定字符串,問一共可以形成多少個PAT?
輸入格式:
輸入只有一行,包含一個字符串,長度不超過105
,只包含P、A、T三種字母。
輸出格式:
在一行中輸出給定字符串中包含多少個PAT。由于結果可能比較大,只輸出對1000000007取余數的結果。
輸入樣例:APPAPT
輸出樣例:2

具體內容可訪問PAT網站:題目鏈接

算法分析

如果使用暴力破解算法,時間復雜度為O(n^3),顯然不是最優的方法。
可以使用遞推的思想來解決該問題。
已知一個長度為n的字符串中“PAT”的個數為sum,如果在這個字符串后添加一個字符后組成的新的字符串中“PAT”的個數會是多少呢?
如果添加的字符為‘P’,新字符串的“PAT”個數不發生變化。
如果添加的字符為‘A’,新字符串的“PAT”個數不發生變化。
如果添加的字符為‘T’,新字符串的“PAT”個數可能發生變化。而發生變化的數量是因為添加的‘T’構成了新的“PAT”。想要知道新構成的“PAT”的數量,則需要知道舊字符串中“PA”的數量,因為舊字符串中“PA”的數量等于新構成的“PAT”的數量。即新字符串的“PAT”個數=舊字符串中“PA”的數量+舊字符串中“PA”的數量。
想要知道舊字符串中“PA”的數量只需要使用上述的方法就可以得到,筆者就不再贅述,下文中將會用形式化方法展示算法的具體實現。

算法實現

令輸入的字符串為string,其下標為[1...n]。
string[x]為string中第x位的字母,x ∈ [1, n]。
pattern為連續的字符串模式,pattern={P, PA, PAT}。在本題中,關心的字符串模式只有上述3種。
sum(x, pattern)定義:對于子字符串string[1...x],對應字符串模式pattern的總數。其中x ∈ [0, n],且sum[0, patter] = 0。

  1. 當string[x] = 'T'時:
    sum(x, P) <- sum(x - 1, P)
    sum(x, PA) <- sum(x - 1, PA)
    sum(x, PAT) <- sum(x - 1, PAT) + sum(x - 1, PA)
  2. 當string[x] = 'A'時:
    sum(x, P) <- sum(x - 1, P)
    sum(x, PA) <- sum(x - 1, PA) + sum(x - 1, P)
    sum(x, PAT) <- sum(x - 1, PAT)
  3. 當string[x] = 'P'時:
    sum(x, P) <- sum(x - 1, P) + 1
    sum(x, PA) <- sum(x - 1, PA)
    sum(x, PAT) <- sum(x - 1, PAT)
    對于一個長度為n的字符串string而言,其中PAT的數量也就是sum(n, PAT)。只需要從1-n遞推地計算sum值,即可得到最終結果。因此,該算法的時間復雜度為O(n)。

代碼實現

代碼是由C++實現的,如下所示。

#include <stdio.h>
#include <string.h>

const int maxStringLength = 100100;
const int module = 1000000007;
char inputArr[maxStringLength] = {0};
int length = 0;

void getInput();
void output(long long result);
long long calcSum();

int main() {
    long long result;
    getInput();
    if (length > 0) {
        result = calcSum();
        output(result);
    } else {
        output(0);
    }
    return 0;
}

void getInput() {
    scanf("%s", inputArr);
    length = strlen(inputArr);
}

void output(long long result) {
    printf("%lld", result % module);
}

long long calcSum() {
    long long sumP, sumPA, sumPAT;
    sumP = sumPA = sumPAT = 0;
    for (int i = 0; i < length; i ++) {
        if (inputArr[i] == 'P') {
            sumP ++;
        } else if (inputArr[i] == 'A') {
            sumPA += sumP;
        } else {
            sumPAT += sumPA;
        }
    }
    return sumPAT;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 指針是C語言中廣泛使用的一種數據類型。 運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數據結構; ...
    朱森閱讀 3,473評論 3 44
  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,769評論 0 33
  • 剛進家里,看到這熟悉有陌生的一切,自己變得惶恐,我是活在記憶里的人,始終無法擺脫過去,看到玲子送我的拖鞋,被老爸穿...
    云游大師閱讀 265評論 0 0
  • 晚餐就是一個蘋果了,實在沒胃口,走之前讓我帶吃的,我就知道我也不會有胃口,果然是這樣。都吃了沒?走親戚的回來沒?所...
    顧影之蓮閱讀 151評論 0 0
  • 妹妹悄悄給我發了一條短信,說爸媽又吵起來了,很嚴重。我當即打電話回家,電話那頭是強忍著不哭的妹妹和滿是委屈的弟弟說...
    然而寒冬r閱讀 554評論 0 1