This problem is a classic two-state dynamic programming problem. Let a[i] be the number of valid strings of length i that end with 0, and let b[i] be the number that end with 1.
If a valid string of length i ends with 0, the previous bit can be 0 or 1 (both valid). If it ends with 1, the previous bit must be 0 to avoid consecutive 1s. Therefore a[i] depends on both a[i-1] and b[i-1], while b[i] depends only on a[i-1].
classSolution {
public:longlong countNoConsecOnes(int N) {
if (N <=0) return0;
longlong a =1; // ends with 0
longlong b =1; // ends with 1
for (int i =2; i <= N; ++i) {
longlong na = a + b;
longlong nb = a;
a = na;
b = nb;
}
return a + b;
}
};
classSolution {
publiclongcountNoConsecOnes(int N) {
if (N <= 0) return 0;
long a = 1; // ends with 0long b = 1; // ends with 1for (int i = 2; i <= N; ++i) {
long na = a + b;
long nb = a;
a = na;
b = nb;
}
return a + b;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution:
defcount_no_consec_ones(self, N: int) -> int:
if N <=0:
return0 a: int =1# ends with 0 b: int =1# ends with 1for _ in range(2, N +1):
na = a + b
nb = a
a = na
b = nb
return a + b
The total count for length N follows Fibonacci numbers: count(N) = fib(N+2). This is visible by expanding the DP: total(N) = a[N] + b[N] = a[N] + a[N-1] and a[N] = total(N-1), which yields the Fibonacci recurrence.
classSolution {
public:// returns pair (F(n), F(n+1))
std::pair<longlong, longlong> fibPair(longlong n) {
if (n ==0) return {0, 1};
auto p = fibPair(n >>1);
longlong a = p.first;
longlong b = p.second;
longlong c = a * (2* b - a);
longlong d = a * a + b * b;
if (n &1) return {d, c + d};
elsereturn {c, d};
}
longlongcountNoConsecOnesFast(longlong N) {
if (N <=0) return0;
return fibPair(N +2).first;
}
};
classSolution:
deffib_pair(self, n: int) -> tuple[int, int]:
if n ==0:
return0, 1 a, b = self.fib_pair(n >>1)
c = a * (2*b - a)
d = a*a + b*b
if n &1:
return d, c + d
return c, d
defcount_no_consec_ones_fast(self, N: int) -> int:
if N <=0:
return0return self.fib_pair(N +2)[0]