有意思的leetcode~

夜深人静写力扣

前言

这几天好兄弟Matty吴分享了几道力扣的题,虽然是简单难度,但是思维要求我觉得还是有点要求的,思路很有趣,记录一下~~

1380.矩阵中的幸运数

题目描述

给你一个\(m*n\)的矩阵,矩阵中的数字各不相同。请你按任意顺序返回矩阵中的幸运数。幸运数字是指矩阵中满足同时下列两个条件的元素:

  • 在同一行的所有元素中最小
  • 在同一列的所有元素中最大

原题目链接:1380. 矩阵中的幸运数 - 力扣

思路说明

实话说,一开始看到这道题是有点懵的,找不到一点思路。如果暴力遍历的话,后面的判断条件以我的功力应该会写的非常拉跨且混乱。还好还好,力扣不缺大佬,此处参考的是宫水三叶大佬的题解和思路(会添加上自己的理解和思路):题解链接

这里使用的思想是模拟思想。简单说说我自己对模拟的理解:在我看来模拟的关键是用代码实现(模拟过程)题目中的要求或者限制,所以对我们的考验就是能不能理解题意并且将它转变为编程语言。回到这道题,最主要的限制是:同行最小,同列最大。这里我们可以将它分解成行和列两部分来验证,也就是使用两个数组来分别存放每行和每列中的最小和最大数值,最后一部开始验证同一位置下的数字是否一致,若一致则说明是幸运数字。最后只需要考虑输出形式就可以了~

代码

		int[] row = new int[55],col = new int[55];
		int n = matrix.length , m = matrix[0].length;
        for(int i = 0 ; i < n ; i++){
            row[i] = 100001;
            for(int j = 0 ; j < m ; j++){
                row[i] = Math.min(row[i],matrix[i][j]);
                col[j] = Math.max(col[j],matrix[i][j]);
            }
        }
        List<Integer> ans = new ArrayList<>();
        for(int i = 0 ; i < n ; i++){
            for(int j = 0 ; j < m ; j ++){
                int t = matrix[i][j];
                if(t == row[i] && t == col[j]) ans.add(t);
            }
        }
        return ans;

1608.特殊数组的特征值

题目

给你一个非负整数数组 nums 。如果存在一个数 x ,使得 nums 中恰好有 x 个元素 大于或者等于 x ,那么就称 nums 是一个 特殊数组 ,而 x 是该数组的 特征值 。

注意: x 不必 是 nums 的中的元素。

如果数组 nums 是一个 特殊数组 ,请返回它的特征值 x 。否则,返回 -1 。可以证明的是,如果 nums 是特殊数组,那么其特征值 x 是 唯一的 。

原题目链接:1608. 特殊数组的特征值

思路

这道题虽然说是简单题,但是思路确实很难找到。说实话一开始看到数组长度在100以内且元素大小1000以内,就觉得应该要用暴力解法,但是具体到实现,又不知道如何写了。看了眼题解,就发现了一个很妙的解法:题解链接

这里的做法是不考虑排序,因为可能会出现重复数字且这道题不关心元素的索引位置,所以我们只要统计每个数字出现的次数就好了,最后就可以将每次数字出现的次数加起来验证特征值。我们使用一个长度比输入大一的数字用来计算(用索引表示数字,元素表示出现次数)。一个比较关键的点:特征值一定在1到数组最大值之间(这里可以自己推导验证一下,结果是成立的)。之后就是使用后序遍历了(因为特征数定义的范围是大于等于,那么这里用倒序会比较好一点(我们那个计数数据是1-N的嘛,倒序来计算,就可以直接累加计算,不用再去减其他一些东西)。

以上就是大概的思路,表达有点不清楚,还是建议参考题解。

代码

class Solution {
    public int specialArray(int[] nums) {
        int maxnum = 0;
        for(int num : nums){
            if(num > maxnum){
                maxnum = num;
            }
        }
        int[] count = new int[maxnum+1];
        for(int num : nums){
            count[num] += 1;
        }
        int sum = 0;
        for(int i = maxnum ; i >= 0 ; i--){
            sum += count[i];
            if(sum == i){
                return i;
            }
        }
        return -1;
    }
}

后续

其实还有一道有意思的题目,也是这位好兄弟的分享,不过这道题当时的思路很清晰,后来也就没考虑把它记录下来了。Anyway,夜深人静写力扣的思路确实会清晰很多hhh~

上一篇:月のLeetCode 每周刷题之 Week5


下一篇:【Leetcode】0001 两数之和