检查 X/Y 的给定 Array floor 的所有对 (X, Y) 是否也存在
给定一个大小为N的数组arr[]和一个整数K ,表示数组元素可以具有的最大值,任务是检查是否所有可能的元素对 (X, Y) 其中 X≥Y, ⌊X/Y ⌋ (X 除以 Y 并向下舍入)也出现在此数组中。
例子:
Input: N = 3, K = 5, arr[]={1, 2, 5}
Output: YES
Explanation: There are such pair of elements (checking all possible conditions)
⌊1/1⌋ = 1, ⌊2/2⌋ = 1, ⌊5/5⌋ = 1
⌊2/1⌋ = 2, ⌊5/1⌋ = 5, ⌊5/2⌋ = 2
As all [X/Y] for any X and Y exists in the array. So print YES
Input: N = 4, K = 8, arr[] = {1, 3, 3, 7}
Output: NO
Explanation: As there is a pair (7, 3) where ⌊7/3⌋ = 2 is not present in the array.
朴素方法:解决这个问题的一种朴素方法是使用嵌套循环并获取 X 和 Y 的每个值并存储在结果数组中。然后稍后检查结果数组的每个元素是否存在于原始数组中。
时间复杂度:O(N*N)
辅助空间:O(1)
高效的方法:这个问题可以基于以下思路来解决:
For any number x all the values in range c*x + d [where c is a positive integer and d is in range [0, x) ] will have the same floor value c when divided by x
为了实现上述观察,使用映射来存储数组中存在的元素,并使用前缀数组来存储直到x (x 在[1, K]范围内)之前存在的元素数量。对于每个这样的x检查其倍数是否存在这样的c (如观察中所述)使用映射和前缀 sum 数组存在于数组中。
请按照以下步骤解决此问题:
- 如上所述,使用哈希数组(例如b[] )存储数组中存在的元素和另一个前缀和数组(例如a[] )。
- 在数组b[]中迭代i > 0 到 K :
- 如果i存在于数组arr[]中:
- 如果使用b[]的数组中也存在x/i的底值,则检查i的倍数(例如x )(由于观察中提到的原因)。
- 如果不存在,则从前缀和数组中检查范围(xi, x]中是否存在任何元素。
- 如果存在,则不满足i和该元素的条件。所以返回false 。否则,继续迭代。
- 否则,继续i的下一个值
- 如果i存在于数组arr[]中:
- 如果所有可能的值都存在,则返回true 。
请按照下图更好地理解
插图:
Consider arr[] = {1, 2, 5}, K = 5
b[] = {0, 1, 1, 0, 0, 1} [denotes 1, 2 and 5 are present]
a[] = {0, 1, 2, 2, 2, 5} [denotes how many element till i is present]
Traverse b[] from i = 1 to 5
For i = 1:
=> Multiple = 1. 1/1 = 1. b[1] = 1, So this is present.
=> Multiple = 2. 2/1 = 2. b[2] = 1, So this is present.
=> Multiple = 3. 3/1 = 3. b[3] = 0, No element in range (2, 3].
=> Multiple = 4. 4/1 = 4. b[4] = 0, No element in range (3, 4].
=> Multiple = 5. 5/1 = 5. b[5] = 1, So this is present.
For i = 2:
=> Multiple = 1. 2/2 = 1. b[1] = 1, So this is present.
=> Multiple = 4. 4/2 = 2. b[2] = 1, So this is present.
For i = 3:
=> 3 is not present in the array. So continue iteration.
For i = 4:
=> 4 is not present in the array. So continue iteration.
For i = 5:
=> Multiple = 5. 5/5 = 5. b[1] = 1, So this is present.
So all possible elements are present for all possible pairs.
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to check whether X/Y is present or not
int solve(int n, int c, int arr[])
{
// Creating hash array
// and prefix sum array
vector a(c + 1, 0), b(c + 1, 0);
for (int i = 0; i < n; i++) {
a[arr[i]]++;
b[arr[i]]++;
}
// Performing prefix sum.
for (int i = 1; i <= c; i++) {
a[i] += a[i - 1];
}
for (int i = 1; i <= c; i++) {
// Taking original array elements
if (b[i] > 0) {
for (int j = i - 1; j <= c; j += i) {
// If element already exist
// it will give 1 hence true case
// if doesnt exist
// we will move forward
if (b[(j + 1) / i] == 0) {
// we will take two indices
// to check whether item
// is present.
// If any element is present
// between then a[id1]!=ad[id2]
int id1 = j;
int id2 = j + i;
id2 = min(id2, c);
if (a[id1] != a[id2]) {
return false;
}
}
}
}
}
// If all above cases turns true
return true;
}
// Driver Code
int main()
{
int N = 3, K = 5;
int arr[] = { 1, 2, 5 };
bool flag = solve(N, K, arr);
if (flag)
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java code to implement the above approach
import java.io.*;
class GFG {
// Function to check whether X/Y is present or not
static boolean solve(int n, int c, int arr[])
{
// Creating hash array
// and prefix sum array
int[] a = new int;
int[] b = new int;
for (int i = 0; i < n; i++) {
a[arr[i]]++;
b[arr[i]]++;
}
// Performing prefix sum.
for (int i = 1; i <= c; i++) {
a[i] += a[i - 1];
}
for (int i = 1; i <= c; i++) {
// Taking original array elements
if (b[i] > 0) {
for (int j = i - 1; j <= c; j += i) {
// If element already exist
// it will give 1 hence true case
// if doesnt exist
// we will move forward
if (b[(j + 1) / i] == 0) {
// we will take two indices
// to check whether item
// is present.
// If any element is present
// between then a[id1]!=ad[id2]
int id1 = j;
int id2 = j + i;
id2 = Math.min(id2, c);
if (a[id1] != a[id2]) {
return false;
}
}
}
}
}
// If all above cases turns true
return true;
}
// Driver Code
public static void main (String[] args) {
int N = 3, K = 5;
int arr[] = { 1, 2, 5 };
boolean flag = solve(N, K, arr);
if (flag)
System.out.println("Yes");
else
System.out.println("No");
}
}
// This code is contributed by hrithikgarg03188.
Python3
# Python code to implement the above approach
# Function to check whether X/Y is present or not
def solve(n, c, arr):
# Creating hash array
# and prefix sum array
a = []
b = []
a = [0 for i in range(c + 1)]
b = [0 for i in range(c + 1)]
for i in range(0, n):
a[arr[i]] += 1
b[arr[i]] += 1
# Performing prefix sum.
for i in range(0, c + 1):
a[i] += a[i - 1]
for i in range(0, c + 1):
# Taking original array elements
if b[i] > 0:
for j in range(i - 1, c + 1, i):
# If element already exist
# it will give 1 hence true case
# if doesnt exist
# we will move forward
if b[(j + 1) / i] == 0:
# we will take two indices
# to check whether item
# is present.
# If any element is present
# between then a[id1]!=ad[id2]
id1 = j
id2 = j + i
id2 = min(id2, c)
if a[id1] != a[id2]:
return False
# If all above cases turns true
return True
# Driver Code
if __name__ == "__main__":
N = 3
K = 5
arr = [1, 2, 5]
flag = solve(N, K, arr)
if (flag == True):
print("Yes")
else:
print("No")
# This code is contributed by Rohit Pradhan
Yes
时间复杂度: O(K * LogK)
辅助空间:O(K)