leetcode 473. 火柴拼正方形-思路整理与细节分析

news2024/11/19 17:45:59

题目:

你将得到一个整数数组matchsticks,其中 matchsticks[i]是第i个火柴棒的长度。你要用所有的火柴棍拼成一个正方形。你不能折断任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须使用一次。如果你能使这个正方形,则返回 true ,否则返回 false 。

示例

输入: matchsticks = [1,4,2,3,5,2,3]
输出: true
解释: 能拼成一个边长为2的正方形,每边两根火柴。

题解

首先来分析一下题目具体是什么问题。题目的意思是给定一组长短不同的火柴,利用这些火柴判断是否能拼成一个正方形。正方形就是四条边均相等,这个问题的抽象化表示就是给定一个数组,是否能把数据分成四个子集,每个子集的数的和相同。为了有效说明以上面的示例为例来分析一下该题目的解题方法。
在这里插入图片描述
给定一组可选择的火柴,把这火柴均分到四条边中。显然根据火柴的列表可以确定每一个边的目标值是6。
那么我们先对“可选火柴”中的第一个数据进行分配。显然该数据放在任何一个边中均可。
在这里插入图片描述
如上图所示,把1放在边1中。这里边1当前已有,还需要再填充5。由于如果结果是真的话就一定有一组数据与1一起正好构成一条值为6的边,因此我们只需要逐个的填满每条边就好。这里需要加一个状态值来记录,当前填充边填充了多少。接下来处理第2个数据4。从目前状态来看4是可以放到边1中的,因为1与4的全为5显然小于6。我们先假定把4放到边1中。
在这里插入图片描述

我们发现继续遍历2一直到最后也无法填充满边1。显然把4放到边1中无法找到有效的分配结果。退回原来状态,跳过4。

在这里插入图片描述

2显然也是能放到边1中的,先尝试把2放到边1中。
在这里插入图片描述

当前的3也是能放到边1中,这样边1正好达到目标值6,由于当前边已填充完,开始填充边2了这里当前边已有值就变成0了。
在这里插入图片描述

把5放到边2中。
在这里插入图片描述
但是到这里我们发现我们无法找到能与5一起填充边的值了,显然,从2开始我们的填充。我们开始回退。这里直接回退到。

在这里插入图片描述

再重新开始,重这些操作直到达到如下状态。

在这里插入图片描述

那么我们现在开始整理我们的思路。我们每一步的输入是“可选火柴”与当前已有值,第一步的选择都是不断的尝试,最终是通过“可选火柴”与当前已有值来判断选择该步数值是否能让所有边都填充完。这显然是一个递归过程,每一步的选择都依赖于对剩下状态的递归。

递归函数

  • 输入:“可选火柴”,当前已有值
  • 输出:是否可正好填充完各边
  • 递归过程:
    1 终止条件,当“可选火柴”无数据可选择时终止
    2 等价问题,选择完一个数之后,判断当前状态是否可填充完各边

代码如下:

class Solution:
    def makesquare(self, matchsticks: List[int]) -> bool:
        #边界确定
        bucket_value,div_value=divmod(sum(matchsticks),4)
        matchsticks.sort(reverse=True)
        if div_value:
            return False
        n=len(matchsticks)

        @cache
        def dfs(state,curr_value):
            #终止条件
            if state==0:
                return True
            for i in range(n):
                #判断i位置是否可选
                if state>>i&1:
                    #判断该位置数据是否能与curr_value分到一个释桶
                    if matchsticks[i]+curr_value<=bucket_value:
                        #判断分完i个数后剩下的数据是否满足要求
                        if dfs(state^(1<<i),(curr_value+matchsticks[i])%bucket_value):
                            return True
            return False
        return dfs((1<<n)-1,0)

代码关键部分介绍

bucket_value,div_value=divmod(sum(matchsticks),4)
matchsticks.sort(reverse=True)
if div_value:
    return False

