最大化可以根据给定条件组合在一起的数字
给定一个大小为N x 2的二维数组A[][] ,其中:
- 每个元素都位于[1, N] 之间。
- A[i][0]表示至多必须有严格小于i+1的 A[i][0]个元素和至多严格大于 i+1 的A[i][1] 个元素。
任务是找到符合上述条件的最大元素数。
例子:
Input: N = 3, A[][] = {{1, 2}, {2, 1}, {1, 1]}
Output: 2
Explanation: If 1, 2, 3 all come together, then there is 0 (at most 1) element less than 1 and 2(at most 2) are greater.
1(at most 2) element less than 2 and 1(at most 1) greater 2.
For 3 there are 2 elements less than 3 but as per the condition there can be at most 1 element smaller than 3.
So cannot include 3. Therefore maximum 2 elements can be selected together.
Input: N = 5, A[][] = {{2, 3}, {4, 2}, {3, 1}, {3, 1}, {1, 1}};
Output: 4
天真的方法:这个想法是基于这样一个概念,即最少 1 个元素可以保存在一个集合中,并且最多可以将所有元素保存在一起,即N
- 最初,对于1 <= K <= N的K值,检查是否可以按照条件将K个元素组合在一起。
- 从N个元素中选择K个元素,并检查从1 到 N的所有K的以下条件。
- 检查每个候选人i从1 到 N :
- 如果C个候选者已经属于K个元素的集合,那么对于 第i 个元素属于一组K数, i必须恰好有C个元素小于且KC-1 个元素大于i 。
- 通过这种方式,计算有效候选者并检查是否可以将K个元素放在一个集合中。
- 检查每个候选人i从1 到 N :
- 最后,最大K就是答案。
时间复杂度: O(N 2 )
辅助空间: O(1)
有效的方法:更好的方法是使用二分搜索来解决。
- 不要检查K的每个可能值,而是在那里使用二分搜索。
- 好像可以将K个元素保持在一起,这意味着也可以将任何较低值的 K 个元素保持在一起。
- 因此,请检查更高的值,如果无法将K个元素保持在一起,则意味着无法将更高的K值组合在一起。
- 当较低和较高的价值都成为答案时。
以下是上述方法的实现:
Java
// C++ code to implement the approach
#include
using namespace std;
// Function to check if it is possible
// to keep k elements together
bool isPossible(vector >& a,
int n, int k)
{
// Initially the set is empty, so
// candidates present is 0
int candidatePresent = 0;
// Loop through all the candidates
for (int i = 0; i < n; i++) {
// For i to be a part of the set
// i's condition must allow to keep
// Atleast candidatePresent number of
// Elements smaller than i
// And k-candidatePresent-1
// Number of elements larger than i
// If so then add i
// To the set of k numbers
if (a[i][0] >= candidatePresent
&& a[i][1] >= k - candidatePresent
- 1)
candidatePresent++;
}
// If possible to keep at lest k
// elements together return true
if (candidatePresent >= k)
return true;
// Else return false
return false;
}
int maxElementsinSet(vector >& a,
int n)
{
int left = 1, right = n;
int ans = 1;
while (left <= right) {
int mid = (left + right) / 2;
// If it is possible to keep mid
// elements together them mid
// is a possible answer and also
// check for higher values of mid
if (isPossible(a, n, mid)) {
ans = mid;
left = mid + 1;
}
// Else check for lower values of mid
else
right = mid - 1;
}
return ans;
}
// Driver Code
int main()
{
int N = 5;
vector > A = {
{ 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
};
cout << maxElementsinSet(A, N);
return 0;
}
Java
// Java code to implement the approach
import java.util.*;
public class GFG {
// Function to check if it is possible
// to keep k elements together
static boolean isPossible(int a[][], int n, int k)
{
// Initially the set is empty, so
// candidates present is 0
int candidatePresent = 0;
// Loop through all the candidates
for (int i = 0; i < n; i++) {
// For i to be a part of the set
// i's condition must allow to keep
// Atleast candidatePresent number of
// Elements smaller than i
// And k-candidatePresent-1
// Number of elements larger than i
// If so then add i
// To the set of k numbers
if (a[i][0] >= candidatePresent
&& a[i][1] >= k - candidatePresent - 1)
candidatePresent++;
}
// If possible to keep at lest k
// elements together return true
if (candidatePresent >= k)
return true;
// Else return false
return false;
}
static int maxElementsinSet(int a[][], int n)
{
int left = 1, right = n;
int ans = 1;
while (left <= right) {
int mid = (left + right) / 2;
// If it is possible to keep mid
// elements together them mid
// is a possible answer and also
// check for highr values of mid
if (isPossible(a, n, mid) == true) {
ans = mid;
left = mid + 1;
}
// Else check for lower values of mid
else
right = mid - 1;
}
return ans;
}
// Driver Code
public static void main(String arg[])
{
int N = 5;
int A[][] = {
{ 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
};
System.out.println(maxElementsinSet(A, N));
}
}
// This code is contributed by Samim Hossain Mondal.
Python
# Python code to implement the approach
# Function to check if it is possible
# to keep k elements together
def isPossible(a, n, k):
# Initially the set is empty, so
# candidates present is 0
candidatePresent = 0
# Loop through all the candidates
for i in range(n):
# For i to be a part of the set
# i's condition must allow to keep
# Atleast candidatePresent number of
# Elements smaller than i
# And k-candidatePresent-1
# Number of elements larger than i
# If so then add i
# To the set of k numbers
if (a[i][0] >= candidatePresent
and a[i][1] >= k - candidatePresent
- 1):
candidatePresent += 1
# If possible to keep at lest k
# elements together return true
if (candidatePresent >= k):
return 1
# Else return false
return 0
def maxElementsinSet(a, n):
left = 1
right = n
ans = 1
while (left <= right):
mid = (left + right) / 2
# If it is possible to keep mid
# elements together them mid
# is a possible answer and also
# check for highr values of mid
if (isPossible(a, n, mid)):
ans = mid
left = mid + 1
# Else check for lower values of mid
else:
right = mid - 1
print(ans)
# Driver Code
if __name__ == "__main__":
N = 5;
A = [[ 2, 3 ], [ 4, 2 ], [ 3, 1 ], [ 3, 1 ], [ 1, 1 ]]
maxElementsinSet(A, N)
# This code is contributed by hrithikgarg03188.
C#
// C# code to implement the approach
using System;
public class GFG {
// Function to check if it is possible
// to keep k elements together
static bool isPossible(int[, ] a, int n, int k)
{
// Initially the set is empty, so
// candidates present is 0
int candidatePresent = 0;
// Loop through all the candidates
for (int i = 0; i < n; i++) {
// For i to be a part of the set
// i's condition must allow to keep
// Atleast candidatePresent number of
// Elements smaller than i
// And k-candidatePresent-1
// Number of elements larger than i
// If so then add i
// To the set of k numbers
if (a[i, 0] >= candidatePresent
&& a[i, 1] >= k - candidatePresent - 1)
candidatePresent++;
}
// If possible to keep at lest k
// elements together return true
if (candidatePresent >= k)
return true;
// Else return false
return false;
}
static int maxElementsinSet(int[, ] a, int n)
{
int left = 1, right = n;
int ans = 1;
while (left <= right) {
int mid = (left + right) / 2;
// If it is possible to keep mid
// elements together them mid
// is a possible answer and also
// check for highr values of mid
if (isPossible(a, n, mid) == true) {
ans = mid;
left = mid + 1;
}
// Else check for lower values of mid
else
right = mid - 1;
}
return ans;
}
// Driver Code
public static void Main(String[] arg)
{
int N = 5;
int[, ] A = {
{ 2, 3 }, { 4, 2 }, { 3, 1 }, { 3, 1 }, { 1, 1 }
};
Console.WriteLine(maxElementsinSet(A, N));
}
}
// This code is contributed by shikhasingrajput
Javascript
4
时间复杂度: O(N*logN)
辅助空间: O(1)