给定两个数组arr []和brr []以及一个整数C ,任务是找到相同索引子数组的最大可能长度,例如K ,使得brr []中K长度子数组中最大元素的总和为K和arr []中K长度子数组之和之间的乘积不超过C。
例子:
Input: arr[] = {2, 1, 3, 4, 5}, brr[] = {3, 6, 1, 3, 4}, C = 25
Output: 3
Explanation: Considering the subarrays arr[] = {2, 1, 3} ( Sum = 6) and brr[] = {3, 6, 1} ( Maximum element = 6), Maximum element + sum * K = 6 + 6 * 3 = 24, which is less than C( = 25).
Input: arr[] ={1, 2, 1, 6, 5, 5, 6, 1}, brr[] = {14, 8, 15, 15, 9, 10, 7, 12}, C = 40
Output: 3
Explanation: Considering the subarrays arr[] = {1, 2, 1} ( Sum = 4) and brr[] = {14, 8, 15} ( Maximum element = 6), Maximum element + sum * K = 15 + 4 * 3 = 27, which is less than C( = 40).
天真的方法:最简单的方法是生成两个给定数组的所有可能的子数组,并考虑两个数组中所有相似的索引子数组,并检查给定条件。打印满足给定条件的子数组的最大长度。
时间复杂度: O(K * N 2 )
辅助空间: O(1)
基于二进制搜索的方法:为了优化上述方法,其思想是使用二进制搜索来找到K的可能值,并使用滑动窗口技术来找到长度为K的每个子数组的总和。请按照以下步骤解决问题:
- 建立细分树以在所有可能范围内找到最大值。
- 在[0,N]范围内执行二进制搜索以找到子数组的最大可能大小。
- 初始化低为0和高为N。
- 找到中间的2值作为(低+高)/。
- 通过检查给定条件,检查是否有可能使子数组的最大大小为中值。如果发现为真,则更新最大长度为中低如(中间+ 1)。
- 否则,更新高(中- 1)。
- 完成上述步骤后,打印存储的最大长度值。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
// Stores the segment tree node values
int seg[10000];
// Function to find maximum element
// in the given range
int getMax(int b[], int ss, int se, int qs,
int qe, int index)
{
// If the query is out of bounds
if (se < qs || ss > qe)
return INT_MIN / 2;
// If the segment is completey
// inside the query range
if (ss >= qs && se <= qe)
return seg[index];
// Calculte the mid
int mid = ss + (se - ss) / 2;
// Return maximum in left & right
// of the segment tree recursively
return max(
getMax(b, ss, mid, qs,
qe, 2 * index + 1),
getMax(b, mid + 1, se,
qs, qe, 2 * index + 2));
}
// Function to check if it is possible
// to have such a subarray of length K
bool possible(int a[], int b[], int n,
int c, int k)
{
int sum = 0;
// Check for first window of size K
for(int i = 0; i < k; i++)
{
sum += a[i];
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k + getMax(
b, 0, n - 1,
0, k - 1, 0);
// If it satisfy the condition
if (total_cost <= c)
return true;
// Find the sum of current subarray
// and calculate total cost
for(int i = k; i < n; i++)
{
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Calculate total cost
// and check <=c
total_cost = sum * k + getMax(
b, 0, n - 1,
i - k + 1, i, 0);
// If possible, then
// return true
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
int maxLength(int a[], int b[], int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high)
{
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid) != false)
{
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Function that builds segment Tree
void build(int b[], int index, int s, int e)
{
// If there is only one element
if (s == e)
{
seg[index] = b[s];
return;
}
// Find the value of mid
int mid = s + (e - s) / 2;
// Build left and right parts
// of segement tree recursively
build(b, 2 * index + 1, s, mid);
build(b, 2 * index + 2, mid + 1, e);
// Update the value at current
// index
seg[index] = max(
seg[2 * index + 1],
seg[2 * index + 2]);
}
// Function that initializes the
// segment Tree
void initialiseSegmentTree(int N)
{
int seg[4 * N];
}
// Driver Code
int main()
{
int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
int C = 40;
int N = sizeof(A) / sizeof(A[0]);
// Initialize and Build the
// Segment Tree
initialiseSegmentTree(N);
build(B, 0, 0, N - 1);
// Function Call
cout << (maxLength(A, B, N, C));
}
// This code is contributed by susmitakundugoaldanga
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Stores the segment tree node values
static int seg[];
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
public static int maxLength(
int a[], int b[], int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high) {
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid)) {
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Function to check if it is possible
// to have such a subarray of length K
public static boolean possible(
int a[], int b[], int n,
int c, int k)
{
int sum = 0;
// Check for first window of size K
for (int i = 0; i < k; i++) {
sum += a[i];
}
// Calculte the total cost and
// check if less than equal to c
int total_cost
= sum * k + getMax(b, 0, n - 1,
0, k - 1, 0);
// If it satisfy the condition
if (total_cost <= c)
return true;
// Find the sum of current subarray
// and calculate total cost
for (int i = k; i < n; i++) {
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Calculate total cost
// and check <=c
total_cost
= sum * k
+ getMax(b, 0, n - 1,
i - k + 1, i, 0);
// If possible, then
// return true
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Function that builds segment Tree
public static void build(
int b[], int index, int s, int e)
{
// If there is only one element
if (s == e) {
seg[index] = b[s];
return;
}
// Find the value of mid
int mid = s + (e - s) / 2;
// Build left and right parts
// of segement tree recursively
build(b, 2 * index + 1, s, mid);
build(b, 2 * index + 2, mid + 1, e);
// Update the value at current
// index
seg[index] = Math.max(
seg[2 * index + 1],
seg[2 * index + 2]);
}
// Function to find maximum element
// in the given range
public static int getMax(
int b[], int ss, int se, int qs,
int qe, int index)
{
// If the query is out of bounds
if (se < qs || ss > qe)
return Integer.MIN_VALUE / 2;
// If the segment is completey
// inside the query range
if (ss >= qs && se <= qe)
return seg[index];
// Calculte the mid
int mid = ss + (se - ss) / 2;
// Return maximum in left & right
// of the segment tree recursively
return Math.max(
getMax(b, ss, mid, qs,
qe, 2 * index + 1),
getMax(b, mid + 1, se,
qs, qe, 2 * index + 2));
}
// Function that initializes the
// segment Tree
public static void
initialiseSegmentTree(int N)
{
seg = new int[4 * N];
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
int C = 40;
int N = A.length;
// Initialize and Build the
// Segment Tree
initialiseSegmentTree(N);
build(B, 0, 0, N - 1);
// Function Call
System.out.println(maxLength(A, B, N, C));
}
}
Python3
# Python3 program for the above approach
import math
# Stores the segment tree node values
seg = [0 for x in range(10000)]
INT_MIN = int(-10000000)
# Function to find maximum element
# in the given range
def getMax(b, ss, se, qs, qe, index):
# If the query is out of bounds
if (se < qs or ss > qe):
return int(INT_MIN / 2)
# If the segment is completey
# inside the query range
if (ss >= qs and se <= qe):
return seg[index]
# Calculte the mid
mid = int(int(ss) + int((se - ss) / 2))
# Return maximum in left & right
# of the segment tree recursively
return max(getMax(b, ss, mid, qs,
qe, 2 * index + 1),
getMax(b, mid + 1, se, qs,
qe, 2 * index + 2))
# Function to check if it is possible
# to have such a subarray of length K
def possible(a, b, n, c, k):
sum = int(0)
# Check for first window of size K
for i in range(0, k):
sum += a[i]
# Calculte the total cost and
# check if less than equal to c
total_cost = int(sum * k +
getMax(b, 0, n - 1,
0, k - 1, 0))
# If it satisfy the condition
if (total_cost <= c):
return 1
# Find the sum of current subarray
# and calculate total cost
for i in range (k, n):
# Include the new element
# of current subarray
sum += a[i]
# Discard the element
# of last subarray
sum -= a[i - k]
# Calculate total cost
# and check <=c
total_cost = int(sum * k + getMax(
b, 0, n - 1,i - k + 1, i, 0))
# If possible, then
# return true
if (total_cost <= c):
return 1
# If it is not possible
return 0
# Function to find maximum length
# of subarray such that sum of
# maximum element in subarray in brr[] and
# sum of subarray in arr[] * K is at most C
def maxLength(a, b, n, c):
# Base Case
if (n == 0):
return 0
# Let maximum length be 0
max_length = int(0)
low = 0
high = n
# Perform Binary search
while (low <= high):
# Find mid value
mid = int(low + int((high - low) / 2))
# Check if the current mid
# satisfy the given condition
if (possible(a, b, n, c, mid) != 0):
# If yes, then store length
max_length = mid
low = mid + 1
# Otherwise
else:
high = mid - 1
# Return maximum length stored
return max_length
# Function that builds segment Tree
def build(b, index, s, e):
# If there is only one element
if (s == e):
seg[index] = b[s]
return
# Find the value of mid
mid = int(s + int((e - s) / 2))
# Build left and right parts
# of segement tree recursively
build(b, 2 * index + 1, s, mid)
build(b, 2 * index + 2, mid + 1, e)
# Update the value at current
# index
seg[index] = max(seg[2 * index + 1],
seg[2 * index + 2])
# Driver Code
A = [ 1, 2, 1, 6, 5, 5, 6, 1 ]
B = [ 14, 8, 15, 15, 9, 10, 7, 12 ]
C = int(40)
N = len(A)
# Initialize and Build the
# Segment Tree
build(B, 0, 0, N - 1)
# Function Call
print((maxLength(A, B, N, C)))
# This code is contributed by Stream_Cipher
C#
// C# program for the above approach
using System;
class GFG{
// Stores the segment tree node values
static int[] seg;
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
static int maxLength(int[] a, int[] b,
int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high)
{
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid))
{
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Function to check if it is possible
// to have such a subarray of length K
static bool possible(int[] a, int[] b, int n,
int c, int k)
{
int sum = 0;
// Check for first window of size K
for(int i = 0; i < k; i++)
{
sum += a[i];
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k +
getMax(b, 0, n - 1,
0, k - 1, 0);
// If it satisfy the condition
if (total_cost <= c)
return true;
// Find the sum of current subarray
// and calculate total cost
for(int i = k; i < n; i++)
{
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Calculate total cost
// and check <=c
total_cost = sum * k +
getMax(b, 0, n - 1,
i - k + 1, i, 0);
// If possible, then
// return true
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Function that builds segment Tree
static void build(int[] b, int index,
int s, int e)
{
// If there is only one element
if (s == e)
{
seg[index] = b[s];
return;
}
// Find the value of mid
int mid = s + (e - s) / 2;
// Build left and right parts
// of segement tree recursively
build(b, 2 * index + 1, s, mid);
build(b, 2 * index + 2, mid + 1, e);
// Update the value at current
// index
seg[index] = Math.Max(
seg[2 * index + 1],
seg[2 * index + 2]);
}
// Function to find maximum element
// in the given range
public static int getMax(int[] b, int ss,
int se, int qs,
int qe, int index)
{
// If the query is out of bounds
if (se < qs || ss > qe)
return Int32.MinValue / 2;
// If the segment is completey
// inside the query range
if (ss >= qs && se <= qe)
return seg[index];
// Calculte the mid
int mid = ss + (se - ss) / 2;
// Return maximum in left & right
// of the segment tree recursively
return Math.Max(
getMax(b, ss, mid, qs,
qe, 2 * index + 1),
getMax(b, mid + 1, se,
qs, qe, 2 * index + 2));
}
// Function that initializes the
// segment Tree
static void initialiseSegmentTree(int N)
{
seg = new int[4 * N];
}
// Driver Code
static void Main()
{
int[] A = { 1, 2, 1, 6, 5, 5, 6, 1 };
int[] B = { 14, 8, 15, 15, 9, 10, 7, 12 };
int C = 40;
int N = A.Length;
// Initialize and Build the
// Segment Tree
initialiseSegmentTree(N);
build(B, 0, 0, N - 1);
// Function Call
Console.WriteLine(maxLength(A, B, N, C));
}
}
// This code is contributed by divyesh072019
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if it is possible
// to have such a subarray of length K
bool possible(int a[], int b[], int n, int c,
int k)
{
// Finds the maximum element
// in each window of size k
deque dq;
// Check for window of size K
int sum = 0;
// For all possible subarrays of
// length k
for (int i = 0; i < k; i++)
{
sum += a[i];
// Until deque is empty
while (dq.size() > 0 && b[i] > b[dq.back()])
dq.pop_back();
dq.push_back(i);
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k + b[dq.front()];
if (total_cost <= c)
return true;
// Find sum of current subarray
// and the total cost
for (int i = k; i < n; i++)
{
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Remove all the elements
// in the old window
while (dq.size() > 0 && dq.front() <= i - k)
dq.pop_front();
while (dq.size() > 0 && b[i] > b[dq.back()])
dq.pop_back();
dq.push_back(i);
// Calculate total cost
// and check <=c
total_cost = sum * k + b[dq.front()];
// If current subarray
// length satisfies
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
int maxLength(int a[], int b[], int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high)
{
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid))
{
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Driver Code
int main()
{
int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
int N = sizeof(A)/sizeof(A[0]);
int C = 40;
cout << maxLength(A, B, N, C);
return 0;
}
// This code is contributed by Dharanendra L V
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
public static int maxLength(
int a[], int b[], int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high) {
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid)) {
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Function to check if it is possible
// to have such a subarray of length K
public static boolean possible(
int a[], int b[], int n, int c, int k)
{
// Finds the maximum element
// in each window of size k
Deque dq
= new LinkedList();
// Check for window of size K
int sum = 0;
// For all possible subarrays of
// length k
for (int i = 0; i < k; i++) {
sum += a[i];
// Until deque is empty
while (dq.size() > 0
&& b[i] > b[dq.peekLast()])
dq.pollLast();
dq.addLast(i);
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k
+ b[dq.peekFirst()];
if (total_cost <= c)
return true;
// Find sum of current subarray
// and the total cost
for (int i = k; i < n; i++) {
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Remove all the elements
// in the old window
while (dq.size() > 0
&& dq.peekFirst()
<= i - k)
dq.pollFirst();
while (dq.size() > 0
&& b[i]
> b[dq.peekLast()])
dq.pollLast();
dq.add(i);
// Calculate total cost
// and check <=c
total_cost = sum * k
+ b[dq.peekFirst()];
// If current subarray
// length satisfies
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
int N = A.length;
int C = 40;
System.out.println(
maxLength(A, B, N, C));
}
}
Python3
# Python3 program for the above approach
# Function to find maximum length
# of subarray such that sum of
# maximum element in subarray in brr[] and
# sum of subarray in []arr * K is at most C
def maxLength(a, b, n, c):
# Base Case
if(n == 0):
return 0
# Let maximum length be 0
max_length = 0
low = 0
high = n
# Perform Binary search
while(low <= high):
# Find mid value
mid = int(low + (high - low) / 2)
# Check if the current mid
# satisfy the given condition
if(possible(a, b, n, c, mid)):
# If yes, then store length
max_length = mid
low = mid + 1
# Otherwise
else:
high = mid - 1
# Return maximum length stored
return max_length
# Function to check if it is possible
# to have such a subarray of length K
def possible(a, b, n, c, k):
# Finds the maximum element
# in each window of size k
dq = []
# Check for window of size K
Sum = 0
# For all possible subarrays of
# length k
for i in range(k):
Sum += a[i]
# Until deque is empty
while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
dq.pop(len(dq) - 1)
dq.append(i)
# Calculte the total cost and
# check if less than equal to c
total_cost = Sum * k + b[dq[0]]
if(total_cost <= c):
return True
# Find sum of current subarray
# and the total cost
for i in range(k, n):
# Include the new element
# of current subarray
Sum += a[i]
# Discard the element
# of last subarray
Sum -= a[i - k]
# Remove all the elements
# in the old window
while(len(dq) > 0 and dq[0] <= i - k):
dq.pop(0)
while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
dq.pop(len(dq) - 1)
dq.append(i)
# Calculate total cost
# and check <=c
total_cost = Sum * k + b[dq[0]]
# If current subarray
# length satisfies
if(total_cost <= c):
return True
# If it is not possible
return False
# Driver Code
A = [1, 2, 1, 6, 5, 5, 6, 1]
B = [14, 8, 15, 15, 9, 10, 7, 12]
N = len(A)
C = 40
print(maxLength(A, B, N, C))
# This code is contributed by avanitrachhadiya2155
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in []arr * K is at most C
public static int maxLength(
int []a, int []b, int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high) {
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid)) {
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Function to check if it is possible
// to have such a subarray of length K
public static bool possible(
int []a, int []b, int n, int c, int k)
{
// Finds the maximum element
// in each window of size k
List dq
= new List();
// Check for window of size K
int sum = 0;
// For all possible subarrays of
// length k
for (int i = 0; i < k; i++) {
sum += a[i];
// Until deque is empty
while (dq.Count > 0
&& b[i] > b[dq[dq.Count - 1]])
dq.RemoveAt(dq.Count - 1);
dq.Add(i);
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k
+ b[dq[0]];
if (total_cost <= c)
return true;
// Find sum of current subarray
// and the total cost
for (int i = k; i < n; i++) {
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Remove all the elements
// in the old window
while (dq.Count > 0
&& dq[0]
<= i - k)
dq.RemoveAt(0);
while (dq.Count > 0
&& b[i]
> b[dq[dq.Count - 1]])
dq.RemoveAt(dq.Count - 1);
dq.Add(i);
// Calculate total cost
// and check <=c
total_cost = sum * k
+ b[dq[0]];
// If current subarray
// length satisfies
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Driver Code
public static void Main(String[] args)
{
int []A = { 1, 2, 1, 6, 5, 5, 6, 1 };
int []B = { 14, 8, 15, 15, 9, 10, 7, 12 };
int N = A.Length;
int C = 40;
Console.WriteLine(
maxLength(A, B, N, C));
}
}
// This code is contributed by Amit Katiyar
3
时间复杂度: O(N *(log N) 2 )
辅助空间: O(N)
高效方法:为了优化上述方法,其思想是通过使用单调队列来使用Deque,以便对于固定长度的每个子数组,我们可以在O(1)时间中找到最大值。对于[i,i + K – 1]范围内的任何子数组,要计算的值表达式由下式给出:
步骤如下:
- 在[0,N]范围内执行二进制搜索以找到子数组的最大可能大小。
- 初始化低为0和高为N。
- 找到中间的2值作为(低+高)/。
- 检查是否可以使子数组的最大大小为中值或不为:
- 使用双端队列在数组brr []中的每个大小为K的子数组中找到最大元素。
- 查找表达式的值,如果最多为C,则打破此条件。
- 否则,检查所有可能的子数组大小的中间值,以及表达式的值以及是否最大为C,然后打破此条件。
- 如果以上条件均不满足,则返回false。
- 如果当前中位数满足给定条件,则将最大长度更新为中位数,将最低长度更新为(mid +1) 。
- 否则,更新高(中- 1)。
- 完成上述步骤后,打印存储的最大长度值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if it is possible
// to have such a subarray of length K
bool possible(int a[], int b[], int n, int c,
int k)
{
// Finds the maximum element
// in each window of size k
deque dq;
// Check for window of size K
int sum = 0;
// For all possible subarrays of
// length k
for (int i = 0; i < k; i++)
{
sum += a[i];
// Until deque is empty
while (dq.size() > 0 && b[i] > b[dq.back()])
dq.pop_back();
dq.push_back(i);
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k + b[dq.front()];
if (total_cost <= c)
return true;
// Find sum of current subarray
// and the total cost
for (int i = k; i < n; i++)
{
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Remove all the elements
// in the old window
while (dq.size() > 0 && dq.front() <= i - k)
dq.pop_front();
while (dq.size() > 0 && b[i] > b[dq.back()])
dq.pop_back();
dq.push_back(i);
// Calculate total cost
// and check <=c
total_cost = sum * k + b[dq.front()];
// If current subarray
// length satisfies
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
int maxLength(int a[], int b[], int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high)
{
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid))
{
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Driver Code
int main()
{
int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
int N = sizeof(A)/sizeof(A[0]);
int C = 40;
cout << maxLength(A, B, N, C);
return 0;
}
// This code is contributed by Dharanendra L V
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in arr[] * K is at most C
public static int maxLength(
int a[], int b[], int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high) {
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid)) {
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Function to check if it is possible
// to have such a subarray of length K
public static boolean possible(
int a[], int b[], int n, int c, int k)
{
// Finds the maximum element
// in each window of size k
Deque dq
= new LinkedList();
// Check for window of size K
int sum = 0;
// For all possible subarrays of
// length k
for (int i = 0; i < k; i++) {
sum += a[i];
// Until deque is empty
while (dq.size() > 0
&& b[i] > b[dq.peekLast()])
dq.pollLast();
dq.addLast(i);
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k
+ b[dq.peekFirst()];
if (total_cost <= c)
return true;
// Find sum of current subarray
// and the total cost
for (int i = k; i < n; i++) {
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Remove all the elements
// in the old window
while (dq.size() > 0
&& dq.peekFirst()
<= i - k)
dq.pollFirst();
while (dq.size() > 0
&& b[i]
> b[dq.peekLast()])
dq.pollLast();
dq.add(i);
// Calculate total cost
// and check <=c
total_cost = sum * k
+ b[dq.peekFirst()];
// If current subarray
// length satisfies
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 1, 2, 1, 6, 5, 5, 6, 1 };
int B[] = { 14, 8, 15, 15, 9, 10, 7, 12 };
int N = A.length;
int C = 40;
System.out.println(
maxLength(A, B, N, C));
}
}
Python3
# Python3 program for the above approach
# Function to find maximum length
# of subarray such that sum of
# maximum element in subarray in brr[] and
# sum of subarray in []arr * K is at most C
def maxLength(a, b, n, c):
# Base Case
if(n == 0):
return 0
# Let maximum length be 0
max_length = 0
low = 0
high = n
# Perform Binary search
while(low <= high):
# Find mid value
mid = int(low + (high - low) / 2)
# Check if the current mid
# satisfy the given condition
if(possible(a, b, n, c, mid)):
# If yes, then store length
max_length = mid
low = mid + 1
# Otherwise
else:
high = mid - 1
# Return maximum length stored
return max_length
# Function to check if it is possible
# to have such a subarray of length K
def possible(a, b, n, c, k):
# Finds the maximum element
# in each window of size k
dq = []
# Check for window of size K
Sum = 0
# For all possible subarrays of
# length k
for i in range(k):
Sum += a[i]
# Until deque is empty
while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
dq.pop(len(dq) - 1)
dq.append(i)
# Calculte the total cost and
# check if less than equal to c
total_cost = Sum * k + b[dq[0]]
if(total_cost <= c):
return True
# Find sum of current subarray
# and the total cost
for i in range(k, n):
# Include the new element
# of current subarray
Sum += a[i]
# Discard the element
# of last subarray
Sum -= a[i - k]
# Remove all the elements
# in the old window
while(len(dq) > 0 and dq[0] <= i - k):
dq.pop(0)
while(len(dq) > 0 and b[i] > b[dq[len(dq) - 1]]):
dq.pop(len(dq) - 1)
dq.append(i)
# Calculate total cost
# and check <=c
total_cost = Sum * k + b[dq[0]]
# If current subarray
# length satisfies
if(total_cost <= c):
return True
# If it is not possible
return False
# Driver Code
A = [1, 2, 1, 6, 5, 5, 6, 1]
B = [14, 8, 15, 15, 9, 10, 7, 12]
N = len(A)
C = 40
print(maxLength(A, B, N, C))
# This code is contributed by avanitrachhadiya2155
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG {
// Function to find maximum length
// of subarray such that sum of
// maximum element in subarray in brr[] and
// sum of subarray in []arr * K is at most C
public static int maxLength(
int []a, int []b, int n, int c)
{
// Base Case
if (n == 0)
return 0;
// Let maximum length be 0
int max_length = 0;
int low = 0, high = n;
// Perform Binary search
while (low <= high) {
// Find mid value
int mid = low + (high - low) / 2;
// Check if the current mid
// satisfy the given condition
if (possible(a, b, n, c, mid)) {
// If yes, then store length
max_length = mid;
low = mid + 1;
}
// Otherwise
else
high = mid - 1;
}
// Return maximum length stored
return max_length;
}
// Function to check if it is possible
// to have such a subarray of length K
public static bool possible(
int []a, int []b, int n, int c, int k)
{
// Finds the maximum element
// in each window of size k
List dq
= new List();
// Check for window of size K
int sum = 0;
// For all possible subarrays of
// length k
for (int i = 0; i < k; i++) {
sum += a[i];
// Until deque is empty
while (dq.Count > 0
&& b[i] > b[dq[dq.Count - 1]])
dq.RemoveAt(dq.Count - 1);
dq.Add(i);
}
// Calculte the total cost and
// check if less than equal to c
int total_cost = sum * k
+ b[dq[0]];
if (total_cost <= c)
return true;
// Find sum of current subarray
// and the total cost
for (int i = k; i < n; i++) {
// Include the new element
// of current subarray
sum += a[i];
// Discard the element
// of last subarray
sum -= a[i - k];
// Remove all the elements
// in the old window
while (dq.Count > 0
&& dq[0]
<= i - k)
dq.RemoveAt(0);
while (dq.Count > 0
&& b[i]
> b[dq[dq.Count - 1]])
dq.RemoveAt(dq.Count - 1);
dq.Add(i);
// Calculate total cost
// and check <=c
total_cost = sum * k
+ b[dq[0]];
// If current subarray
// length satisfies
if (total_cost <= c)
return true;
}
// If it is not possible
return false;
}
// Driver Code
public static void Main(String[] args)
{
int []A = { 1, 2, 1, 6, 5, 5, 6, 1 };
int []B = { 14, 8, 15, 15, 9, 10, 7, 12 };
int N = A.Length;
int C = 40;
Console.WriteLine(
maxLength(A, B, N, C));
}
}
// This code is contributed by Amit Katiyar
3
时间复杂度: O(N * log N)
辅助空间: O(N)