*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;
}