【动态规划】【数学】【C++算法】805 数组的均值分割

作者推荐

【动态规划】【数学】【C++算法】18赛车

本文涉及知识点

动态规划 数学

805 数组的均值分割

给定你一个整数数组 nums
我们要将 nums 数组中的每个元素移动到 A 数组 或者 B 数组中,使得 A 数组和 B 数组不为空,并且 average(A) == average(B) 。
如果可以完成则返回true , 否则返回 false 。
注意:对于数组 arr , average(arr) 是 arr 的所有元素的和除以 arr 长度。
示例 1:
输入: nums = [1,2,3,4,5,6,7,8]
输出: true
解释: 我们可以将数组分割为 [1,4,5,8] 和 [2,3,6,7], 他们的平均值都是4.5。
示例 2:
输入: nums = [3,1]
输出: false
参数范围:
1 <= nums.length <= 30
0 <= nums[i] <= 104

动态规划

令n=nums.length half=n/2。不失一般性,令A的长度小于等于B,则lena的长度取值范围[1,half],lenb=n-lena。
数组A的和为:Sum i = 0 : n − 1 \Large_{i=0}^{:n-1} i=0:n1nums[i]*lena/n ,数组A的和必须是整数。nums[i]的和最大为104*30 ,lean最大为15,可以直接相乘,看对n的余数是否为0。如果超出整数范围,可以先对lena和n约分。

预处理CountToTotal

将nums分成两部分。vLeft[i]记录所有从nums[0,half)选择i个数 可能的和。 vRight[i]记录所有从nums[half,n)中选择i个数的和。下面以vLeft为例,vRightei类似。三层循环
第一层循环:枚举[0,half)。时间复杂度O(n)
第二层循环:从大到小枚举vLeft[j]。 时间复杂度(n)。
第三层循环:枚举vLeft[j-1]。 时间复杂度O(2^n)
动态规划的转移方程:本轮的vLeft[j]一定是上一轮的vLeft[j-1]+nums[i]。总时间复杂度O(1515215) 约106

处理

第一层循环:用变量i枚举lena。
第二层循环:枚举A从左边选择了j个元素,j的取值范围[0,i]。
第三层循环:通过iLeft枚举vLeft[j],看vRight[i-j]是否存在totalA - iLeft。
时间复杂度: O(nn2n)

代码

核心代码

