LeetCode 2047. 句子中的有效单词数 / 1996. 游戏中弱角色的数量 / 1765. 地图中的最高点

158 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

2047. 句子中的有效单词数

2022.1.27 每日一题

题目描述

句子仅由小写字母('a' 到 'z')、数字('0' 到 '9')、连字符('-')、标点符号('!'、'.' 和 ',')以及空格(' ')组成。每个句子可以根据空格分解成 一个或者多个 token ,这些 token 之间由一个或者多个空格 ' ' 分隔。

如果一个 token 同时满足下述条件,则认为这个 token 是一个有效单词:

仅由小写字母、连字符和/或标点(不含数字)。 至多一个 连字符 '-' 。如果存在,连字符两侧应当都存在小写字母("a-b" 是一个有效单词,但 "-ab" 和 "ab-" 不是有效单词)。 至多一个 标点符号。如果存在,标点符号应当位于 token 的 末尾 。

这里给出几个有效单词的例子:"a-b."、"afad"、"ba-c"、"a!" 和 "!" 。

给你一个字符串 sentence ,请你找出并返回 sentence 中 有效单词的数目 。

示例 1:

输入:sentence = "cat and dog" 输出:3 解释:句子中的有效单词是 "cat"、"and" 和 "dog"

示例 2:

输入:sentence = "!this 1-s b8d!" 输出:0 解释:句子中没有有效单词 "!this" 不是有效单词,因为它以一个标点开头 "1-s" 和 "b8d" 也不是有效单词,因为它们都包含数字

示例 3:

输入:sentence = "alice and bob are playing stone-game10" 输出:5 解释:句子中的有效单词是 "alice"、"and"、"bob"、"are" 和 "playing" "stone-game10" 不是有效单词,因为它含有数字

示例 4:

输入:sentence = "he bought 2 pencils, 3 erasers, and 1 pencil-sharpener." 输出:6 解释:句子中的有效单词是 "he"、"bought"、"pencils,"、"erasers,"、"and" 和 "pencil-sharpener."

提示:

1 <= sentence.length <= 1000 sentence 由小写英文字母、数字(0-9)、以及字符(' '、'-'、'!'、'.' 和 ',')组成 句子中至少有 1 个 token

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/nu… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

模拟

class Solution {
    public int countValidWords(String sentence) {
        //以一个或多个空格分割
        String[] token = sentence.split(" +");
        //System.out.println(token[3]);

        int res = 0;
        for(String s : token){
            int l = s.length();
            int count = 0;
            for(int i = 0; i < l; i++){
                char c = s.charAt(i);
                if(Character.isDigit(c))
                    break;
                if((c == '!' | c == '.' || c == ',') && i != l - 1)
                    break;
                if(c == '-'){
                    if(i == 0 || i == l - 1)
                        break;
                    if(!Character.isLetter(s.charAt(i - 1)) || !Character.isLetter(s.charAt(i + 1)))
                        break;
                    count++;
                    if(count > 1)
                        break;
                }
                if(i == l - 1)
                    res++;
            }
        }
        return res;
    }
}

1996. 游戏中弱角色的数量

2022.1.28 每日一题

题目描述

你正在参加一个多角色游戏,每个角色都有两个主要属性:攻击 和 防御 。给你一个二维整数数组 properties ,其中 properties[i] = [attacki, defensei] 表示游戏中第 i 个角色的属性。

如果存在一个其他角色的攻击和防御等级 都严格高于 该角色的攻击和防御等级,则认为该角色为 弱角色 。更正式地,如果认为角色 i 弱于 存在的另一个角色 j ,那么 attackj > attacki 且 defensej > defensei 。

返回 弱角色 的数量。

示例 1:

输入:properties = [[5,5],[6,3],[3,6]] 输出:0 解释:不存在攻击和防御都严格高于其他角色的角色。

示例 2:

输入:properties = [[2,2],[3,3]] 输出:1 解释:第一个角色是弱角色,因为第二个角色的攻击和防御严格大于该角色。

示例 3:

输入:properties = [[1,5],[10,4],[4,3]] 输出:1 解释:第三个角色是弱角色,因为第二个角色的攻击和防御严格大于该角色。

提示:

2 <= properties.length <= 10^5 properties[i].length == 2 1 <= attacki, defensei <= 10^5

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/th… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

