leetcode 第224场周赛(2021/1/17)
周赛链接 :https://leetcode-cn.com/contest/weekly-contest-224/
5243. 同积元组【medium】(https://leetcode-cn.com/problems/tuple-with-same-product/)
第一眼看题很容易想到暴力解法:
解法1:
public 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即为结果数量。
解法2:
public 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; }


浙公网安备 33010602011771号