【钛铂数据专场】力扣第 269 场周赛(2029 / 4292)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【钛铂数据专场】力扣第 269 场周赛(2029 / 4292)

一、5938. 找出数组排序后的目标下标

1、题目简介

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)

b60ff3afe336466daa6bb630459dbaac.png

2、题目解析

  • 签到题,直接排序原数组,遍历一遍等于 target 的即可

3、题目代码

class Solution {
    public List<Integer> targetIndices(int[] nums, int target) {
        List<Integer> list = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == target){
                list.add(i);
            }
        }
        return list;
    }
}

1c329b67c32643ac819298dbfae997b1.png

二、5939. 半径为 k 的子数组平均值

1、题目简介

2、题目解析

  • 给你一个数组,让你求 [i - k, i + k] / (2 * k + 1)
  • 题目有两种做法
  • 第一种是前缀和,我们求出整体的前缀和,通过 arr[i + k] - arr[i - k - 1] / (2 * k + 1) 即可求出所有的 avg
  • 第二种是滑动窗口,当我们窗口在滑动时,我们的 sum = sum + arr[i + k] - arr[i - k - 1] 即可求出所有的 avg题目比较坑的点在于给的取值范围为 10^5 * 10^5 超过了 Int 的范围,需要使用 long 类型来进行接收

3、题目代码

class Solution {
     public int[] getAverages(int[] nums, int k) {
        long sum = 2 * k + 1;
        int n = nums.length;
        long[] arr = new long[n];
        arr[0] = nums[0];
        int[] target = new int[n];
        int num = 0;
        for (int i = 1; i < n; i++) {
            arr[i] = arr[i - 1] + nums[i];
        }
        for (int i = 0; i < n; i++) {
            if (i - k >= 0 && i + k < n) {
                if (i - k == 0) {
                    target[num++] = (int)(arr[i + k] / sum);
                } else {
                    target[num++] = (int) ((arr[i + k] - arr[i - k - 1]) / sum);
                }
            } else {
                target[num++] = -1;
            }
        }
        return target;
    }
}


4d7df2d3ec0d4e1cb99cbf93a15dea2f.png

三、5940. 从数组中移除最大值和最小值

1、题目简介

2、题目解析

  • 这个题目刚上来本来想用暴力递归转动态去做,但后来想了想,好像可以贪心做
  • 我们先进行遍历,求出 最小值最大值 的下标,然后计算其与 0length 的距离,求这四个距离的最小值
  • 去掉距离的最小值后,这个时候我们已经去除了一个元素,然后计算另一个元素和 0length 距离即可

3、题目代码


class Solution {
    public int minimumDeletions(int[] nums) {
        int sum = 0;
        int n = nums.length;
        if(n <= 1){
            return 1;
        }
        int min = nums[0];
        int indexMin = 0;
        int max = nums[0];
        int indexMax = 0;
        for(int i = 1; i < n; i++){
            if(min > nums[i]){
                min = nums[i];
                indexMin = i;
            }
            if(max < nums[i]){
                max = nums[i];
                indexMax = i;
            }
        }
        int num1 = n - 1 - indexMin;
        int num2 = n - 1 - indexMax;
        // 先排除一个最小的
        int numMin = Math.min(Math.min(indexMin, indexMax), Math.min(num1, num2));
        //System.out.println(numMin);
        if(numMin == indexMin){
            sum = sum + indexMin + 1;
            sum = sum + Math.min(num2, indexMax - indexMin - 1) + 1;
        }else if(numMin == indexMax){
            sum = sum + indexMax + 1;
            sum = sum + Math.min(num1, indexMin - indexMax - 1) + 1;
        }else if(numMin == num1){
            sum = sum + num1 + 1;
            sum = sum + Math.min(indexMax, num2 - num1 - 1) + 1;
        }else{
            sum = sum + num2 + 1;
            sum = sum + Math.min(indexMin, num1 - num2 - 1) + 1;
        }
        return sum;
    }
}

1980aa8ae35b47c885ba726033a519e3.png

四、5941. 找出知晓秘密的所有专家

1、题目简介

2、题目解析

  • 看到这种传播性,直接就锁定并查集:三分钟学会并查集
  • 简单来说,我们把相同时间的专家在一起进行处理,将他们进行合并
  • 当我们合并完之后,我们需要判断哪些是没有收到消息的,这里的判断题主一开始想差了,后来想到 并查集中的 isSame 可以判断,我们只需要判断当前的点和 0号专家 在不在一个集合即可,如果不在一个集合,我们需要进行还原处理
  • 还原处理的话,可以直接使用 parent[a] = a;,当然也可以使用初始化并查集(不过,好像会超时)
  • 最后,遍历一下哪些点与 0好专家 在一个集合,输出即可

3、题目代码

class Solution {
    public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {
        Set<Integer> time = new HashSet<>();
        HashMap<Integer, List<int[]>> setHashMap = new HashMap<>();
        for (int i = 0; i < meetings.length; i++) {
            if (setHashMap.containsKey(meetings[i][2])) {
                List<int[]> list = setHashMap.get(meetings[i][2]);
                list.add(meetings[i]);
            } else {
                List<int[]> list = new ArrayList<>();
                list.add(meetings[i]);
                setHashMap.put(meetings[i][2], list);
            }
            time.add(meetings[i][2]);
        }
        // 次数出现最多的输出,大顶堆
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
        for (Integer key : time) {
            priorityQueue.add(key);
        }
        UnionAndFind unionAndFind = new UnionAndFind(n);
        unionAndFind.union(0, firstPerson);
        while (!priorityQueue.isEmpty()) {
            Integer integer = priorityQueue.poll();
            List<int[]> list = setHashMap.get(integer);
            for (int i = 0; i < list.size(); i++) {
                int[] arr = list.get(i);
                unionAndFind.union(arr[0], arr[1]);
            }
            for (int i = 0; i < list.size(); i++) {
                if (!unionAndFind.isSameSet(0, list.get(i)[0])) {
                    unionAndFind.guli(list.get(i)[0]);
                    unionAndFind.guli(list.get(i)[1]);
                }
            }
        }
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            if (unionAndFind.isSameSet(0, i)) {
                list.add(i);
            }
        }
        return list;
    }
}
class UnionAndFind {
    // 当前自己的大哥是谁
    private int[] parent;
    // 当前自己的队伍有多少人(只有大哥有)
    private int[] size;
    // 辅助数组
    private int[] help;
    // 江湖还有几个派系
    int sets;
    // 初始化
    // 每个人的大哥都是自己
    public UnionAndFind(int N) {
        parent = new int[N];
        size = new int[N];
        help = new int[N];
        sets = N;
        for (int i = 0; i < N; i++) {
            parent[i] = i;
            size[i] = 1;
        }
    }
    public int find(int i) {
        int h = 0;
        while (i != parent[i]) {
            help[h++] = i;
            i = parent[i];
        }
        for (h--; h >= 0; h--) {
            parent[help[h]] = i;
        }
        return i;
    }
    public boolean isSameSet(int a, int b) {
        return find(a) == find(b);
    }
    public void union(int a, int b) {
        int A = find(a);
        int B = find(b);
        if (A != B) {
            if (size[A] >= size[B]) {
                size[A] += size[B];
                parent[B] = A;
            } else {
                size[B] += size[A];
                parent[A] = B;
            }
            sets--;
        }
    }
    public void guli(int a) {
        parent[a] = a;
    }
}

3d028635bd894a2ca6180ce975963600.png

五、总结

这次由于题目简单,导致三题已经是吊车尾的水平了

比较可惜的是,并查集前天刚刚复习,没想到还原并查集的操作,错失了人生中的第一次AK

下次加油加油


相关文章
|
7月前
|
Go
golang力扣leetcode 第 291 场周赛
golang力扣leetcode 第 291 场周赛
72 0
|
7月前
|
Go vr&ar
golang力扣leetcode 第 288 场周赛
golang力扣leetcode 第 288 场周赛
56 0
|
7月前
|
Go
golang力扣leetcode 第 286 场周赛
golang力扣leetcode 第 286 场周赛
65 0
|
算法 Android开发
LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
70 1
|
7月前
|
Go
golang力扣leetcode第 294 场周赛
golang力扣leetcode第 294 场周赛
61 0
|
7月前
|
算法 Java Go
golang力扣leetcode 第 293 场周赛
golang力扣leetcode 第 293 场周赛
89 0
|
7月前
|
Go
golang力扣leetcode 第 290 场周赛
golang力扣leetcode 第 290 场周赛
54 0
|
7月前
|
Go C++
golang力扣leetcode 第 284 场周赛
golang力扣leetcode 第 284 场周赛
62 0
|
7月前
|
Go
golang力扣leetcode 第 292 场周赛
golang力扣leetcode 第 292 场周赛
73 0
|
7月前
|
存储
Leetcode第383场周赛
在LeetCode第383场周赛中,选手完成了3道题目。第一题是关于边界上的蚂蚁,蚂蚁根据非零整数数组nums的值移动,返回蚂蚁返回边界上的次数。解题方法是计算数组累加和为0的次数。第二题涉及计算网格的区域平均强度,给定一个灰度图像和阈值,返回每个像素所属区域的平均强度。解题关键在于理解相邻像素和区域定义,并计算平均强度。第三题是恢复单词初始状态的最短时间问题,通过移除前k个字符并添加k个字符,求恢复原词所需的最短时间。解题策略是检查去除前k个字符后的子串是否能作为原词的前缀。
38 1
Leetcode第383场周赛