二分查找:LeetCode2035:将数组分成两个数组并最小化数组和的差

本文涉及的基础知识点

二分查找算法合集

作者推荐

动态规划LeetCode2552:优化了6版的1324模式

题目

给你一个长度为 2 * n 的整数数组。你需要将 nums 分成 两个 长度为 n 的数组,分别求出两个数组的和,并 最小化 两个数组和之 差的绝对值 。nums 中每个元素都需要放入两个数组之一。
请你返回 最小 的数组和之差。
示例 1:
输入:nums = [3,9,7,3]
输出:2
解释:最优分组方案是分成 [3,9] 和 [7,3] 。
数组和之差的绝对值为 abs((3 + 9) - (7 + 3)) = 2 。
示例 2:
输入:nums = [-36,36]
输出:72
解释:最优分组方案是分成 [-36] 和 [36] 。
数组和之差的绝对值为 abs((-36) - (36)) = 72 。
示例 3:
输入:nums = [2,-1,0,4,-2,-9]
输出:0
解释:最优分组方案是分成 [2,4,-9] 和 [-1,0,-2] 。
数组和之差的绝对值为 abs((2 + 4 + -9) - (-1 + 0 + -2)) = 0 。
参数范围
1 <= n <= 15
nums.length == 2 * n
-107 <= nums[i] <= 107

折半查找后二分

时间复杂度

O(2nlog2n)。

变量解释

vLeftvLeft[i]表示从前n个数据中选择i个数的和,记录所有可能
vRight类似,记录的是右边

分析

如果从左边选择i个数,那么需要从右边选择n-i个数。假定从左边i个数的和是n1,右边选择n-i个数的和为n2。枚举n1,从v2中选择第一个大于等于n2的数和第一个小于n2的数。iTotal 是nums的和。
n1+n2= iTotal-n1-n2 => n2 =iTotal/2 - n1
iTotal要分奇数和偶数分别处理。我们将所有数都乘以2,iTotal就必定是偶数了。

注意

不要忘记

v[0].emplace_back(0);

代码

核心代码

class Solution {
public:
	int minimumDifference(vector<int>& nums) {
		const int iTotal = std::accumulate(nums.begin(), nums.end(), 0);
		int n = nums.size() / 2;
		vector<vector<int>> vLeft(n + 1), vRight(n + 1);
		auto Build = [&n](vector<vector<int>>& v,int* p, int len)
		{
			v[0].emplace_back(0);
			for (int i = 0; i < len; i++)
			{
				for (int j = n; j >= 1 ; j--)
				{
					for (const auto& num : v[j - 1])
					{
						v[j].emplace_back(num + p[i] * 2);
					}
				}
			}
		};
		Build(vLeft, nums.data(), n);
		Build(vRight, nums.data()+n, n);
		int iRet = INT_MAX;
		for (int i = 0; i <= n; i++)
		{
			auto& v1 = vLeft[i];
			auto& v2 = vRight[n - i];
			sort(v1.begin(), v1.end());
			sort(v2.begin(), v2.end());
			for (const auto& n1 : v1)
			{
				auto it = std::upper_bound(v2.begin(), v2.end(),iTotal- n1);
				if (v2.end() != it)
				{
					iRet = min(iRet, *it + n1 - iTotal);
				}
				if (v2.begin() != it)
				{
					iRet = min(iRet, iTotal - n1 - *(std::prev(it)));
				}
			}
		}
		return iRet;
	}
};

测试用例

template
void Assert(const vector& v1, const vector& v2)
{
if (v1.size() != v2.size())
{
assert(false);
return;
}
for (int i = 0; i < v1.size(); i++)
{
assert(v1[i] == v2[i]);
}
}

template
void Assert(const T& t1, const T& t2)
{
assert(t1 == t2);
}

int main()
{
vector nums;
int res;
{
nums = { 3,9,7,3 };
Solution slu;
auto res = slu.minimumDifference(nums);
Assert(2, res);
}
{
nums = { -36,36 };
Solution slu;
auto res = slu.minimumDifference(nums);
Assert(72, res);
}
{
nums = { 2,-1,0,4,-2,-9 };
Solution slu;
auto res = slu.minimumDifference(nums);
Assert(0, res);
}

  //CConsole::Out(res);

}

2023年2月旧版

