2023-12-20:用go语言,给定一个数组arr,长度为n,在其中要选两个不相交的子数组。

两个子数组的累加和都要是T,返回所有满足情况中,两个子数组长度之和最小是多少?

如果没有有效方法,返回-1。

正式 :

2 <= n <= 10^6

0 <= arr[i] <= 10000

1 <= T <= 10^8

扩展 :

2 <= n <= 10^6

-10000 <= arr[i] <= 10000

1 <= T <= 10^8

都能时间复杂度做到O(N)。

来自字节。

答案2023-12-20:

来自左程云

灵捷3.5

大体步骤如下:

Algorithm 1: minLenBothT1

1.初始化数组arr的累加和数组sum,并计算arr的累加和。

2.初始化变量ans为一个较大的整数。

3.使用四重循环遍历所有可能的起始和结束索引组合(a, b, c, d)。

4.检查子数组[a, b]和[c, d]的累加和是否等于目标值T。

5.如果满足条件,则更新ans为两个子数组长度之和的最小值。

6.如果ans的值没有被更新过,则返回-1,否则返回ans。

Algorithm 2: minLenBothT2

1.初始化变量ans为一个较大的整数。

2.遍历数组arr,寻找和为0的连续子数组,记录其长度为cnt。

3.如果cnt大于等于2,则返回2作为结果。

4.对于每个起始索引l,从右侧扩展子数组的结束索引r,使得子数组的和尽量接近目标值T。

5.记录满足和为T的子数组的最小长度到right[l]数组中。

6.从右到左遍历数组arr,对于每个结束索引r,从左侧缩小子数组的起始索引l,使得子数组的和尽量接近目标值T。

7.如果和为T且right[r+1]不是无穷大,则更新ans为当前长度+r-l+right[r+1]的最小值。

8.如果ans的值没有被更新过,则返回-1,否则返回ans。

Algorithm 3: minLenBothT3

1.初始化变量ans为一个较大的整数。

2.构建累加和出现次数的映射表sums,初始时将0的索引设置为-1。

3.构建左侧最小长度的数组left,初始时将所有元素设置为一个较大的整数。

4.遍历数组arr,计算累加和sum,并检查sum-t在sums中是否存在。

5.如果存在,则更新左侧最小长度left[i]为当前索引i与sums[sum-t]之差。

6.更新sums[sum]为当前索引i。

7.从左到右遍历left数组,将每个位置的值更新为其与前一个位置的较小值。

8.清空sums映射表,并将0的索引设置为数组arr的长度。

9.从右到左遍历数组arr,计算累加和sum,并检查sum-t在sums中是否存在且左侧最小长度left[i-1]不是一个较大的整数。

10.如果满足条件,则更新ans为当前长度+sums[sum-t]-i的最小值。

11.更新sums[sum]为当前索引i。

12.如果ans的值没有被更新过,则返回-1,否则返回ans。

Algorithm 1:

  • 时间复杂度:O(n^4)

  • 空间复杂度:O(n)

Algorithm 2:

  • 时间复杂度:O(n)

  • 空间复杂度:O(n)

Algorithm 3:

  • 时间复杂度:O(n)

  • 空间复杂度:O(n)

go语言完整代码如下:

package main

