Leetcode 第 132 场双周赛题解
Leetcode 第 132 场双周赛题解
题目1:3174. 清除数字
思路
用栈模拟,遇到数字就弹出栈顶,遇到字母就插入栈。
最后留在栈里的就是答案。
代码
/*
* @lc app=leetcode.cn id=3174 lang=cpp
*
* [3174] 清除数字
*/
// @lc code=start
class Solution
{
public:
string clearDigits(string s)
{
stack<char> stk;
for (char &c : s)
{
if (isdigit(c))
stk.pop();
else
stk.push(c);
}
string ans;
while (!stk.empty())
{
ans.insert(ans.begin(), stk.top());
stk.pop();
}
return ans;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是字符串 s 的长度。
空间复杂度:O(n),其中 n 是字符串 s 的长度。
题目2:3175. 找到连续赢 K 场比赛的第一位玩家
思路
和 Leetcode1535. 找出数组游戏的赢家 几乎一样,把代码中的 arr[mx_i] 改成最大值的下标 mx_i 即可。
代码
/*
* @lc app=leetcode.cn id=1535 lang=cpp
*
* [1535] 找出数组游戏的赢家
*/
// @lc code=start
class Solution
{
public:
int getWinner(vector<int> &arr, int k)
{
int n = arr.size();
int mx_i = 0, win = 0;
for (int i = 1; i < n && win < k; i++)
{
if (arr[i] > arr[mx_i])
{
mx_i = i;
win = 0;
}
win++;
}
return mx_i;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 skills 的长度。
空间复杂度:O(1)。
题目3:3176. 求出最长好子序列 I
思路
dp[x][y]:以y为起点后面还有x次不一样的机会。
我们逆序遍历 i 从 n-1 到 y+1:
- 如果nums[i] == nums[y],证明我们直接与 i 相连不需要浪费错误机会,那么dp[x][y] = dp[x][i] + 1。
- 如果nums[i] != nums[y],证明我们与 i 连接需要花费错误机会,那么dp[x][y] = dp[x-1][i] +1。
代码
/*
* @lc app=leetcode.cn id=3176 lang=cpp
*
* [3176] 求出最长好子序列 I
*/
// @lc code=start
class Solution
{
public:
int maximumLength(vector<int> &nums, int k)
{
int n = nums.size();
vector<vector<int>> dp(k + 1, vector<int>(n, 0));
// 初始化
for (int i = n - 1; i >= 0; i--)
for (int j = n - 1; j > i; j--)
if (nums[i] == nums[j])
dp[0][i] = max(dp[0][i], dp[0][j] + 1);
// 状态转移
for (int i = 1; i <= k; i++)
for (int j = n - 1; j >= 0; j--)
for (int q = n - 1; q > j; q--)
{
if (nums[j] == nums[q])
dp[i][j] = max(dp[i][q] + 1, dp[i][j]);
else
dp[i][j] = max(dp[i - 1][q] + 1, dp[i][j]);
}
int ans = 0;
for (int i = 0; i < n; i++)
ans = max(ans, dp[k][i] + 1);
return ans;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(k*n2),其中 n 是数组 nums 的长度。
空间复杂度:O(k*n),其中 n 是数组 nums 的长度。
题目4:3177. 求出最长好子序列 II
思路
需要对第三题进行优化。
题解:动态规划+优化(Python/Java/C++/Go)
代码
/*
* @lc app=leetcode.cn id=3177 lang=cpp
*
* [3177] 求出最长好子序列 II
*/
// @lc code=start
class Solution
{
public:
int maximumLength(vector<int> &nums, int k)
{
unordered_map<int, vector<int>> fs;
vector<array<int, 3>> records(k + 1);
for (int x : nums)
{
if (!fs.contains(x))
{
fs[x] = vector<int>(k + 1);
}
auto &f = fs[x];
for (int j = k; j >= 0; j--)
{
f[j]++;
if (j)
{
auto &r = records[j - 1];
int mx = r[0], mx2 = r[1], num = r[2];
f[j] = max(f[j], (x != num ? mx : mx2) + 1);
}
// records[j] 维护 fs[.][j] 的 mx, mx2, num
int v = f[j];
auto &p = records[j];
if (v > p[0])
{
if (x != p[2])
{
p[2] = x;
p[1] = p[0];
}
p[0] = v;
}
else if (x != p[2] && v > p[1])
{
p[1] = v;
}
}
}
return records[k][0];
}
};
// @lc code=end
复杂度分析
时间复杂度:O(k*n),其中 n 是数组 nums 的长度。
空间复杂度:O(k*n),其中 n 是数组 nums 的长度。