class Solution {
public:
int minimumDifference(vector& nums) {
m_c = nums.size() / 2;
vector<std::unordered_set> vSetSumsLeft, vSetSumsRight;
std::vector v1( nums.begin(), nums.begin() + m_c);
CalSumSet(vSetSumsLeft, v1);
std::vector v2(nums.begin() + m_c, nums.end());
CalSumSet(vSetSumsRight,v2 );
int iTotal = std::accumulate(nums.begin(), nums.end(), 0);
int iMin = INT_MAX;
for (int i = 0; i <= m_c; i++ )
{
std::vector v1(vSetSumsLeft[i].begin(), vSetSumsLeft[i].end());
std::vector v2(vSetSumsRight[m_c - i].begin(), vSetSumsRight[m_c - i].end());
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
auto it = v1.begin();
auto ij = v2.rbegin();
while ((it != v1.end()) && (ij != v2.rend()))
{
int iDiff = iTotal - (*it + *ij) * 2;
iMin = min(iMin, abs(iDiff));
if (iDiff > 0)
{
it++;
}
else
{
ij++;
}
}
}
return iMin;
}
static void CalSumSet(vector<std::unordered_set>& vSetSums,vector& nums)
{
int c = nums.size() ;
vSetSums.resize(c + 1);
vSetSums[0].insert(0);
for (const auto& n : nums)
{
vector<std::unordered_set> dp = vSetSums;
for (int i = 0; i < c; i++)
{
for (auto it : vSetSums[i])
{
dp[i + 1].insert(it + n);
}
}
vSetSums.swap(dp);
}
}

 int m_c;

};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业

。也就是我们常说的专业的人做专业的事。 |
|如果程序是一条龙,那算法就是他的是睛|

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境:

VS2022 C++17

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nodejs微信小程序+python+PHP贵州旅游系统的设计与实现-计算机毕业设计推荐MySQL

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

巧用MACD精准抄底和逃顶

一、认识MACD MACD又称平滑异同移动平均线&#xff0c;是由美国投资家杰拉尔德阿佩尔在 20 世纪 70 年代末提出的。 MACD 指标的设计基于MA均线原理&#xff0c;是对收盘价进行平滑处理&#xff08;求出加权平均值&#xff09;后的一种趋向类指标。它是股票交易中一种常见的技术…

IDEA2023安装教程(超详细)

文章目录 前言安装IntelliJ IDEA1. 下载IntelliJ IDEA2. 运行安装程序3. 选择安装路径4. 选择启动器设置5. 等待安装完成6. 启动IntelliJ IDEA7. 配置和设置8. 激活或选择许可证9. 开始使用 总结 前言 随着软件开发的不断发展&#xff0c;IntelliJ IDEA成为了许多开发人员首选…

pygame实现贪吃蛇小游戏

import pygame import random# 游戏初始化 pygame.init()# 游戏窗口设置 win_width, win_height 800, 600 window pygame.display.set_mode((win_width, win_height)) pygame.display.set_caption("Snake Game")# 颜色设置 WHITE (255, 255, 255) BLACK (0, 0, 0…

avue-tabs设置默认选中的tab

文章目录 一、问题二、解决三、最后 一、问题 最近在用avue这个UI框架来开发页面&#xff0c;有用到avue-tabs这个tab切换组件。结果竟然发现element-ui中el-tabs的v-model在avue-tabs中竟然是没有用的&#xff0c;无法设置默认选中哪个tab。avue这个基于element-ui开发的UI框…

【计算机网络笔记】802.11无线局域网

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

制作一个RISC-V的操作系统二-RISC-V ISA介绍

文章目录 ISA的基本介绍啥是ISA为什么要设计ISACISCvsRISCISA的宽度知名ISA介绍 RISC-V历史和特点RISC-V发展RISC-V ISA 命名规范模块化的ISA通用寄存器Hart特权级别Control and Status Register&#xff08;CSR&#xff09;内存管理与保护异常和中断 ISA的基本介绍 啥是ISA …

十大经典系统架构设计面试题

十大经典系统架构设计面试题_架构_程序员石磊_InfoQ写作社区翻译自&#xff1a;https://medium.com/geekculture/top-10-system-design-interview-questions-10f7b5ea123d在我作为微软和Facebhttps://xie.infoq.cn/article/4c0c9328a725a76922f6547ad 任何 SDI 问题的提示 通过…

