给定一个数组arr []以及两个整数N和K ,任务是选择大小为K的非重叠N个子数组,以使所有子数组的最大元素最小。
注意:如果不可能选择N个这样的子数组,则返回-1。
例子:
Input: arr[] = {1, 10, 3, 10, 2}, N = 3, K = 1
Output: 3
Explanation:
The three non-overlapping subarrays are –
Subarrays => {{1}, {2}, {3}}
Maximum of these subarrays are => 3
Input: arr[] = {7, 7, 7, 7, 12, 7, 7}, N = 2, K = 3
Output: 12
Explanation:
The two non-overlapping subarrays are –
Subarrays => {{7, 7, 7}, {7, 12, 7}}
Maximum element of these subarrays are => 12
方法:想法是使用二进制搜索。以下是二进制搜索的图示:
- 搜索空间:由于我们必须从N个子数组中找到最大元素,这是数组中的元素之一。因此,搜索空间将是数组的最小元素到最大元素。
- 二进制搜索函数:对分检索的函数是找到K的计数大小在阵列可能与所有元素小于给定数目,这将是搜索空间的中部。
- 左搜索空间:当可能的K个大小的子数组的数量大于或等于N时的条件,则可能的答案可能在左搜索空间中。
- 右搜索空间:当K个大小可能的子数组的数量小于N时的条件,则答案可能扫描位于右搜索空间中。
下面是上述方法的实现:
C++
// C++ implementation to choose
// N subarrays of size K such that
// the maximum element of
// subarrays is minimum
#include
using namespace std;
// Function to choose
// N subarrays of size K such that
// the maximum element of
// subarrays is minimum
int minDays(vector& arr,
int n, int k)
{
int l = arr.size(),
left = 1, right = 1e9;
// Condition to check if it
// is not possible to choose k
// sized N subarrays
if (n * k > l)
return -1;
// Using binary search
while (left < right) {
// calculating mid
int mid = (left + right) / 2,
cnt = 0, product = 0;
// Loop to find the count of the
// K sized subarrays possible with
// elements less than mid
for (int j = 0; j < l; ++j) {
if (arr[j] > mid) {
cnt = 0;
}
else if (++cnt >= k) {
product++;
cnt = 0;
}
}
// Condition to check if the
// answer is in right subarray
if (product < n) {
left = mid + 1;
}
else {
right = mid;
}
}
return left;
}
// Driver Code
int main()
{
vector arr{ 1, 10, 3, 10, 2 };
int n = 3, k = 1;
// Function Call
cout << minDays(arr, n, k) << endl;
return 0;
}
Java
// Java implementation to choose
// N subarrays of size K such that
// the maximum element of
// subarrays is minimum
class GFG{
// Function to choose
// N subarrays of size K such that
// the maximum element of
// subarrays is minimum
static int minDays(int []arr,
int n, int k)
{
int l = arr.length,
left = 1, right = (int) 1e9;
// Condition to check if it
// is not possible to choose k
// sized N subarrays
if (n * k > l)
return -1;
// Using binary search
while (left < right)
{
// calculating mid
int mid = (left + right) / 2,
cnt = 0, product = 0;
// Loop to find the count of the
// K sized subarrays possible with
// elements less than mid
for (int j = 0; j < l; ++j)
{
if (arr[j] > mid)
{
cnt = 0;
}
else if (++cnt >= k)
{
product++;
cnt = 0;
}
}
// Condition to check if the
// answer is in right subarray
if (product < n)
{
left = mid + 1;
}
else
{
right = mid;
}
}
return left;
}
// Driver Code
public static void main(String[] args)
{
int []arr = {1, 10, 3, 10, 2};
int n = 3, k = 1;
// Function Call
System.out.print(minDays(arr, n, k) + "\n");
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 implementation to choose
# N subarrays of size K such that
# the maximum element of
# subarrays is minimum
# Function to choose
# N subarrays of size K such that
# the maximum element of
# subarrays is minimum
def minDays(arr, n, k):
l = len(arr)
left = 1
right = 1e9
# Condition to check if it
# is not possible to choose k
# sized N subarrays
if (n * k > l):
return -1
# Using binary search
while (left < right):
# calculating mid
mid = (left + right) // 2
cnt = 0
product = 0
# Loop to find the count of the
# K sized subarrays possible with
# elements less than mid
for j in range (l):
if (arr[j] > mid):
cnt = 0
else:
cnt += 1
if (cnt >= k):
product += 1
cnt = 0
# Condition to check if the
# answer is in right subarray
if (product < n):
left = mid + 1
else:
right = mid
return left
# Driver Code
if __name__ == "__main__":
arr = [1, 10, 3, 10, 2]
n = 3
k = 1
# Function Call
print (int(minDays(arr, n, k)))
# This code is contributed by Chitranayal
C#
// C# implementation to choose N
// subarrays of size K such that
// the maximum element of
// subarrays is minimum
using System;
class GFG{
// Function to choose N subarrays
// of size K such that the maximum
// element of subarrays is minimum
static int minDays(int []arr,
int n, int k)
{
int l = arr.Length;
int left = 1, right = (int)1e9;
// Condition to check if it
// is not possible to choose k
// sized N subarrays
if (n * k > l)
return -1;
// Using binary search
while (left < right)
{
// Calculating mid
int mid = (left + right) / 2,
cnt = 0, product = 0;
// Loop to find the count of the
// K sized subarrays possible with
// elements less than mid
for(int j = 0; j < l; ++j)
{
if (arr[j] > mid)
{
cnt = 0;
}
else if (++cnt >= k)
{
product++;
cnt = 0;
}
}
// Condition to check if the
// answer is in right subarray
if (product < n)
{
left = mid + 1;
}
else
{
right = mid;
}
}
return left;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 1, 10, 3, 10, 2 };
int n = 3, k = 1;
// Function Call
Console.Write(minDays(arr, n, k) + "\n");
}
}
// This code is contributed by Amit Katiyar
输出:
3
时间复杂度: O(N * logN)