[Leetcode Weekly Contest]259

链接:LeetCode

[Leetcode]2011. 执行操作后的变量值

存在一种仅支持 4 种操作和 1 个变量 X 的编程语言:

++X 和 X++ 使变量 X 的值 加 1
--X 和 X-- 使变量 X 的值 减 1
最初,X 的值是 0

给你一个字符串数组 operations ,这是由操作组成的一个列表,返回执行所有操作后, X 的 最终值 。

遍历即可。

class Solution {
    public int finalValueAfterOperations(String[] operations) {
        int res = 0;
        for(var operation:operations) {
            if(operation.contains("--")){
                res --;
            }
            else {
                res ++;
            }
        }
        return res;
    }
}

[Leetcode]2012. 数组美丽值求和

给你一个下标从 0 开始的整数数组 nums 。对于每个下标 i(1 <= i <= nums.length - 2),nums[i] 的 美丽值 等于:

  • 2,对于所有 0 <= j < i 且 i < k <= nums.length - 1 ,满足 nums[j] < nums[i] < nums[k]
  • 1,如果满足 nums[i - 1] < nums[i] < nums[i + 1] ,且不满足前面的条件
  • 0,如果上述条件全部不满足
    返回符合 1 <= i <= nums.length - 2 的所有 nums[i] 的 美丽值的总和 。

根据题意,依次判断条件即可。难点在于判断美丽值是否为2的条件,即需要判断中间的数满足大于左边所有数,并且小于右边所有数。也就是,中间的数需要大于左边最大的数,小于右边最小的数。我们可以先遍历两遍数值,得出每个索引位置左边最大数和右边最小数,最后判断即可。

class Solution {
    public int sumOfBeauties(int[] nums) {
        int n = nums.length;
        int[] leftMax = new int[n];
        int [] rightMin = new int[n];
        leftMax[0] = -1;
        rightMin[n-1] = Integer.MAX_VALUE;
        for(int i=1;i<n;++i){
            leftMax[i] = Math.max(leftMax[i-1],nums[i-1]);
        }
        for(int i=n-2;i>=0;--i) {
            rightMin[i] = Math.min(rightMin[i+1],nums[i+1]);
        }
        int res = 0;
        for(int i=1;i<n-1;++i) {
            if(nums[i] > leftMax[i] && nums[i] < rightMin[i]) {
                res += 2;
            }
            else if(nums[i] > nums[i-1] && nums[i] < nums[i+1]) {
                res += 1;
            }
        }
        return res;
    }
}

[Leetcode]2013. 检测正方形

给你一个在 X-Y 平面上的点构成的数据流。设计一个满足下述要求的算法:

添加 一个在数据流中的新点到某个数据结构中。可以添加 重复 的点,并会视作不同的点进行处理。
给你一个查询点,请你从数据结构中选出三个点,使这三个点和查询点一同构成一个 面积为正 的 轴对齐正方形 ,统计 满足该要求的方案数目。
轴对齐正方形 是一个正方形,除四条边长度相同外,还满足每条边都与 x-轴 或 y-轴 平行或垂直。

实现 DetectSquares 类:

DetectSquares() 使用空数据结构初始化对象
void add(int[] point) 向数据结构添加一个新的点 point = [x, y]
int count(int[] point) 统计按上述方式与点 point = [x, y] 共同构造 轴对齐正方形 的方案数。

枚举所有对角线的点判断是否构成正方形即可。

class DetectSquares {
        Map<String, Integer> map;

        public DetectSquares() {
            map = new HashMap<>();
        }

        public void add(int[] point) {
            String key = point[0] + "," + point[1];
            map.put(key, map.getOrDefault(key, 0) + 1);
        }

        public int count(int[] point) {
            int res = 0;
            int x = point[0];
            int y = point[1];
            for (String key : map.keySet()) {
                int delX = Integer.parseInt(key.split(",")[0]);
                int delY = Integer.parseInt(key.split(",")[1]);
                int delCnt = map.get(key);
                if (delX != x && delY != y && Math.abs(delX - x) == Math.abs(delY - y) && delCnt > 0) {
                    int xParCnt = map.getOrDefault(delX + "," + y, 0);
                    int yParCnt = map.getOrDefault(x + "," + delY, 0);
                    res += delCnt * xParCnt * yParCnt;
                }
            }
            return res;
        }
    }

[Leetcode]2014. 重复 K 次的最长子序列

给你一个长度为 n 的字符串 s ,和一个整数 k 。请你找出字符串 s 中 重复 k 次的 最长子序列 。

子序列 是由其他字符串删除某些(或不删除)字符派生而来的一个字符串。

如果 seq * k 是 s 的一个子序列,其中 seq * k 表示一个由 seq 串联 k 次构造的字符串,那么就称 seq 是字符串 s 中一个 重复 k 次 的子序列。

举个例子,"bba" 是字符串 "bababcba" 中的一个重复 2 次的子序列,因为字符串 "bbabba" 是由 "bba" 串联 2 次构造的,而 "bbabba" 是字符串 "bababcba" 的一个子序列。
返回字符串 s 中 重复 k 次的最长子序列 。如果存在多个满足的子序列,则返回 字典序最大 的那个。如果不存在这样的子序列,返回一个 空 字符串。

BFS。由于一共就26个字母,遍历字母组合即可。

class Solution {
    public String longestSubsequenceRepeatedK(String s, int k) {
        String res = "";
        // q保存只放可行子串
        Queue<String> q = new LinkedList<>();
        q.add("");
        while (!q.isEmpty()) {
            int size = q.size();
            // 按层BFS,同层长度相同
            while (size-- > 0) {
                String cur = q.poll();
                for (int i = 0; i < 26; i++) {
                    String next = cur + (char) ('a' + i);
                    if (isSub(s, next, k)) {
                        // 找最大的,所以要更新
                        res = next;
                        q.add(next);
                    }
                }
            }
        }
        return res;
    }

    //   sub * k 是否 s的子串.
    private boolean isSub(String s, String sub, int k) {
        int j = 0;
        int repeat = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == sub.charAt(j)) {
                j++;
                if (j == sub.length()) {
                    repeat++;
                    if (repeat == k) {
                        return true;
                    }
                    j = 0;
                }
            }
        }
        return false;
    }
}

Leetcode

posted @ 2021-09-22 23:10  Jamest  阅读(23)  评论(0编辑  收藏  举报