力扣:第 305 场周赛

193 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

力扣:第 305 场周赛

6136. 算术三元组的数目 - 力扣(LeetCode)

问题解析

可以注意到数据范围很小,只有200,直接暴力做法三层for循环枚举i,j,k,再看枚举的数符不符合条件即可。

AC代码

class Solution {
public:
    int arithmeticTriplets(vector<int>& nums, int diff) {
        int n=nums.size(),cnt=0;
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                for(int k=j+1;k<n;k++)
                {
                    if(nums[j]-nums[i]==diff&&nums[k]-nums[j]==diff)cnt++;
                }
            }
        }
        return cnt;
    }
};

6139. 受限条件下可到达节点的数目 - 力扣(LeetCode)

问题解析

根据edges数组建图,然后以点0为起点dfs一趟遍历所有的点,如果即将进入的点是不可进入点,那就跳过他走其他的路径。

dfs过程中记录走过点的数量即可。

AC代码

class Solution {
public:
    vector<int>tree[100050];
    unordered_map<int,int>mymap;
    int cnt=0,st[100050];
    void dfs(int x,int y)
    {
        cnt++;
        for(auto i:tree[x])
        {
            if(i!=y&&!mymap.count(i))
            {
                dfs(i,x);
            }
                
        }
    }
    int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
        for(int i=0;i<n-1;i++)
        {
            int x=edges[i][0],y=edges[i][1];
            tree[x].push_back(y);
            tree[y].push_back(x);
        }
        for(auto i:restricted)mymap[i]=1;
        dfs(0,-1);
        return cnt;
    }
};

6137. 检查数组是否存在有效划分 - 力扣(LeetCode)

问题解析

设置状态转移数组f:f[i]表示为,第前i个位置能否存在至少一个有效划分。初始都设置为false,第0,1位置初始化为true。

状态转移方程为:

  • i>=2时,如果nums[i]==nums[i-1],那么f[i] |= f[i-2];
  • i>=3时,如果nums[i]==nums[i-1]&&nums[i-1]==nums[i-2] 或者nums[i]-nums[i-1]==1&&nums[i-1]-nums[i-2]==1,那么f[i] |= f[i-3]

因为如果前面的两个位置或者1个位置能和当前位置组合后满足条件,那么说明这一段是一个有效划分,此时如果第f[i-2] (f[i-3])位置也是true,说明到当前位置为止的所有点都是可以有至少一个有效划分的。

AC代码

class Solution {
public:
    bool f[100050];
    bool validPartition(vector<int>& nums) {
        int n=nums.size();
        f[0]=true;
        f[1]==true;
        if(nums[0]==nums[1])f[2]=true;
        for(int i=3;i<=n;i++)
        {
            if(nums[i-1]==nums[i-2])f[i]|=f[i-2];
            if(nums[i-2]==nums[i-1]&&nums[i-1]==nums[i-3])f[i]|=f[i-3];
            if(nums[i-1]-nums[i-2]==1&&nums[i-2]-nums[i-3]==1)f[i]|=f[i-3];
        }
        return f[n];
    }
};

6138. 最长理想子序列 - 力扣(LeetCode)

问题解析

设置状态转移数组f,f[i]表示以26字母表中第i个字母结尾的理想子序列长度为f[i]。初始都为0。

当我们遍历 s 中的字母时,只要找到当前字母的前 k 个字母和后 k 个字母的f值,加上1后比较一下当前字母的f值,取两者最大值即可。

最后返回max(f[i])即可。

AC代码

class Solution {
public:
    int f[26];
    int longestIdealString(string s, int k) {
        int n=s.size(),mx=0;
        for(int i=0;i<n;i++)
        {
            int x=s[i]-'a';
            int l=max(0,x-k),r=min(25,x+k),ans=1;
            for(int j=l;j<=r;j++)
            {
                ans=max(ans,f[j]+1);
            }
            f[x]=ans;
            mx=max(mx,f[x]);
        }
        return mx;
    }
};

\