前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021-08-28:给定一个正数数组arr,长度一定大于6(>=7),一定要选3个数字做分割点,从而分出4个部分,并且每部分都

2021-08-28:给定一个正数数组arr,长度一定大于6(>=7),一定要选3个数字做分割点,从而分出4个部分,并且每部分都

作者头像
福大大架构师每日一题
发布2021-09-03 15:26:14
1890
发布2021-09-03 15:26:14
举报

2021-08-28:给定一个正数数组arr,长度一定大于6(>=7),一定要选3个数字做分割点,从而分出4个部分,并且每部分都有数,分割点的数字直接删除,不属于任何4个部分中的任何一个。返回有没有可能分出的4个部分累加和一样大,如:{3,2,3,7,4,4,3,1,1,6,7,1,5,2},可以分成{3,2,3}、{4,4}、{1,1,6}、{1,5,2}。分割点是不算的!

福大大 答案2021-08-28:

前缀和存map。i位置作为第1刀。

时间复杂度:O(N)。

空间复杂度:O(N)。

代码用golang编写。代码如下:

代码语言:javascript
复制
package main

import "fmt"

func main() {
    arr := []int{1, 2, 1, 2, 1, 2, 1}
    ret := canSplits2(arr)
    fmt.Println(ret)
}

func canSplits2(arr []int) bool {
    if len(arr) < 7 {
        return false
    }
    // key 某一个累加和, value出现的位置
    map0 := make(map[int]int)
    sum := arr[0]
    for i := 1; i < len(arr); i++ {
        map0[sum] = i
        sum += arr[i]
    }
    lsum := arr[0]                       // 第一刀左侧的累加和
    for s1 := 1; s1 < len(arr)-5; s1++ { // s1是第一刀的位置
        checkSum := lsum*2 + arr[s1] // 100 x 100   100*2 + x
        if _, ok := map0[checkSum]; ok {
            s2 := map0[checkSum] // j -> y
            checkSum += lsum + arr[s2]
            if _, ok := map0[checkSum]; ok { // 100 * 3 + x + y
                s3 := map0[checkSum] // k -> z
                if checkSum+arr[s3]+lsum == sum {
                    return true
                }
            }
        }
        lsum += arr[s1]
    }
    return false
}

执行结果如下:

***

[左神java代码](https://github.com/algorithmzuo/coding-for-great-offer/blob/main/src/class24/Code01_Split4Parts.java)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档