这一块其实就是判断给定的list是否是能被4整除。如果不能整除直接就返回False。
这里使用了状态压缩,这里状态压缩就是用一个数来表示“可选火柴”,怎么表示呢。在遍历可选火柴列表时,已选过的数标记为0表示不能再选了,标记为1的数才可以遍历。如下图所示,只有数据1与数据3的状态表示为1,表示只有剩下这两个数待填充。

在这里插入图片描述

这种表示是一一对应的形式,为了书写方便通常表示倒顺的表示。

在这里插入图片描述

为什么要这么写,比如判断i个位置是否可选择使用state>>i&1,如果要是第一种对应的话就得变成state>>(n-i)&1。后面的state^(1<<i)表示把第i位置的数据为成0表示已选择过不可选了。

计算复杂度

  • 时间复杂度: O ( n × 2 n ) O(n×2^n) O(n×2n) ,其中 n 为 数组 的长度,共有 2 n 2^n 2n个状态,每一个状态进行了 n 次尝试。
  • 空间复杂度: O ( 2 n ) O(2^n) O(2n),其中n 为数组 nums 的长度,主要为状态数组的空间开销。

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

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

相关文章

FPGA新起点V1开发板(五)——Modelsim软件的使用(联合仿真)

文章目录一、简介1.1 前仿真1.2 后仿真二、联合仿真2.1 选择modesim的安装路径2.2 设置选择eda的工具2.3 test bench文件2.4 打开test bench文件2.5 给系统时钟和复位信号赋初值2.6 配置仿真功能三、RTL仿真3.1 打开波形窗口3.2添加内部信号四、时序仿真一、简介 1.1 前仿真 主…

web大学生网页作业成品 响应式网站水果超市7页(html+css+javascript+jquery+bootstarp)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

web期末大作业 用HTML+CSS做一个漂亮简单的节日网页【传日文化节日中秋节】

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

