202316给定一个由0和1组成的数组arr,将数组分成3个
20230316:给定一个由0和1组成的数组arr,将数组分成3个非空的部分,
使得所有这些部分表示相同的二进制值。
如果可以做到,请返回任何〔i,j〕,其中i1j,这样一来,
arr〔0〕,arr〔1〕,。。。,arr〔i〕为第一部分,
arr〔i1〕,arr〔i2〕,。。。,arr〔j1〕为第二部分,
arr〔j〕,arr〔j1〕,。。。,arr〔arr。length1〕为第三部分,
这三个部分所表示的二进制值相等,
如果无法做到,就返回〔1,1〕。
注意,在考虑每个部分所表示的二进制时,应当将其看作一个整体,
例如,〔1,1,0〕表示十进制中的6,而不会是3。此外,前导零也是被允许的,
所以〔0,1,1〕和〔1,1〕表示相同的值。
输入:arr〔1,0,1,0,1〕,
输出:〔0,3〕。
输入:arr〔1,1,0,0,1〕,
输出:〔0,2〕。
答案20230316:
给定一个由0和1组成的数组arr,需要将其分成三个非空部分,使得每个部分中1的数量相等。如果无法做到,则返回〔1,1〕。
输入:由0和1组成的数组arr,长度为n(1n3104),且只包含数字0和1。
输出:长度为2的数组,表示能够将arr分成三个部分第一个和第二个部分的结束位置(下标从0开始)。如果无法做到则返回〔1,1〕。
解法思路:
首先统计整个数组中1的数量ones,如果ones不能被3整除,则说明无法分成三个相等的部分,直接返回〔1,1〕。
如果ones等于0,则整个数组都是0,可以返回〔0,n1〕。
接着需要找到第一个、第二个和第三个部分的起始位置。根据题意,第一个部分和第二个部分的1的数量应该是ones3,因此可以先计算出目标值partones3,然后从左到右遍历整个数组,在找到第一个和第二个部分之后,继续遍历找到第三个部分的起始位置。
接下来检查第三个部分是否也等于目标值part。如果是,则返回〔end1,end2〕,否则返回〔1,1〕。
rust代码实现:fnmain(){letarr1vec!〔0,0,0,0,0〕;println!({:?},threeequalparts(arr1));〔0,4〕letarr2vec!〔1,0,1,0,1,0〕;println!({:?},threeequalparts(arr2));〔1,4〕letarr3vec!〔1,0,1,0,1〕;println!({:?},threeequalparts(arr3));〔0,3〕letarr4vec!〔1,0,1,1,1〕;println!({:?},threeequalparts(arr4));〔1,1〕letarr5vec!〔0,1,0,1,0,1,0,1,0,1〕;println!({:?},threeequalparts(arr5));〔1,1〕letarr6vec!〔1,1,0,1,1,0,1,1〕;println!({:?},threeequalparts(arr6));〔1,5〕}pubfnthreeequalparts(arr:Veci32)Veci32{letonesarr。iter()。filter(numnum1)。count();统计数组中1的个数ifones3!0{如果无法分成三个相等的部分,则返回〔1,1〕returnvec!〔1,1〕;}letnarr。len();ifones0{如果整个数组都是0,则返回〔0,n1〕returnvec!〔0,nasi321〕;}letpartones3;计算每个子数组中1的数量letmutstart11;第一个子数组的起始位置letmutstart21;第二个子数组的起始位置letmutstart31;第三个子数组的起始位置letmutcnt0;当前已经遇到的1的数量foriin0。。n{ifarr〔i〕1{cnt1;ifstart11cnt1{start1iasi32;找到第一个子数组的起始位置}ifstart21cntpart1{start2iasi32;找到第二个子数组的起始位置}ifstart31cnt2part1{start3iasi32;找到第三个子数组的起始位置}}}whilestart3nasi32{ifarr〔start1asusize〕!arr〔start2asusize〕arr〔start1asusize〕!arr〔start3asusize〕{returnvec!〔1,1〕;如果找到的三个子数组不相等,则返回〔1,1〕}start11;start21;start31;}vec!〔start11,start2〕返回第一个和第二个子数组的结束位置}
算法分析:
该算法的时间复杂度为O(n),其中n是输入数组的长度,因为需要遍历整个数组一次。空间复杂度为O(1),只需要常量级别的额外空间存储一些变量。该算法的优点是简单易懂,缺点是可能会超时,比如当输入数组中有很多连续的1时。可以通过进一步优化算法来提高效率。
测试结果:
1。测试用例:〔0,0,0,0,0〕,预期输出:〔0,4〕。
rust
asserteq!(threeequalparts(vec!〔0,0,0,0,0〕),vec!〔0,4〕);
2。测试用例:〔1,0,1,0,1,0〕,预期输出:〔1,4〕。
rust
asserteq!(threeequalparts(vec!〔1,0,1,0,1,0〕),vec!〔1,4〕);
3。测试用例:〔1,0,1,0,1〕,预期输出:〔0,3〕。
rust
asserteq!(threeequalparts(vec!〔1,0,1,0,1〕),vec!〔0,3〕);
4。测试用例:〔1,0,1,1,1〕,预期输出:〔1,1〕。
rust
asserteq!(threeequalparts(vec!〔1,0,1,1,1〕),vec!〔1,1〕);
5。测试用例:〔0,1,0,1,0,1,0,1,0,1〕,预期输出:〔1,1〕。
rust
asserteq!(threeequalparts(vec!〔0,1,0,1,0,1,0,1,0,1〕),vec!〔1,1〕);
6。测试用例:〔1,1,0,1,1,0,1,1〕,预期输出:〔1,5〕。
rust
asserteq!(threeequalparts(vec!〔1,1,0,1,1,0,1,1〕),vec!〔1,5〕);
总结和展望:
本文介绍了一种简单的算法,可以解决给定一个由0和1组成的数组arr,需将其分成三个非空部分,使得每个部分中1的数量相等的问题。该算法的核心思路是计算目标值targetval,并在遍历整个数组两次的过程中找到第一个和第二个部分的结束位置i和j。该算法的时间复杂度为O(n),空间复杂度为O(1)。
有一些情况下该算法可能会超时,比如当输入数组中有很多连续的1时。可以通过进一步优化算法来提高效率。例如,可以使用双指针来记录第一个和第二个部分的结束位置,从而减少遍历数组的次数。另外,可以使用位运算来加速计算当前部分的二进制数值。
总之,对于此类问题,需要先分析题目要求,找到合适的算法思路,再实现具体的代码。在实现代码时,需要注意代码的可读性、正确性和效率,并进行充分的测试和验证。同时,也需要不断学习和探索新的算法思路,以提高自己的编程能力和解决问题的能力。