Python世界:力扣题解1712,将数组分成三个子数组的方案数,中等

Python世界:力扣题解1712:将数组分成三个子数组的方案数,中等

    • 任务背景
    • 思路分析
    • 代码实现
    • 测试套件
    • 本文小结

任务背景


问题来自力扣题目1712. Ways to Split Array Into Three Subarrays,大意如下:

A split of an integer array is good if:

  • The array is split into three non-empty contiguous subarrays - named left, mid, right respectively from left to right.
  • The sum of the elements in left is less than or equal to the sum of the elements in mid, and the sum of the elements in mid is less than or equal to the sum of the elements in right.

Given nums, an array of non-negative integers, return the number of good ways to split nums. As the number may be too large, return it modulo 10^9 + 7.

翻译下,需求是:对给定无序数组划分成三组子数组,划分后要求左、中、右数组元素和递增,返回可划分的方法总数,若不可划分,则返回-1.

思路分析


第一个坑,读题失误,不是元素个数和递增,而是元素之和要递增。下面为错误做法,埋坑警戒。

import mathclass Solution(object):def waysToSplit(self, nums):""":type nums: List[int]:rtype: int"""res = 0nums_len = len(nums)ways_total = 0left_max = nums_len // 3 + 1for l in range(1, left_max):mid_max = (nums_len - l) // 2 + 1for m in range(l, mid_max):r = nums_len - l - mif (l <= m) and (m <= r) and (l + m + r == nums_len):ways_total += 1res = ways_totalreturn res

搞清楚真正意图后,思路如下:

  • 先获取一个同样大小sum_arr数组,累加nums的元素和,构造有序数组,创造二分条件
  • 对sum_arr数组做两个划分,即插两个板子,先定左板依次向右遍历
  • 再浮动右板,找到第一个大于左板划分子数组mid,即找数组左上界low
  • 再移动右板,找到第一个超过右板划分子数组right,即找数组右上界high
  • 区间长度len=high-low,即为该定左板的可划分总数
  • 依次移动左板,重复此步骤,累加len得到总的split_ways

代码实现


在这里插入图片描述

# nums,升序;找到第一个大于target值的索引
def get_array_left_bound(nums, l, h, t):# range: [low, high)target = tlow = lhigh = hfound_flag = Falsewhile (low < high):mid = low + (high - low) // 2if (nums[mid] >= 2*target):high = midfound_flag = Trueelse:low = mid + 1if found_flag:return lowreturn -1# nums,升序;找到最后一个大于target值的索引
def get_array_right_bound(nums, l, h, t):# range: [low, high)tar = tlow = lhigh = h# range: [low, high)found_flag = Falsewhile (low < high):mid = low + (high - low) // 2acc = nums[mid] - nums[l]left = acc + tarright = nums[h - 1] - nums[mid]if (left > right): # 不满足预期,缩减右界high = midelse: # 若 left <= rightlow = mid + 1found_flag = Trueif low > h - 1:low = h - 1if found_flag:return low  # 返回low-1则表示right右界,能取到;返回low,则表示右界临界值,无法取。return -1def get_array_sum(nums):nums_len = len(nums)nums_sum = []val_sum = 0for i in range(nums_len):val_sum += nums[i]nums_sum.append(val_sum)# print(nums_sum)return nums_sumdef get_ways(nums, l):h = len(nums)t = nums[l] # left res, 0-lstart = get_array_left_bound(nums, l + 1, h, t)# start最大只能为倒数第二个索引,要确保最后至少有一个子数组if (start < 1 or start + 1 >= h):return 0t = nums[start] - nums[l] # mid res, [l+1, start]end = get_array_right_bound(nums, start, h, t)if (end <= start): # start最远能偏移的边界return 0ways = end - startreturn ways# sum + binary
class Solution(object):def waysToSplit(self, nums):""":type nums: List[int]:rtype: int"""res = 0nums_len = len(nums)nums_sum = get_array_sum(nums)# 左右边界挡板ways_total = 0left_max = nums_len - 1for l in range(0, left_max):if (2*nums_sum[l] > nums_sum[nums_len - 1]):breakways_total += get_ways(nums_sum, l)res = ways_total % 1_000_000_007return res

这里也埋了个坑,最开始94行没有注意处理大数取余10^9+7,导致[0, 0, 0, 0, 0, …]大数用例一直无法通过。

测试套件


单例测试demo:

# one case test
nums = [1,1,1]
nums = [1,2,2,2,5,0]
nums = [3,2,1]
nums = [0,0,0,0]
nums = [0, 0, 0, 0] # 3
nums = [0, 0, 0, 0, 0] # 6sol = Solution()
res = sol.waysToSplit(nums)
print(res)

