Leetcode - 周赛403

目录

一,3200. 三角形的最大高度

二,3195. 包含所有 1 的最小矩形面积 I

三,3196. 最大化子数组的总成本

四,3197. 包含所有 1 的最小矩形面积 II


一,3200. 三角形的最大高度

本题是一道模拟题,可以先排序再用两个变量枚举最大值和最小值,不断比较,返回最小值,代码如下:

class Solution {
    public double minimumAverage(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        double ans = 50.0;
        int i = 0, j = n - 1;
        while(i < j){
            ans = Math.min(ans, (nums[i] + nums[j])/2.0);
            i++;
            j--;
        }
        return ans;
    }
}

二,3195. 包含所有 1 的最小矩形面积 I

本题求最小矩形的面积,就是求它的长和宽,即求它的上下左右,代码如下:

class Solution {
    public int minimumArea(int[][] grid) {
        int n = grid.length, m = grid[0].length;
        int left=m, right=0, top=n, bottom=0;
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                if(grid[i][j] == 1){
                    left = Math.min(left, j);
                    right = Math.max(right, j);
                    top = Math.min(top, i);
                    bottom = Math.max(bottom, i);
                }
            }
        }
        return (right-left+1)*(bottom-top+1);
    }
}

三,3196. 最大化子数组的总成本

本题可以使用选或不选来做,即选择第 i 个数是在上一个子数组中(选),还是以它为起点重开了一个子数组(不选),所以我们需要一个参数 i 来确定下标,此外,要计算子数组的cost(l,r),我们还需要一个参数 j 来判断该数是加还是减,定义dfs(i,j):[0,i] 的最大总成本,且由 j 可得知,如果选,当前数是加还是减(j==0 ? + : -):

  • 选,第 i 个数是在上一个子数组中,那么接下来要判断的是第 i + 1 个数选或不选,且 j^1,(j^1就是将0变1,1变0),即下一个状态是 dfs(i+1,j^1)
  • 不选,第 i 个是新子数组的开头,那么接下来要判断的是第 i + 1 个数选或不选,注意如果第i+1个数要选的话,那么一定是减法( j = 1),即下一个状态是 dfs(i+1, 1)

代码如下:

class Solution {
    public long maximumTotalCost(int[] nums) {
        int n = nums.length;
        memo = new long[n][2];
        for(long[] r : memo) Arrays.fill(r, -1);
        return dfs(0, 0, nums);
    }
    long[][] memo;
    long dfs(int i, int j, int[] nums){
        if(i == nums.length) return 0;
        if(memo[i][j] != -1) return memo[i][j];
        return memo[i][j] = Math.max(dfs(i+1, j^1, nums) + (j==0?1:-1)*nums[i], dfs(i+1, 1, nums)+nums[i]);
    }
}

记忆化 1:1 改成递推

由上述代码可知:

  • f [i][j]定义:[0,i] 的最大总成本,且由 j 可得知,如果选,当前数是加还是减(j==0 ? - : +)
  • 递推公式 f[i][j] = Math.max( f[ i+1 ][ j^1 ] + (j==0?-1:1)*nums[i],f[i+1][1]+nums[i])
  • 当 j = 0 时,f[i][0] = Math.max(f[i+1][1] - nums[i],f[i+1][1] + nums[i]) = f[i+1][1] + nums[i]
  • 当 j = 1 时,f[i][1] = Math.max(f[i+1][0] - nums[i],f[i+1][1] + nums[i])
  • 答案是f[0][0]

由递推公式可知,要得到f[i][j]就必须先得到f[i+1][j],所以需要倒着遍历,代码如下:

class Solution {
    public long maximumTotalCost(int[] nums) {
        int n = nums.length;
        long[][] f = new long[n+1][2];
        for(int i=n-1; i>=0; i--){
            f[i][0] = f[i+1][1] + nums[i];
            f[i][1] = Math.max(f[i+1][0] - nums[i], f[i+1][1] + nums[i]);
        }
        return f[0][0];
    }
}

四,3197. 包含所有 1 的最小矩形面积 II

本题可以直接暴力求解,题目要求三个不重叠的矩形,并没有要求每个矩形必须有1,所以我们可以将该矩形分成三个部分,在使用T2的方法求最小面积,就可以得到答案,我们一共有6种分法:

但是我们只需要写上面三个就行,因为下面三个可以由上面三个矩形向右旋转90度获得,代码如下:

class Solution {
    public int minimumArea(int[][] grid, int x1, int x2, int y1, int y2) {
        int left=y2, right=0, top=x2, bottom=0;
        for(int i=x1; i<x2; i++){
            for(int j=y1; j<y2; j++){
                if(grid[i][j] == 1){
                    left = Math.min(left, j);
                    right = Math.max(right, j);
                    top = Math.min(top, i);
                    bottom = Math.max(bottom, i);
                }
            }
        }
        return (right-left+1)*(bottom-top+1);
    }

    public int Sum(int[][] grid) {
        int n = grid.length, m = grid[0].length;
        int ans = n*m;
        if(n >= 3){
            for(int i=1; i<n; i++){
                for(int j=i+1; j<n; j++){
                    //上中下
                    int res = minimumArea(grid, 0, i, 0, m);
                    res += minimumArea(grid, i, j, 0, m);
                    res += minimumArea(grid, j, n, 0, m);
                    ans = Math.min(ans, res);
                }
            }
        }
        if(n>=2 && m>=2){
            for(int i=1; i<n; i++){
                for(int j=1; j<m; j++){
                    //上左右
                    int res = minimumArea(grid, 0, i, 0, m);
                    res += minimumArea(grid, i, n, 0, j);
                    res += minimumArea(grid, i, n, j, m);
                    ans = Math.min(ans, res);
                    //左右下
                    res = minimumArea(grid, 0, i, 0, j);
                    res += minimumArea(grid, 0, i, j, m);
                    res += minimumArea(grid, i, n, 0, m);
                    ans = Math.min(ans, res);
                }
            }
        }
        return ans;
    }

    public int[][] rotate(int[][] grid){
        int n = grid.length, m = grid[0].length;
        int[][] a = new int[m][n];
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                a[j][n-i-1] = grid[i][j];
            }
        }
        return a;
    }

    public int minimumSum(int[][] grid) {
        return Math.min(Sum(grid), Sum(rotate(grid)));
    }
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶祇秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值