给定一个由N个整数组成的数组A [] ,任务是构造一个数组B [] ,使得对于每个第i个索引, B [i] = X – Y ,其中X和Y是A [的出现次数i]在第i个索引之前和之后。
例子:
Input: A[] = {3, 2, 1, 2, 3}
Output: 1 1 0 -1 -1
Explanation:
arr[0] = 3, X = 1, Y = 0. Therefore, print 1.
arr[1] = 2, X = 1, Y = 0. Therefore, print 1.
arr[2] = 1, X = 0, Y = 0. Therefore, print 0.
arr[3] = 2, X = 0, Y = 1. Therefore, print -1.
arr[4] = 3, X = 0, Y = 1. Therefore, print -1.
Input: A[] = {1, 2, 3, 4, 5}
Output: 0 0 0 0 0
天真的方法:
解决问题的最简单方法是遍历数组并考虑每个数组元素,并将其与左右两侧的所有元素进行比较。对于每个数组元素,在其左侧和右侧打印其出现的差异。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:请按照以下步骤优化上述方法:
- 初始化两个数组left []和right []以存储每个数组元素的左和右索引上存在的数组元素的频率。
- 计算左右累积频率表。
- 打印两个频率阵列中相同索引元素的差。
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function to construct array of
// differences of counts on the left
// and right of the given array
void constructArray(int A[], int N)
{
// Initialize left and right
// frequency arrays
int left[N + 1] = { 0 };
int right[N + 1] = { 0 };
int X[N + 1] = { 0 }, Y[N + 1] = { 0 };
// Construct left cumulative
// frequency table
for (int i = 0; i < N; i++) {
X[i] = left[A[i]];
left[A[i]]++;
}
// Construct right cumulative
// frequency table
for (int i = N - 1; i >= 0; i--) {
Y[i] = right[A[i]];
right[A[i]]++;
}
// Print the result
for (int i = 0; i < N; i++) {
cout << Y[i] - X[i] << " ";
}
}
// Driver Code
int main()
{
int A[] = { 3, 2, 1, 2, 3 };
int N = sizeof(A) / sizeof(A[0]);
// Function Call
constructArray(A, N);
return 0;
}
Java
// Java program of the above approach
import java.io.*;
class GFG{
// Function to construct array of
// differences of counts on the left
// and right of the given array
static void constructArray(int A[], int N)
{
// Initialize left and right
// frequency arrays
int[] left = new int[N + 1];
int[] right = new int[N + 1];
int[] X = new int[N + 1];
int[] Y = new int[N + 1];
// Construct left cumulative
// frequency table
for(int i = 0; i < N; i++)
{
X[i] = left[A[i]];
left[A[i]]++;
}
// Construct right cumulative
// frequency table
for(int i = N - 1; i >= 0; i--)
{
Y[i] = right[A[i]];
right[A[i]]++;
}
// Print the result
for (int i = 0; i < N; i++)
{
System.out.print(Y[i] - X[i] + " ");
}
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 3, 2, 1, 2, 3 };
int N = A.length;
// Function Call
constructArray(A, N);
}
}
// This code is contributed by akhilsaini
Python3
# Python3 program of the above approach
# Function to construct array of
# differences of counts on the left
# and right of the given array
def constructArray(A, N):
# Initialize left and right
# frequency arrays
left = [0] * (N + 1)
right = [0] * (N + 1)
X = [0] * (N + 1)
Y = [0] * (N + 1)
# Construct left cumulative
# frequency table
for i in range(0, N):
X[i] = left[A[i]]
left[A[i]] += 1
# Construct right cumulative
# frequency table
for i in range(N - 1, -1, -1):
Y[i] = right[A[i]]
right[A[i]] += 1
# Print the result
for i in range(0, N):
print(Y[i] - X[i], end = " ")
# Driver Code
if __name__ == '__main__':
A = [ 3, 2, 1, 2, 3 ]
N = len(A)
# Function Call
constructArray(A, N)
# This code is contributed by akhilsaini
C#
// C# program of the above approach
using System;
class GFG{
// Function to construct array of
// differences of counts on the left
// and right of the given array
static void constructArray(int[] A, int N)
{
// Initialize left and right
// frequency arrays
int[] left = new int[N + 1];
int[] right = new int[N + 1];
int[] X = new int[N + 1];
int[] Y = new int[N + 1];
// Construct left cumulative
// frequency table
for(int i = 0; i < N; i++)
{
X[i] = left[A[i]];
left[A[i]]++;
}
// Construct right cumulative
// frequency table
for(int i = N - 1; i >= 0; i--)
{
Y[i] = right[A[i]];
right[A[i]]++;
}
// Print the result
for(int i = 0; i < N; i++)
{
Console.Write(Y[i] - X[i] + " ");
}
}
// Driver Code
public static void Main()
{
int[] A = { 3, 2, 1, 2, 3 };
int N = A.Length;
// Function Call
constructArray(A, N);
}
}
// This code is contributed by akhilsaini
输出:
1 1 0 -1 -1
时间复杂度: O(N)
辅助空间: O(N)