给定三个整数X , Y和P ,任务是找到最小窗口大小K ,以使该大小的[X,Y]范围内的每个窗口都具有至少P个质数。
例子:
Input: X = 2, Y = 8, P = 2
Output: 4
Explanation:
In the range [2, 8], window size of 4 contains atleast 2 primes in each window.
Possible Windows –
{2, 3, 4, 5} – No of Primes = 3
{3, 4, 5, 6} – No of Primes = 2
{4, 5, 6, 7} – No of Primes = 2
{5, 6, 7, 8} – No of Primes = 2
Input: X = 12, Y = 42, P = 3
Output: 14
Explanation:
In the range [12, 42], window size of 14 contains atleast 3 primes in each window.
天真的方法:遍历所有可能的窗口大小,对于每个窗口大小在[X,Y]范围内遍历,并检查每个窗口是否包含至少K个质数。这些窗口大小的最小值将是所需的值。
高效方法:此问题的主要观察结果是,如果窗口大小W是满足条件的最小窗口大小,则在[W,Y – X + 1]范围内的所有窗口大小都将满足条件。使用此方法,我们可以将每一步的搜索空间减少一半,而这正是Binary Search的想法。下面是步骤说明:
- 搜索空间:此问题的搜索空间可以是窗口大小的最小长度为1,最大窗口大小可以是范围的结束值和范围的起始值之差。
low = 1 high = Y - X + 1
- 下一个搜索空间:在每个步骤中,通常的想法是在滑动窗口技术的帮助下,检查给定窗口大小下每个窗口中的质数是否具有P个质数。鉴于以下决定,可以减少问题的搜索空间:
- 情况1:当每个窗口中的质数至少包含P个质数时,可以减小窗口的大小以找到小于当前窗口的窗口大小。
if (checkPPrimes(mid) == True) high = mid - 1
- 情况2:当每个窗口中包含的素数没有时,则窗口大小必须大于当前窗口大小。然后,
if (checkPPrimes(mid) == False) low = mid + 1
- 情况1:当每个窗口中的质数至少包含P个质数时,可以减小窗口的大小以找到小于当前窗口的窗口大小。
下面是上述方法的实现:
C++
// C++ implementation to find the
// minimum window size in the range
// such that each window of that size
// contains atleast P primes
#include
using namespace std;
// Function to check that a number is
// a prime or not in O(sqrt(N))
bool isPrime(int N)
{
if (N < 2)
return false;
if (N < 4)
return true;
if ((N & 1) == 0)
return false;
if (N % 3 == 0)
return false;
int curr = 5, s = sqrt(N);
// Loop to check if any number
// number is divisible by any
// other number or not
while (curr <= s) {
if (N % curr == 0)
return false;
curr += 2;
if (N % curr == 0)
return false;
curr += 4;
}
return true;
}
// Function to check whether window
// size satisfies condition or not
bool check(int s, int p,
int prefix_sum[], int n)
{
bool satisfies = true;
// Loop to check each window of
// size have atleast P primes
for (int i = 0; i < n; i++) {
if (i + s - 1 >= n)
break;
// Checking condition
// using prefix sum
if (prefix_sum[i + s - 1] -
(i - 1 >= 0 ?
prefix_sum[i - 1] : 0) < p)
satisfies = false;
}
return satisfies;
}
// Function to find the minimum
// window size possible for the
// given range in X and Y
int minimumWindowSize(int x, int y,
int p)
{
// Prefix array
int prefix_sum[y - x + 1] = { 0 };
// Mark those numbers
// which are primes as 1
for (int i = x; i <= y; i++) {
if (isPrime(i))
prefix_sum[i - x] = 1;
}
// Convert to prefix sum
for (int i = 1; i < y - x + 1; i++)
prefix_sum[i] +=
prefix_sum[i - 1];
// Applying binary search
// over window size
int low = 1, high = y - x + 1;
int mid;
while (high - low > 1) {
mid = (low + high) / 2;
// Check whether mid satisfies
// the condition or not
if (check(mid, p,
prefix_sum, y - x + 1)) {
// If satisfies search
// in first half
high = mid;
}
// Else search in second half
else
low = mid;
}
if (check(low, p,
prefix_sum, y - x + 1))
return low;
return high;
}
// Driver Code
int main()
{
int x = 12;
int y = 42;
int p = 3;
cout << minimumWindowSize(x, y, p);
return 0;
}
Java
// Java implementation to find the
// minimum window size in the range
// such that each window of that size
// contains atleast P primes
import java.util.*;
class GFG{
// Function to check that a number is
// a prime or not in O(Math.sqrt(N))
static boolean isPrime(int N)
{
if (N < 2)
return false;
if (N < 4)
return true;
if ((N & 1) == 0)
return false;
if (N % 3 == 0)
return false;
int curr = 5, s = (int) Math.sqrt(N);
// Loop to check if any number
// number is divisible by any
// other number or not
while (curr <= s) {
if (N % curr == 0)
return false;
curr += 2;
if (N % curr == 0)
return false;
curr += 4;
}
return true;
}
// Function to check whether window
// size satisfies condition or not
static boolean check(int s, int p,
int prefix_sum[], int n)
{
boolean satisfies = true;
// Loop to check each window of
// size have atleast P primes
for (int i = 0; i < n; i++) {
if (i + s - 1 >= n)
break;
// Checking condition
// using prefix sum
if (prefix_sum[i + s - 1] -
(i - 1 >= 0 ?
prefix_sum[i - 1] : 0) < p)
satisfies = false;
}
return satisfies;
}
// Function to find the minimum
// window size possible for the
// given range in X and Y
static int minimumWindowSize(int x, int y,
int p)
{
// Prefix array
int []prefix_sum = new int[y - x + 1];
// Mark those numbers
// which are primes as 1
for (int i = x; i <= y; i++) {
if (isPrime(i))
prefix_sum[i - x] = 1;
}
// Convert to prefix sum
for (int i = 1; i < y - x + 1; i++)
prefix_sum[i] +=
prefix_sum[i - 1];
// Applying binary search
// over window size
int low = 1, high = y - x + 1;
int mid;
while (high - low > 1) {
mid = (low + high) / 2;
// Check whether mid satisfies
// the condition or not
if (check(mid, p,
prefix_sum, y - x + 1)) {
// If satisfies search
// in first half
high = mid;
}
// Else search in second half
else
low = mid;
}
if (check(low, p,
prefix_sum, y - x + 1))
return low;
return high;
}
// Driver Code
public static void main(String[] args)
{
int x = 12;
int y = 42;
int p = 3;
System.out.print(minimumWindowSize(x, y, p));
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 implementation to find the
# minimum window size in the range
# such that each window of that size
# contains atleast P primes
from math import sqrt
# Function to check that a number is
# a prime or not in O(sqrt(N))
def isPrime(N):
if (N < 2):
return False
if (N < 4):
return True
if ((N & 1) == 0):
return False
if (N % 3 == 0):
return False
curr = 5
s = sqrt(N)
# Loop to check if any number
# number is divisible by any
# other number or not
while (curr <= s):
if (N % curr == 0):
return False
curr += 2
if (N % curr == 0):
return False
curr += 4
return True
# Function to check whether window
# size satisfies condition or not
def check(s, p, prefix_sum, n):
satisfies = True
# Loop to check each window of
# size have atleast P primes
for i in range(n):
if (i + s - 1 >= n):
break
# Checking condition
# using prefix sum
if (i - 1 >= 0):
x = prefix_sum[i - 1]
else:
x = 0
if (prefix_sum[i + s - 1] - x < p):
satisfies = False
return satisfies
# Function to find the minimum
# window size possible for the
# given range in X and Y
def minimumWindowSize(x, y, p):
# Prefix array
prefix_sum = [0]*(y - x + 1)
# Mark those numbers
# which are primes as 1
for i in range(x ,y+1):
if (isPrime(i)):
prefix_sum[i - x] = 1
# Convert to prefix sum
for i in range(1 ,y - x + 1):
prefix_sum[i] += prefix_sum[i - 1]
# Applying binary search
# over window size
low = 1
high = y - x + 1
while (high - low > 1):
mid = (low + high) // 2
# Check whether mid satisfies
# the condition or not
if (check(mid, p ,prefix_sum, y - x + 1)):
# If satisfies search
# in first half
high = mid
# Else search in second half
else:
low = mid
if (check(low, p, prefix_sum, y - x + 1)):
return low
return high
# Driver Code
x = 12
y = 42
p = 3
print(minimumWindowSize(x, y, p))
# This code is contributed by shubhamsingh10
C#
// C# implementation to find the
// minimum window size in the range
// such that each window of that size
// contains atleast P primes
using System;
class GFG{
// Function to check that a number is
// a prime or not in O(Math.Sqrt(N))
static bool isPrime(int N)
{
if (N < 2)
return false;
if (N < 4)
return true;
if ((N & 1) == 0)
return false;
if (N % 3 == 0)
return false;
int curr = 5, s = (int) Math.Sqrt(N);
// Loop to check if any number
// number is divisible by any
// other number or not
while (curr <= s) {
if (N % curr == 0)
return false;
curr += 2;
if (N % curr == 0)
return false;
curr += 4;
}
return true;
}
// Function to check whether window
// size satisfies condition or not
static bool check(int s, int p,
int []prefix_sum, int n)
{
bool satisfies = true;
// Loop to check each window of
// size have atleast P primes
for (int i = 0; i < n; i++) {
if (i + s - 1 >= n)
break;
// Checking condition
// using prefix sum
if (prefix_sum[i + s - 1] -
(i - 1 >= 0 ?
prefix_sum[i - 1] : 0) < p)
satisfies = false;
}
return satisfies;
}
// Function to find the minimum
// window size possible for the
// given range in X and Y
static int minimumWindowSize(int x, int y,
int p)
{
// Prefix array
int []prefix_sum = new int[y - x + 1];
// Mark those numbers
// which are primes as 1
for (int i = x; i <= y; i++) {
if (isPrime(i))
prefix_sum[i - x] = 1;
}
// Convert to prefix sum
for (int i = 1; i < y - x + 1; i++)
prefix_sum[i] +=
prefix_sum[i - 1];
// Applying binary search
// over window size
int low = 1, high = y - x + 1;
int mid;
while (high - low > 1) {
mid = (low + high) / 2;
// Check whether mid satisfies
// the condition or not
if (check(mid, p,
prefix_sum, y - x + 1)) {
// If satisfies search
// in first half
high = mid;
}
// Else search in second half
else
low = mid;
}
if (check(low, p,
prefix_sum, y - x + 1))
return low;
return high;
}
// Driver Code
public static void Main(String[] args)
{
int x = 12;
int y = 42;
int p = 3;
Console.Write(minimumWindowSize(x, y, p));
}
}
// This code is contributed by 29AjayKumar
14
时间复杂度: O(N * log(N))
辅助空间: O(N)