按照攻击力升序,防御力降序排序,这样保证攻击力相同的,防御力最高的最先遍历到 然后单调栈处理 提交了发现太慢了,主要消耗时间的就是排序,想了一下去掉排序好像不行 然后看了题解,发现思路还是这个思路

class Solution {
    public int numberOfWeakCharacters(int[][] properties) {
        //有一次周赛的题,最后才做出来,印象深刻
        //按照攻击力升序,防御降序排序
        //那么后面的角色攻击力肯定是严格大于前面角色的攻击
        //但是防御力怎么严格判定呢
        //我之前是陷入了一个怪圈,我总要统计几个人比当前人都强
        //而题目要求是有一个强就是弱角色了,所以不用管其他人强不强

        int l = properties.length;
        Arrays.sort(properties, (a, b) -> {
            if(a[0] != b[0]){
                return a[0] - b[0];
            }else{
                return b[1] - a[1];
            }
        });

        int res = 0;
        Stack<Integer> stack = new Stack<>();
        for(int[] p : properties){
            while(!stack.isEmpty() && stack.peek() < p[1]){
                stack.pop();
                res++;
            }
            stack.push(p[1]);
        }
        return res;

    }
}

1765. 地图中的最高点

2022.1.29 每日一题

题目描述

给你一个大小为 m x n 的整数矩阵 isWater ,它代表了一个由 陆地 和 水域 单元格组成的地图。

如果 isWater[i][j] == 0 ,格子 (i, j) 是一个 陆地 格子。 如果 isWater[i][j] == 1 ,格子 (i, j) 是一个 水域 格子。

你需要按照如下规则给每个单元格安排高度:

每个格子的高度都必须是非负的。 如果一个格子是是 水域 ,那么它的高度必须为 0 。 任意相邻的格子高度差 至多 为 1 。当两个格子在正东、南、西、北方向上相互紧挨着,就称它们为相邻的格子。(也就是说它们有一条公共边)

找到一种安排高度的方案,使得矩阵中的最高高度值 最大 。

请你返回一个大小为 m x n 的整数矩阵 height ,其中 height[i][j] 是格子 (i, j) 的高度。如果有多种解法,请返回 任意一个 。

示例 1:

输入:isWater = [[0,1],[0,0]] 输出:[[1,0],[2,1]] 解释:上图展示了给各个格子安排的高度。 蓝色格子是水域格,绿色格子是陆地格。

示例 2:

输入:isWater = [[0,0,1],[1,0,0],[0,0,0]] 输出:[[1,1,0],[0,1,1],[1,2,2]] 解释:所有安排方案中,最高可行高度为 2 。 任意安排方案中,只要最高高度为 2 且符合上述规则的,都为可行方案。

提示:

m == isWater.length n == isWater[i].length 1 <= m, n <= 1000 isWater[i][j] 要么是 0 ,要么是 1 。 至少有 1 个水域格子。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ma… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

看到题,第一反应就是多源bfs,从水域开始扩散,扩散到的位置高度加1 但是不确定最后的结果对不对;想举一个反例,但是想不出来,感觉应该没问题,就提交了,过了 看了下官方的解释:如果扩散到的位置高度小于等于当前高度,那么在之前的轮次,肯定已经被扩散到了,因为每次扩展都是从相同的高度开始出发

class Solution {
    int[][] dir = {{0,1}, {0,-1}, {1,0}, {-1,0}};
    public int[][] highestPeak(int[][] isWater) {
        //有那种多源bfs的感觉
        //从0开始扩散
        int m = isWater.length;
        int n = isWater[0].length;

        boolean[][] isVisited = new boolean[m][n];
        Queue<int[]> queue = new LinkedList<>();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(isWater[i][j] == 1){
                    queue.offer(new int[]{i, j});
                    isWater[i][j] = 0;
                    isVisited[i][j] = true;
                }
            }
        }

        int max = 0;
        while(!queue.isEmpty()){
            int size = queue.size();
            while(size-- > 0){
                int[] point = queue.poll();
                int height = isWater[point[0]][point[1]];
                for(int[] d : dir){
                    int x = point[0] + d[0];
                    int y = point[1] + d[1];
                    if(x < 0 || x >= m || y < 0 || y >= n || isVisited[x][y])
                        continue;
                    isWater[x][y] = height + 1;
                    isVisited[x][y] = true;
                    queue.offer(new int[]{x, y});
                }
            }
        }
        return isWater;

    }
}