1. 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5}
是某栈的压栈序列,序列 {4,5,3,2,1}
是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2}
就不可能是该压栈序列的弹出序列。
Example 1
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
Example 2
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。
Constraints:
0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
1 <= n, m <= 10^5
pushed
是popped
的排列。
代码 [二分]
class Solution {
public:
vector<int> successfulPairs(vector<int> &spells, vector<int> &potions, long long success) {
sort(potions.begin(), potions.end());
vector<int> result(spells.size());
for (int i = 0; i < spells.size(); ++i) {
int lo = min(100001ll, (success - 1) / spells[i] + 1);
result[i] = potions.end() - lower_bound(potions.begin(), potions.end(), lo);
}
return result;
}
};
2. 括号的分数
给定一个平衡括号字符串 S
,按下述规则计算该字符串的分数:
()
得 1 分。AB
得A + B
分,其中 A 和 B 是平衡括号字符串。(A)
得2 * A
分,其中 A 是平衡括号字符串。
Example 1
输入: "()"
输出: 1
Example 2
输入: "(())"
输出: 2
Constraints:
S
是平衡括号字符串,且只含有(
和)
。2 <= S.length <= 50
代码 1 [栈 - 脑残版本]
#include<bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
stack<tuple<int, int, int>> scores; // start, end, score
stack<int> st;
for (int i = 0, prev; i < s.size(); ++i) {
if (s[i] == '(') {
st.push(i);
continue;
}
if (!scores.empty() && st.top() == get<0>(scores.top()) - 1) { // s[i] == ')' - double
auto[start, end, score]=scores.top();
scores.pop();
st.pop();
scores.push({start - 1, end + 1, score * 2});
} else {
prev = st.top();
st.pop();
scores.push({prev, i, 1});
}
if (scores.size() >= 2) { // add
auto[start, end, score]=scores.top();
scores.pop();
if (start == get<1>(scores.top()) + 1) {
auto[start_, end_, score_]=scores.top();
scores.pop();
scores.push({start_, end, score + score_});
} else {
scores.push({start, end, score});
}
}
}
cout << get<2>(scores.top());
return 0;
}
代码 2 [分治]
class Solution {
private:
int divide(const string &s, int i, int j) {
int ans = 0, bal = 0;
for (int k = i; k < j; ++k) {
bal += s[k] == '(' ? 1 : -1;
if (bal == 0) {
ans += k - i == 1 ? 1 : 2 * divide(s, i + 1, k);
i = k + 1;
}
}
return ans;
}
public:
int scoreOfParentheses(const string &s) { return divide(s, 0, s.size()); }
};
代码 3 [栈]
class Solution {
public:
int scoreOfParentheses(const string &s) {
stack<int> st;
st.push(0);
for (char ch:s) {
if (ch == '(') {
st.push(0);
} else {
int v = st.top(); st.pop();
int w = st.top(); st.pop();
st.push(w + max(2 * v, 1));
}
}
return st.top();
}
};
代码 4 [统计核心的数目]
class Solution {
public:
int scoreOfParentheses(const string &s) {
int ans = 0, bal = 0;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '(') {
bal++;
} else {
bal--;
if (s[i - 1] == '(') ans += 1 << bal;
}
}
return ans;
}
};
3. 反转每对括号间的子串
给出一个字符串 s
(仅含有小写英文字母和括号)。
请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。
注意,您的结果中 不应 包含任何括号。
Example 1
输入:s = "(abcd)"
输出:"dcba"
Example 2
输入:s = "(u(love)i)"
输出:"iloveu"
解释:先反转子字符串 "love" ,然后反转整个字符串。
Constraints:
0 <= s.length <= 2000
s
中只有小写英文字母和括号- 题目测试用例确保所有括号都是成对出现的
代码 1 [栈]
class Solution {
public:
string reverseParentheses(string s) {
stack<string> st;
string str;
for (char ch:s) {
if (ch == '(') {
st.push(str);
str = "";
} else if (ch == ')') {
reverse(str.begin(), str.end());
str = st.top() + str;
st.pop();
} else {
str.push_back(ch);
}
}
return str;
}
};
代码 2 [预处理括号]
class Solution {
public:
string reverseParentheses(string s) {
int n = s.length();
vector<int> pair(n);
stack<int> stk;
for (int i = 0; i < n; i++) {
if (s[i] == '(') {
stk.push(i);
} else if (s[i] == ')') {
int j = stk.top();
stk.pop();
pair[i] = j, pair[j] = i;
}
}
string ret;
int index = 0, step = 1;
while (index < n) {
if (s[index] == '(' || s[index] == ')') {
index = pair[index];
step = -step;
} else {
ret.push_back(s[index]);
}
index += step;
}
return ret;
}
};
4. 对角线遍历
给你一个大小为 m x n
的矩阵 mat
,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。
Example 1
输入:mat = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,4,7,5,3,6,8,9]
Example 2
输入:mat = [[1,2],[3,4]]
输出:[1,2,3,4]
Constraints:
m == mat.length
n == mat[i].length
1 <= m, n <= 10^4
1 <= m * n <= 10^4
-10^5 <= mat[i][j] <= 10^5
代码
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>> &mat) {
int m = mat.size(), n = mat[0].size();
int cnt = m + n - 1;
vector<int> result;
result.reserve(m * n);
for (int k = 0, x, y, dx, dy; k < cnt; ++k) {
if ((k & 1) == 0) { // k % 2 == 0
x = min(k, m - 1), y = k - x;
dx = -1, dy = +1;
} else {
y = min(k, n - 1), x = k - y;
dx = +1, dy = -1;
}
while (x >= 0 && y >= 0 && x < m && y < n) {
result.push_back(mat[x][y]);
x += dx;
y += dy;
}
}
return result;
}
};