套件测试demo:

# 导入单元测试
import unittestdef test_base(self, nums, ret):sol = Solution()res = sol.waysToSplit(nums)self.assertEqual(res, ret)# 编写测试套
class TestSol(unittest.TestCase):def test_special1(self):nums = [1,1,1]ret = 1test_base(self, nums, ret)def test_special2(self):nums = [0,0,0]ret = 1test_base(self, nums, ret)def test_special3(self):nums = [0,0,0,0]ret = 3test_base(self, nums, ret)def test_special4(self):nums = [0,0,0,0,0]ret = 6test_base(self, nums, ret)def test_common1(self):nums = [1,2,2,2,5,0]ret = 3test_base(self, nums, ret)def test_common2(self):nums = [3,2,1]ret = 0test_base(self, nums, ret)def test_common3(self):nums = [1,2,2,2,5,0]ret = 3test_base(self, nums, ret)# 含测试套版本主调
if __name__ == '__main__':print('start!')unittest.main() # 启动单元测试print('done!')

本文小结


此题关键点在于二分法左右边界的获取,需要对边界条件有很熟练的处理,同时注意题意处理和特殊用例,如全零大数组处理,可用排列组合Cm2公式来处理,获取理论值。

  1. 参考实现1:https://leetcode.com/problems/ways-to-split-array-into-three-subarrays/solutions/999157/python3-binary-search-2-pointer/
  2. 参考实现2:https://blog.csdn.net/weixin_59916649/article/details/125187567

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

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

相关文章

Java集合基础——针对实习面试

目录 Java集合基础什么是Java集合&#xff1f;说说List,Set,Queue,Map的区别&#xff1f;说说List?说说Set?说说Map&#xff1f;说说Queue?为什么要用集合&#xff1f;如何选用集合&#xff1f; Java集合基础 什么是Java集合&#xff1f; Java集合&#xff08;Java Collect…

基于单片机的客车载客状况自动检测系统(论文+源码)

1系统整体设计 本课题为客车载客状况自动检测系统&#xff0c;在此以STM32单片机为核心控制器&#xff0c;结合压力传感器、红外传感器、蜂鸣器、语音提示模块、继电器、液晶等构成整个客车载客状况自动检测系统&#xff0c;整个系统架构如图2.1所示&#xff0c;在此通过两个红…

渗透测试(socket,namp,scapy)

socket:可以用来实现不同虚拟机或者不同计算机之间的通信。 socket常用函数&#xff1a; sock.bind(host,port) //host可接受client范围&#xff0c;以及连接的端口 sock.listen()//sever开启监听连接 sock.accpet()//返回 sock&#xff0c;addr 用来接受和发送数据 addr…

【mongodb】数据库的安装及连接初始化简明手册

NoSQL(NoSQL Not Only SQL )&#xff0c;意即"不仅仅是SQL"。 在现代的计算系统上每天网络上都会产生庞大的数据量。这些数据有很大一部分是由关系数据库管理系统&#xff08;RDBMS&#xff09;来处理。 通过应用实践证明&#xff0c;关系模型是非常适合于客户服务器…

内网对抗-信息收集篇SPN扫描DC定位角色区域定性服务探针安全防护凭据获取

知识点&#xff1a; 1、信息收集篇-网络架构-出网&角色&服务&成员 2、信息收集篇-安全防护-杀毒&防火墙&流量监控 3、信息收集篇-密码凭据-系统&工具&网站&网络域渗透的信息收集&#xff1a; 在攻防演练中&#xff0c;当完成边界突破后进入内…

OpenWebUI,RAG+外部知识库+AI写文的开源应用

引言 自从去年AI火起来之后&#xff0c;很多人便热衷于寻找适合自用的AI开源项目&#xff0c;把各家大模型API接入到自己的AI程序里&#xff0c;便可以通过AI辅助完成一系列日常任务&#xff0c;比如内容翻译/润色/总结/撰写、格式转换、数据分类、代码分析、角色扮演等等。 …

qt QErrorMessage详解

1、概述 QErrorMessage是Qt框架中用于显示错误消息的一个对话框类。它提供了一个简单的模态对话框&#xff0c;用于向用户显示错误或警告消息。QErrorMessage通常用于应用程序中&#xff0c;当需要向用户报告错误但不希望中断当前操作时。它提供了一个标准的错误消息界面&…

一文了解Android的Doze模式

Android 的 Doze 模式是一项省电功能&#xff0c;主要用于减少设备的功耗&#xff0c;特别是在屏幕关闭且设备长时间未被使用的情况下。Doze 模式在 Android 6.0&#xff08;API Level 23&#xff09;首次引入&#xff0c;并在后续版本中不断改进&#xff0c;以便更智能地管理后…

