【Leetcode】805. Split Array With Same Average
创始人
2024-02-22 13:30:51
0

题目地址:

https://leetcode.com/problems/split-array-with-same-average/description/

给定一个长nnn数组AAA,A[i]≥0A[i]\ge 0A[i]≥0。问是否能将其划分为两个非空子集,使得两个子集的平均数相等。n≤30,A[i]≤104n\le 30, A[i]\le 10^4n≤30,A[i]≤104。

设划分的两个子集分别为B,CB,CB,C,则有∑B∣B∣=∑C∣C∣=∑B+∑C∣B∣+∣C∣=∑A∣A∣\frac{\sum B}{|B|}=\frac{\sum C}{|C|}=\frac{\sum B+\sum C}{|B|+|C|}=\frac{\sum A}{|A|}∣B∣∑B​=∣C∣∑C​=∣B∣+∣C∣∑B+∑C​=∣A∣∑A​而∑A∣A∣\frac{\sum A}{|A|}∣A∣∑A​与划分无关,所以我们其实就是要求是否存在一个子集,其平均值等于∑A∣A∣\frac{\sum A}{|A|}∣A∣∑A​。考虑新数组B[i]=A[i]−∑A∣A∣B[i]=A[i]-\frac{\sum A}{|A|}B[i]=A[i]−∣A∣∑A​,那么问题即转化为问BBB数组是否存在和为000的非平凡子集(非平凡的意思是不能为空,也不能为BBB自己)。为了避免处理浮点数,我们可以将BBB乘以一个系数,使其每个数都为整数。
这个是背包问题,通常来讲,这种题目可以用动态规划做,但此题的数据范围较为特殊,nnn较小,而A[i]A[i]A[i]的范围较大,如果用动态规划容易爆空间。可以考虑用双向DFS来做,参考https://blog.csdn.net/qq_46105170/article/details/115587834。具体思路是,我们先考虑前n/2n/2n/2个数,进行DFS,用哈希表存一下其所有子集的和以及每个子集的元素个数(这是为了排除掉平凡子集),如果前n/2n/2n/2个数就已经有非平凡子集和为000了,那就说明有解,可以提前结束;否则再暴力DFS后n/2n/2n/2个数的每个子集的和sss,看哈希表是否存在−s-s−s并且元素个数总和大于000小于nnn,如果是,则有解。暴力枚举完毕没发现解,则无解。代码如下:

class Solution {public:bool splitArraySameAverage(vector &A) {int sum = 0;for (int x : A) sum += x;int g = gcd(sum, A.size());int a = sum / g, b = A.size() / g;for (int &x : A) x = x * b - a;unordered_map mp;return dfs1(0, 0, 0, A, mp) || dfs2(A.size() / 2, 0, 0, A, mp);}bool dfs2(int u, int cnt, int sum, vector &A,unordered_map &mp) {auto it = mp.find(-sum);if (it != mp.end() && it->second + cnt && it->second + cnt < A.size())return true;for (int i = u; i < A.size(); i++)if (dfs2(i + 1, cnt + 1, sum + A[i], A, mp)) return true;return false;}// 统计前一半的数的每个子集的和以及元素个数bool dfs1(int u, int cnt, int sum, vector &A,unordered_map &mp) {if (!sum && cnt && cnt < A.size()) return true;auto it = mp.find(sum);if (it == mp.end() || it->second > cnt) mp[sum] = cnt;for (int i = u; i < A.size() / 2; i++)if (dfs1(i + 1, cnt + 1, sum + A[i], A, mp)) return true;return false;}int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
};

时间复杂度O(2n/2+1)O(2^{n/2+1})O(2n/2+1),空间O(2n/2)O(2^{n/2})O(2n/2)。

相关内容

热门资讯

猪八戒吃西瓜怎么改为夸张句 猪八戒吃西瓜怎么改为夸张句猪八戒张开了宇宙一般的血盆大口吞下了地球般大的西瓜
一个木一个羽念什么 一个木一个羽念什么    栩,读作xǔ。  栩 xǔ  〈名〉  形声。从木,羽声。亦称“杼”。本义...
赛尔号雷神天明闪怎么打 赛尔号雷神天明闪怎么打赛尔号中雷伊雷神天明闪建议使用特训后的雷伊打,现在打起来比较简单,带过地面石、...
古文言中有哪个字韵脚是“an”... 古文言中有哪个字韵脚是“an”而且有“用”的意思Ban:办,半,般,班,拌,搬,板,伴,瓣Can:蚕...
与长江三峡水电站相关的重要地理... 与长江三峡水电站相关的重要地理分界线是什么?第二阶梯与第一阶梯分界线因为这个地区海拔高度落差大,水的...
传奇的魔法神石怎么样获得? 传奇的魔法神石怎么样获得?魔法神石是在幽明领地的BOSS爆的说不定的``GM喜欢他在那里爆就在那里爆...
华谊公司旗下艺人有哪些优秀艺人... 华谊公司旗下艺人有哪些优秀艺人?华谊兄弟旗下的艺人多达四十多人,但有名的不是很多华谊旗下有很多很不错...
丁磊说大多数的中国学生不具备独... 丁磊说大多数的中国学生不具备独立思考能力,他为何这么说?是因为现在有很多的学生都非常依赖自己的父母,...
为何18岁男子脑死亡火化前妈妈... 为何18岁男子脑死亡火化前妈妈大喊别离开下一秒突然复活?我觉得应该是哪里出现了纰漏,这名男子并没有死...
关于宇宙的科普电影 关于宇宙的科普电影银河系漫游指南 绝对是是吧,《旅行到宇宙边缘》旅行到宇宙边缘
北京工商大学会计专业考研科目都... 北京工商大学会计专业考研科目都有什么?专业复习用书都用什么?初始考802管理学指定参考书是周三多《管...
作者为什么要写丁香结? 作者为什么要写丁香结?“丁香结”的本义是小小的花苞圆圆的,鼓鼓的,恰如衣襟上的盘花扣。象征意义是人生...
原核生物和真核生物的区别 原核生物和真核生物的区别真核有复杂的内膜系统(细胞器),原核生物无真核有细胞核,原核无成型的细胞核基...
怎样不吃药摆脱抑郁症 怎样不吃药摆脱抑郁症以前靠心理治疗,但是后面有一段时期加重了。但是药的副作用太大,可以不吃药吗?想开...
诺曼底登陆的作用和对二战的意义 诺曼底登陆的作用和对二战的意义改变了二战的战局,加快盟军胜利的到来。
怎么样才能学习学得“细”呢? 怎么样才能学习学得“细”呢?细是注意细节地方,平时做题多思考,尽量全面一些,不要学习时觉的理解了就完...
去年几滴相思水,化做树下种花泪... 去年几滴相思水,化做树下种花泪,谁家少年踏春来,折下枝头红玫瑰!这首诗的意思是什么?暗示爱意。指思念...
小花仙找主人! 小花仙找主人!我只要你帮我照顾花朵,每月一个礼物可以吗?我有额外条件:一个星期星期一,三,五一定要上...
手机在信号不好的时候 对方打不... 手机在信号不好的时候 对方打不进来 能设置来电转移吗rt 是否需要开通什么业务 怎么办理不需要去移...
与看透生死或看透人生有关的歌曲... 与看透生死或看透人生有关的歌曲 比如悟我觉得三国演义主题曲有一种世态苍爽的感觉 ,得意的笑 潇洒走...