每日算法系列【LeetCode 927】三等分
题目描述
给定一个由 0 和 1 组成的数组 A,将数组分成 3 个非空的部分,使得所有这些部分表示相同的二进制值。
如果可以做到,请返回任何 [i, j],其中 i+1 < j,这样一来:
- A[0], A[1], ..., A[i] 组成第一部分;
- A[i+1], A[i+2], ..., A[j-1] 作为第二部分;
- A[j], A[j+1], ..., A[A.length - 1] 是第三部分。
- 这三个部分所表示的二进制值相等。
如果无法做到,就返回 [-1, -1]。
注意,在考虑每个部分所表示的二进制时,应当将其看作一个整体。例如,[1,1,0] 表示十进制中的 6,而不会是 3。此外,前导零也是被允许的,所以 [0,1,1] 和 [1,1] 表示相同的值。
示例1
输入:
[1,0,1,0,1]
输出:
[0,3]
示例2
输入:
[1,1,0,1,1]
输出:
[-1,-1]
提示
- 3 <= A.length <= 30000
- A[i] == 0 或 A[i] == 1
题解
这题虽然名义上是个难题,其实基本没有用到什么算法,只是代码实现上略微繁琐了一点。
想象如果这个数组能分成三个子数组,每个子数组表示的数字都相同,那么首先每个子数组中 1 的数量一定要相等!
所以我们先统计 1 的数量,如果它不是 3 的倍数,那么一定不存在划分方式,直接返回无解就行了。如果数量是 0 ,就说明数组全 0 ,那么随便划分都是合理的,任意返回就行了。
接下来将 1 的数量等分为 3 份 ,然后遍历数组,找出 3 个子数组的左右边界(注意这个边界表示的是每个子数组第一个 1 和最后一个 1 的位置)。这时候还没结束,因为最后一个子数组末尾会多出来很多 0 。所以我们需要在前两个子数组后面加上等量的 0 。
最后遍历一遍三个子数组,判断是否完全相等就行了。
听起来是很简单,代码实现的时候还是有几个小细节的。比如求边界的时候,可以利用求余操作,保存到两个数组里,这样写起来美观方便。
代码
c++
class Solution {public:vector<int> threeEqualParts(vector<int>& A) {int n = A.size();int cnt1 = accumulate(A.begin(), A.end(), 0);if (cnt1 % 3) return {-1, -1};if (!cnt1) return {0, 2};cnt1 /= 3;int cnt = 0, l[3], r[3];for (int i = 0; i < n; ++i) {if (!A[i]) continue;cnt++;if ((cnt-1)%cnt1 == 0) l[(cnt-1)/cnt1] = i;if (cnt%cnt1 == 0) r[(cnt-1)/cnt1] = i;}for (int i = 0; i < 3; ++i) {r[i] += n - 1 - r[2];}for (int i = 0; i <= r[0]-l[0]; ++i) {if (A[l[1]+i] != A[l[0]+i] || A[l[2]+i] != A[l[0]+i])return {-1, -1};}return {r[0], r[1]+1};}
};
python
class Solution:def threeEqualParts(self, A: List[int]) -> List[int]:n = len(A)cnt1 = sum(A)if cnt1%3 != 0:return [-1, -1]if cnt1 == 0:return [0, 2]cnt1 //= 3cnt = 0l, r = [0]*3, [0]*3for i in range(n):if A[i] == 0:continuecnt += 1if (cnt-1)%cnt1 == 0:l[(cnt-1)//cnt1] = iif cnt%cnt1 == 0:r[(cnt-1)//cnt1] = ifor i in range(3):r[i] += n - 1 - r[2]if A[l[1]:r[1]+1] != A[l[0]:r[0]+1] or A[l[2]:r[2]+1] != A[l[0]:r[0]+1]:return [-1, -1]return [r[0], r[1]+1]
每日算法系列【LeetCode 927】三等分相关推荐
- 重复次数最多的 子串_每日算法系列【LeetCode 424】替换后的最长重复字符
题目描述 给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度. 示例1 输入: s = &quo ...
- 求栈中元素个数算法_每日算法系列【LeetCode 315】计算右侧小于当前元素的个数...
题目描述 给定一个整数数组 nums ,按要求返回一个新数组 counts .数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量. 示例 ...
- LeetCode每日一题:927. 三等分 (困难) 数组 数学
题目:力扣 给定一个由 0 和 1 组成的数组 arr ,将数组分成 3 个非空的部分 ,使得所有这些部分表示相同的二进制值. 如果可以做到,请返回任何 [i, j],其中 i+1 < j,这 ...
- 数组最大可以开多大_每日算法系列【LeetCode 689】三个无重叠子数组的最大和
题目描述 给定数组 由正整数组成,找到三个互不重叠的子数组的最大和. 每个子数组的长度为 ,我们要使这 个项的和最大化. 返回每个区间起始索引的列表(索引从 0 开始).如果有多个结果,返回字典序最小 ...
- 如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 523】连续的子数组和...
题目描述 给定一个包含非负数的数组和一个目标整数 k,编写一个函数来判断该数组是否含有连续的子数组,其大小至少为 2,总和为 k 的倍数,即总和为 n*k,其中 n 也是一个整数. 示例1 输入: [ ...
- 如何表示数组所有数都不等于一个数_每日算法系列【LeetCode 330】按要求补齐数组...
题目描述 给定一个已排序的正整数数组 nums ,和一个正整数 n .从 [1, n] 区间内选取任意个数字补充到 nums 中,使得 [1, n] 区间内的任何数字都可以用 nums 中某几个数字的 ...
- 序列复杂度怎么看_每日算法系列【LeetCode 376】摆动序列
题目描述 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个 ...
- 找出最具竞争力的子序列_每日算法系列【LeetCode 376】摆动序列
题目描述 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个 ...
- LeetCode每日一题——927. 三等分
LeetCode每日一题系列 题目:927. 三等分 难度:困难 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 给定一个由 0 和 1 组成的数组 arr ,将数组分成 3 个 ...
- java回文数算法for_【Java】【每日算法/刷穿 LeetCode】9. 回文数(简单)
首页 专栏 java 文章详情 0 [每日算法/刷穿 LeetCode]9. 回文数(简单) 宫水三叶发布于 今天 15:30 题目描述 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从 ...
最新文章
- 【C语言】07-预处理指令;-宏定义
- Codeforces Round #319 (Div. 1) B. Invariance of Tree 构造
- Spring 和 SpringBoot 最核心的 3 大区别,详解!
- 云爆发架构是否难以实施?
- UIScrollView属性和用法
- IT英语职场之网管英语大全
- sonar 规则之漏洞类型
- mysql中的钱null_MySQL数据库中null的知识点总结
- boost::asio向socket中异步读写数据
- Stack Overflow监控系统内部架构初探
- 腐蚀rust电脑分辨率调多少_腐蚀Rust画面怎么设置 _游侠网
- 从零基础入门Tensorflow2.0 ----九、44.3 keras模型转换成savedmodel
- 【语音处理】基于matlab低通滤波器语音信号加噪与去噪【含Matlab源码 1709期】
- Bootstrap-CSS全样式
- 神经网络控制学习笔记——神经网络背景1
- 解决VMware中虚拟机(centos7)无法上网的一种方法
- Android签名 - APK签名系统SignApk.jar
- [幽默网文]好男人遭遇野蛮美女老婆
- networkx常用函数总结(持续更新)
- ChatGPT国内在线版、微信版