2023-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:

  1. 定义全局变量 nslr,分别表示数组长度、数组元素之和、左侧集合的元素个数和右侧集合的元素个数。
  2. 定义两个数组 lvaluesrvalues,用于存储左侧集合和右侧集合的指标值。
  3. 编写函数 splitArraySameAverage(nums []int) bool,其中 nums 是输入的整数数组。首先检查数组长度是否为 1,如果是则返回 false。
  4. 计算数组元素之和 s
  5. 创建一个长度为 n/2 的切片 larr 和一个长度为 n-len(larr) 的切片 rarr,将前半部分元素存储在 larr 中,将后半部分元素存储在 rarr 中。
  6. 调用函数 collect(larr, true) 收集左侧集合的指标值,并调用函数 collect(rarr, false) 收集右侧集合的指标值。
  7. 对右侧集合的指标值进行排序,以便进行二分查找。
  8. 遍历左侧集合的指标值,在右侧集合中查找是否存在相反数,如果存在则说明可以分割成两个具有相同平均数的子集,返回 true;否则返回 false。
  9. 编写函数 collect(arr []int, isLeft bool),其中 arr 是需要遍历的整数数组,isLeft 指示是否为左侧集合。在函数中调用递归函数 process(arr, 0, 0, 0, isLeft)
  10. 编写函数 process(arr []int, index int, sum int, num int, isLeft bool),其中 index 表示当前处理的元素下标,sum 表示当前元素之和,num 表示当前元素个数。如果 index 等于数组长度,则计算指标值并将其存储在 lvaluesrvalues 中。
  11. 对于每个元素,都有两种选择:不加入集合(包括左侧集合和右侧集合),或者加入集合并递归到下一个元素。因此,递归函数应该调用 process(arr, index+1, sum, num, isLeft)process(arr, index+1, sum+arr[index], num+1, isLeft) 这两个函数。
  12. 编写函数 contains(num int) bool,其中 num 是需要查找的元素。使用二分查找算法在 rvalues 数组中查找相应的元素。

时间复杂度:

该算法的时间复杂度主要受到递归函数 process 对数组的遍历方式和左侧集合大小的约束,以及二分查找函数 contains 的时间复杂度的影响。

process 函数中,对于每个元素都有两种选择,因此共有

2

n

2^n

2n 种可能的组合。对于每种组合,最坏情况下需要进行一个二分查找操作,因此 process 函数的时间复杂度为

O

(

n

×

2

n

log

n

)

O(n\times 2^n \log n)

O(n×2nlogn)。

contains 函数中,二分查找的时间复杂度为

O

(

log

n

)

O(\log n)

O(logn)。

因此,该算法的总时间复杂度为

O

(

n

×

2

n

log

n

)

O(n\times 2^n \log n)

O(n×2nlogn)。

空间复杂度:

该算法的空间复杂度主要受到存储左侧集合指标值的数组 lvalues 和存储右侧集合指标值的数组 rvalues 的影响。这两个数组的长度分别为

2

n

/

2

2^{n/2}

2n/2 和

2

n

n

/

2

2^{n-n/2}

2n−n/2,因此总空间复杂度为

O

(

2

n

)

O(2^n)

O(2n)。

此外,还需要定义一些全局变量和局部变量,它们的空间占用不会随着输入规模的增加而增加,因此可以忽略。

总的来说,该算法的空间复杂度为

O

(

2

n

)

O(2^n)

O(2n)。由于

n

n

n 的取值范围较小,因此该算法的空间复杂度是可以接受的。