int GCD(int n1, int n2)
{int t1 = min(n1, n2);int t2 = max(n1, n2);if (0 == t1){return t2;}return GCD(t2 % t1, t1);
}class Solution {
public:bool splitArraySameAverage(vector<int>& nums) {const int n = nums.size();const int half = n / 2;vector<unordered_set<int>> vLeft(1), vRight(1);		CountToTotal( vLeft, nums.data(),0, half);CountToTotal(vRight, nums.data()+half, 0, n-half);const int total = std::accumulate(nums.begin(), nums.end(),0);for (int i = 1; i <= half; i++){const int iGCD = GCD(i, n);if (0 != total % (n / iGCD)){continue;//A的和必定为整数}const int totalA = total * i / n;for (int j = 0; j <= i; j++){// A数组总共选择i个,其中从左边选择j个for (const auto& iLeft : vLeft[j]){if (vRight[i - j].count(totalA - iLeft)){return true;}}}}return false;}void CountToTotal(std::vector<std::unordered_set<int>>& v, const int* p,int left,int r){v[0].emplace(0);for (int i = left; i < r ; i++){v.emplace_back();for (int j = v.size() - 1; j >= 1; j--){for (const auto& pre : v[j - 1]){v[j].emplace(pre + p[i]);}}}}
};

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{vector<int> nums;{Solution sln;nums = { 1,2,3,4,5,6,7,8 };auto res = sln.splitArraySameAverage(nums);Assert(true, res);}{Solution sln;nums = { 3,1};auto res = sln.splitArraySameAverage(nums);Assert(false, res);}{Solution sln;nums = { 18,10,5,3 };auto res = sln.splitArraySameAverage(nums);Assert(false, res);}}

2023年1月

class Solution {
public:
bool splitArraySameAverage(vector& nums) {
if (1 == nums.size())
{
return false;
}
const int iLeftMaxLen = nums.size() / 2;
const int iRightMaxLen = nums.size() - iLeftMaxLen;
vector<std::unordered_set> vLeftLenSums(iLeftMaxLen+1),vRightLenSums(iRightMaxLen+1);
vLeftLenSums[0].insert(0);
for (int i = 0; i < iLeftMaxLen; i++)
{
for (int j = i ; j >=0 ; j-- )
{
for (auto& it : vLeftLenSums[j])
{
vLeftLenSums[j + 1].insert(it +nums[i]);
}
}
vLeftLenSums[1].insert(nums[i]);
}
vRightLenSums[0].insert(0);
for (int i = iLeftMaxLen; i < nums.size(); i++)
{
for (int j = i - iLeftMaxLen; j >= 0; j–)
{
for (auto& it : vRightLenSums[j])
{
vRightLenSums[j + 1].insert(it + nums[i]);
}
}
}
int iTotalSum = std::accumulate(nums.begin(), nums.end(), 0);
for (int iALen = 1; iALen + 1 <= nums.size(); iALen++)
{
double dSum = iTotalSum 1.0 / nums.size() iALen;
int iSum = dSum;
bool bInt = ((dSum - iSum) < 0.0001) || ((dSum - iSum) > 0.9999);
if (!bInt)
{
continue;
}
for (int iLeftLen = max(0,iALen-iRightMaxLen); (iLeftLen <= min(iALen, iLeftMaxLen)); iLeftLen++)
{
for (const auto& it : vLeftLenSums[iLeftLen])
{
if (vRightLenSums[iALen - iLeftLen].count(iSum - it))
{
return true;
}
}
}
}
return false;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

Java基础(2)

一 String、StringBuffer、StringBuilder String 为什么要设计成不可变的&#xff1f; String是不可变的&#xff08;修改String时&#xff0c;不会在原有的内存地址修改&#xff0c;而是重新指向一个新对象&#xff09;&#xff0c;String用final修饰&#xff0c;不可继承&…

两个bbox的IoU计算步骤分析

IoU&#xff1a;交并比&#xff0c;数值上等于交集面积除以并集面积。 两个bbox的位置关系无外乎以上三种情况&#xff1a;&#xff08;1&#xff09;部分相交。&#xff08;2&#xff09;不相交。&#xff08;3&#xff09;包含。 计算步骤&#xff1a; 计算交集&#xff08…

flutter中使用基于flutter_sound的flutter_sound_record录音

flutter_sound_record 前言文章案例所使用插件的版本号插件安装引入安卓和ios权限支持的编码自定义生成的文件名代码main.dartaudio_player.dart 源码地址 前言 使用flutter_sound,总是出现莫名的错误,所以改为flutter_sound_record,实现录音录制和播放 文章案例所使用插件的…

操作系统-操作系统引导(磁盘 操作系统引导过程)

文章目录 总览一个刚买来的磁盘&#xff08;硬盘&#xff09;往磁盘安装操作系统后操作系统引导过程例&#xff1a;windows操作系统的初始化程序 总览 一个刚买来的磁盘&#xff08;硬盘&#xff09; 此时空空如也 往磁盘安装操作系统后 操作系统在C盘 主引导记录不属于某…

C# 更改Bitmap图像色彩模式

方法一&#xff1a;直接修改RGB的值 首先将BitmapData扫描线上的所有像素复制到字节数组中&#xff0c;然后遍历数组并对每个像素的RGB值进行修改&#xff0c;最后将修改后的像素值复制回BitmapData。这个过程不会影响原始的Bitmap对象&#xff0c;但会改变锁定的位图区域的数…

java idea 中的 Scratches and Consoles

IDEA 中&#xff0c;"Scratches and Consoles" 是一个用于临时代码编辑和交互式开发的工具窗口&#xff0c;作用如下&#xff1a;Scratches&#xff08;草稿&#xff09;&#xff1a;Scratches 是一个用于临时编写和运行代码片段的工具&#xff0c;你可以在其中创建临…

Python实现中英文互译

&#xff1a; 使用预训练模型时经常会涉及到中英文互译&#xff0c;总结一下方法 translate库 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple translate使用 #中文翻译成英文translator Translator(from_langchinese,to_langenglish)result translator.t…

Python基础第四篇(Python函数)

文章目录 一、函数介绍二、函数的定义三、函数的参数与返回值四、函数说明文档五、函数的嵌套六、变量域七、函数案例1.源代码2.读出结果 在程序设计领域&#xff0c;函数成为一个不可或缺的角色&#xff0c;它们为我们提供了精练、高效和易于管理的编程方式。本篇博客将带您深…

Win32 GetDeviceCaps 函数学习

GetDeviceCaps 函数检索指定设备的设备特定信息。 其第二个参数取不同的值,返回不同结果; void CdevcapView::OnDraw(CDC* pDC) {CdevcapDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// TODO: 在此处为本机数据添加绘制代码CString str1;int ret;ret =…

无人机航迹规划(四):七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划(提供MATLAB代码)

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁殖…

【JavaEE】_网络编程基础

目录 1. 网络编程基础 1.1 网络编程定义 1.2 网络编程中的基本概念 1.2.1 API 1.2.2.发送端和接收端 1.2.3 请求和响应 1.2.4 客户端和服务端 2. Socket 套接字 2.1 概念 2.2 分类 3. UDP数据报套接字编程 3.1 DatagramSocket API 3.1.1 含义 3.1.2 构造方法 3…

【C++记忆站】类和对象(一)

类和对象(一) 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间…

计算机:无所不在的角色与跨学科函数概念的生动探索

The Computer’s Ubiquitous Role and the Conceptual Underpinnings of Functions Across Disciplines: A Vivid Exploration 计算机&#xff1a;无所不在的角色与跨学科函数概念的生动探索 A computer is an extraordinary apparatus that has the remarkable ability to exe…

标准库--容器

1.vector (1). 支持的迭代器类别 为random_access_iterator_tag (2). 内存组织 逻辑上连续的元素&#xff0c;线性地址空间内也连续。 (3). 内存扩张和收缩 a. 初始化时会默认分配一块可容纳指定数量的线性地址空间。 b. 执行reserve(n)&#xff0c;在现有地址空间不足容纳n个元…

初识HarmonyOS

文章目录 本章节目标一、 HarmonyOS简介初识HarmonyOSHarmonyOS系统定位HarmonyOS典型应用场景 二、HarmonyOS架构与安全1. HarmonyOS架构解析内核层系统服务层框架层应用层应用服务智能分发 2. HarmonyOS系统安全正确的人正确的设备正确地使用数据 三、HarmonyOS关键特性1. 硬…

redis远程连接不上解决办法

问题描述&#xff1a; redis远程服务端运行在192.168.3.90计算机上&#xff0c;客户端计算机&#xff08;ip:192.168.3.110&#xff09;通过redsi-cli.exe客户端工具连接时&#xff0c;没有反应&#xff0c;连接不上。 如图所示&#xff1a; 解决步骤&#xff1a; 步骤一&…

OpenCV编译C++测试程序获取cuda设备信息

视频讲解 OpenCV编译C测试程序获取CUDA设备信息 测试代码 test-cv.cpp #include <opencv2/opencv.hpp> #include <opencv2/cudaimgproc.hpp> #include <iostream>using namespace cv; using namespace cv::cuda; using namespace std;int main(int argc, c…

计算机网络(第六版)复习提纲6

SS2.3 导引型传输媒体 1.三类位非导引型传输媒体 a)双绞线&#xff1a;两根铜线平行会相互干扰&#xff0c;垂直干扰最小&#xff0c;双绞线近似垂直&#xff0c;绞合度越高&#xff0c;可用的数据传输率越高。 i.无屏蔽双绞线UTP&#xff08;便宜&#xff09; ii.屏蔽双绞线&a…

USB-C接口给显示器带来怎样的变化?

随着科技的不断发展&#xff0c;Type-C接口已经成为现代电子设备中常见的接口标准。它不仅可以提供高速的数据传输&#xff0c;还可以实现快速充电和视频传输等功能。因此&#xff0c;使用Type-C接口的显示器方案也受到了广泛的关注。本文将介绍Type-C接口显示器的优势、应用场…

如何进行正确的 CodeReview

软件开发生命周期中至关重要的一步是代码审查。它使开发人员能够显著提升代码质量。它类似于书籍的创作过程。首先&#xff0c;作者写故事&#xff0c;然后经过编辑以确保不会出现诸如混淆“you’re”和“yours”之类的错误。在这个语境中&#xff0c;代码审查指的是检查和评估…