Python面试宝典第50题:分割等和子集

news2024/9/19 8:25:54

题目

        给你一个只包含正整数的非空数组nums,请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

        示例 1:

输入:nums = [1, 5, 11, 5]
输出:True
解释:数组可以分割成[1, 5, 5]和[11]。

        示例 2:

输入:nums = [1, 2, 3, 5]
输出:False
解释:数组不能分割成两个元素和相等的子集。

备忘录法

        备忘录法的基本思想是:在递归过程中缓存已计算的结果,避免重复计算相同子问题。这样可以显著减少递归树的分支,提高算法效率。使用备忘录法求解本题的主要步骤如下。

        1、定义递归函数can_partition_helper。该函数接受四个参数:数组nums、目标和target、当前索引index、备忘录memo。其中,备忘录memo用于存储已计算过的子问题的结果。

        2、基本情况。

        (1)如果target为0,则表示找到了一个子集,返回True。

        (2)如果target小于0,或者index超出了数组范围,则表示无法找到合适的子集,返回False。

        (3)如果target和index的组合已经存在于备忘录memo中,则直接返回备忘录中的结果。

        3、进行递归。

        (1)对于每个元素nums[index],有两种选择:包含或不包含该元素。

        (2)如果包含nums[index],则递归调用can_partition_helper函数,计算剩余元素是否可以构成目标和target - nums[index]。

        (3)如果不包含nums[index],则递归调用can_partition_helper 函数,计算剩余元素是否可以构成目标和target。

        (4)如果任一递归路径返回True,则更新备忘录memo,并返回True。

        4、如果所有递归路径都返回False,则表示无法分割成两个子集,返回False。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def partition_equal_subset_sum_by_memoization(nums):
    total_sum = sum(nums)
    # 如果总和不是偶数,则无法分割成两个子集
    if total_sum % 2 != 0:
        return False
    
    target = total_sum // 2
    memo = {}

    def can_partition_helper(nums, target, index):
        # 如果target为0,则表示找到了一个子集
        if target == 0:
            return True
        
        # 如果target小于0,或者index超出了数组范围,则表示无法找到合适的子集
        if target < 0 or index >= len(nums):
            return False
        
        # 如果target和index的组合已经存在于备忘录中,则直接返回备忘录中的结果
        if (target, index) in memo:
            return memo[(target, index)]

        # 包含nums[index]
        include = can_partition_helper(nums, target - nums[index], index + 1)
        # 不包含nums[index]
        exclude = can_partition_helper(nums, target, index + 1)

        # 更新备忘录memo
        memo[(target, index)] = include or exclude
        # 返回结果
        return include or exclude

    return can_partition_helper(nums, target, 0)

nums = [1, 5, 11, 5]
print(partition_equal_subset_sum_by_memoization(nums))

nums = [1, 2, 3, 5]
print(partition_equal_subset_sum_by_memoization(nums))

动态规划法

        使用动态规划法时,我们需要构建一个一维数组dp来存储达到每个子集和的可能性。数组dp的索引表示子集和,dp[i]表示能否通过选择数组中的元素达到和为i的子集。使用动态规划法求解本题的主要步骤如下。

        1、初始化。计算数组nums的总和total_sum,如果total_sum不是偶数,则无法分割成两个子集,直接返回False。否则,计算目标和target为total_sum // 2。

        2、构建DP数组。创建一个长度为target + 1的布尔型数组dp,其中dp[0]初始化为True,表示总和为0的子集始终存在,其他位置初始化为False。

        3、填充DP数组。对于每个元素num,从target到num的每个子集和i,更新dp[i]为dp[i]或dp[i - num]。

        4、返回dp[target],表示是否存在和为目标和target的子集。

        根据上面的算法步骤,我们可以得出下面的示例代码。

def partition_equal_subset_sum_by_dp(nums):
    total_sum = sum(nums)
    # 如果总和不是偶数,则无法分割成两个子集
    if total_sum % 2 != 0:
        return False
    
    target = total_sum // 2
    # 创建一个长度为target + 1的布尔型数组
    dp = [False] * (target + 1)
    dp[0] = True
    
    # 填充DP数组
    for num in nums:
        # 从target到num的每个子集和i
        for i in range(target, num - 1, -1):
            # 更新dp[i]
            dp[i] = dp[i] or dp[i - num]
    
    return dp[target]

