LeetCode第240场周赛记录

在这里插入图片描述

1 5750. 人口最多的年份

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

class Solution {
public:
    int maximumPopulation(vector<vector<int>>& logs) {
        int n = logs.size();
        int res = 1950, tmax = 0;
        for(int i = 1950; i <= 2050; i++)
        {
            int sum = 0;
            for(int j = 0; j < n; j++)
            {
                int l = logs[j][0], r = logs[j][1];
                if(i >= l && i < r)
                    sum ++;
            }
            if(sum > tmax)
            {
                tmax = sum;
                res = i;
            }
        }
        return res;
    }
};



2 5751. 下标对中的最大距离

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

思路:双指针:两个指针i,j分别指向nums1和nums2的末尾,当i指针向左移动时j不动或向左移动。

class Solution {
public:
    int maxDistance(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size(), m = nums2.size();
        int res = 0;
        for(int i = n - 1, j = m - 1; i >= 0 && j >= 0; i--)
        {
            while(j >= i && nums2[j] < nums1[i])j--;
            if(j >= i)res = max(res, j - i);
        }
        return res;
    }
};



3 5752. 子数组最小乘积的最大值

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

类似于求最大子矩阵那道题
思路:

  1. 可以把它看做是求子矩阵面积,高为最小值,宽为数组元素之和。
  2. 遍历所有元素,若当前元素为矩阵的高,则其宽度为左边第1个小于它的元素到右边第1个大于它的元素构成的区间(开区间)内所有元素之和。(边界值特殊处理)
  3. 预处理出前缀和数组,利用单调递增栈,当即将入栈的元素大于栈顶,此时将栈顶作为高。用其构成的矩阵来更新答案。具体细节看代码
typedef unsigned long long ULL;
class Solution {
public:
    int maxSumMinProduct(vector<int>& nums) {
        int n = nums.size();
        stack<int>stk;
        vector<ULL>s(n + 1, 0);
        const int mod = 1e9 + 7;
        for(int i = 0; i < n; i++)s[i + 1] = s[i] + nums[i];
        nums.push_back(-1);
        ULL res = 0;
        for(int i = 0; i <= n; i++)
        {
            while(!stk.empty() && nums[i] < nums[stk.top()])
            {
                ULL h = nums[stk.top()];
                stk.pop();
                if(stk.empty())res = max(res, h * s[i - 1 + 1]);
                else res = max(res, h * (s[i - 1 + 1] - s[stk.top() + 1 + 1 - 1]));
            }
            stk.push(i);
        }
        return res % mod;
    }
};



4 5753. 有向图中最大颜色值

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

PS:之前想到往树形DP的方向做,不过没有时间了~
思路:

  1. 若拓扑排序后节点个数小于n,则有环(环中所有节点无法将入度减为0)
  2. 对于任意一条路径,在拓扑排序后前驱节点一定排在后继节点前面。
  3. DP:设f[u,c]为终点为u,颜色c的节点数量最多的路径,属性值为节点c的数量,有f[u,c] = max(f[pre1][c],f[pre2][c],…f[prek][c]) + (colors[u]==c)。即选取所有前驱节点中颜色c节点最多的路径来更新当前节点的值。
  4. 可以在拓扑排序的过程中用前驱节点更新其所有后继节点(当轮到该后继节点时,它已经被自己的所有前驱节点更新过了)。
class Solution {
public:
    int largestPathValue(string colors, vector<vector<int>>& edges) {
        int n = colors.size();
        int m = edges.size();
        vector<vector<int>>g(n);
        vector<int>ru(n, 0);//入度
        for(int i = 0; i < m; i++)//建立邻接表
        {
            int a = edges[i][0], b = edges[i][1];
            g[a].push_back(b);
            ru[b]++;
        }
        queue<int>q;
        int cnt = 0;//已排序节点
        for(int i = 0; i < n; i++)//入度为0进队列
            if(ru[i] == 0)
                q.push(i);
        vector<vector<int> >f(n, vector<int>(26, 0));
        while(q.size())//拓扑排序
        {
            int t = q.front();
            q.pop();
            cnt++;
            f[t][colors[t] - 'a']++;
            for(int i = 0; i < g[t].size(); i++)//更新所有后继节点f[][]和入度
            {
                int j = g[t][i];
                for(int k = 0; k < 26; k++)
                    f[j][k] = max(f[j][k], f[t][k]);
                if(--ru[j] == 0)//入度为0进队列
                    q.push(j);
            }
        }
        if(cnt < n)return -1;//有环
        int res = 0;//选出最大
        for(int i = 0; i < n; i++)
            for(int j = 0; j < 26; j++)
                res = max(res, f[i][j]);
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值