web前端期末大作业—— HTML+CSS豪华车 (9页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

蚂蚁金服开源的这份SpringBoot笔记,曾在24小时内GitHub星标48k

前言 Spring的影响力想必就不用小编多说了&#xff0c;今天要跟大家说的是SpringBoot。Spring Boot作为目前Spring技术体系中炙手可热的框架之一&#xff0c;已经是开发者们的必备神器了。在实际的项目中&#xff0c;需要集成各种的插件支持&#xff0c;还有很多或许我们平时不…

【计算机考研408-计算机网络-教书匠视频笔记】主机访问浏览器的全部过程

主机H1利用浏览器通过该域名请求访问web服务器 由于题目给定主机H1的ARP表是空的 &#xff08;1&#xff09;主机H1首先会发送ARP请求报文&#xff0c;ARP请求报文会被封装在以太网的MAC帧中发送 ARP请求报文&#xff1a;FF-FF-FF-FF-FF-FF 源MAC地址&#xff1a;00-11-22-3…

Docker 容器使用

文章目录Docker 容器使用Docker 客户端运行一个web应用查看 WEB 应用容器网络端口的快捷方式查看WEB应用程序日志查看WEB应用程序容器的进程检查WEB应用程序停止WEB应用容器重启WEB应用容器移除WEB应用容器Docker 容器使用 Docker 客户端 docker 客户端非常简单 ,我们可以直接…

全网显示 IP 归属地,用上这个开源库,实现也太简单了

细心的小伙伴可能会发现&#xff0c;最近蘑菇新上线了 IP 属地的功能&#xff0c;小伙伴在发表动态、发表评论以及聊天的时候&#xff0c;都会显示自己的 IP 属地信息 动态显示IP属地 在蘑菇群聊中&#xff0c;也 可 以 展 示 IP 属 地&#xff0c;下面是小伙伴们在交流群中显…

【强化学习论文合集】十八.2019国际表征学习大会论文(ICLR2019)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

面试官:你觉得你最大的缺点是什么?

面试官:你觉得你最大的缺点是什么? 前言 相信百分之80的同学们都会被问到这个问题&#xff1a;你觉得你最大的缺点是什么? 这也是求职者一个充满恐惧的问题&#xff0c;特别是我们程序员&#xff0c;大家在与人沟通并没有我们与代码沟通这么得心应手&#xff0c;如果你没回…

网络请求工具wget和curl

一. wget命令 wget命令来自于英文词组”web get“的缩写&#xff0c;其功能是用于从指定网址下载网络文件。 wget命令支持如HTTP、HTTPS、FTP等常见协议&#xff0c;可以在命令行中直接下载网络文件。 注意&#xff1a;不同busybox版本集成的wget命令&#xff0c;可能不…

统计检验分析

1. 正态分布检验 2. 统计检验 正态分布且方差齐非正态分布或方差不齐para test non-para testnon-pairedpaired2组 t-testWilcoxon rank-sum testWilcoxon signed-rank test3组及以上One way ANOVA Kruskal-Wallis testt-test: Paired t-test: 确定某个总体的成对测量值之间…

说说WM_DESTROY和WM_NCDESTROY的区别

在一个 Windows 窗口被销毁的时候&#xff0c;你会发现有两个比较类似的消息&#xff1a;WM_DESTROY和WM_NCDESTROY&#xff0c;那么&#xff0c;这俩兄弟之间有什么区别呢&#xff1f;今天就来讲讲。 不同之处在于&#xff0c;WM_DESTROY消息在窗口销毁序列的开头发送&#x…

MySQL执行计划误选索引及修改方案

MySQL的优化器 MySQL在执行查询语句时使用那个索引是由server层的优化器决定的。优化器的作用是找到一个最优的执行方案&#xff0c;用最小的代价去执行语句。由于MySQL使用预估的方式去选择索引&#xff0c;所以MySQL可能会出现选择索引出错的情况&#xff0c;无法命中最优索…

刘韧工作手册(2023年版)

刘韧于2022年9月22日为云算科技做内部演讲。由谭缘整理成文&#xff0c;李欣欣编辑&#xff0c;朱芳文审定。一、认知篇01 干中学&#xff0c;重复做。“学”是为了“习”&#xff0c;学到的东西是为了下一次习的时候&#xff0c;做得更好。“习”&#xff0c;是最终实践的成果…

WSL安装教程

wsl安装教程引言前期准备工作安装wsl第一步第二步 检测系统版本第三步 确定虚拟机特性第四步 下载Linux内核的更新包第五步 设置WSL 2作为默认版本第六步 选择Linux发行版本并设置Linux账号小TIPS引言 Windows Subsystem for Linux&#xff08;简称WSL&#xff09;是一个在Win…

大家都在画圣诞树,我们用代码敲一颗吧~圣诞树

前段时间发布的文章很多人问怎么操作的&#xff0c;今天具体说明一下&#xff1a;PS&#xff1a;如果需要下载可以点击左下角阅读全文下载代码使用更方便具体步骤如下&#xff1a;复制下面代码在电脑里面新建一个记事本&#xff0c;将代码复制到新建的记事本里保存记事本&#…

虚拟机网络连通性选择

做运维的朋友对于虚拟机这个概念应该不会陌生&#xff0c;这里不做讲解。今天主要想对虚拟机的网络连通性的选择方法做一个简单的介绍&#xff0c;如果是老人就没必要看了&#xff0c;此文章针对刚入门初次使用虚拟机进行测试、工作的小伙伴。 咱们常见的虚拟机平台软件有很多&…

【实时数仓】用户行为日志采集模块单机模式部署,Nginx介绍、安装和配置,采集模块集群部署并使用Nginx进行反向代理

文章目录一 日志采集模块1 打包单机部署&#xff08;1&#xff09;修改gmall2022-logger中的logback.xml配置文件&#xff08;2&#xff09;修改SpringBoot核心配置文件application.propeties&#xff08;3&#xff09;测试&#xff08;4&#xff09;程序运行流程2 Nginx&#…

Grafana 的介绍和安装

版本&#xff1a;9.3.1 介绍 Grafana是一款能够提供查询、告警和可视化指标、日志、链路跟踪的软件&#xff0c;并且提供了TSDB时序数据库用于存储数据。 一共有3个版本&#xff0c;Grafana OSS&#xff08;开源版&#xff09;&#xff0c;Grafana Enterprise&#xff08;企业…