将数组分成和相等的三个部分(简单难度)

简介: 将数组分成和相等的三个部分(简单难度)

题目概述(简单难度)

给你一个整数数组 arr,只有可以将其划分为三个和相等的 非空 部分时才返回 true,否则返回 false。


形式上,如果可以找出索引 i + 1 < j 且满足 (arr[0] + arr[1] + ... + arr[i] == arr[i + 1] + arr[i + 2] + ... + arr[j - 1] == arr[j] + arr[j + 1] + ... + arr[arr.length - 1]) 就可以将数组三等分。


附上leetcode链接:

点击此处进入leetcode

示例 1:

输入:arr = [0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1

示例 2:


输入:arr = [0,2,1,-6,6,7,9,-1,2,0,1]
输出:false


示例 3:


输入:arr = [3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5+ 1 - 9 + 4

思路与代码

思路展现

这个题目非常的经典,思路是这样的:

1:如果想要把一个数组分成三个部分,且这三个部分每个部分数字加起来的和还要相等,就意味着我们数组中所有数字加起来的和是必须可以被3取余的,如果不能被3取余,就意味着当取平均数target的时候是一个小数.

2:定义一个临时变量cur去记录我们每个部分的和,然后我们开始从头遍历我们的数组,当遍历到某个数组下标时,此时的cur的值等于我们的平均数target的时候,停止我们的遍历,此时代表我们第一部分已经划分完毕了,假设遍历到数组最后一个元素,我们变量cur的值还不等于target,就说明这个数组中不存在三个和相等的非空部分,直接返回false即可

3:欧克那么我们现在第一部分已经找到了,但这还远远不够,为什么呢?

原因是第二部分的和未必是等于target的,并且还有一种情况,就是即使第二部分和等于target,我们的第三部分也未必存在,所以还需要进行第三部分是否存在的判断,所以首先我们先从第一部分的最后一个元素的下一个元素作为我们第二部分遍历开始的地点,所以我们定义j=i+1,但是要注意这里的循环条件我们有一个小技巧在这里:首先我们需要明确的一点就是假设前两部分的和都等于target,且第三部分还存在,那么我们根本就不用判断第三部分的和是否等于target,因为它一定等于target.所以此处的循环条件我们可以设置为j+1

然后到了我们循环体的内部:我们退出循环的条件是当cur的值等于二倍的target的值的时候,return true,说明此时我们数组找到了第二部分,且第三部分存在.


代码示例

class Solution {
    public boolean canThreePartsEqualSum(int[] A) {
        int s = 0;
        //s代表所有数字的和
        for (int num : A) {
            s += num;
        }
        //取余3不等于0说明根本划分不成桑格和相等的非空部分.
        if (s % 3 != 0) {
            return false;
        }
        int target = s / 3;
        //cur代表当前数字的和
        int n = A.length, i = 0, cur = 0;
        while (i < n) {
            cur += A[i];
            if (cur == target) {
                break;
            }
            ++i;
        }
        //这块是第一块非空部分都没出现的情况,那么就直接return false即可
        if (cur != target) {
            return false;
        }
        //假设此时第一部分已经等于target,此时让下标指向第二部分的第一个元素
        int j = i + 1;
        // 需要满足最后一个数组非空,所以循环条件为j+1<n
        while (j + 1 < n) {  
            cur += A[j];
            //当数组元素加到第二部分最后一个元素的时候就进行判断
            if (cur == target * 2) {
                //如果前两部分所有的元素和等于两倍的target,返回true
                return true;
            }
            ++j;
        }
        return false;
    }
}

总结

对于数组的巧用,需要大家牢记:

时间复杂度:O(N),其中 N是数组 A 的长度。我们最多只需要遍历一遍数组就可以得到答案。

空间复杂度:O(1)。我们只需要使用额外的索引变量 i,j 以及一些存储数组信息的变量。



相关文章
|
数据采集 机器学习/深度学习 自然语言处理
nlp入门之基于贝叶斯算法的拼写错误检测器
基于贝叶斯思想简单的实现了一个拼写错误检测器
|
开发框架 前端开发 JavaScript
循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码
循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码
ChatGPT高效提问—prompt基础
ChatGPT高效提问—prompt基础
507 0
|
JavaScript JSON 前端开发
深/浅拷贝,有哪些实现方式
深/浅拷贝,有哪些实现方式
|
SQL 弹性计算 安全
通过阿里云的活动购买的云服务器,后续购买并挂载云盘、设置密码及安全组教程
现在大多数用户购买阿里云的云服务器通常都是通过阿里云的活动来购买,这种购买方式主要是价格更实惠,且购买流程简单,但是选购活动中的云服务器,一般只有系统盘,没有数据盘,这需要我们在购买之后单独购买并挂载云盘作为数据盘,而且云服务器的密码和安全组等基础设置也是需要在购买之后再设置的。本文为大家介绍后续购买并挂载云盘、设置密码及安全组的相关教程,以供参考。
通过阿里云的活动购买的云服务器,后续购买并挂载云盘、设置密码及安全组教程
|
网络协议 关系型数据库 Linux
PostGresql数据库Linux服务器安装
PostGresql数据库,Linux服务器,在线,离线安装
4455 2
PostGresql数据库Linux服务器安装
|
JavaScript
type和interface的异同?
type和interface的异同?
581 0
|
存储 SQL 缓存
PostgreSQL 内核解读系列 - 第4节 存储管理(下)
本文整理自阿里云数据库开源社区 Maintainer 于巍(花名漠雪),在PostgreSQL数据库内核解读系列的分享。本篇内容主要分为四个部分: 1. 磁盘管理 2. 空闲空间映射表(FSM) 3. 可见性映射表(VM) 4. 内存管理。
PostgreSQL 内核解读系列 - 第4节 存储管理(下)
|
编解码 前端开发 数据处理
前端基础向--从项目入手封装公共组件
前端基础向--从项目入手封装公共组件
469 0