LeetCode:第305场周赛【总结】

打了三场,算是发现力扣的一点小规律了,上次考两个搜索,这次考两个线性dp,奈何没把线性dp学明白。

6136. 算术三元组的数目【暴力or哈希】

在这里插入图片描述

思路

暴力做法:三重循环可做
哈希做法:将nums放入set,查找num + diff和num - diff是否都在set里。

AC代码

class Solution:
    def arithmeticTriplets(self, nums: List[int], diff: int) -> int:
        # 用哈希表做映射,判断nums[j] - diff 和 nums[j] + diff 是否在哈希表里
        s = set(nums)
        ans = 0
        for num in nums:
            if num - diff in s and num + diff in s:
                ans += 1
        return ans
        # return sum(num - diff in s and num + diff in s for num in nums)

6139. 受限条件下可到达节点的数目【BFS】

在这里插入图片描述
在这里插入图片描述

思路

建一个无向图,然后用bfs来判断有多少可达到点

AC代码

class Solution {
public:
    static const int N = 1e5 + 7;
    int vis[N];
    vector<int> tree[N];
    int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
        for (auto rs: restricted) {
            vis[rs] = 1;
        }
        // 建图
        for (int i = 0; i < edges.size(); ++i) {
            tree[edges[i][0]].push_back(edges[i][1]);
            tree[edges[i][1]].push_back(edges[i][0]);
        }
        queue<int> q;
        q.push(0);
        int ans = 0;
        while(!q.empty()) {
            int cur = q.front(); q.pop();
            ans++;
            vis[cur] = 1;
            for (int i = 0; i < tree[cur].size(); ++i) {
                if (vis[tree[cur][i]] == 0) {
                    q.push(tree[cur][i]);
                }
            }
        }
        return ans;
    }
};

6137. 检查数组是否存在有效划分【线性DP】

在这里插入图片描述

思路

这题比赛时,完全看不出来是dp,dp是做少了,做题时一点思路没有,又止步于第三题了。
本题巧妙运用了python中数组-1下标的思想,来作为边界条件

  • 考虑是对子时,要满足nums[i] == nums[i - 1] 并且由dp[i - 2]转移而来。
  • 考虑是顺子时,要满足nums[i] == nums[i - 1] + 1 == nums[i - 2] + 2并且由dp[i - 3]转移而来。
  • 考虑是炸时,要满足nums[i] == nums[i - 1] == nums[i - 2]并且由dp[i - 3]转移而来。
    返回最后一个数dp[-2],这里的dp[-1]不是最后一个数,而是边界条件。

AC代码

class Solution:
    def validPartition(self, nums: List[int]) -> bool:
        length = len(nums)
        dp = [False] * length + [True] # 利用dp[-1]作为边界条件,其实dp[-1]为
        for i in range(length):
            # 当nums[i, i + 1]为对子时
            if i > 0 and dp[i - 2] and nums[i] == nums[i - 1]: 
                dp[i] = True
            # 当nums[i, i - 1, i - 2]为炸时
            if i > 1 and dp[i - 3] and nums[i] == nums[i - 1] == nums[i - 1] == nums[i - 2]:
                dp[i] = True
            # 当nums[i, i - 1, i - 2]为顺子时
            if i > 1 and dp[i - 3] and nums[i] == nums[i - 1] + 1 == nums[i - 2] + 2:
                dp[i] = True
        return dp[-2]

6138. 最长理想子序列【线性DP】

在这里插入图片描述

思路

利用dp[i]表示以字符i结尾的最长理想字符串长度。
于是转移方程为dp[i] = max(dp[left : right]) + 1, left是i - c,right是i + c,并且注意不能越界。

AC代码

class Solution:
    def longestIdealString(self, s: str, k: int) -> int:
        dp = [0] * 26
        for c in s:
            i = ord(c) - ord('a')
            left = max(0, i - k)
            right = min(26, i + k + 1)
            dp[i] = max(dp[left : right]) + 1
        return max(dp)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空皓月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值