Elasticsearch:什么是自然语言处理(NLP)?

自然语言处理定义 自然语言处理 (natural language processing - NLP) 是人工智能 (AI) 的一种形式&#xff0c;专注于计算机和人们使用人类语言进行交互的方式。 NLP 技术帮助计算机使用我们的自然交流模式&#xff08;语音和书面文本&#xff09;来分析、理解和响应我们。 自…

OpenCV-Python:计算机视觉介绍

目录 1.背景 2.计算机视觉发展历史 3.计算机视觉主要任务 4.计算机视觉应用场景 5.知识笔记 1.背景 OpenCV是计算机视觉的一个框架&#xff0c;想要学习OpenCV&#xff0c;需要对计算机视觉有一个大致的了解。计算机视觉是指通过计算机技术和算法来模拟人类视觉系统的能力…

Go语言实现深度学习的正向传播和反向传播

文章目录 开发前言开发理论图解理论数据类型数学函数数据节点统一抽象变量数据节点常量数据节点单目运算封装双目运算封装算子节点统一抽象基础算子加法算子减法算子乘法算子除法算子指数算子对数算子正切算子正弦算子余弦算子数据流图正向传播反向传播运行示例开发总结 开发前…

甄知黄建华:从“天赋平平”到IT行业“六边形战士”,探索出企业数智化转型的“强IT”之路

本期我们先抛开人物和主体不表&#xff0c;从大环境开始谈起。随着科技的快速发展和全球商业环境的不断变化&#xff0c;中国企业对灵活性、创新性、全球化和效率的需求是迫切的&#xff0c;进行数字化转型来支撑企业的业务变革、组织优化已是业界共识。如何根据企业的实际情况…

Hdoop学习笔记(HDP)-Part.17 安装Spark2

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

接口测试 —— Requests库介绍

1、Requests库 Requests库是用Python语言编写&#xff0c;基于urllib3模块&#xff0c;采用Apache2 Licensed开源协议的 HTTP 库。 虽然Python的标准库中urllib3模块已经包含了平常我们使用的大多数功能&#xff0c;但是它的 API使用起来让人感觉不太友好。而Requests库使用的…

揭秘原型链:探索 JavaScript 面向对象编程的核心(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

type-c充电器输出电压5V9V12V15V20V PD协议诱骗快充应用方案

Type-C接口的PD充电器&#xff08;如iPhone的20W充电器&#xff09;默认是没有电压输出的&#xff0c;想要让Type-C的充电器输出5V、9V、12V、15V、20V&#xff0c;只需要在产品上使用一颗快充取电芯片XSP08即可。 工作原理&#xff1a; 各类小家电产品如平板电脑、智能穿戴产…

申请Azure学生订阅——人工验证

一&#xff1a;联系客服进行人工验证 点击 Services Hub 填写资料申请人工验证 点击 Azure - Sign up 进行学生验证 二&#xff1a;与客服的邮件沟通的记录 ​​​​一、结果&#xff08;输入客服给的验证码后&#xff0c;笔者便得到了学生订阅&#xff09;&#xff1a; 二…

TypeScript编程语言学习,为学习HarmonyOS开发做准备

1. 编程语言 ArkTS是HarmonyOS优选的应用开发语言&#xff0c;它在TypeScript&#xff08;TS&#xff09;的基础上&#xff0c;匹配ArkUI扩展&#xff0c;扩展了声明式UI、状态管理等相应的能力。 JavaScript&#xff08;JS&#xff09;&#xff0c;使用在Web应用开发&#xf…

linux之buildroot(3)配置软件包

Linux之buildroot(3)配置软件包 Author&#xff1a;Onceday Date&#xff1a;2023年11月30日 漫漫长路&#xff0c;才刚刚开始… 全系列文章请查看专栏: buildroot编译框架_Once_day的博客-CSDN博客。 参考文档&#xff1a; Buildroot - Making Embedded Linux Easymdev.t…

C++——初始化列表

初始化列表&#xff1a;一一个冒号开始&#xff0c;接着是一个以逗号分隔的数据成员列表&#xff0c;每个“成员变量”后面跟一个放在括号中的初始值或表达式。 #include <iostream> using namespace std; class Date { public:Date(int year, int month, int day): _ye…