25. Boolean Parenthesization
The problem can be found at the following link: Question Link
Problem Description
Given a boolean expression s
consisting of:
Operands:
'T'
β True'F'
β False
Operators:
'&'
β Boolean AND'|'
β Boolean OR'^'
β Boolean XOR
Count the number of ways we can parenthesize the expression such that it evaluates to True.
Examples
Example 1:
Input:
s = "T|T&F^T"
Output:
4
Explanation:
The expression evaluates to True in 4 ways:
((T | T) & (F ^ T)) β (T | T) β T, (F ^ T) β T, T & T = T β
(T | (T & (F ^ T))) β (F ^ T) β T, (T & T) β T, T | T = T β
(((T | T) & F) ^ T) β (T | T) β T, (T & F) β F, F ^ T = T β
(T | ((T & F) ^ T)) β (T & F) β F, (F ^ T) β T, T | T = T β
Example 2:
Input:
s = "T^F|F"
Output:
2
Explanation:
The expression evaluates to True in 2 ways:
((T^F)|F)
(T^(F|F))
Constraints:
$(1 \leq |s| \leq 100)$
My Approach: Dynamic Programming (Bottom-Up Table)
The problem follows optimal substructure and overlapping subproblems, making Dynamic Programming (DP) the most efficient approach.
We use a bottom-up DP approach where we maintain two 2D DP tables:
T[i][j]
β Number of ways to parenthesizes[i:j]
to get True.F[i][j]
β Number of ways to parenthesizes[i:j]
to get False.
Algorithm Steps:
Initialize the DP tables:
If
s[i] == 'T'
, setT[i][i] = 1
(since a singleT
is alwaysTrue
).If
s[i] == 'F'
, setF[i][i] = 1
(since a singleF
is alwaysFalse
).
Fill the DP tables using a bottom-up approach:
Iterate over subexpressions of increasing length (
l
), from 2 to n.For each subexpression
s[i:j]
, check each operators[k]
(wherek
is an odd index).Compute
T[i][j]
andF[i][j]
using previously computed DP values.
Update DP values based on the operator
s[k]
:If
s[k] == '&'
(AND operator):T[i][j] += lt * rt
(both left and right must be True).F[i][j] += lt * rf + lf * rt + lf * rf
(any case where at least one is False).
If
s[k] == '|'
(OR operator):T[i][j] += lt * rt + lt * rf + lf * rt
(only both False make it False).F[i][j] += lf * rf
.
If
s[k] == '^'
(XOR operator):T[i][j] += lt * rf + lf * rt
(one True, one False).F[i][j] += lt * rt + lf * rf
(both True or both False).
Return
T[0][n-1]
, which gives the total ways to evaluates
toTrue
.
Time and Auxiliary Space Complexity
Expected Time Complexity: O(NΒ³), as we process all partitions
(i, k, j)
for each segment ofs
.Expected Auxiliary Space Complexity: O(NΒ²), for storing
T
andF
DP tables.
Code (C++)
class Solution {
public:
int countWays(string &s) {
int n = s.size();
vector<vector<int>> T(n, vector<int>(n)), F(n, vector<int>(n));
for (int i = 0; i < n; i += 2) T[i][i] = s[i] == 'T', F[i][i] = s[i] == 'F';
for (int l = 2; l < n; l += 2)
for (int i = 0; i < n - l; i += 2)
for (int k = i + 1, j = i + l; k < j; k += 2) {
int lt = T[i][k - 1], lf = F[i][k - 1], rt = T[k + 1][j], rf = F[k + 1][j];
if (s[k] == '&') T[i][j] += lt * rt, F[i][j] += lt * rf + lf * rt + lf * rf;
else if (s[k] == '|') T[i][j] += lt * rt + lt * rf + lf * rt, F[i][j] += lf * rf;
else T[i][j] += lt * rf + lf * rt, F[i][j] += lt * rt + lf * rf;
}
return T[0][n - 1];
}
};
Code (Java)
class Solution {
static int countWays(String s) {
int n = s.length();
int[][] T = new int[n][n], F = new int[n][n];
for (int i = 0; i < n; i += 2) T[i][i] = s.charAt(i) == 'T' ? 1 : 0;
for (int i = 0; i < n; i += 2) F[i][i] = s.charAt(i) == 'F' ? 1 : 0;
for (int l = 2; l < n; l += 2)
for (int i = 0; i < n - l; i += 2)
for (int k = i + 1, j = i + l; k < j; k += 2) {
int lt = T[i][k - 1], lf = F[i][k - 1], rt = T[k + 1][j], rf = F[k + 1][j];
if (s.charAt(k) == '&') {
T[i][j] += lt * rt;
F[i][j] += lt * rf + lf * rt + lf * rf;
} else if (s.charAt(k) == '|') {
T[i][j] += lt * rt + lt * rf + lf * rt;
F[i][j] += lf * rf;
} else {
T[i][j] += lt * rf + lf * rt;
F[i][j] += lt * rt + lf * rf;
}
}
return T[0][n - 1];
}
}
Code (Python)
class Solution:
def countWays(self, s):
n = len(s)
T, F = [[0] * n for _ in range(n)], [[0] * n for _ in range(n)]
for i in range(0, n, 2):
T[i][i], F[i][i] = int(s[i] == 'T'), int(s[i] == 'F')
for l in range(2, n, 2):
for i in range(0, n - l, 2):
for k, j in zip(range(i + 1, i + l, 2), [i + l] * (l // 2)):
lt, lf, rt, rf = T[i][k - 1], F[i][k - 1], T[k + 1][j], F[k + 1][j]
if s[k] == '&':
T[i][j] += lt * rt
F[i][j] += lt * rf + lf * rt + lf * rf
elif s[k] == '|':
T[i][j] += lt * rt + lt * rf + lf * rt
F[i][j] += lf * rf
else:
T[i][j] += lt * rf + lf * rt
F[i][j] += lt * rt + lf * rf
return T[0][n - 1]
Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: Any Questions. Letβs make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated