【day04】力扣(LeetCode)每日一刷[1306. 跳跃游戏 III ][703. 数据流中的第 K 大元素 ][1337. 矩阵中战斗力最弱的 K 行]

简介: 了解学习 跳跃游戏 III , 数据流中的第 K 大元素 , 矩阵中战斗力最弱的 K 行。

刷题打卡第四天


一、(中等题)1306. 跳跃游戏 III

二、(简单题)703. 数据流中的第 K 大元素

三、(简单题)1337. 矩阵中战斗力最弱的 K 行


一、(中等题)1306. 跳跃游戏 III


原题链接:1306. 跳跃游戏 III


题目描述:


这里有一个非负整数数组 arr,你最开始位于该数组的起始下标 start 处。当你位于下标 i 处时,你可以跳到 i + arr[i] 或者 i - arr[i]。


请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。


注意,不管是什么情况下,你都无法跳到数组之外。

微信图片_20221029134551.png

这道题可以用递归来解决,具体做法可以看注释:

class Solution {
    public boolean canReach(int[] arr,int start){
        boolean[] check = new boolean[arr.length];
        //判断是否找到元素值为0的下标的递归函数
        return zero(check,arr,start);
    }
    public boolean zero(boolean[] check,int[] arr,int start){
        //如果下标超出数组范围,然会假
        if(start < 0 || start >= arr.length) return false;
        //找到元素值为0的对应下标,返回真
        if(arr[start] == 0) return true;
        //如果当前下标被遍历过,说明重复遍历了,返回假
        if(check[start]){
            return false;
        }else{//如果是第一次遍历,给记录下来,方便下次比对
            check[start] = true;
        }
        //递归地重复上述遍历操作
        return zero(check,arr,start+arr[start]) || zero(check,arr,start-arr[start]);
    }
}

提交结果:

微信图片_20221029134604.png


二、(简单题)703. 数据流中的第 K 大元素


原题链接:703. 数据流中的第 K 大元素


题目描述:


设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。

微信图片_20221029134615.png微信图片_20221029134623.png

解题思路:

题目要求数据流数组中的第k大元素,只需要将元素都放到最小堆中,堆节点数大于k就删除堆顶节点来调整,让堆节点数保持在k个,这么一来堆顶元素就是我们要求的第k大元素。


解题代码:

class KthLargest {
    //设置全局变量,分别是k以及优先队列;
    int k;
    PriorityQueue<Integer> que;
    public KthLargest(int k, int[] nums) {
         que = new PriorityQueue<Integer>();//设置为最小堆
         this.k = k;                        //传递进来的整数赋值给k                        
         for(int num : nums)                //增强for循环遍历数据流
         add(num);                          
    }
    public int add(int val) {
        que.offer(val);       //将数据放入最小堆
        while(que.size() > k){//如果堆节点数大于k
            que.poll();       //删除堆顶的最小值
        }
        return que.peek();    //返回当前堆顶元素便是第k大元素
    }
}
/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest obj = new KthLargest(k, nums);
 * int param_1 = obj.add(val);
 */

提交结果:

微信图片_20221029134659.png

三、(简单题)1337. 矩阵中战斗力最弱的 K 行


原题链接:矩阵中战斗力最弱的 K 行


题目描述:


给你一个大小为 m * n 的矩阵 mat,矩阵由若干军人和平民组成,分别用 1 和 0 表示。


请你返回矩阵中战斗力最弱的 k 行的索引,按从最弱到最强排序。


如果第 i 行的军人数量少于第 j 行,或者两行军人数量相同但 i 小于 j,那么我们认为第 i 行的战斗力比第 j 行弱。


军人 总是 排在一行中的靠前位置,也就是说 1 总是出现在 0 之前。


/

示例 1:


输入:mat =


[[1,1,0,0,0],


[1,1,1,1,0],


[1,0,0,0,0],


[1,1,0,0,0],


[1,1,1,1,1]],


k = 3


输出:[2,0,3]


解释:


每行中的军人数目:


行 0 -> 2


行 1 -> 4


行 2 -> 1


行 3 -> 2


行 4 -> 5


从最弱到最强对这些行排序后得到 [2,0,3,1,4]

/

示例 2:


输入:mat =


[[1,0,0,0],


[1,1,1,1],


[1,0,0,0],


[1,0,0,0]],


k = 2


输出:[0,2]


解释:


每行中的军人数目:


行 0 -> 1


行 1 -> 4


行 2 -> 1


行 3 -> 1


从最弱到最强对这些行排序后得到 [0,2,3,1]


解题思路:

题目要求给队伍的实力由弱到强排位,军人数量越多越强,军人数量一致时,队伍下标的大小越大越强。

那么我们就可以用一个长度为2的一维数组来存放每一条队伍:

int[]{val,index}

val 代表队伍中军人的总数;

index 代表队伍的行数大小;

将每条队伍的数据放入最小堆中排序,int[0]小的优先,若军人数相同时,int[1]小的优先。

最后再分别取出堆顶元素储存,便为队伍按由弱到强的顺序排好了。


解题代码:

class Solution {
    public int[] kWeakestRows(int[][] mat, int k) {
        //创建优先队列,默认为最小堆
        //堆中的节点元素为数组int[]{val,index},
        //1.val代表军人数量,2.index代表第index行
        //最小堆排序规则是先对比军人数量,若相同再对比行数index的大小,小的优先
        PriorityQueue<int[]> que = new PriorityQueue<>(new Comparator<int[]>(){
                public int compare(int[] a,int[] b){
                return a[0] != b[0]?a[0] - b[0]:a[1]-b[1];
            }
            });
            //用来记录每一行的军人数量
            int sum;
            for(int i = 0;i < mat.length;++i){
            sum = 0;
            for(int n : mat[i]){
                if(n == 1) sum++;
            }
            que.offer(new int[]{sum,i});//将int[]{军人数,第index行}放入最小堆排序
        }
        int[] sort = new int[k];
        for(int i = 0;i < k;++i){
            sort[i] = que.poll()[1];//取出堆顶的最弱的第index行队伍
        }
        return sort;//输出队伍排行
    }
}

提交结果:

微信图片_20221029134715.png

贵在坚持: ✨关注作者,与作者一同进步…

微信图片_20221029111446.jpg



目录
相关文章
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
160 1
|
8月前
|
算法 Go 索引
【LeetCode 热题100】45:跳跃游戏 II(详细解析)(Go语言版)
本文详细解析了力扣第45题“跳跃游戏II”的三种解法:贪心算法、动态规划和反向贪心。贪心算法通过选择每一步能跳到的最远位置,实现O(n)时间复杂度与O(1)空间复杂度,是面试首选;动态规划以自底向上的方式构建状态转移方程,适合初学者理解但效率较低;反向贪心从终点逆向寻找最优跳点,逻辑清晰但性能欠佳。文章对比了各方法的优劣,并提供了Go语言代码实现,助你掌握最小跳跃次数问题的核心技巧。
340 15
|
8月前
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
510 90
|
8月前
|
算法 Go
【LeetCode 热题100】73:矩阵置零(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 73——矩阵置零问题,提供两种解法:一是使用额外标记数组,时间复杂度为 O(m * n),空间复杂度为 O(m + n);二是优化后的原地标记方法,利用矩阵的第一行和第一列记录需要置零的信息,将空间复杂度降低到 O(1)。文章通过清晰的代码示例与复杂度分析,帮助理解“原地操作”及空间优化技巧,并推荐相关练习题以巩固矩阵操作能力。适合刷题提升算法思维!
270 9
|
8月前
|
算法 Go
【LeetCode 热题100】55:跳跃游戏(详细解析)(Go语言版)
本篇解析详细讲解了 LeetCode 热题 55——跳跃游戏(Jump Game)。通过判断是否能从数组起点跳至终点,介绍了两种高效解法:贪心算法和反向思维。贪心法通过维护最远可达位置 `maxReach` 实现一次遍历,时间复杂度 O(n),空间复杂度 O(1);反向法则从终点回溯,判断是否可到达起点。两者均简洁高效,适合面试使用。延伸题目如 LeetCode 45 进一步提升挑战。
253 7
【LeetCode 27】347.前k个高频元素
【LeetCode 27】347.前k个高频元素
138 0
|
算法 C++
Leetcode第59题(螺旋矩阵2)
这篇文章介绍了解决LeetCode第59题“螺旋矩阵II”的算法,通过C++编程实现按顺时针顺序填充一个n x n的正方形矩阵。
163 0
Leetcode第55题(跳跃游戏)
LeetCode第55题“跳跃游戏”要求判断在一个非负整数数组中,从第一个位置出发,是否能够到达最后一个位置,其中每个位置的元素代表可跳跃的最大长度。
110 0
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
274 6
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
376 2