给定一个非负数组a ,任务是查找子数组的数量,其元素乘积可以表示为两个不同数字的差。
例子:
Input: arr = {2, 5, 6}
Output: 2
Explanation:
Product of elements of subarray {5} can be represented as 32 – 22 is equal to 5
Product of elements of subarray {2, 5, 6} can be represented as 82 – 22 is equal to 60
Hence, there are two subarrays which can be represented.
Input: arr = {1, 2, 3}
Output: 2
天真的方法:
上面提到的问题的幼稚解决方案是从给定数组计算所有可能的子数组。然后,我们必须计算每个子数组的乘积。但是这种方法不是很有效并且很费时。
高效的方法:
对上述问题的有效方法的普遍观察是,被2除而不是4的数字在除以4时得到余数2。因此,所有数字都可以表示为两个不同数字的乘积,除了数字当用4取模时得到余数2。为了解决这个问题,我们采用一对向量并将元素与下一个可被2整除的元素的位置一起存储。之后遍历数组并寻找必要的条件如下:
- 如果遇到奇数,则该数字将形成所有子数组,除非出现一个可被2整除的数字。现在,当另一个数字被2可整除时,该数字也可形成子数组。这两个都存储在对类型向量中。
- 如果遇到一个可以被4整除的数字,那么这个数字可以构成所有子数组。
- 如果出现一个只能被2整除的数字,则该数字不能形成子数组,除非出现另一个数字,该数字是2的倍数。
下面是上述方法的实现:
C++
// C++ program to Find count of
// Subarrays whose product can be
// represented as the difference between
// two different numbers
#include
using namespace std;
// Function to print number of subarrays
void numberOfSubarrays(int arr[], int n)
{
vector > next(n);
vector > next_to_next(n);
int f = -1;
int s = -1;
for (int i = n - 1; i >= 0; i--) {
next[i].first = arr[i];
next_to_next[i].first = arr[i];
// check if number is divisible by 2
if (arr[i] % 2 == 0) {
s = f;
f = i;
}
// Store the position
// of the next element
next[i].second = f;
// Store the position of
// next to next element
// which is multiple of 2
next_to_next[i].second = s;
}
int total = 0;
for (int i = 0; i < n; i++) {
int calculate;
// Check if the element is divisible
// is divisible by 4
if (next[i].first % 4 == 0) {
calculate = n - i;
total += calculate;
}
// Check if current element
// is an odd number
else if (next[i].first & 1 == 1) {
if (next[i].second == -1) {
calculate = n - i;
total += calculate;
}
else {
// check if after the current element
// only 1 element exist which is a
// multiple of only 2 but not 4
if (next_to_next[i].second == -1
&& next[next[i].second].first % 4 != 0)
{
calculate = next[i].second - i;
total += calculate;
}
// Check if after the current element an element exist
// which is multiple of only 2 and not 4 and after that
// an element also exist which is multiple of 2
else if (next_to_next[i].second != -1
&& next[next[i].second].first % 4 != 0) {
calculate = n - i;
total += calculate;
total -= next_to_next[i].second - next[i].second;
}
// All subarrays can be formed by current element
else {
calculate = n - i;
total = total + calculate;
}
}
}
// Condition for an even number
else {
// Check if next element does not
// exist which is multiple of 2
if (next_to_next[i].second == -1)
total = total;
// Check if next element exist
// which is multiple of 2
else {
calculate = n - i;
total += calculate;
total = total - next_to_next[i].second + i;
}
}
}
// Print the output
cout << total << "\n";
}
// Driver Code
int main()
{
// array initialisation
int arr[] = { 2, 5, 6 };
int size = sizeof(arr) / sizeof(arr[0]);
numberOfSubarrays(arr, size);
return 0;
}
Java
// Java program to find count of
// subarrays whose product can be
// represented as the difference
// between two different numbers
import java.io.*;
import java.util.*;
class GFG{
// Function to print number of subarrays
static void numberOfSubarrays(int arr[], int n)
{
int[][] next = new int[n][2];
int[][] next_to_next = new int[n][2];
int f = -1;
int s = -1;
for(int i = n - 1; i >= 0; i--)
{
next[i][0] = arr[i];
next_to_next[i][0] = arr[i];
// Check if number is divisible by 2
if (arr[i] % 2 == 0)
{
s = f;
f = i;
}
// Store the position
// of the next element
next[i][1] = f;
// Store the position of
// next to next element
// which is multiple of 2
next_to_next[i][1] = s;
}
int total = 0;
for(int i = 0; i < n; i++)
{
int calculate;
// Check if the element is divisible
// is divisible by 4
if (next[i][0] % 4 == 0)
{
calculate = n - i;
total += calculate;
}
// Check if current element
// is an odd number
else if ((next[i][0] & 1) == 1)
{
if (next[i][1] == -1)
{
calculate = n - i;
total += calculate;
}
else
{
// Check if after the current element
// only 1 element exist which is a
// multiple of only 2 but not 4
if (next_to_next[i][1] == -1 &&
next[next[i][1]][0] % 4 != 0)
{
calculate = next[i][1] - i;
total += calculate;
}
// Check if after the current element
// an element exist which is multiple
// of only 2 and not 4 and after that
// an element also exist which is
// multiple of 2
else if (next_to_next[i][1] != -1 &&
next[next[i][1]][0] % 4 != 0)
{
calculate = n - i;
total += calculate;
total -= next_to_next[i][1] -
next[i][1];
}
// All subarrays can be formed
// by current element
else
{
calculate = n - i;
total = total + calculate;
}
}
}
// Condition for an even number
else
{
// Check if next element does not
// exist which is multiple of 2
if (next_to_next[i][1] == -1)
total = total;
// Check if next element exist
// which is multiple of 2
else
{
calculate = n - i;
total += calculate;
total = total - next_to_next[i][1] + i;
}
}
}
// Print the output
System.out.println(total);
}
// Driver Code
public static void main(String args[])
{
// Array initialisation
int arr[] = { 2, 5, 6 };
int size = arr.length;
numberOfSubarrays(arr, size);
}
}
// This code is contributed by offbeat
Python3
# Python program to find count of
# subarrays whose product can be
# represented as the difference
# between two different numbers
# Function to print number of subarrays
def numberOfSubarrays(arr, n):
Next = [[0 for i in range(2)] for j in range(n)]
next_to_next = [[0 for i in range(2)] for j in range(n)]
f = -1
s = -1
for i in range(n - 1, -1, -1) :
Next[i][0] = arr[i]
next_to_next[i][0] = arr[i]
# Check if number is divisible by 2
if (arr[i] % 2 == 0) :
s = f
f = i
# Store the position
# of the next element
Next[i][1] = f
# Store the position of
# next to next element
# which is multiple of 2
next_to_next[i][1] = s
total = 0
for i in range(n) :
calculate = 0
# Check if the element is divisible
# is divisible by 4
if (Next[i][0] % 4 == 0) :
calculate = n - i
total += calculate
# Check if current element
# is an odd number
elif ((Next[i][0] & 1) == 1) :
if (Next[i][1] == -1) :
calculate = n - i
total += calculate
else :
# Check if after the current element
# only 1 element exist which is a
# multiple of only 2 but not 4
if (next_to_next[i][1] == -1 and Next[Next[i][1]][0] % 4 != 0) :
calculate = Next[i][1] - i
total += calculate
# Check if after the current element
# an element exist which is multiple
# of only 2 and not 4 and after that
# an element also exist which is
# multiple of 2
elif (next_to_next[i][1] != -1 and Next[Next[i][1]][0] % 4 != 0) :
calculate = n - i
total += calculate
total -= next_to_next[i][1] - Next[i][1]
# All subarrays can be formed
# by current element
else :
calculate = n - i
total = total + calculate
# Condition for an even number
else :
# Check if next element does not
# exist which is multiple of 2
if (next_to_next[i][1] == -1) :
total = total
# Check if next element exist
# which is multiple of 2
else :
calculate = n - i
total += calculate
total = total - next_to_next[i][1] + i
# Print the output
print(total)
# Array initialisation
arr = [ 2, 5, 6 ]
size = len(arr)
numberOfSubarrays(arr, size)
# This code is contributed by divyesh072019
C#
// C# program to find count of
// subarrays whose product can be
// represented as the difference
// between two different numbers
using System;
class GFG{
// Function to print number
// of subarrays
static void numberOfSubarrays(int[] arr,
int n)
{
int[,] next = new int[n, 2];
int[,] next_to_next = new int[n, 2];
int f = -1;
int s = -1;
for(int i = n - 1; i >= 0; i--)
{
next[i, 0] = arr[i];
next_to_next[i, 0] = arr[i];
// Check if number is
// divisible by 2
if (arr[i] % 2 == 0)
{
s = f;
f = i;
}
// Store the position
// of the next element
next[i, 1] = f;
// Store the position of
// next to next element
// which is multiple of 2
next_to_next[i, 1] = s;
}
int total = 0;
for(int i = 0; i < n; i++)
{
int calculate;
// Check if the element is
// divisible is divisible by 4
if (next[i, 0] % 4 == 0)
{
calculate = n - i;
total += calculate;
}
// Check if current element
// is an odd number
else if ((next[i, 0] & 1) == 1)
{
if (next[i, 1] == -1)
{
calculate = n - i;
total += calculate;
}
else
{
// Check if after the current element
// only 1 element exist which is a
// multiple of only 2 but not 4
if (next_to_next[i, 1] == -1 &&
next[next[i, 1], 0] % 4 != 0)
{
calculate = next[i, 1] - i;
total += calculate;
}
// Check if after the current element
// an element exist which is multiple
// of only 2 and not 4 and after that
// an element also exist which is
// multiple of 2
else if (next_to_next[i, 1] != -1 &&
next[next[i, 1], 0] % 4 != 0)
{
calculate = n - i;
total += calculate;
total -= next_to_next[i, 1] -
next[i, 1];
}
// All subarrays can be formed
// by current element
else
{
calculate = n - i;
total = total + calculate;
}
}
}
// Condition for an even number
else
{
// Check if next element does not
// exist which is multiple of 2
if (next_to_next[i, 1] == -1)
{
//total = total;
}
// Check if next element exist
// which is multiple of 2
else
{
calculate = n - i;
total += calculate;
total = total -
next_to_next[i, 1] + i;
}
}
}
// Print the output
Console.WriteLine(total);
}
static void Main()
{
// Array initialisation
int[] arr = {2, 5, 6};
int size = arr.Length;
numberOfSubarrays(arr, size);
}
}
// This code is contributed by divyeshrabadiya07
Javascript
输出:
2
时间复杂度: O(N)