给定数组中不同的交替索引三元组的计数 |设置 2
给定一个大小为N的二进制数组arr[] ,任务是找出不同交替三元组的计数。
注意:如果这些索引的值是 {0, 1, 0} 或 {1, 0, 1} 形式,则三元组是交替的。
例子:
Input: arr[] = {0, 0, 1, 1, 0, 1}
Output: 6
Explanation: Here four sequence of “010” and two sequence of “101” exist.
So, the total number of ways of alternating sequence of size 3 is 6.
Input: arr[] = {0, 0, 0, 0, 0}
Output: 0
Explanation: As there are no 1s in the array so we cannot find any 3 size alternating sequence.
朴素方法:本文的Set 1中提到了朴素方法和基于动态规划的方法。
高效方法:这个问题可以使用基于以下思想的前缀和有效地解决:
- The possible groups that can be formed are {0, 1, 0} or {1, 0, 1}
- So for any 1 encountered in the array the total possible combinations can be calculated by finding the number of ways to select one 0 from its left and one 0 from its right. This value is same as the product of number of 0s to its left and the number of 0s to its right.
- For a 0, the number of possible triplets can be found in the same way.
- The final answer is the sum of these two values.
请按照以下步骤解决问题:
- 从左边开始遍历数组并计算 0 的数量(比如count1 )和 1 的总数(比如count2 )。
- 然后,将两个数字的 left_count 初始化为 0。
- 从i = 0 到 N遍历数组:
- 现在,假设遇到 1,所以首先使用这个 1 计算 {0, 1, 0} 可能的组合。为此,将left_count_Zero和count1相乘,并将结果添加到我们的最终答案中。
- 将此值与sum 相加。
- 现在,减少 count2 作为它出现在左边的下一个元素,因此增加left_count_One 。
- 同样,遇到 0 时执行相同操作。
- 返回最终总和。
以下是上述方法的实现:
C++
// C++ code for the above approach:
#include
using namespace std;
// Function to calculate the possible
// number of ways to select 3 numbers
long long numberOfWays(int A[], int N)
{
int left_count_Zero = 0, count1 = 0;
int left_count_One = 0, count2 = 0;
long long ans = 0;
// Storing the right counts of
// 1s and 2s in the array
for (int i = 0; i < N; i++) {
if (A[i] == 1)
count2++;
else
count1++;
}
// Traversing the array from left side
for (int i = 0; i < N; i++) {
// If 1 is encountered,
// looking for all combinations of
// 0, 1, 0 possible
if (A[i] == 1) {
// Number of ways to select one
// 0 from left side * Number of
// ways to select one 0 from right
ans += (left_count_Zero * count1);
// Decrement right_count of 1
// and increment left_count of 1
left_count_One++;
count2--;
}
// If 0 is encountered,
// looking for all combinations
// of 1, 0, 1 possible
else {
// Number of ways to select
// one 1 from left side
// * Number of ways to select a 1
// from right
ans += (left_count_One * count2);
// Decrement right_count of 2
// and increment left_count of 2
left_count_Zero++;
count1--;
}
}
return ans;
}
// Drivers code
int main()
{
int arr[] = { 0, 0, 1, 1, 0, 1 };
int N = 6;
// Function call
cout << numberOfWays(arr, N);
return 0;
}
输出
6
时间复杂度: O(N)
辅助空间: O(1)