LeetCode周赛记录(247)

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 0i,0<i<word.length1,各位置出现的奇偶情况便可计算(i,j)的各字母出现奇偶情况。

对于以j为结尾的完美字符串,只需先计算(0,j)时各字母出现的奇偶情况,后续寻找 ( 0 , i ) , i < j (0,i),i<j 0ii<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;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值