LeetCode周赛158

今天周赛就是暴力出奇迹。。。

1221. Split a String in Balanced Strings

类似于括号匹配,不用括号匹配做也行,用sum统计遇到L,++,else --,sum == 0就为一个子串。

class Solution {
public:
    int balancedStringSplit(string s) {
        stack<char> st;
        st.push(s[0]);
        int re = 0;
        for (int i = 1; i < s.size(); i++) {
            if (!st.empty() && s[i] != st.top())
                st.pop();
            else
                st.push(s[i]);
            if (st.empty())
                re++;
        }
        return re;
    }
};

1222. Queens That Can Attack the King

其实就是搜索king的八个方向是否有queen有且是第一次出现即合法

class Solution {
    bool marked[8][8] = {false};
public:
    vector<vector<int>> queensAttacktheKing(vector<vector<int>>& queens, vector<int>& king) {
        vector<vector<int>> re;
        for (auto queen : queens) 
            marked[queen[0]][queen[1]] = true;
        
        for (int dx = -1; dx <= 1; dx++) {
            for (int dy = -1; dy <= 1; dy++) {
                if (dx == 0 && dy == 0)
                    continue;
                int x = king[0] + dx;
                int y = king[1] + dy;
                while (x >= 0 && x < 8 && y >= 0 && y < 8) {
                    if (marked[x][y]) {
                        re.push_back({x,y});
                        break;
                    }
                    x += dx;
                    y += dy;
                }
            }
        }
        return re;
    }
};

1223. Dice Roll Simulation

掷骰子,有个rollMax数组限制了每个点数连续出现次数。就是递推结果。
d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k] 为第i次,投出j,并且j已经连续出现k次了。
这样的关系式可以分为两种情况讨论。

  1. k = 1,即第一次连续出现,那这个状态可以这样写: d p [ i ] [ j ] [ 1 ] = c n t − d p [ i − 1 ] [ j ] [ k ] ( k ∈ 2... r o l l M a x [ j ] ) dp[i][j][1] = cnt - dp[i - 1][j][k] (k \in 2 .. .rollMax[j]) dp[i][j][1]=cntdp[i1][j][k](k2...rollMax[j])
    其中cnt是上一个所有状态总计。排除他不能转移的状态即可
  2. k > 1 ,只有一种可能 d p [ i ] [ j ] [ k ] = d p [ i − 1 ] [ j ] [ k − 1 ] dp[i][j][k] = dp[i - 1][j][k - 1] dp[i][j][k]=dp[i1][j][k1]
int dp[5010][6][16];
int MOD = 1e9 + 7;
class Solution {
public:
    int dieSimulator(int n, vector<int>& rollMax) {
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < 6; i++)
            dp[1][i][1] = 1;
        for (int i = 2; i <= n; i++) {
            int cnt = 0;
            for (int j = 0; j < 6; j++) {
                for (int k = 1; k <= rollMax[j]; k++) {
                    cnt = (cnt + dp[i - 1][j][k]) % MOD;
                }
            }
            for (int j = 0; j < 6; j++) {
                dp[i][j][1] += cnt;
                for (int k = 1; k <= rollMax[j]; k++) {
                    dp[i][j][1] = (dp[i][j][1] - dp[i - 1][j][k] + MOD) % MOD;  //负值处理
                }
                for (int k = 2; k <= rollMax[j]; k++) {
                    dp[i][j][k] = dp[i - 1][j][k - 1];
                }
            }
        }
        int re = 0;
        for (int i = 0; i < 6; i++) {
            for (int j = 1; j <= rollMax[i]; j++) {
                re = (re + dp[n][i][j]) % MOD;
            }
        }
        return re;
    }
};

注意 d p [ i ] [ j ] [ 1 ] = ( d p [ i ] [ j ] [ 1 ] − d p [ i − 1 ] [ j ] [ k ] + M O D ) dp[i][j][1] = (dp[i][j][1] - dp[i - 1][j][k] + MOD) % MOD dp[i][j][1]=(dp[i][j][1]dp[i1][j][k]+MOD),因为之前相加的时候模掉了大于MOD的数,也就是减的时候可能为负,需要处理一下。

1224. Maximum Equal Frequency

判断前缀是否合法,要求是删去一个数,剩下的前缀数出现频率相同。也是分情况。需要两个map记录信息,mp记录出现某个频率的次数,mpp记录哪个数出现的次数。

class Solution {
public:
    int maxEqualFreq(vector<int>& nums) {
        unordered_map<int, int> mp;
        unordered_map<int, int> mpp;
        int re = 0;
        for (int i = 0; i < nums.size(); i++) {
            int temp = nums[i];
            if (mpp.count(temp)) {
                int f = mpp[temp];
                mp[f]--;
                if (mp[f] == 0)
                    mp.erase(f);
                mp[f + 1]++;
                mpp[temp]++;
            } else {
                mpp[temp]++;
                mp[1]++;
            }

            if (mp.size() == 1 && i < nums.size() - 1) {
                re = max(re, i + 2);
            }
            if (mp.size() == 2) {
                auto a = mp.begin();
                auto b = ++mp.begin();
                if (a->first == 1 && a->second == 1) 
                    re = max(re, i + 1);
                if (b->first == 1 && b->second == 1)
                    re = max(re, i + 1);
                if (a->first == 1 + b->first && a->second == 1)
                    re = max(re, i + 1);
                if (b->first == 1 + a->first && b->second == 1)
                    re = max(re, i + 1);
            }
        }
        return re;
    }
};

当出现频率种类为1,即可直接判断有效。
当出现频率种类为2,有如下情况:

  • 出现了一个频率为1,且频率为1次数也为1,删去则合法
  • 出现两个频率之间差值为,并且较大的频率次数为1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值