力扣周赛314 笔记

力扣周赛314 笔记

第一题

题目
6200

解法:说实话这道题建议出题人看看自己在说什么,首先n这个数据毫无意义,说白了就是通过两两时间相减找到耗时最大任务并且返回对应员工,对于时间一样都是最大的员工取id最小。

第二题

题目:
6201

解法:这道题其实自己在纸上写一写也能找到规律,从灵神那里得到了一种规律,即关于差分数组和前缀和数组之间与初始数组之间的转化:
数组转化
这里的差分指的是一种概念,即对于两两相邻的数进行某一种运算或规律,而前缀和运算则是对i之前的数组中的所有数进行某种运算或规律的重复执行,这里pref数组是一个前缀和数组(对到i的数进行异或),所以我们想要得到原数组只要对pref数组数组进行差分操作,即两两相邻异或即可。

第三题

题目
6202

解法:这道题主要是考察栈的思维,然后还加入了一个栈顶元素和后面最小元素的比较问题,我因为没想到怎么快速找到后面数据的最小字符超时了,运用灵神的思路时间复杂度可以降到O(n)

class Solution {
public:
    string robotWithString(string s) {
        string ans;
        int cnt[26]{}, min = 0; // min 表示剩余最小字母,min=0代表剩余最小的是a
        for (char c : s) ++cnt[c - 'a'];//用一个计数的数组来获取剩下字符串的最小值
        stack<char> st;
        for (char c : s) {
            --cnt[c - 'a'];//遍历到的时候count--
            while (min < 25 && cnt[min] == 0) ++min;//count数等于0说明在后面的字符中已经没有该字母了,剩下的是更大的,min++
            st.push(c);
            while (!st.empty() && st.top() - 'a' <= min) {
                ans += st.top();
                st.pop();
            }
        }
        return ans;
    }
};


第四题

题目
2435

解法:我自己第一时间直接无脑dfs了,结果不出所料超出时间限制捏

class Solution {
public:
    int numberOfPaths(vector<vector<int>>& grid, int k) {
        int ans=0;
        int n=grid.size();
        int m=grid[0].size();
        function <void(int,int,int)> dfs = [&](int sum,int x,int y){
            if(x==m-1 && y==n-1){
                sum+=grid[y][x];
                if(sum%k==0){
                    ans++;
                    return ;
                }
            }
            else if(x>=m || y>=n){
                return ;
            }
            else{
                sum+=grid[y][x];
                dfs(sum,x+1,y);
                dfs(sum,x,y+1);
            }
        };
        dfs(0,0,0);
        return ans;
    }
};

来看看正确的方法:
想要降低运算时间还是得用动态规划存储子问题答案,我的方法之所以超时是因为我保存的记忆化搜索是sum,这个值说白了每一条路都不一样,没有记录的意义。不妨设f[i][j][v]为从(0,0)出发到(i,j)路径和模k得v的路径数总和,这样可以得到答案为f[m][n][0],对于一个点位(i,j),到这个位置时其路径和对于k的模是有意义的,首先这个变量和答案挂钩,其次因为是模,所以情况也就只有k种,记录到数组中可以被当做子问题来使用:

class Solution {
public:
    int numberOfPaths(vector<vector<int>> &grid, int k) {
        const int mod = 1e9 + 7;
        int m = grid.size(), n = grid[0].size(), f[m + 1][n + 1][k];
        memset(f, 0, sizeof(f));
        f[0][1][0] = 1;
        for (int i = 0; i < m; ++i)
            for (int j = 0; j < n; ++j)
                for (int v = 0; v < k; ++v)
                    f[i + 1][j + 1][(v + grid[i][j]) % k] = (f[i + 1][j][v] + f[i][j + 1][v]) % mod;
        return f[m][n][0];
    }
};

以上题解只是对灵神题解的总结,非原创捏1


  1. 灵神b站题解 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值