文章目录
0左边必有1的二进制字符串数量
题目
给定一个整数N,求由”0“字符与”1“字符组成的长度为N的所有字符串中,满足”0“字符的左边必有”1“字符的字符串数量。
举例:
N=1。只由”0“与”1“组成,长度为1的所有字符串:”0“、”1“。只有字符串”1“满足要求,返回1.
N=2。只由”0“和”1“组成,长度为2的所有字符串为:”00“、”01“、”10“、”11“。只有字符串”10“和”11“满足要求,所以返回2.
N=3.只由”0“与”1“组成,长度为3的所有字符串为:”000“、”001“、”010“、”011“、”100“、”101“、”110“、”111“。字符串”101“、”110“、”111“满足要求,所以返回3.
代码
经过分析,发现整个序列的规律符合斐波那契数列,所以有以下解法。详细解释可以参数原书籍。
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
//i<N-1时,p(i)=p(i+1)+p(i+2); i= N-1时,p(i)=2;i = N时,p(i) = 1;
//经过分析可以达到使用递归得到O(2^N)的解法
//循环方法的求解过程类似于循环求解斐波那契数列,时间复杂度可以降到O(N)
//进一步使用矩阵乘法的方法可以是世间复杂度降到O(logN)
int process(int i, int n)
{
if (i == n - 1)
return 2;
if (i == n)
return 1;
return process(i + 1, n) + process(i + 2, n);
}
int getNum1(int n)
{
if (n < 1)
return 0;
return process(1, n);
}
int getNum2(int n)
{
if (n < 1)
return 0;
if (n == 1)
return 1;
int pre = 1;
int cur = 1;
int tmp = 0;
for (int i = 2; i < n + 1; i++)
{
tmp = cur;
cur += pre;
pre = tmp;
}
return cur;
}
vector<vector<int>> multiMatrix(vector<vector<int>> m1, vector<vector<int>> m2)
{
int m = m1.size();
int n = m1[0].size();
int t = m2[0].size();
vector<vector<int>> res(m, vector<int>(t, 0));
for (int i = 0; i < m; i++)
{
for (int k = 0; k < n; k++)
{
int tmp = m1[i][k];
for (int j = 0; j < t; j++)
res[i][j] += tmp * m2[k][j];
}
}
return res;
}
vector<vector<int>> matrixPower(vector<vector<int>> in, int p)
{
int m = in.size();
int n = in[0].size();
vector<vector<int>> res(m, vector<int>(n, 0));
for (int i = 0; i < m; i++)
res[i][i] = 1;
vector<vector<int>> tmp(in);
for (; p != 0; p >>= 1)
{
if ((p & 1) != 0)
res = multiMatrix(res, tmp);
tmp = multiMatrix(tmp, tmp);
}
return res;
}
int getNum3(int n)
{
if (n < 1)
return 0;
if (n == 1 || n == 2)
return n;
vector<vector<int>> base(2, vector<int>(2, 0));
base[0