import (
"fmt"
"math"
"math/rand"
"time"
) func minLenBothT1(arr []int, t int) int {
n := len(arr)
sum := make([]int, n)
sum[0] = arr[0]
for i := 1; i < n; i++ {
sum[i] = sum[i-1] + arr[i]
}
ans := math.MaxInt32
for a := 0; a < n-1; a++ {
for b := a; b < n-1; b++ {
for c := b + 1; c < n; c++ {
for d := c; d < n; d++ {
if sum1(a, b, sum) == t && sum1(c, d, sum) == t {
ans = min(ans, b+d-a-c+2)
}
}
}
}
}
if ans == math.MaxInt32 {
return -1
}
return ans
} func sum1(l, r int, sum []int) int {
if l == 0 {
return sum[r]
}
return sum[r] - sum[l-1]
} func minLenBothT2(arr []int, t int) int {
n := len(arr)
if t < 0 {
return -1
}
if t == 0 {
cnt := 0
for _, num := range arr {
if num == 0 {
cnt++
}
}
if cnt >= 2 {
return 2
}
return -1
}
right := make([]int, n)
for i := 0; i < n; i++ {
right[i] = math.MaxInt32
}
for l, r, sum := 1, 1, 0; l < n; l++ {
r = max(r, l)
for r < n && sum < t {
sum += arr[r]
r++
}
if sum == t {
right[l] = r - l
}
sum -= arr[l]
}
for i := n - 2; i >= 0; i-- {
right[i] = min(right[i], right[i+1])
}
ans := math.MaxInt32
for r, l, sum := n-2, n-2, 0; r >= 0; r-- {
l = min(l, r)
for l >= 0 && sum < t {
sum += arr[l]
l--
}
if sum == t && right[r+1] != math.MaxInt32 {
ans = min(ans, r-l+right[r+1])
}
sum -= arr[r]
}
if ans == math.MaxInt32 {
return -1
}
return ans
} func minLenBothT3(arr []int, t int) int {
n := len(arr)
sums := make(map[int]int)
sums[0] = -1
left := make([]int, n)
for i := 0; i < n; i++ {
left[i] = math.MaxInt32
}
for i, sum := 0, 0; i < n-1; i++ {
sum += arr[i]
if l, found := sums[sum-t]; found {
left[i] = i - l
}
sums[sum] = i
}
for i := 1; i < n-1; i++ {
left[i] = min(left[i-1], left[i])
}
ans := math.MaxInt32
sums = make(map[int]int)
sums[0] = n
for i, sum := n-1, 0; i >= 1; i-- {
sum += arr[i]
if _, found := sums[sum-t]; found && left[i-1] != math.MaxInt32 {
ans = min(ans, left[i-1]+sums[sum-t]-i)
}
sums[sum] = i
}
if ans == math.MaxInt32 {
return -1
}
return ans
} func min(a, b int) int {
if a < b {
return a
}
return b
} func max(a, b int) int {
if a > b {
return a
}
return b
} func randomArray1(n, v int) []int {
arr := make([]int, n)
for i := 0; i < n; i++ {
arr[i] = rand.Intn(v + 1)
}
return arr
} func randomArray2(n, v int) []int {
arr := make([]int, n)
for i := 0; i < n; i++ {
arr[i] = rand.Intn(2*v+1) - v
}
return arr
} func main() {
rand.Seed(time.Now().UnixMicro())
N := 100
V := 100
T := 100
testTimes := 10000
fmt.Println("正式方法测试开始")
for i := 0; i < testTimes; i++ {
n := rand.Intn(N) + 2
v := rand.Intn(V) + 1
arr := randomArray1(n, v)
t := rand.Intn(T)
ans1 := minLenBothT1(arr, t)
ans2 := minLenBothT2(arr, t)
if ans1 != ans2 {
fmt.Println("出错了!")
}
}
fmt.Println("正式方法测试结束") fmt.Println("扩展方法测试开始")
for i := 0; i < testTimes; i++ {
n := rand.Intn(N) + 2
v := rand.Intn(V) + 1
arr := randomArray2(n, v)
t := rand.Intn(T)
ans1 := minLenBothT1(arr, t)
ans3 := minLenBothT3(arr, t)
if ans1 != ans3 {
fmt.Println("出错了!")
}
}
fmt.Println("扩展方法测试结束")
}