golang完整代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. "sort"
  5. )
  6. var (
  7. n int
  8. s int
  9. l int
  10. r int
  11. lvalues [1 << 15]int
  12. rvalues [1 << 15]int
  13. )
  14. func splitArraySameAverage(nums []int) bool {
  15. n = len(nums)
  16. if n == 1 {
  17. return false
  18. }
  19. s = 0
  20. for _, num := range nums {
  21. s += num
  22. }
  23. l = 0
  24. r = 0
  25. larr := make([]int, n/2)
  26. for i := 0; i < len(larr); i++ {
  27. larr[i] = nums[i]
  28. }
  29. rarr := make([]int, n-len(larr))
  30. for i := len(larr); i < len(nums); i++ {
  31. rarr[i-len(larr)] = nums[i]
  32. }
  33. // 左侧 : 收集指标的时候,不能一个数也没有
  34. collect(larr, true)
  35. // 右侧 : 收集指标的时候,不能所有数都用
  36. collect(rarr, false)
  37. sort.Ints(rvalues[:r])
  38. for i := 0; i < l; i++ {
  39. // 左侧x -x
  40. if contains(-lvalues[i]) {
  41. return true
  42. }
  43. }
  44. return false
  45. }
  46. func collect(arr []int, isLeft bool) {
  47. process(arr, 0, 0, 0, isLeft)
  48. }
  49. func process(arr []int, index int, sum int, num int, isLeft bool) {
  50. if index == len(arr) {
  51. if isLeft && num > 0 {
  52. lvalues[l] = s*num - n*sum
  53. l++
  54. }
  55. if !isLeft && num != len(arr) {
  56. rvalues[r] = s*num - n*sum
  57. r++
  58. }
  59. } else {
  60. process(arr, index+1, sum, num, isLeft)
  61. process(arr, index+1, sum+arr[index], num+1, isLeft)
  62. }
  63. }
  64. func contains(num int) bool {
  65. left := 0
  66. right := r - 1
  67. for left <= right {
  68. mid := (left + right) / 2
  69. if rvalues[mid] == num {
  70. return true
  71. } else if rvalues[mid] < num {
  72. left = mid + 1
  73. } else {
  74. right = mid - 1
  75. }
  76. }
  77. return false
  78. }
  79. func main() {
  80. nums := []int{1, 2, 3, 4, 5, 6, 7, 8}
  81. if splitArraySameAverage(nums) {
  82. fmt.Println("可以分割成两个具有相同平均数的子集")
  83. } else {
  84. fmt.Println("无法分割成两个具有相同平均数的子集")
  85. }
  86. }

rust完整代码如下:

  1. use std::cmp::Ordering;
  2. static mut L_VALUES: [i32; 1 << 15] = [0; 1 << 15];
  3. static mut R_VALUES: [i32; 1 << 15] = [0; 1 << 15];
  4. static mut N: i32 = 0;
  5. static mut S: i32 = 0;
  6. static mut L: i32 = 0;
  7. static mut R: i32 = 0;
  8. pub fn split_array_same_average(nums: Vec<i32>) -> bool {
  9. unsafe {
  10. N = nums.len() as i32;
  11. if N == 1 {
  12. return false;
  13. }
  14. S = nums.iter().sum();
  15. L = 0;
  16. R = 0;
  17. let mut larr = vec![0; N as usize / 2];
  18. for i in 0..larr.len() {
  19. larr[i] = nums[i];
  20. }
  21. let mut rarr = vec![0; N as usize - larr.len()];
  22. for i in larr.len()..nums.len() {
  23. rarr[i - larr.len()] = nums[i];
  24. }
  25. collect(&mut larr, 0, 0, 0, true);
  26. collect(&mut rarr, 0, 0, 0, false);
  27. let mut r_values = [0; 1 << 15];
  28. for i in 0..R {
  29. r_values[i as usize] = R_VALUES[i as usize];
  30. }
  31. r_values.sort_unstable();
  32. for i in 0..L {
  33. if contains(-L_VALUES[i as usize], &r_values) {
  34. return true;
  35. }
  36. }
  37. false
  38. }
  39. }
  40. fn collect(arr: &mut [i32], index: usize, sum: i32, num: i32, is_left: bool) {
  41. unsafe {
  42. if index == arr.len() {
  43. if is_left && num > 0 {
  44. L_VALUES[L as usize] = S * num - N * sum;
  45. L += 1;
  46. }
  47. if !is_left && num != arr.len() as i32 {
  48. R_VALUES[R as usize] = S * num - N * sum;
  49. R += 1;
  50. }
  51. } else {
  52. collect(arr, index + 1, sum, num, is_left);
  53. collect(arr, index + 1, sum + arr[index], num + 1, is_left);
  54. }
  55. }
  56. }
  57. fn contains(num: i32, r_values: &[i32]) -> bool {
  58. let mut left = 0;
  59. let mut right = r_values.len() - 1;
  60. while left <= right {
  61. let mid = (left + right) / 2;
  62. match r_values[mid].cmp(&num) {
  63. Ordering::Equal => return true,
  64. Ordering::Less => left = mid + 1,
  65. Ordering::Greater => right = mid - 1,
  66. }
  67. }
  68. false
  69. }
  70. fn main() {
  71. let nums = vec![1, 2, 3, 4, 5, 6, 7, 8];
  72. let result = split_array_same_average(nums);
  73. println!("{}", result);
  74. }

