2022-04-23:给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 集合 或者 B 集合中 使得 A 集合和 B 集合不为空,并且 average(A) == aver
2022-04-23:给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 集合 或者 B 集合中使得 A 集合和 B 集合不为空,并且 average(A) == average(B)如果可以完成则返回 true,否则返回 false。注意:对于数组 arr, average(arr) 是 arr 的所有元素的和除以 arr 长度。输入: nums = [1,2,3,4,5,6,7,8]。输出: true。
答案 2022-04-23:
- 定义全局变量 - n、- s、- l和- r,分别表示数组长度、数组元素之和、左侧集合的元素个数和右侧集合的元素个数。
- 定义两个数组 - lvalues和- rvalues,用于存储左侧集合和右侧集合的指标值。
- 编写函数 - splitArraySameAverage(nums []int) bool,其中- nums是输入的整数数组。首先检查数组长度是否为 1,如果是则返回 false。
- 计算数组元素之和 - s。
- 创建一个长度为 - n/2的切片- larr和一个长度为- n-len(larr)的切片- rarr,将前半部分元素存储在- larr中,将后半部分元素存储在- rarr中。
- 调用函数 - collect(larr, true)收集左侧集合的指标值,并调用函数- collect(rarr, false)收集右侧集合的指标值。
- 对右侧集合的指标值进行排序,以便进行二分查找。 
- 遍历左侧集合的指标值,在右侧集合中查找是否存在相反数,如果存在则说明可以分割成两个具有相同平均数的子集,返回 true;否则返回 false。 
- 编写函数 - collect(arr []int, isLeft bool),其中- arr是需要遍历的整数数组,- isLeft指示是否为左侧集合。在函数中调用递归函数- process(arr, 0, 0, 0, isLeft)。
- 编写函数 - process(arr []int, index int, sum int, num int, isLeft bool),其中- index表示当前处理的元素下标,- sum表示当前元素之和,- num表示当前元素个数。如果- index等于数组长度,则计算指标值并将其存储在- lvalues或- rvalues中。
- 对于每个元素,都有两种选择:不加入集合(包括左侧集合和右侧集合),或者加入集合并递归到下一个元素。因此,递归函数应该调用 - process(arr, index+1, sum, num, isLeft)和- process(arr, index+1, sum+arr[index], num+1, isLeft)这两个函数。
- 编写函数 - contains(num int) bool,其中- num是需要查找的元素。使用二分查找算法在- rvalues数组中查找相应的元素。
时间复杂度:
该算法的时间复杂度主要受到递归函数 process 对数组的遍历方式和左侧集合大小的约束,以及二分查找函数 contains 的时间复杂度的影响。
在 process 函数中,对于每个元素都有两种选择,因此共有  种可能的组合。对于每种组合,最坏情况下需要进行一个二分查找操作,因此 process 函数的时间复杂度为 。
在 contains 函数中,二分查找的时间复杂度为 。
因此,该算法的总时间复杂度为 。
空间复杂度:
该算法的空间复杂度主要受到存储左侧集合指标值的数组 lvalues 和存储右侧集合指标值的数组 rvalues 的影响。这两个数组的长度分别为  和 ,因此总空间复杂度为 。
此外,还需要定义一些全局变量和局部变量,它们的空间占用不会随着输入规模的增加而增加,因此可以忽略。
总的来说,该算法的空间复杂度为 。由于 的取值范围较小,因此该算法的空间复杂度是可以接受的。
golang 完整代码如下:
 
 rust 完整代码如下:
 
 版权声明: 本文为 InfoQ 作者【福大大架构师每日一题】的原创文章。
原文链接:【http://xie.infoq.cn/article/fd5e318bcf97de46d06b37ccf】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。











 
    
评论