leetcode 第224场周赛(2021/1/17)

leetcode周赛题目

摘录的一些周赛题目
周赛链接 :https://leetcode-cn.com/contest/weekly-contest-224/

5243. 同积元组【medium】(https://leetcode-cn.com/problems/tuple-with-same-product/)
在这里插入图片描述
第一眼看题很容易想到暴力解法:

解法1public int tupleSameProduct(int[] nums) {
        int res = 0;
        for (int a = 0; a < nums.length; a++){
            for (int b = 0; b < nums.length; b++){
                if (b == a){
                    continue;
                }
                for (int c = 0 ;c < nums.length; c++){
                    if (c == a || c == b){
                        continue;
                    }
                    for (int d = 0; d < nums.length; d++){
                        if (d == a || d == b || d == c){
                            continue;
                        }
                        if (nums[a] * nums[b] == nums[c] * nums[d]){
                            res++;
                        }
                    }
                }
            }
        }
        return res;
    }
然而这个解法因为使用了4层循环,时间复杂度为 O(n^4),部分运算示例会显示超时!!!
回过头来分析一下问题,题目给了一个很重要的信息,数组的元素是不同的,再看题目中的题解(2, 6, 4, 3)这四个数字组成了8个结果,也就是说最后的结果数量肯定是8的倍数;
因此可以先将数据进行排序,先使用a,b指针固定一个区间范围,再在a,b之间使用双指针寻找c和d的位置,从而减少复杂度,找到的数量再乘以8即为结果数量。
解法2public int tupleSameProduct(int[] nums) {
        Arrays.sort(nums);
        int res = 0;
        for (int a = 0; a < nums.length - 3; a++){
            for (int b = nums.length - 1; b >= a + 3; b--){
                int c = a + 1, d = b - 1;
                int product = nums[a] * nums[b];
                while (c < d){
                    if (nums[c] * nums[d] == product){
                        res++;
                        c++;
                        d--;
                    }else if (nums[c] * nums[d] < product){
                        c++; // 乘积较小,c右移一位
                    }else {
                        d--; // 乘积较大,d左移一位
                    }
                }
            }
        }
        return res * 8;
    }

5655. 重新排列后的最大子矩阵【medium】(https://leetcode-cn.com/problems/largest-submatrix-with-rearrangements/)
在这里插入图片描述
这道题需要计算的是矩阵当中所有最大的为1的链接矩形的面积,解法如下:
1、使用一个scanRow数据记录当前扫描行所有列的连续为1的数量;
2、对scanRow进行排序,连续为1的列最多的即排在了最后的位置;
3、通过scanRow后面即可计算出矩形的面积;

public int largestSubmatrix(int[][] matrix) {
        int m = matrix.length; // 行数
        int n = matrix[0].length; // 列数
        int res = 0;
        int[] scanRow = new int[n]; // 记录当前扫描行各列连续为1的数量
        int[] tempRow = new int[n]; // 记录行扫描后进行排序
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(matrix[i][j] == 1){
                    scanRow[j]++;
                }else{
                    scanRow[j] = 0; // 当前行是0的话即重置为0
                }
            }
            
            System.arraycopy(scanRow, 0, tempRow, 0, n);
            Arrays.sort(tempRow);
            
            for(int j = n - 1; j >= 0 && tempRow[j] > 0; j--){
                res = Math.max(res, (n - j) * tempRow[j]);
            }
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值