zoukankan      html  css  js  c++  java
  • [Leetcode Weekly Contest]261

    链接:LeetCode

    [Leetcode]2027. 转换字符串的最少操作次数

    给你一个字符串 s ,由 n 个字符组成,每个字符不是 'X' 就是 'O' 。
    一次 操作 定义为从 s 中选出 三个连续字符 并将选中的每个字符都转换为 'O' 。注意,如果字符已经是 'O' ,只需要保持 不变 。
    返回将 s 中所有字符均转换为 'O' 需要执行的 最少 操作次数。

    遍历即可。

    class Solution {
        public int minimumMoves(String s) {
            int i = 0, n = s.length();
            int res = 0;
            while(i<n) {
                if(s.charAt(i) == 'X') {
                    res ++;
                    i += 3;
                }
                else {
                    i ++;
                }
            }
            return res;
        }
    }
    

    [Leetcode]2028. 找出缺失的观测数据

    现有一份 n + m 次投掷单个 六面 骰子的观测数据,骰子的每个面从 1 到 6 编号。观测数据中缺失了 n 份,你手上只拿到剩余 m 次投掷的数据。幸好你有之前计算过的这 n + m 次投掷数据的 平均值 。
    给你一个长度为 m 的整数数组 rolls ,其中 rolls[i] 是第 i 次观测的值。同时给你两个整数 mean 和 n 。
    返回一个长度为 n 的数组,包含所有缺失的观测数据,且满足这 n + m 次投掷的 平均值 是 mean 。如果存在多组符合要求的答案,只需要返回其中任意一组即可。如果不存在答案,返回一个空数组。
    k 个数字的 平均值 为这些数字求和后再除以 k 。
    注意 mean 是一个整数,所以 n + m 次投掷的总和需要被 n + m 整除。

    mean * (m + n) 求总数。
    sum(rolls) 求已经有的数量。
    sum = mean * (m+n) - sum(rolls) 剩下需要补充的平均分配就行。< N * 1 或者 > N * 6 则不可能有合法分配。

    class Solution {
        public int[] missingRolls(int[] rolls, int mean, int n) {
            int m = rolls.length, sum_ = 0;
            for(var roll:rolls) {
                sum_ += roll;
            }
            int rest = (m+n) * mean - sum_;
            if(rest < n || rest > 6 * n) {
                return new int[0];
            }
            int dev = rest / n;
            int restNum = rest % n;
            int[] res = new int[n];
            Arrays.fill(res,dev);
            for(int i=0;i<restNum;++i) {
                res[i] += 1;
            }
            return res;
        }
    }
    

    [Leetcode]2029. 石子游戏 IX

    Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones ,其中 stones[i] 是第 i 个石子的价值。
    Alice 和 Bob 轮流进行自己的回合,Alice 先手。每一回合,玩家需要从 stones 中移除任一石子。
    如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 3 整除,那么该玩家就 输掉游戏 。
    如果不满足上一条,且移除后没有任何剩余的石子,那么 Bob 将会直接获胜(即便是在 Alice 的回合)。
    假设两位玩家均采用 最佳 决策。如果 Alice 获胜,返回 true ;如果 Bob 获胜,返回 false 。
    给你一个字符串 word ,如果 word 可以被放入 board 中,请你返回 true ,否则请返回 false 。

    由于我们只关心总和能否被 33 整除,我们可以将 ( extit{stones}) 按照模 3 的结果分为 3 组,即 0、1 和 2。
    根据题意,第一回合不能移除 0,否则直接输掉游戏,因此第一回合只能移除 1 或者 2。我们可以枚举这两种情况,如果其中一种可以让 Alice 获胜就返回 ( exttt{true}),否则返回 ( exttt{false})
    下面以第一回合移除 1 来说明。在不考虑移除 0 的前提下,后面的移除由于要满足总和不能被 3 整除,因此移除的石子是固定的,整体构成一个 (112121212dots) 循环的序列。
    对于 0,由于移除之后不会改变总和模 33 的结果,因此不会改变后续 11 和 22 的移除顺序,所以我们可以在序列的任意非开头位置插入 0。两人为了不让自己输掉,必然会按照上述序列进行,直到没有石子,或某一方只能移除导致总和被 3 整除的石子时分出胜负。因此我们需要求出让总和不能被 3 整除的最大的回合数,这相当于 (112121212dots) 序列的最长长度,加上 0 的个数。
    若该回合数为奇数,且还有剩余石子,那么下一回合要轮到 Bob 移除石子,且他只能移除一枚让总和被 3 整除的石子,于是 Alice 获胜;否则 Bob 获胜。
    对于第一回合移除 2 的情况,同样会构成一个 (221212121dots) 循环的序列,做法同上。

    class Solution {
        public boolean stoneGameIX(int[] stones) {
            HashMap<Integer,Integer> hm = new HashMap<>();
            for(var stone:stones)
            {
                var key =stone % 3;
                hm.put(key,hm.getOrDefault(key,0)+1);
            }
            hm.put(0,hm.getOrDefault(0,0)%2);
            int n = 0;
            for(var val:hm.values()) n += val;
            boolean res = getRes(n,hm,1) || getRes(n,hm,2);
            return res;
        }
    
        public boolean getRes(int n, HashMap hm, int first) {
            var dic = (HashMap<Integer,Integer>)hm.clone();
            if(dic.getOrDefault(first,0) == 0) {
                return false;
            }
            dic.put(first,dic.get(first)-1);
            var cur = first;
            for(int i=0;i<n-1;++i) {
                int need_to_remove;
                if(dic.getOrDefault(0,0)>0) {
                    need_to_remove = 0;
                }
                else if(dic.getOrDefault(cur,0)>0) {
                    need_to_remove = cur;
                }
                else {
                    return (i & 1) == 0;
                }
                cur  = (cur + need_to_remove) % 3;
                dic.put(need_to_remove,dic.getOrDefault(need_to_remove,0)-1);
            }
            return false;
        }
    }
    

    [Leetcode]2030. 含特定字母的最小子序列

    给你一个字符串 s ,一个整数 k ,一个字母 letter 以及另一个整数 repetition 。
    返回 s 中长度为 k 且 字典序最小 的子序列,该子序列同时应满足字母 letter 出现 至少 repetition 次。生成的测试用例满足 letter 在 s 中出现 至少 repetition 次。
    子序列 是由原字符串删除一些(或不删除)字符且不改变剩余字符顺序得到的剩余字符串。
    字符串 a 字典序比字符串 b 小的定义为:在 a 和 b 出现不同字符的第一个位置上,字符串 a 的字符在字母表中的顺序早于字符串 b 的字符。

    单调栈。首先:这题是要求一个子序列res,以下是这个res需要满足的条件:

    • 从原序列中删去n-k个元素,之后得到res
    • res中有至少repetition 个letter
    • res是满足上面两点要求的集合中字典序最小的。

    如果是只满足1,3就是一个单调栈的基本做法。从前往后扫描(枚举),只要(s[i]<res.back()),且还能删(pop),就继续res.pop_back().
    然后再来看看2怎么满足,我们是从前往后枚举的,因此不能删除到后面letter不够的情况,因此用cnt来维护后面还剩下多少个letter,不够就不能删,这样就会出现我们最后删除的个数< n - k ,但是字典序还是最小的,因此我们可以将最后的res长度删减为k,并补上letter在末尾。

    class Solution {
        public String smallestSubsequence(String s, int k, char letter, int repetition) {
            int n = s.length();
            int[] suffix_cnt = new int[n];
            int acc = 0;
            for(int i=n-1;i>=0;--i) {
                if(s.charAt(i)==letter) acc ++;
                suffix_cnt[i] = acc;
            }
            Deque <Character> stk = new LinkedList<>();
            int x = 0;
            for(int i=0;i<n;++i) {
                int y = x;
                while((stk.size()>0) && (stk.size()+(n-i-1)>=k) && (s.charAt(i) < stk.peek())) {
                    if(stk.peek() == letter) y--;
                    if(y+suffix_cnt[i]<repetition) break;
                    stk.pop();
                    x = y;
                }
                if(stk.size()<k) {
                    if(s.charAt(i) == letter || k - stk.size() > repetition - x) {
                        stk.push(s.charAt(i));
                        if (s.charAt(i) == letter) x++;
                    }
                }
            }
            StringBuilder SB = new StringBuilder();
            while (!stk.isEmpty())
            {
                SB.append(stk.pollLast());
            }
            return SB.toString();
        }
    }
    

    Leetcode

  • 相关阅读:
    简单记事本 V0.5
    一次对webplayer的嗅探
    引用的DLL不能调试的问题
    软件:让人越懒越好
    如何设置mysql远程访问
    ASP.NET基础培训 Cookie的正确利用
    Mysql中新建和调用存储过程
    CentOS下mysql的中文编码问题
    mysmall.ini、mymedium.ini、mylarge.ini、myhuge.ini文件的作用
    创建自定义线程池
  • 原文地址:https://www.cnblogs.com/hellojamest/p/15382964.html
Copyright © 2011-2022 走看看