给定一个非负数组 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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live