Return the result of evaluating a given boolean expression
, represented as a string.
An expression can either be:
"t"
, evaluating toTrue
;"f"
, evaluating toFalse
;"!(expr)"
, evaluating to the logical NOT of the inner expressionexpr
;"&(expr1,expr2,...)"
, evaluating to the logical AND of 2 or more inner expressionsexpr1, expr2, ...
;"|(expr1,expr2,...)"
, evaluating to the logical OR of 2 or more inner expressionsexpr1, expr2, ...
Example 1:
Input: expression = "!(f)"
Output: true
Example 2:
Input: expression = "|(f,t)"
Output: true
Example 3:
Input: expression = "&(t,f)"
Output: false
Example 4:
Input: expression = "|(&(t,f,t),!(t))"
Output: false
Constraints:
1 <= expression.length <= 20000
expression[i]
consists of characters in{'(', ')', '&', '|', '!', 't', 'f', ','}
.expression
is a valid expression representing a boolean, as given in the description.
這道題說是給了一個布爾型的表達式,讓我們進行解析,並返回最終的值。其中的t和f分別表示 true 和 false,這里還有其他三種操作符,與,或,和非,這些都是最基本的邏輯運算,沒有太大的難度。這道題的難點在於給定的是一個字符串,而且可能出現嵌套的運算,比如例子4,運算順序應該是從內而外的。如何才能拆分出正確的邏輯塊並進行運算是一個難點,由於存在嵌套,所以從左到右遍歷的話可能會遇到很多的左括號,什么時候知道遇到最內層的邏輯塊了呢,就是第一次遇到右括號的時候,這樣跟之前一個左括號之間的內容一定是當前最內層的邏輯塊了,可以進行計算了。所以右括號的位置是一個觸發點,並且需要回溯到前一個左括號的位置,這種后進先出的特點可以使用棧來做。所以大體是思路就有了,遍歷表達式的每一個字符,只要遇到的不是右括號或者逗號(逗號入棧沒有意義,可以直接忽略),就壓入棧。若遇到了右括號,則此時要出棧,直至到上一個左括號,中間的可能有大量的t和f,重復出現的不影響結果,可以將所有內容放入到一個 HashSet 中,這樣方便之后查找。當對應的左括號也出棧之后,接下來棧頂的就是操作符了,將其出棧,並且根據其不同進行邏輯運算:若是與運算,則只要看 HashSet 中是否有 false,有的話結果就是 false,壓入棧;若是或運算,只要看 HashSet 中是否有 true,有的話就是 true,壓入棧。若是非運算,則 HashSet 中只有一個布爾型變量,對其取反並壓入棧。最終遍歷完成后,棧中只會剩余一個布爾型變量,根據其結果返回對應的 true 或者 false 即可,參見代碼如下:
class Solution {
public:
bool parseBoolExpr(string expression) {
stack<char> st;
for (int i = 0; i < expression.size(); ++i) {
char c = expression[i];
if (c == ')') {
unordered_set<char> seen;
while (!st.empty() && st.top() != '(') {
seen.insert(st.top()); st.pop();
}
st.pop();
char op = st.top(); st.pop();
if (op == '&') {
st.push(seen.count('f') ? 'f' : 't');
} else if (op == '|') {
st.push(seen.count('t') ? 't' : 'f');
} else {
st.push(seen.count('t') ? 'f' : 't');
}
} else if (c != ',') {
st.push(c);
}
}
return st.top() == 't';
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1106
參考資料:
https://leetcode.com/problems/parsing-a-boolean-expression/
https://leetcode.com/problems/parsing-a-boolean-expression/discuss/323307/Python-Easy-1-line-Cheat