Leetcode 第 410 场周赛题解
- Leetcode 第 410 场周赛题解
- 题目1:3248. 矩阵中的蛇
- 思路
- 代码
- 复杂度分析
- 题目2:3249. 统计好节点的数目
- 思路
- 代码
- 复杂度分析
- 题目3:3250. 单调数组对的数目 I
- 思路
- 代码
- 复杂度分析
- 题目4:3251. 单调数组对的数目 II
- 思路
- 代码
- 复杂度分析
Leetcode 第 410 场周赛题解
题目1:3248. 矩阵中的蛇
思路
遍历字符串数组 commands,模拟🐍的移动过程。
如果最后🐍的位置为 (i, j),则编号为 (i * n) + j。
代码
/** @lc app=leetcode.cn id=3248 lang=cpp** [3248] 矩阵中的蛇*/// @lc code=start
class Solution
{
public:int finalPositionOfSnake(int n, vector<string> &commands){int i = 0, j = 0;for (string &cmd : commands){switch (cmd[0]){case 'U':i--;break;case 'R':j++;break;case 'D':i++;break;case 'L':j--;break;default:break;}}return (i * n) + j;}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是字符串数组 commands 的长度。
空间复杂度:O(1)。
题目2:3249. 统计好节点的数目
思路
建树,然后从根节点 0 开始 DFS 这棵树。
DFS 返回子树大小。
对于节点 x,如果其是叶子节点,或者其所有儿子子树大小都一样,那么答案加一。
代码
/** @lc app=leetcode.cn id=3249 lang=cpp** [3249] 统计好节点的数目*/// @lc code=start
class Solution
{
public:int countGoodNodes(vector<vector<int>> &edges){int n = edges.size() + 1; // 节点数// 构建邻接表vector<vector<int>> adj(n);for (vector<int> &edge : edges){int u = edge[0], v = edge[1];adj[u].push_back(v);adj[v].push_back(u);}int ans = 0;// parent 为父节点function<int(int, int)> dfs = [&](int u, int parent) -> int{int cnt_sum = 1; // 节点总数,先计入自身int single_cnt = 0;bool valid = true;for (int v : adj[u]){// 规避邻接点中已访问过的父节点,不需要 visited 数组if (v == parent)continue;int cnt = dfs(v, u);cnt_sum += cnt;// 检测子树的节点数量是否相同if (single_cnt == 0)single_cnt = cnt;else if (single_cnt != cnt)valid = false;}ans += valid;return cnt_sum;};dfs(0, -1); // -1 即不存在父节点return ans;}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 edges 的长度。
空间复杂度:O(n),其中 n 是数组 edges 的长度。
题目3:3250. 单调数组对的数目 I
思路
题目输入一个数组nums。
假设有两个数组A和B,A递增,B递减,且 Ai + Bi = numsi
问有多少对(A,B)数组对。
解法:
代码
#
# @lc app=leetcode.cn id=3250 lang=python3
#
# [3250] 单调数组对的数目 I
## @lc code=start# 记忆化搜索class Solution:def countOfPairs(self, nums: List[int]) -> int:MOD = 10 ** 9 + 7n = len(nums)@cachedef dfs(i, a):if i == n - 1:return 1res = 0b = nums[i] - afor na in range(nums[i + 1] + 1):nb = nums[i + 1] - naif a <= na and b >= nb:res += dfs(i + 1, na)return res % MODres = 0for num in range(nums[0] + 1):res += dfs(0, num)res %= MODreturn res
# @lc code=end
复杂度分析
时间复杂度:O(n * m2),其中 n 是数组 nums 的长度。
空间复杂度:O(n * m),其中 n 是数组 nums 的长度。
题目4:3251. 单调数组对的数目 II
思路
设 f[i][j] 表示下标 0 到 i 中的单调数组对的个数,且 arr1[i]=j。
代码
/** @lc app=leetcode.cn id=3251 lang=cpp** [3251] 单调数组对的数目 II*/// @lc code=start
class Solution
{
private:const int MOD = 1e9 + 7;public:int countOfPairs(vector<int> &nums){int n = nums.size();int m = *max_element(nums.begin(), nums.end());vector<vector<long long>> dp(n, vector<long long>(m + 1));vector<long long> preSum(m + 1);fill(dp[0].begin(), dp[0].begin() + nums[0] + 1, 1);for (int i = 1; i < n; i++){partial_sum(dp[i - 1].begin(), dp[i - 1].end(), preSum.begin()); // dp[i-1] 的前缀和for (int j = 0; j <= nums[i]; j++){int max_k = j + min(nums[i - 1] - nums[i], 0);dp[i][j] = max_k >= 0 ? preSum[max_k] % MOD : 0;}}return accumulate(dp[n - 1].begin(), dp[n - 1].begin() + nums[n - 1] + 1, 0LL) % MOD;}
};
// @lc code=end
复杂度分析
时间复杂度:O(n * m),其中 n 是数组 nums 的长度,m=max(nums)。
空间复杂度:O(n * m),其中 n 是数组 nums 的长度,m=max(nums)。