2023-04-23:给定你一个整数数组 nums 我们要将 nums 数组中的每个元素移动到 A 集合 或者 B 集合中 使得 A 集合和 B 集合不为空,并且 average(A) == aver的更多相关文章

  1. LeetCode 周赛 342(2023/04/23)容斥原理、计数排序、滑动窗口、子数组 GCB

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,我是小彭. 前天刚举办 2023 年力扣杯个人 SOLO 赛,昨天周赛就出了一场 Easy - Ea ...

  2. 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。

    /** * 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标. * * 你可以假设每种输入只会对应一个答案.但是,数组中 ...

  3. 整数数组的定义,然后输入一个整数X,假定X不在这个数组,返回小于X位置的最大数目i而超过X位置的最小数目j

    //整数数组的定义,然后输入一个整数x,假定X不在这个数组,返回小于X位置的最大数目i而超过X位置的最小数目j: //如果X在该阵列,返回位置的阵列中的数. 资源: #include<iostr ...

  4. 【spring set注入 注入集合】 使用set注入的方式注入List集合和Map集合/将一个bean注入另一个Bean

    Dao层代码: package com.it.dao; public interface SayHell { public void sayHello(); } Dao的Impl实现层: packag ...

  5. LeetCode竞赛题:K 次取反后最大化的数组和(给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。)

    给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次.(我们可以多次选择同一个索引 i.) 以这种方式修改数组后 ...

  6. 9.11排序与查找(三)——给定一个排序后的数组,包括n个整数,但这个数组已被旋转过多次,找出数组中的某个元素

    /**  * 功能:给定一个排序后的数组.包括n个整数.但这个数组已被旋转过多次,次数不详.找出数组中的某个元素.  * 能够假定数组元素原先是按从小到大的顺序排列的.  */ /** * 思路:数组 ...

  7. 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target。

    描述 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是 0 到 n-1. ...

  8. 作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)

    题目描述 给定一个整数数组,找出其中两个数相加等于目标值 输入 [1,3,5,7,9,11] 10 输出 1,9 3,7 代码: import java.util.HashMap; import ja ...

  9. 刷题之给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数

    今天下午,看了一会github,想刷个题呢,就翻出来了刷点题提高自己的实际中的解决问题的能力,在面试的过程中,我们发现,其实很多时候,面试官 给我们的题,其实也是有一定的随机性的,所以我们要多刷更多的 ...

  10. 给定一个整数数组 nums 和一个目标值 target,求nums和为target的两个数的下表

    这个是来自力扣上的一道c++算法题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案 ...

随机推荐

  1. windows代码获取系统硬件信息的两种方式

    欢迎访问我的个人博客:xie-kang.com 原文地址 目前windows有两种方式获取系统硬件信息: 1)通过GetSystemFirmwareTable API获取SMBIOS信息,一段含丰富信 ...

  2. XSS(Cross-site Scripting)-跨站脚本

    XSS介绍 XSS 是基于 JavaScript 的,因此对该语言有基本的了解会很有帮助.了解XSS需要对客户端-服务器请求和响应有基本的了解 跨站点脚本,在网络安全社区中更广为人知的是 XSS,被归 ...

  3. Javaweb学习笔记第六弹

    本章节的存在意义是:学到PreparedStatement反应较慢,理解不透彻,来做个比较,加深印象 详细讲述PrepareStatement 与 Statement 连接数据库的部分区别 在我学习的 ...

  4. springboot--配置格式文件

    修改端口号的三种方法 1.server.port = 80 2.新建application.yml文件. 3.新建application.yaml文件. 配置文件加载顺序: 当三个文件都存在时prop ...

  5. 你需要知道的 14 个常用的 JavaScript 函数

    1.确定任意对象的具体类型 众所周知,JavaScript 中有六种原始数据类型(Boolean.Number.String.Null.Undefined.Symbol)和一个对象数据类型.但是你知道 ...

  6. java顺序结构

    java顺序结构 java的基本结构就是顺序结构,一句一句执行 package charpter2; public class ShunXu { public static void main(Str ...

  7. Centos 7 配置Tomcat跳转Https

    前言:在网络安全盛行的时代下,有时业务为了安全需求要使用https协议,包括http.nginx.tomcat等,本篇简单分享一下tomcat跳转https配置. 1.环境 Centos 7.9 2. ...

  8. node.js解决跨域方案

    服务端 1.通过使用cors模块解决跨域问题 var express = require('express') , cors = require('cors') , app = express(); ...

  9. opengl helloworld vscode 通过glfw 绘制三角形

    opengl helloworld vscode 调用glfw 绘制三角形 目录 opengl helloworld vscode 调用glfw 绘制三角形 打开 glfw.org, 我下的64 目录 ...

  10. [Web服务容器/Apache Tomcat]WINDOWS系统下:一台机器部署多个[解压版]Tomcat

    以windows为例. 1 思路 1.1 前置条件 已成功配置JDK (JAVA_HOME / Path) 控制面板>所有控制面板项>系统>高级系统设置>系统变量(S): JA ...