美团代付微信小程序系统 read.php 任意文件读取漏洞复现

0x01 产品简介 美团代付微信小程序系统是美团点评旗下的一款基于微信小程序技术开发的应用程序功能之一,它允许用户方便快捷地请求他人为自己支付订单费用。随着移动支付的普及和微信小程序的广泛应用,美团作为中国领先的本地生活服务平台,推出了代付功能,以满足用户多样化…

SpringBoot-员工管理系统(1)

目录 一、首页配置 二、国际化 2.1 配置文件编写 2.2 使配置文件生效 2.3 配置页面国际化值 2.4 实现根据按钮自动切换中英文 三、登录拦截器 一、首页配置 1、所有页面的静态资源都需要用thymeleaf接管 2、url使用{}格式 二、国际化 2.1 配置文件编写 1、在resourc…

JavaSE:初识Java(学习笔记)

java是高级语言的面向对象语言 .[最贴近生活.最快速分析和设计程序] 一&#xff0c;计算机语言发展历史 二&#xff0c;Java体系结构 1&#xff0c;JavaSE&#xff08;Java Standard Edition&#xff09; 标准版&#xff0c;定位在个人计算机上的应用 这个版本是Jav…

Android——多线程、线程通信、handler机制

Android——多线程、线程通信、handler机制 模拟网络请求&#xff0c;会阻塞主线程 private String getStringForNet() {StringBuilder stringBuilder new StringBuilder();for (int i 0; i < 100; i) {stringBuilder.append("字符串" i);}try {Thread.sleep(…

Jumpserver

概述 一款开源的堡垒机&#xff0c;可使系统的管理员和开发人员安全的连接到企业内部服务器上执行操作&#xff0c;是一款非常安全的远程连接工具。 4A 身份验证授权控制账号管理安全审计 安装 [rootjumpserver project]# tar -xf jumpserver-offline-installer-v2.28.6-amd64…

【专题】2024年全球生物医药交易报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p38191 在当今复杂多变的全球经济环境下&#xff0c;医药行业正面临着诸多挑战与机遇。2024 年&#xff0c;医药行业的发展态势备受关注。 一方面&#xff0c;全球生物医药交易活跃&#xff0c;2021 - 2023 年的交易中&#xff0c;已…

统信UOS开发环境支持rust

集成了Rust编译器和包管理工具,支持系统级编程、网络应用等多场景,为开发者提供丰富的库支持。 文章目录 一、环境部署1. rust开发环境安装2. rust开发环境配置二、代码示例三、常见问题1. 借用和所有权问题2. 编译器错误和警告一、环境部署 1. rust开发环境安装 rust是一门…

Addressables资源打包(AA包)代码中改变远程地址

接着上一篇“Unity资源打包Addressable AA包” 还是先贴代码 LoadPath.cs 中定义一个远程服务器的地址&#xff0c;这个地址将来在代码中会修改 namespace HFS {public class LoadPath{public static string Path "http://172.18.216.168:6565/HFS/1/";} } 远程服…

linux基础-完结(详讲补充)

linux基础-完结 一、Linux目录介绍 二、基础命令详细讲解 1. ls&#xff08;列出目录内容&#xff09; 2. cd&#xff08;更改目录&#xff09; 3. clear&#xff08;清除终端屏幕&#xff09; 4. pwd(显示你当前所在的目录) 5. vim(文本编辑器) 6. touch&#xff08;创…

开启鸿蒙开发之旅:准备篇

写在前面 Q:为什么要学习鸿蒙&#xff1f; A:没有特定的理由&#xff0c;有可能是因为大环境不好的原因&#xff0c;大家越来越卷&#xff0c;技术革新越来越快&#xff0c;如果手里多掌握一门技术&#xff0c;心里会更有底气一些。再一个自己只有前端开发经验&#xff0c;平时…

倒计时3天 | 2024 CCF中国开源大会仪式解读

点击蓝字 关注我们 CCF Opensource Development Committee CCF 大会简介 2024 CCF中国开源大会&#xff08;CCF ChinaOSC&#xff09;将于2024年11月9日至10日在深圳召开。本届大会由中国计算机学会主办&#xff0c;CCF开源发展委员会、鹏城实验室、新一代人工智能产业技术创新…

硬件基础17 半导体存储器——随机存取存储器RAM

目录 一、异步SRAM 二、同步SRAM 三、DRAM 四、字长位数扩展 五、字数的扩展 RAM是另一大类存储器&#xff0c;它与ROM的最大区别就是数据易失性&#xff0c;一旦失去电源供电&#xff0c;所存储的数据立即丢失。最大优点是可以随时快速地从其中任一指定地址读出&#xff…