来源:力扣(LeetCode)

描述:

给定一个由 01 组成的数组 arr ,将数组分成 3 个非空的部分 ,使得所有这些部分表示相同的二进制值。

如果可以做到,请返回任何 [i, j],其中 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] 为第三部分。

  • 这三个部分所表示的二进制值相等。

如果无法做到,就返回 [-1, -1]

注意,在考虑每个部分所表示的二进制时,应当将其看作一个整体。例如,[1,1,0] 表示十进制中的 6,而不会是 3。此外,前导零也是被允许的,所以 [0,1,1][1,1] 表示相同的值。

示例 1:

输入:arr = [1,0,1,0,1]
输出:[0,3]

示例 2:

输入:arr = [1,1,0,1,1]
输出:[-1,-1]

示例 3:

输入:arr = [1,1,0,0,1]
输出:[0,2]

提示:

  • 3 <= arr.length <= 3 * 104
  • arr[i] 是 0 或 1

方法 :将 1 的数量三等分

思路与算法

  如果存在一种分法使得三个非空部分所表示的二进制值相同,那么最终每一部分 1 的数量一定是相等的。根据这个思想,我们首先统计数组 arr 中 1 的个数,把它设为 sum。如果 sum 不能被 3 整除,那么显然不存在正确分法。否则,每一个部分都应当有 partial = sum / 3 个 1。

  我们尝试找到 arr 中第 1 个 1 出现的位置 first,第 partial + 1 个 1 出现的位置 second 以及第 2 × partial + 1 个 1 出现的位置 third。因为每一部分末尾的 0 可以移动到下一部分的首部从而改变二进制值的大小, 所以每一部分的末尾难以界定。但是注意到,数组的末尾是无法改变的,因此区间 [third, arr.length − 1] 所表示的二进制值可以固定。

  设 len = arr.length − third,表示二进制值的长度。接下来只需要判断 [first, first + len)、 [second, second + len) 和 [third, third + len) 是否完全相同即可。前提是 first + len ≤ second 并且 second + len ≤ third。

  如果以上三段区间是完全相同的,那么答案就是 [first + len − 1, second + len]。最后需要注意到,如果 sum = 0,我们需要直接返回答案 [0, 2](或者其他任意合法答案)。

代码:

class Solution {public:vector<int> threeEqualParts(vector<int>& arr) {int sum = accumulate(arr.begin(), arr.end(), 0);if (sum % 3 != 0) {return {-1, -1};}if (sum == 0) {return {0, 2};}int partial = sum / 3;int first = 0, second = 0, third = 0, cur = 0;for (int i = 0; i < arr.size(); i++) {if (arr[i] == 1) {if (cur == 0) {first = i;}else if (cur == partial) {second = i;}else if (cur == 2 * partial) {third = i;}cur++;}}int len = (int)arr.size() - third;if (first + len <= second && second + len <= third) {int i = 0;while (third + i < arr.size()) {if (arr[first + i] != arr[second + i] || arr[first + i] != arr[third + i]) {return {-1, -1};}i++;}return {first + len - 1, second + len};}return {-1, -1};}
};

执行用时:24 ms, 在所有 C++ 提交中击败了98.26%的用户
内存消耗:37.9 MB, 在所有 C++ 提交中击败了79.86%的用户
复杂度分析
时间复杂度: O(n),其中 n 是 arr 的长度。找到三个下标的时间复杂度为 O(n),判断三个部分是否相同的时间复杂度也是 O(n)。
空间复杂度: O(1),只用到常数个变量空间。
author:LeetCode-Solution

