2024.6.25力扣刷题记录-周赛403

news2024/11/22 21:52:21

目录

一、3194. 最小元素和最大元素的最小平均值

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

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

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


博主在比赛时只过了前两题。剩下跟着灵神做,来自视频:

【状态机 DP【力扣周赛 403】】 https://www.bilibili.com/video/BV1MZ421M74P/?share_source=copy_web&vd_source=dc0e55cfae3b304619670a78444fd795

一、3194. 最小元素和最大元素的最小平均值

1.自写:

class Solution:
    def minimumAverage(self, nums: List[int]) -> float:
        nums.sort()
        ans = inf
        l, r = 0, len(nums) - 1
        while l <= r:
            ans = min(ans, nums[l] + nums[r])
            l += 1
            r -= 1
        return ans / 2

2.灵神:

class Solution:
    def minimumAverage(self, nums: List[int]) -> float:
        n = len(nums)
        nums.sort()
        ans = inf
        for i in range(n // 2):
            j = n - 1 - i
            ans = min(ans, nums[i] + nums[j])
        return ans / 2

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

1.自写:

我每次一遇到这种题,就只一股脑用前缀和(笑哭)。

class Solution:
    def minimumArea(self, grid: List[List[int]]) -> int:
        # 前缀和
        n, m = len(grid), len(grid[0])
        mx = 0
        ans = 0
        flag = (0, 0)
        add = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
        for i in range(n):
            for j in range(m):
                add[i + 1][j + 1] = add[i][j + 1] + add[i + 1][j] - add[i][j] + grid[i][j]
                if add[i + 1][j + 1] > mx:
                    mx = add[i + 1][j + 1]
                    ans = (i + 1) * (j + 1)
                    flag = ((i + 1), (j + 1))
        # 找到前面空的
        i = 1
        while i <= n:
            if add[i][-1] != 0:
                break
            i += 1
        j = 1
        while j <= m:
            if add[-1][j] != 0:
                break
            j += 1
        ans -= (i - 1) * flag[1] + (j - 1) * flag[0] - (i - 1) * (j - 1)
        return ans

2.灵神:

class Solution:
    def minimumArea(self, grid: List[List[int]]) -> int:
        # 边界
        left, right = len(grid[0]), 0
        up, down = len(grid), 0
        for i, row in enumerate(grid):
            for j, x in enumerate(row):
                if x:
                    left = min(left, j)
                    right = max(right, j)
                    up = min(up, i)
                    down = i    # 从上到下遍历
        return (down - up + 1) * (right - left + 1)

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

当时第一反应是dp,但是我当时想的是前缀,没能解决。

灵神:

附一个自己画的状态转移的简单图解:

(1)递归

class Solution:
    def maximumTotalCost(self, nums: List[int]) -> int:
        # dp
        # 后缀
        # 递归
        @cache
        def dfs(i: int, j: int) -> int:
            if i == len(nums):
                return 0
            if j == 0:
                return dfs(i + 1, 1) + nums[i]
            return max(dfs(i + 1, 1) + nums[i], dfs(i + 1, 0) - nums[i])
        return dfs(0, 0)    # 第一位肯定为正

(2)递推,一比一翻译

class Solution:
    def maximumTotalCost(self, nums: List[int]) -> int:
        # dp
        # 后缀
        # 递推,一比一翻译
        n = len(nums)
        f = [[0, 0] for _ in range(n + 1)]
        for i in range(n - 1, -1, -1):
            f[i][0] = f[i + 1][1] + nums[i]
            f[i][1] = max(f[i + 1][1] + nums[i], f[i + 1][0] - nums[i])
        return f[0][0]

(3)递推,滑动窗口

class Solution:
    def maximumTotalCost(self, nums: List[int]) -> int:
        # dp
        # 后缀
        # 递推,滑动窗口
        n = len(nums)
        j0, j1 = 0, 0
        # 切片nums[::-1],会消耗额外空间
        # reversed()生成迭代器,不会消耗额外空间
        for x in reversed(nums):
            j0, j1 = j1 + x, max(j1 + x, j0 - x)
        return j0

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

听了讲解后自己写的代码,旋转90度的代码参考视频。

class Solution:
    def minimumSum(self, grid: List[List[int]]) -> int:
        n, m = len(grid), len(grid[0])
        return min(self.f(grid, n, m), self.f(self.rotate(grid, n, m), m, n))
        
    def cover(self, grid: List[List[int]], left: int, right: int, up: int, down: int) -> int:
        # 计算最小面积
        # 闭区间
        # 注意区域内可能没有1,区别第二题
        # 要么返回时判断,要么初始化时设置大一点
        l, r = right, left
        u, d = down, up
        for i in range(up, down + 1):
            for j in range(left, right + 1):
                if grid[i][j]:
                    l = min(l, j)
                    r = max(r, j)
                    u = min(u, i)
                    d = i
        return (r - l + 1) * (d - u + 1) if r >= l and d >= u else 0
    
    def f(self, grid: List[List[int]], n: int, m: int) -> int:
        ans = 901
        # 划分横着三个区域
        if n >= 3:
            for line1 in range(n - 2):
                for line2 in range(line1 + 1, n - 1):
                    m1 = self.cover(grid, 0, m - 1, 0, line1)
                    m2 = self.cover(grid, 0, m - 1, line1 + 1, line2)
                    m3 = self.cover(grid, 0, m - 1, line2 + 1, n - 1)
                    ans = min(ans, m1 + m2 + m3)

        if n >= 2 and m >= 2:
            for line1 in range(n - 1):
                for line2 in range(m - 1):
                    # 划分上横下二区域
                    m1 = self.cover(grid, 0, m - 1, 0, line1)
                    m2 = self.cover(grid, 0, line2, line1 + 1, n - 1)
                    m3 = self.cover(grid, line2 + 1, m - 1, line1 + 1, n - 1)
                    ans = min(ans, m1 + m2 + m3)
                    # 划分下横上二区域
                    m1 = self.cover(grid, 0, line2, 0, line1)
                    m2 = self.cover(grid, line2 + 1, m - 1, 0, line1)
                    m3 = self.cover(grid, 0, m - 1, line1 + 1, n - 1)
                    ans = min(ans, m1 + m2 + m3)
        return ans
    
    def rotate(self, grid: List[List[int]], n: int, m: int) -> List[List[int]]:
        # 顺时针旋转90度
        ans = [[0 for _ in range(n)] for _ in range(m)]
        for i in range(n):
            for j in range(m):
                ans[j][n - 1 - i] = grid[i][j]
        return ans

参考评论区评论(. - 力扣(LeetCode)),事先使用一个覆盖框预处理(想起了R-CNN),修改代码如下:

class Solution:
    def minimumSum(self, grid: List[List[int]]) -> int:
        n, m = len(grid), len(grid[0])
        return min(self.f(grid, n, m), self.f(self.rotate(grid, n, m), m, n))
        
    def cover(self, grid: List[List[int]], left: int, right: int, up: int, down: int) -> int:
        # 计算最小范围
        # 闭区间
        l, r = right, left
        u, d = down, up
        for i in range(up, down + 1):
            for j in range(left, right + 1):
                if grid[i][j]:
                    l = min(l, j)
                    r = max(r, j)
                    u = min(u, i)
                    d = i
        return l, r, u, d

    def minArea(self, grid: List[List[int]], l: int, r: int, u: int, d: int) -> int:
        # 注意区域内可能没有1,区别第二题
        # 要么返回时判断,要么初始化时设置大一点
        l, r, u, d = self.cover(grid, l, r, u, d)   # 找出最小覆盖范围
        return (r - l + 1) * (d - u + 1) if r >= l and d >= u else 0
    
    def f(self, grid: List[List[int]], n: int, m: int) -> int:
        # 先事先筛选一个大矩形框
        left, right, up, down = self.cover(grid, 0, m - 1, 0, n - 1)
        # left -> 0, right -> m - 1, up -> 0, down -> n - 1
        
        ans = 901
        # 划分横着三个区域
        if n >= 3:
            for line1 in range(up, down - 1):
                for line2 in range(line1 + 1, down):
                    m1 = self.minArea(grid, left, right, up, line1)
                    m2 = self.minArea(grid, left, right, line1 + 1, line2)
                    m3 = self.minArea(grid, left, right, line2 + 1, down)
                    ans = min(ans, m1 + m2 + m3)

        if n >= 2 and m >= 2:
            for line1 in range(up, down):
                for line2 in range(left, right):
                    # 划分上横下二区域
                    m1 = self.minArea(grid, left, right, up, line1)
                    m2 = self.minArea(grid, left, line2, line1 + 1, down)
                    m3 = self.minArea(grid, line2 + 1, right, line1 + 1, down)
                    ans = min(ans, m1 + m2 + m3)
                    # 划分下横上二区域
                    m1 = self.minArea(grid, left, line2, up, line1)
                    m2 = self.minArea(grid, line2 + 1, right, up, line1)
                    m3 = self.minArea(grid, left, right, line1 + 1, down)
                    ans = min(ans, m1 + m2 + m3)
        return ans
    
    def rotate(self, grid: List[List[int]], n: int, m: int) -> List[List[int]]:
        # 顺时针旋转90度
        ans = [[0 for _ in range(n)] for _ in range(m)]
        for i in range(n):
            for j in range(m):
                ans[j][n - 1 - i] = grid[i][j]
        return ans

 灵神还有一种使用dp进行预处理降低时间复杂度的方法,但是我没学,感觉这暂时不是我能学会的,感兴趣的可以看他的题解(. - 力扣(LeetCode))。

感谢你看到这里!一起加油吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1862705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dwg文件转换的软件,分享4款软件!

在数字化设计领域&#xff0c;DWG文件作为CAD&#xff08;计算机辅助设计&#xff09;的核心文件格式&#xff0c;其重要性不言而喻。然而&#xff0c;在实际应用中&#xff0c;我们有时需要将DWG文件转换为其他格式以便于分享、展示或进行其他操作。那么&#xff0c;DWG文件转…

vue3,pinia状态管理,手写插件实现持久化

状态管理和持久化 先简单概述一下状态管理和持久化 状态管理&#xff1a;使任意两个组件共享数据持久化&#xff1a;将共享的数据保存在本地&#xff0c;不随页面销毁而消失 要实现状态的持久化&#xff0c;可以直接采用插件的形式实现&#xff0c;插件其实就是一个函数&#…

民生银行北京分行金融科技校招面试记录

本文介绍2024届春招中&#xff0c;中国民生银行下属北京分行的金融科技岗位1场面试的基本情况、提问问题等。 2024年04月投递了中国民生银行下属北京分行的金融科技岗位&#xff0c;暂时不清楚所在部门。目前完成了一面与终面&#xff0c;在这里记录一下面试的相关经历。 首先&…

UFS协议—新手快速入门(四)【10】

目录 十、UPIU数据包格式详解 1、Transaction Type&#xff08;类型&#xff09; 2、Flags&#xff08;附加信息&#xff09; 其它 3、LUN&#xff08;逻辑单元号&#xff09;&#xff1a; 4、Task Tag&#xff08;任务标签&#xff09;&#xff1a; 5、Command Type&…

你还不知道Modbus RTU???

1. 什么是Modbus RTU Modbus RTU&#xff08;Remote Terminal Unit&#xff09;是Modbus通信协议的一种变种&#xff0c;用于串行通信。它是一种常见的工业控制系统通信协议&#xff0c;通常用于采集传感器数据、控制执行器和监控设备状态。Modbus RTU采用二进制编码&#xff0…

突破Web3红海,DePIN如何构建创新生态系统?

撰文&#xff1a;TinTinLand 本文来源香港Web3媒体Techub News专栏作者TinTinLand 2023 年 DePIN 赛道的火热成为 Web3 行业的重点关注方向&#xff0c;当前如何以可扩展、去中心化、安全方式推动 DePIN 赛道赋能下的 AI 版图建设&#xff0c;寻找更多 Web3 行业创新机遇成为…

静电场的基本方程

目录 场积分方程 通量&#xff08;高斯定理&#xff09; 环量 场微分方程 散度 旋度 小结 补充知识 立体角 场积分方程 通量&#xff08;高斯定理&#xff09; 环量 场微分方程 散度 旋度 小结 补充知识 立体角

打开自动联网,设置静态IP

TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic # 设置为static DEFROUTEyes IPV4_FAILURE_FATALno IPV6INITyes IPV6_AUTOCONFyes IPV6_DEFROUTEyes IPV6_FAILURE_FATALno IPV6_ADDR_GEN_MODEstable-privacy NAMEens18 UUIDce34dd13-05cb-4d6d-95e4-252355b1…

c++网络通信

TCP/IP协议 OSI参考模型采用分层划分原则&#xff0c;将网络中的数据传输划分为7层&#xff0c;其中&#xff0c;物理层居于最下层&#xff0c;是最基础、核心的网络硬件层&#xff1b;应用层居于最上层&#xff0c;负责应用资源的管理。每一层使用下层的服务&#xff0c;并向…

内存卡数据移走了怎样恢复?简易步骤与解决方案

随着科技的快速发展&#xff0c;内存卡已成为我们日常生活中不可或缺的一部分&#xff0c;特别是在行车记录仪、手机、相机等设备上。然而&#xff0c;当内存卡中的数据意外移走或删除时&#xff0c;我们往往会感到焦虑和困惑。本文将为您介绍如何简易恢复内存卡中移走的数据&a…

[leetcode]valid-triangle-number. 有效三角形的个数

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int triangleNumber(vector<int>& nums) {int n nums.size();sort(nums.begin(), nums.end());int ans 0;for (int i 0; i < n; i) {for (int j i 1; j < n; j) {int left j 1, righ…

文件上传漏洞---Pyload

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 本文重点从靶场案例分析文件上传漏洞常见的Pylod&#xff0c;本文演示靶场upload-labs 一.文件类型---Pyload 不同的文件对应不同的文件类型&#xff0c;后端代码通过限制特定的文件类型…

618首战大捷!西圣Mike无线领夹麦克风全平台秒空!全网直接卖断货!

​在今年618购物狂欢节的首轮激战中&#xff0c;西圣Mike无线领夹麦克风以其卓越的品质和出色的性能以及高性价比&#xff0c;在全平台掀起了一股抢购热潮&#xff0c;实现了令人瞩目的“秒空”壮举&#xff0c;全网直接卖断货&#xff01; 不得不说西圣Mike是真的牛&#xff0…

Python 参数类型

一 理解Python中的Parameters & Arguments Parameters&#xff1a;形参 Arguments&#xff1a;实参 二 Python的实参&#xff08;Arguments&#xff09;类型 实参类型总结 位置参数&#xff08;Positional Arguments&#xff09; &#xff1a;函数调用时通过入参的顺序来…

JAVA每日作业day6.25

ok了家人们今天我们学习了&#xff0c;接口这个知识&#xff0c;我们闲话少叙&#xff0c;一起看看吧。 一&#xff0c;接口 1.1 接口概述 接口是功能的集合。接口的内部主要就是定义方法&#xff0c;包含常量&#xff0c;抽象方法&#xff08;JDK 7及以前&#xff09;&#…

让我们聊聊网络安全中会涉及到的IP地址(IP协议)、MAC地址、路由、DNS协议(域名系统)、NAT技术(协议)、以太网帧、ARP协议

网络安全中会涉及到的IP地址&#xff08;IP协议&#xff09;、MAC地址、路由、DNS协议&#xff08;域名系统&#xff09;、NAT技术&#xff08;协议&#xff09;、以太网帧、ARP协议 一.IP地址&#xff08;IP协议&#xff09;1.IP地址&#xff08;IP协议&#xff09;的作用2.IP…

第一百二十六节 Java面向对象设计 - Java枚举类

Java面向对象设计 - Java枚举类 枚举类型的超类 编译枚举类型时&#xff0c;编译器会创建一个类。 枚举类型可以具有构造函数&#xff0c;字段和方法。枚举类型仅在编译器生成的代码中实例化。 每个枚举类型都隐式地扩展java.lang.Enum类。 Enum类中定义的所有方法都可以与…

SAP 初始化库存移动类型561501511区别简介

项目上线初始化库存经常会用到561这个移动类型&#xff0c;同时我们在平时测试的过程中也会用到会进行库存的初始化&#xff0c;用的比较多是就是561和501这两个移动类型&#xff0c;本文将测试移动类型561&501&511这三个移动类型&#xff0c;分析三者之间的区别&#…

【图像处理实战】去除光照不均(Python)

这篇文章主要是对参考文章里面实现一种小拓展&#xff1a; 可处理彩色图片&#xff08;通过对 HSV 的 V 通道进行处理&#xff09;本来想将嵌套循环改成矩阵运算的&#xff0c;但是太麻烦了&#xff0c;而且代码也不好理解&#xff0c;所以放弃了。 代码 import cv2 import …

一分钟彻底掌握Java多线程生产者与消费者模型

代码 package com.example.KFC; public class Cooker extends Thread { public void run() { while (true) { synchronized (Desk.lock) { if (Desk.maxCount 0) { break; } else { if (!Desk.flag) { System.out.println("Cooker makes a hamburger"); …