You are given a valid boolean expression as a string expression
consisting of the characters '1','0','&' (bitwise AND operator),'|' (bitwise OR operator),'(', and ')'.
For example, "()1|1" and "(1)&()" are not valid while "1", "(((1))|(0))", and "1|(0&(1))" are valid expressions.
Return theminimum cost to change the final value of the expression.
For example, if expression = "1|1|(0&0)&1", its value is 1|1|(0&0)&1 = 1|1|0&1 = 1|0&1 = 1&1 = 1. We want to apply operations so that thenew expression evaluates to 0.
The cost of changing the final value of an expression is the number of operations performed on the expression. The types of operations are described as follows:
Turn a '1' into a '0'.
Turn a '0' into a '1'.
Turn a '&' into a '|'.
Turn a '|' into a '&'.
Note:'&' does not take precedence over '|' in the order of calculation. Evaluate parentheses first , then in left-to-right order.
Input: expression ="1&(0|1)"Output: 1Explanation: We can turn "1&(0 _**|**_ 1)" into "1&(0 _**&**_ 1)" by changing the '|' to a '&' using 1 operation.The new expression evaluates to 0.
Input: expression ="(0&0)&(0&0&0)"Output: 3Explanation: We can turn "(0 _**& 0**_)**_&_**(0&0&0)" into "(0 _**|1**_)_**|**_(0&0&0)" using 3 operations.The new expression evaluates to 1.
Input: expression ="(0|(1|0&1))"Output: 1Explanation: We can turn "(0|(_**1**_ |0&1))" into "(0|(_**0**_ |0&1))" using 1 operation.The new expression evaluates to 0.
We parse the expression recursively, keeping track of the minimum cost to flip the result to 0 or 1 at each subexpression. For each operator, we combine the costs from its left and right children according to the operator’s logic, and use a stack to handle parentheses.
classSolution {
funminOperationsToFlip(expr: String): Int {
dataclassPair(val zero: Int, val one: Int)
val stk = ArrayDeque<Pair>()
val ops = ArrayDeque<Char>()
funmerge(a: Pair, b: Pair, op: Char): Pair {
returnif (op =='&') {
val to1 = a.one + b.one
var to0 = minOf(a.zero, b.zero)
if (a.zero == b.zero) to0++ Pair(to0, to1)
} else {
val to0 = a.zero + b.zero
var to1 = minOf(a.one, b.one)
if (a.one == b.one) to1++ Pair(to0, to1)
}
}
for (c in expr) {
when (c) {
'0'-> stk.addLast(Pair(0,1))
'1'-> stk.addLast(Pair(1,0))
'('-> ops.addLast(c)
')'-> {
while (ops.last() !='(') {
val b = stk.removeLast()
val a = stk.removeLast()
val op = ops.removeLast()
stk.addLast(merge(a, b, op))
}
ops.removeLast()
}
'&', '|'-> {
while (ops.isNotEmpty() && ops.last() !='(') {
val b = stk.removeLast()
val a = stk.removeLast()
val op = ops.removeLast()
stk.addLast(merge(a, b, op))
}
ops.addLast(c)
}
}
}
while (ops.isNotEmpty()) {
val b = stk.removeLast()
val a = stk.removeLast()
val op = ops.removeLast()
stk.addLast(merge(a, b, op))
}
val res = stk.last()
return maxOf(res.zero, res.one)
}
}
classSolution:
defminOperationsToFlip(self, expr: str) -> int:
stk = []
ops = []
defmerge(a: tuple[int,int], b: tuple[int,int], op: str) -> tuple[int,int]:
if op =='&':
to1 = a[1] + b[1]
to0 = min(a[0], b[0])
if a[0] == b[0]: to0 +=1return (to0, to1)
else:
to0 = a[0] + b[0]
to1 = min(a[1], b[1])
if a[1] == b[1]: to1 +=1return (to0, to1)
for c in expr:
if c =='0': stk.append((0,1))
elif c =='1': stk.append((1,0))
elif c =='(': ops.append(c)
elif c ==')':
while ops[-1] !='(':
b = stk.pop(); a = stk.pop(); op = ops.pop()
stk.append(merge(a, b, op))
ops.pop()
elif c in'&|':
while ops and ops[-1] !='(':
b = stk.pop(); a = stk.pop(); op = ops.pop()
stk.append(merge(a, b, op))
ops.append(c)
while ops:
b = stk.pop(); a = stk.pop(); op = ops.pop()
stk.append(merge(a, b, op))
res = stk[-1]
return max(res)