forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
minimum-cost-to-change-the-final-value-of-expression.cpp
86 lines (82 loc) · 3.18 KB
/
minimum-cost-to-change-the-final-value-of-expression.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Time: O(n)
// Space: O(n)
class Solution {
public:
int minOperationsToFlip(string expression) {
static const unordered_map<char, int> precedence = {{'&', 0}, {'|', 0}};
vector<vector<int>> operands;
vector<char> operators;
for (const auto& c : expression) {
if (isdigit(c)) {
operands.push_back({int(c != '0'), int(c != '1')});
} else if (c == '(') {
operators.emplace_back(c);
} else if (c == ')') {
while (operators.back() != '(') {
compute(&operands, &operators);
}
operators.pop_back();
} else if (precedence.count(c)) {
while (!empty(operators) && precedence.count(operators.back()) &&
precedence.at(operators.back()) >= precedence.at(c)) {
compute(&operands, &operators);
}
operators.emplace_back(c);
}
}
while (!empty(operators)) {
compute(&operands, &operators);
}
return *max_element(cbegin(operands.back()), cend(operands.back()));
}
private:
template<typename T>
void compute(vector<T> *operands, vector<char> *operators) {
const auto right = operands->back(); operands->pop_back();
const auto left = operands->back(); operands->pop_back();
const char op = operators->back(); operators->pop_back();
if (op == '&') {
operands->push_back({min(left[0], right[0]), min(left[1] + right[1], min(left[1], right[1]) + 1)});
} else if (op == '|') {
operands->push_back({min(left[0] + right[0], min(left[0], right[0]) + 1), min(left[1], right[1])});
}
}
};
// Time: O(n)
// Space: O(n)
class Solution2 {
public:
int minOperationsToFlip(string expression) {
unordered_set<char> operands_set = {')', '0', '1'};
vector<tuple<int, int, char>> stk = {{0, 0, ' '}};
for (const auto& c : expression) {
if (c == '(') {
stk.emplace_back(0, 0, ' ');
} else if (operands_set.count(c)) {
int dp0 = 0, dp1 = 0;
if (c == ')') {
dp0 = get<0>(stk.back());
dp1 = get<1>(stk.back());
stk.pop_back();
} else {
dp0 = int(c != '0');
dp1 = int(c != '1');
}
if (get<2>(stk.back()) == '&') {
stk.back() = {min(get<0>(stk.back()), dp0),
min(get<1>(stk.back()) + dp1, min(get<1>(stk.back()), dp1) + 1),
' '};
} else if (get<2>(stk.back()) == '|') {
stk.back() = {min(get<0>(stk.back()) + dp0, min(get<0>(stk.back()), dp0) + 1),
min(get<1>(stk.back()), dp1),
' '};
} else {
stk.back() = {dp0, dp1, ' '};
}
} else { // operator
get<2>(stk.back()) = c;
}
}
return max(get<0>(stk[0]), get<1>(stk[0]));
}
};