nums = [1, 5, 11, 5]
print(partition_equal_subset_sum_by_dp(nums))

nums = [1, 2, 3, 5]
print(partition_equal_subset_sum_by_dp(nums))

总结

        使用备忘录法时,每个子问题只被计算一次,子问题的数量与数组nums的长度、目标和target成正比。总的时间复杂度为O(N * target),其中N是数组nums的长度,target是目标和的一半。备忘录的最大大小为N * target,故其空间复杂度为O(N * target)。相比纯递归法,备忘录法通过避免重复计算相同的子问题,大大提升了效率。

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

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

相关文章

C++之第十二课

课程列表 哎呀呀&#xff0c;失踪人口回归了&#xff01;&#xff08;前段时间跑去B站了&#xff0c;久等了&#xff09; 今天来讲——数组 有一道题是这样的&#xff1a; 有n个数&#xff0c;请输出其中最大的数。 原来我们就要&#xff1a; int a,b,c... 但是——数组…

Golang开发的OCR-身份证号码识别(不依赖第三方)

身份证号码识别&#xff08;golang&#xff09; 使用golang的image库写的身份证号码识别&#xff0c;还有用了一个resize外部库&#xff0c;用来更改图片尺寸大小&#xff0c;将每个数字所在的图片的大小进行统一可以更好的进行数字识别&#xff0c;库名 &#xff1a;“github…

ARM 工业边缘计算机与 C# 编程的完美融合

在工业领域&#xff0c;随着智能化和数字化的不断推进&#xff0c;ARM 工业边缘计算机凭借其出色的性能和低功耗等优势&#xff0c;逐渐成为众多应用场景的重要支撑。而 C# 编程语言的强大功能和广泛适用性&#xff0c;使其在与 ARM 工业边缘计算机的结合中展现出了巨大的潜力。…

Python | Leetcode Python题解之第415题字符串相加

题目&#xff1a; 题解&#xff1a; class Solution:def addStrings(self, num1: str, num2: str) -> str:res ""i, j, carry len(num1) - 1, len(num2) - 1, 0while i > 0 or j > 0:n1 int(num1[i]) if i > 0 else 0n2 int(num2[j]) if j > 0 e…

C++ -命名空间-详解

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【C】 欢迎点赞&#x1f44d;收藏⭐关注❤️ C -命名空间-详解 1.C语言缺点之一 -- 命名冲突2.命名空间2.1定义2.2使用访问命名空间中的变量展开命名空间域指定访问命名空间域 2.3其他功能 3.C 标准库中的命名空间指定展开…

