三等分
难度:
标签:
题目描述
代码结果
运行时间: 50 ms, 内存: 17.7 MB
/*
* Problem Statement:
* Given an array arr of 0s and 1s, divide the array into 3 non-empty parts such that all of these parts represent the same binary value.
* If possible, return any [i, j] with i + 1 < j, such that:
* - arr[0], arr[1], ..., arr[i] is the first part;
* - arr[i + 1], arr[i + 2], ..., arr[j - 1] is the second part;
* - arr[j], arr[j + 1], ..., arr[arr.length - 1] is the third part.
* These parts must represent the same binary value.
* If it's not possible, return [-1, -1].
*
* Example:
* Input: arr = [1,0,1,0,1]
* Output: [0, 3]
*
* Approach:
* 1. Count the total number of 1s in the array.
* 2. If this number is not divisible by 3, return [-1, -1] since we cannot split them equally.
* 3. Identify the positions of the 1s and attempt to divide them into three equal parts.
* 4. Verify that the segments between these positions represent the same binary value.
*/
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Solution {
public int[] threeEqualParts(int[] arr) {
long countOnes = Arrays.stream(arr).filter(i -> i == 1).count();
if (countOnes % 3 != 0) return new int[]{-1, -1};
if (countOnes == 0) return new int[]{0, arr.length - 1};
long k = countOnes / 3;
List<Integer> positions = Arrays.stream(arr).boxed().collect(Collectors.toList());
int first = positions.indexOf(1);
int second = nthIndexOf(arr, 1, k + 1);
int third = nthIndexOf(arr, 1, 2 * k + 1);
while (third < arr.length && arr[first] == arr[second] && arr[second] == arr[third]) {
first++;
second++;
third++;
}
if (third == arr.length) return new int[]{first - 1, second};
return new int[]{-1, -1};
}
private int nthIndexOf(int[] arr, int value, long n) {
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == value) {
n--;
if (n == 0) {
index = i;
break;
}
}
}
return index;
}
}
解释
方法:
该题解策略首先计算数组中1的总数。如果1的总数不能被3整除,直接返回[-1, -1]。如果整个数组都是0,返回[0, 2]。然后,将数组中1的位置存储在一个列表中,根据1的总数除以3的结果,确定三个部分中每一部分1的起始和结束位置。计算第三部分结束后剩余的0的数量,用这个信息来确定第一部分和第二部分的结束位置。最后,进行一次遍历来确认三部分的内容是否完全相同。如果相同,则返回第一部分和第三部分的结束位置作为结果;如果在任何点不相同,则返回[-1, -1]。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在你的算法中,如何保证每一部分的二进制值相等即使在存在前导零的情况下?
▷🦆
为什么在计算1的总数不能被3整除时,就直接返回`[-1, -1]`,这里的逻辑基础是什么?
▷🦆
在计算最后一部分后的0的数量时,为何这些0的数量对于第一部分和第二部分的结束位置有决定性影响?
▷🦆
当数组全为0时,返回`[0, 2]`的逻辑依据是什么?是否有其他可能的切分方法满足题目要求?
▷