【927. 三等分】相关推荐

  1. LeetCode每日一题——927. 三等分

    LeetCode每日一题系列 题目:927. 三等分 难度:困难 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 给定一个由 0 和 1 组成的数组 arr ,将数组分成 3 个 ...

  2. LeetCode每日一题:927. 三等分 (困难) 数组 数学

    题目:力扣 给定一个由 0 和 1 组成的数组 arr ,将数组分成  3 个非空的部分 ,使得所有这些部分表示相同的二进制值. 如果可以做到,请返回任何 [i, j],其中 i+1 < j,这 ...

  3. leetcode 927. Three Equal Parts | 927. 三等分(Java)

    题目 https://leetcode.com/problems/three-equal-parts/ 题解 不知道为什么是 hard,感觉这道题没有套路(印象中这几道 hard 都没有什么套路,这就 ...

  4. 如何学好C语言--你的学渣朋友告诉你

    光说不练假把式,光练不说傻把式,又练又说真把式. 真实感受,不是我不想学,是我真的不知道我哪里不会啊和得怎么做啊?本文作者当初就是这么废掉的 推荐两个练习的网站 (一)C语言网 https://www ...

  5. LeetCode题解汇总

    题目 推荐指数 1. 两数之和 1 2. 两数相加 1 4. 寻找两个正序数组的中位数 2AAAA 6. Z 字形变换 1 7. 整数反转 2 8. 字符串转换整数 (atoi) 2AAA 9. 回文 ...

  6. 算法学习-数组的相关操作,简单的数据结构逆天的难度,扮猪吃老虎(持续更新中)

    文章目录 相关知识 Java中Arrays常用api 相关题目 26.删除有序数组中的重复项 80.删除有序数组中的重复项II 66.加一 75.颜色分类 268.丢失的数字 448.找到所有数组中消 ...

  7. leetcode 转载

    转载: https://blog.csdn.net/love905661433/article/details/84980135 LeetCode 1- 100 1. 两数之和 : https://b ...

  8. 字节跳动2021年4月面试算法题库

    本文汇总了牛客2021.4.1~2021.4.30 面经考到的Leetcode题目 最终的高频题榜单数据可以在CodeTop题库(https://codetop.cc)查询,支持按部门.岗位分类筛选. ...

  9. 【Leetcode】每日一题打卡(64)

    1619. 删除某些元素后的数组均值 - 简单ac class Solution { public:double trimMean(vector<int>& arr) {sort( ...

最新文章

  1. python的基础网络编程是下列_Python基础(六)网络编程
  2. htmlunit爬虫工具使用--模拟浏览器发送请求,获取JS动态生成的页面内容
  3. 跳表(SkipList)设计与实现(java)
  4. fmt.Println、fmt.Printf、fmt.Sprintf、fmt.Sprintln
  5. Soring冲刺计划第三天(个人)
  6. SFB 项目经验-02-共存迁移-Lync 2013-TO-SFB 2015-规划02
  7. C#循环给多个控件赋值
  8. 01-hibernate注解:类级别注解,@Entity,@Table,@Embeddable
  9. java执行数学表达式_数学表达式解析-JAVA版
  10. Webpack入门教程二
  11. Ubuntu学习日记--Lesson10:gcc、make、makefile、cmake、cmakelists区别
  12. kafka传数据到Flink存储到mysql之Flink使用SQL语句聚合数据流(设置时间窗口,EventTime)...
  13. 2022级sdut知到/智慧树---c语言第一章测试题解
  14. 苹果7系统更新12无服务器,别再为苹果手机无法更新系统犯难,这几种方式帮你解决!...
  15. 树莓派引脚介绍与GPIO的初步认识与应用
  16. Visio中画各种线条与箭头
  17. 学计算机应用技术买什么笔记本电脑,大学什么专业用电脑 要不要买电脑
  18. JavaScript数组扁平化
  19. 基于JAVA家电售后管理系统计算机毕业设计源码+数据库+lw文档+系统+部署
  20. 如何改变视频的MD5值?一分钟让你学会操作

热门文章

  1. go语言进行web开发之安装iris框架
  2. 计算机网络练习题(应用层)
  3. ad 2008文件服务器搭建教程,Windows Server 2016 AD服务器搭建的步骤(图文)
  4. allegro学习之总结pcb设计流程
  5. linux虚拟机无法关闭防火墙
  6. 使用Apache poi 导出excel含有柱状图
  7. 基于qt和opencv实现人脸识别打卡系统
  8. 数据库与身份认证——黑马课程笔记
  9. 标准型计算机用户怎么改成管理员,Win10系统将标准用户更改为管理员的技巧
  10. python 残差网络--ResNeXt (附python代码)