力扣周赛245期

178 阅读2分钟

这是我参与更文挑战的第20天,活动详情查看:更文挑战

1898. 可移除字符的最大数目

其实最后还是没找出错误,希望万能的掘友帮我看下

问题地址

代码如下(我觉得问题大概率是check函数)

class Solution {
public:
    bool arr[100007] = {false};
    
    int maximumRemovals(string s, string p, vector<int>& removable) {
        int left = 0, right = removable.size() - 1;
        int mid = 0;
        while(left < right){
            mid = (left + right)/2 + 1;
            if(check(s, p, mid, removable)){
                left = mid;
            }else{
                right = mid - 1;
            }
        }
        // cout << removable.size() << endl;
        // printf("left:%d , right: %d, mid: %d \n",left,right,mid);
        if(left == right && left == 0){
            return check(s, p, 0, removable) ?  1 : 0;
        }
        if(left == right && right == removable.size() - 1){
            
            return check(s, p, right, removable) ? right + 1 :right;
        } 
        return left + 1;
    }
    bool check(string s, string p, int k, vector<int>& removable){
         for(int i = 0; i <= k; i++){
                arr[removable[i]] = true;
            }
        for(int i = k + 1; i < removable.size(); i ++){
            arr[removable[i]] = false;
        }
        int j = 0;
        for(int i = 0; i < p.size(); i ++){
            while(j < s.size() && (s[j] != p[i] || arr[j] == true)) j++;
            if(j == s.size()){
                return false;
            }
        }
        return true;
    }
};

1900. 最佳运动员的比拼回合

截屏2021-06-21 下午10.20.43.png

截屏2021-06-21 下午10.20.57.png

这道题说实话很难想到是动态规划,因为大量的条件(过深的维度)让人很难发现这是一道动态规划题, 这道题就是通过每次比赛来减少参赛人数,算出最强两者相遇的回合数。

由于除最强两者以外,不同的比赛胜负结果会产生不同的回合数,因此,为了计算出最少回合数和最多回合数,我们必须分类讨论

而这,就是动态规划的状态转移方程所要操作的地方。

  • 首先,我们知道互换最强两者的位置并不会得到不同的结果,
  • 其次,我们知道逆序该队列也不会影响最后的结果。

因此我们可以假定,两个最强者f和s,f在队列的左侧,s在f的后面(无论fs如何分布,都可以通过逆序与互换操作得到该结果)

那么分类讨论的条件就变为了s到底是在左侧,还是在中间还是在右侧。

假定f前面减少了i个元素,n个元素最少回合数:dp1[n,f,s],n个元素最多回合数,dp2[n,f,s]

  • s如果在左侧,那么f与s之间可能少了j个元素,则dp1[n,f,s]= dp1[n1,f - i, s - i - j] + 1 ; dp2[n,f,s] = dp2[n1,f - i, s - i - j] + 1
  • s如果在中间,那其实和在左侧是没有区别的。
  • s如果在右边,
    • s和f如果是恰好相对,则dp1[n,f,s] = 1
    • 如果s对应的s'在f左边,那么可以使用逆序,再重新计算
    • 如果s对应的s'在f右边,那么可以设置j的范围为[s-n/2-i,n-s-f]之间,计算最小/最大值。