數組字符串轉換爲字母組合的種數

/**************************************************************************************
 *description:數組字符串轉換爲字母組合的種數
 *            給定一個字符串str,全部由數字組成,如果str中某一個或相鄰兩個字符
 *            組成的子串值介於1~26之間,則子串可轉換爲一個字母。規定1轉換爲A...
 *            26轉換爲Z。求str有多少種不同的轉換結果。

 *************************************************************************************/

#include <iostream>
#include<vector>
using namespace std;

//方法一:暴力遞歸。時間複雜度O(2^N),空間複雜度O(N):遞歸函數棧大小
//process(i)代表arr[0...i-1]已轉換,arr[i...N-1]的轉換種數
//process(N)表示arr[0...N-1]已轉換,所以種數是1.
//process(i):1.arr[i]=0時,首位爲零,不能轉換,process(i)=0
//           2.arr[i][i+1]大於26時,process(i)=process(i+1)
//           3.arr[i][i+1]小於等於26時,process(i)=process(i+1)+process(i+2)
int process(vector<int> arr, int i)
{
    if (i == arr.size())
        return 1;
    if (arr[i] == 0)
        return 0;
    int res = process(arr, i+1);
    if ( i+1 < arr.size() && arr[i]*10+arr[i+1] < 27)
        res += process(arr, i+2);
    return res;
}
int numOfMethods_1(vector<int> arr)
{
    if (arr.size() == 0)
        return 0;
    return process(arr, 0);
}

//方法二:時間複雜度O(2^N),空間複雜度O(N):遞歸函數棧大小
//在方法一的基礎上看到process(i)只和process(i+1)process(i+2)相關
//用斐波那契方法的思路從後往前求取就行
int numOfMethods_2(vector<int> arr)
{
    if (arr.size() == 0)
        return 0;
    int cur = arr[arr.size()-1] == 0 ? 0 : 1;
    int next = 1;
    int tmp = 0;
    for (int i = arr.size()-2; i >= 0; i--)
    {
        if (arr[i] == 0)
        {
            next = cur;
            cur = 0;
        }
        else
        {
           tmp = cur;
           if (arr[i]*10+arr[i+1] < 27)
               cur += next;
           next = tmp;
        }
    }
    return cur;
}

int main_12()
{
    int data[] = {1, 1, 1, 1};
    vector<int> arr(data, data+4);
    cout << numOfMethods_2(arr);

    return 0;
}


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