华为OD机试 - 二维伞的雨滴效应(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

徒增成本,还是有备无患?说说4G模组SIM双卡切换

初学开发的小伙伴提出疑问&#xff1a; 手机双卡可以理解&#xff0c;人情世故各种缘由…… 物联网设备有必要双卡吗&#xff0c;会不会太浪费&#xff1f; 实际应用中&#xff0c;双卡可不是徒增成本的摆设&#xff0c;而是有备无患的必需。 在使用4G模组双卡功能的场景下&a…

2024年数学建模比赛题目及解题代码

目录 一、引言 1. 1竞赛背景介绍 1.1.1数学建模竞赛概述 1.1.2生产过程决策问题在竞赛中的重要性 1.2 解题前准备 1.2.2 工具与资源准备 1.2.3 心态调整与策略规划 二、问题理解与分析 三、模型构建与求解 3.1 模型选择与设计 3.1.1 根据问题特性选择合适的数学模型类…

每日学习一个数据结构-红黑树

文章目录 什么是红黑树&#xff1f;示意图红黑树的特点红黑树的节点结构插入和删除操作旋转操作重新着色 红黑树的应用 树的构造过程插入新节点自平衡调整策略 示例 查询过程 什么是红黑树&#xff1f; 红黑树&#xff08;Red-Black Tree&#xff09;是一种自平衡的二叉查找树…

关于嵌入式硬件需要了解的基础知识

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于嵌入式硬件基础知识的相关内容&#xff…

TCP: Textual-based Class-aware Prompt tuning for Visual-Language Model

文章汇总 存在的问题 原文&#xff1a;具有图像特定知识的图像条件提示符号在提升类嵌入分布方面的能力较差。 个人理解&#xff1a;单纯把"a photo of {class}"这种提示模版作为输入是不利于text encoder学习的 动机 在可学习的提示和每一类的文本知识之间建立…

2024短剧系统开发,付费短剧小程序app源码教程,分销功能讲解搭建上线

短剧系统技术栈 前端&#xff1a;vue3uniapp 后端&#xff1a; php 数据库&#xff1a;mysql 服务器环境&#xff1a; centos7.6 宝塔 php7.4 MySQL5.7 一、短剧系统功能 短剧用户端&#xff1a; 小程序、抖音小程序、快手小程序、APP、 z付宝小程序 系统用户端详细功能&…

Java创建教程!(*  ̄3)(ε ̄ *)

Java 构造函数 Java面向对象设计 - Java构造函数 构造函数是用于在对象创建后立即初始化对象的代码块。 构造函数的结构看起来类似于一个方法。 声明构造函数 构造函数声明的一般语法是 <Modifiers> <Constructor Name>(<parameters list>) throws <…

安卓14剖析SystemUI的ShadeLogger/LogBuffer日志动态控制输出dumpsy机制

背景&#xff1a; 看SystemUI的锁屏相关代码时候发现SystemUI有一个日志打印相关的方法调用&#xff0c;相比于常规的Log.i直接可以logcat查看方式还是比较新颖。 具体日志打印代码如下&#xff1a; 下面就来介绍一下这个ShadeLogger到底是如何打印的。 分析源码&#xff1…

scanf()函数的介绍及基础用法

目录 scanf&#xff08;&#xff09;函数的介绍及基础用法 一&#xff1a;头文件 二&#xff1a;一般用法 三&#xff1a;返回值 1. 正整数的情况&#xff1a; 2. 0 的情况&#xff1a; 3. EOF的情况&#xff1a; 四&#xff1a;说明 scanf&#xff08;&#xff09;函数…

CCF202006_1

问题描述 试题编号&#xff1a;202006-1试题名称&#xff1a;线性分类器时间限制&#xff1a;1.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 题解&#xff1a; #include<bits/stdc.h>using namespace std; int n, m;struct Node {int x, y;char ch; }node[1010…

9.16日常记录

1.LRU算法 核心思想:LRU算法&#xff08;Least Recently Used&#xff09;是一种常用的缓存淘汰策略&#xff0c;它的核心思想是“如果数据最近被访问过&#xff0c;那么将来被访问的几率也更高”。LRU算法主要用于内存管理和缓存系统。当内存或缓存空间已满&#xff0c;需要腾…

【工具变量】气候适应型试点城市DID(2005-2022年)

数据来源&#xff1a;本数据来源于中国ZF网发布的《关于深化气候适应型城市建设试点的通知》 时间跨度&#xff1a;2005-2022年数据简介&#xff1a;适应型试点城市是指在应对气候变化、提高城市适应能力方面进行先行先试的城市。根据中国ZF网发布的《关于深化气候适应型城市建…

在 Stable Diffusion 1.5 中 Lora, Dreambooth, Textual Inversion的详解指北

Lora, Dreambooth and Textual Inversion 说明 您是否想象过您可爱的宠物与埃菲尔铁塔合影的画面&#xff0c;或者想象过如何生成一张带有您朋友面孔的人工智能图像&#xff1f; 是的&#xff0c;通过稳定扩散技术的微调&#xff0c;这完全是可能的&#xff01; 创建这些场景…

NISP 一级 | 7.2 信息安全风险管理

关注这个证书的其他相关笔记&#xff1a;NISP 一级 —— 考证笔记合集-CSDN博客 0x01&#xff1a;信息安全风险 信息系统不可能达到绝对安全&#xff0c;但可以通过安全风险&#xff08;以下简称“风险”&#xff09;控制来实现符合个人或单位目标的一定程度的安全。信息安全管…