LeetCode周赛记录(247)
第一题:5797. 两个数对之间的最大乘积差
可优化,可以一次遍历获得结果。
class Solution {
public int maxProductDifference(int[] nums) {
Arrays.sort(nums);
int length = nums.length;
return nums[length - 1] * nums[length - 2] - nums[0] * nums[1];
}
}
第二题:5798. 循环轮转矩阵
需要仔细分析每一层的情况,依次计算。
class Solution {
public int[][] rotateGrid(int[][] grid, int k) {
int row = grid.length;
int col = grid[0].length;
int[][] ans = new int[row][col];
//第n层从0开始:x=n,或row-1-n或y=n,col-1-n
//第n层高:row-2n,宽:col-2n
//每一层元素数量:2row-4n+2col-4n-4=2(row+col)-4-8n
//左上角坐标为:n,n,左下角为:row-1-n,n,右下角为:row-1-n,col-1-n,右上角为n,col-1-n
for (int i = 0; i < Math.min(row, col) / 2; i++) {
int index = k;
int tempLen = 2 * (row + col) - 4 - 8 * i;
int[] temp = new int[tempLen];
for (int j = i; j < row - 1 - i; j++) {
temp[index % tempLen] = grid[j][i];
index++;
}
for (int j = i; j < col - 1 - i; j++) {
temp[index % tempLen] = grid[row - 1 - i][j];
index++;
}
for (int j = row - 1 - i; j > i; j--) {
temp[index % tempLen] = grid[j][col - 1 - i];
index++;
}
for (int j = col - 1 - i; j > i; j--) {
temp[index % tempLen] = grid[i][j];
index++;
}
//赋值
index = 0;
for (int j = i; j < row - 1 - i; j++) {
ans[j][i] = temp[index++];
}
for (int j = i; j < col - 1 - i; j++) {
ans[row - 1 - i][j] = temp[index++];
}
for (int j = row - 1 - i; j > i; j--) {
ans[j][col - 1 - i] = temp[index++];
}
for (int j = col - 1 - i; j > i; j--) {
ans[i][j] = temp[index++];
}
}
return ans;
}
}
第三题:5799. 最美子字符串的数目
对于任意的最美字符串(i,j),满足(0,i)、(0,j)各字母出现的奇偶情况至多有一个不同。因此只需要记录 ( 0 , i ) , 0 < i < w o r d . l e n g t h − 1 (0,i),0<i<word.length-1 (0,i),0<i<word.length−1,各位置出现的奇偶情况便可计算(i,j)的各字母出现奇偶情况。
对于以j为结尾的完美字符串,只需先计算(0,j)时各字母出现的奇偶情况,后续寻找 ( 0 , i ) , i < j (0,i),i<j (0,i),i<j ,满足与该奇偶情况至多仅有一个字符不同的i的个数。
因此需要通过已知的奇偶情况,方便的查询出相关奇偶情况出现的次数,即需要建立已知奇偶情况的记录表。由于可能出现的字母共有十个,因此所有奇偶情况共有210种,可以建立长度为210的数组记录已有的奇偶情况。
具体实现如下:
class Solution {
public long wonderfulSubstrings(String word) {
long res = 0;
int[] cnt = new int[1 << 10];
//边界处理,长度为0时即为全部为偶的情况
cnt[0]++;
//记录当前的奇偶情况
int now = 0;
for (int i = 0; i < word.length(); i++) {
//计算当前的奇偶情况
now ^= (1 << (word.charAt(i) - 'a'));
//加上与当前奇偶情况相同的次数
res += cnt[now];
//加上与当前奇偶情况仅有一位不同的情况
for (int j = 0; j < 10; j++) {
res += cnt[now ^ (1 << j)];
}
cnt[now]++;
}
return res;
}
}