2023-12-20:用go语言,给定一个数组arr,长度为n,在其中要选两个不相交的子数组。 两个子数组的累加和都要是T,返回所有满足情况中,两个子数组长度之和最小是多少? 如果没有有效方法,返回-的更多相关文章

  1. 给定一个递增序列,a1 <a2 <...<an 。定义这个序列的最大间隔为d=max{ai+1 - ai }(1≤i<n),现在要从a2 ,a3 ..an-1 中删除一个元素。问剩余序列的最大间隔最小是多少?

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...

  2. jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?

    1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自 ...

  3. EF Core 中DbContext不会跟踪聚合方法和Join方法返回的结果,及FromSql方法使用讲解

    EF Core中: 如果调用Queryable.Count等聚合方法,不会导致DbContext跟踪(track)任何实体. 此外调用Queryable.Join方法返回的匿名类型也不会被DbCont ...

  4. 了解PHP中的Array数组和foreach

    1. 了解数组 PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.详细的解释可参见:PHP.net中的Array数组    . 2.例子:一般的数组 这里,我 ...

  5. Spring MVC的方法返回值和参数传递

    1. SpringMVC方法的返回值类型 3.1String类作为返回值 3.1.1Controller层 /** * 返回值类型为String时,一般用于返回视图名称 * 1.当方法返回值为null ...

  6. 给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)

    """ #给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 #返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况) 解题思路: 1.设定一个 ...

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

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

  8. Gym 101064 D Black Hills golden jewels 【二分套二分/给定一个序列,从序列中任意取两个数形成一个和,两个数不可相同,要求求出第k小的组合】

    D. Black Hills golden jewels time limit per test 2 seconds memory limit per test 256 megabytes input ...

  9. 求数组中两两相加等于20的组合(Python实现)

    题目 求数组中两两相加等于20的组合. 例:给定一个数组[1, 7, 17, 2, 6, 3, 14],这个数组中满足条件的有两对:17+3=20, 6+14=20. 解析 分为两个步骤: 先采用堆排 ...

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

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

随机推荐

  1. defined('BASEPATH') OR exit('No direct script access allowed'); 的作用

    起到保护.php文件的作用, 如果直接访问此php文件会得到"不允许直接访问脚本"的错误提示 如果你是用ci框架或者其他的什么, 就建议加上, 如果你怕别人恶意攻击你的话

  2. 关于关闭Sublime Text自动更新提示

    Sublime Text默认提示自动更新,实在让人烦不胜烦,那么有没有办法解决嘞,那当然是有的,下面就教你如何关闭Sublime Text自动更新提示 首先注册,不注册的话,一切操作都没有用:(注册码 ...

  3. 小札 Combinatorics & Inclusion-Exclusion Principle 1

    「codeforces - 340E」Iahub and Permutations link. 把 \(1,\dots,n\) 中剩下没被固定的数的数量记作 \(s\),再把这其中不担心有会填到自己身 ...

  4. umich cv-1

    UMICH CV Image Classification---KNN 在本节课中,首先justin老师为我们介绍了图像分类了基础概念以及其用途,这里就不多涉及了 接着我们思考图像分类问题,如果我们想 ...

  5. Go结构体深度探索:从基础到应用

    在Go语言中,结构体是核心的数据组织工具,提供了灵活的手段来处理复杂数据.本文深入探讨了结构体的定义.类型.字面量表示和使用方法,旨在为读者呈现Go结构体的全面视角.通过结构体,开发者可以实现更加模块 ...

  6. C++类内存分布+ Studio工具

    书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 工欲善其事,必先利其器,我们先用好Visual Stu ...

  7. Go语言系列——01-HelloWorld、02-命名规范、03-变量、04-类型、05-常量、06-函数(Function)、07-包、08-if-else语句、09-循环、10-switch语句

    文章目录 01-HelloWorld 一 建立 Go 工作区 二 运行 Go 程序 2.1 hello world 程序代码介绍 02-开发环境搭建 一 下载地址 二 安装 Linux安装 Windo ...

  8. 文心一言 VS 讯飞星火 VS chatgpt (118)-- 算法导论10.3 3题

    三.用go语言,在ALLOCATE-OBJECT和 FREE-OBJECT过程的实现中,为什么不需要设置或重置对象的 prev 属性呢? 文心一言: 在 Go 语言中,ALLOCATE-OBJECT ...

  9. Redis主从复制部署小结

    Redis主从 搭建主从架构 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离. 主从数据同步原理 全量同步 主从第一次建立连接时,会执行全量同 ...

  10. 虹科干货|Redis企业版数据库为企业「数据安全」叠加最强Buff!

    "这是一场可预见的噩梦!" 近期,黑客通过攻击亚洲最大两家数据中心-万国数据和新科电信媒体,获取国际巨头企业的登录凭证,引发了2000多家企业史诗级数据泄露.中国作为全球第二大托管 ...