通过进行最大吸收来最小化 Array 的大小
给定一个由N个整数和一个整数K组成的数组A ,任务是通过应用任意次数的吸收来最小化数组 A 的长度,使得:
- A (A[i]) 中的任何元素都可以吸收 A (A[j]) 中的任何其他元素,如果它至少是另一个元素的 K 倍,即A[i] >= K*A[j] 。
- 如果元素X被任何其他元素Y吸收,则Y将从阵列中移除并且不能被任何其他元素吸收。但是,X 的值保持不变。
例子:
Input: N = 8, K = 2, A = {2, 5, 7, 6, 9, 8, 2, 4}
Output: 5
Explanation: Following are the absorptions done and accordingly changes in the array:
{2, 5, 7, 6, 9, 8, 2, 4} -> {5, 7, 6, 9, 8, 2, 4}: 2 is absorbed by 5, as 5>= 2*2
{5, 7, 6, 9, 8, 2, 4} -> {5, 7, 6, 9, 8, 4}: 2 is absorbed by 8, as 8>= 2*2
{5, 7, 6, 9, 8, 4} -> {5, 7, 6, 9, 8}: 4 is absorbed by 9, as 9>=2*4
No further absorptions are possible and final size of the array becomes 5. It can be checked that if absorptions are done in some other way, the size of final array would be more than or equal to 5. Hence, the minimal possible size would be 5.
Input: N=5, K=4, A={10, 11, 12, 13, 14}
Output: 5
方法:问题可以通过两点方法解决:
Observations:
- The minimum possible size of final array can be N/2 (the case in which each element either absorbs another element or gets absorbed by another element).
- To perform the absorption process optimally, we can divide the array into two halves such that first half contain smaller elements and second half contains greater elements and greedily perform maximum absorptions.
请按照以下步骤解决此问题:
- 对给定的数组进行排序。
- 初始化两个变量i和j,它们分别指向数组的第一和第二半的第一个元素。
- 如果i处的元素的 K 次小于j处的元素,则将数组的大小减 1(因为 A[i] 将被 A[j] 吸收)。此外,将i和j加 1。
- 如果不是这样,这意味着我们需要一个更大的整数来吸收i处的整数,所以我们将j增加 1。
- 迭代完成后,返回数组的大小。
以下是基于上述方法的代码:
C++
// C++ program for Minimize the size
// of the array by doing maximum absorptions
#include
using namespace std;
// function to find the minimum size of
// the array by doing maximum absorptions
int minimumSize(int N, int K, int A[])
{
// sorting the given array
sort(A, A + N);
// initializing two variables i and j,
// i iterates through the first half
// of A and j iterates through the
// second half of A
int i = 0, j = (N + 1) / 2;
// variable to store minimum size of
// array after doing maximum absorptions.
// Initially, size of array is N
int answer = N;
// iterating the array through 2
// pointers(i and j)
while (i < (N + 1) / 2 && j < N) {
// num1 and num2 stores the value of
// elements at indices i and j in
// sorted array A. Obviously,
// num1<=num2
int num1 = A[i];
int num2 = A[j];
// checking if num2 can absorb num1
if (K * num1 <= num2) {
// if num1 is absorbed by num2,
// we increment i and j by 1 and
// decrement the size of array
// (stored in answer) by 1
i++;
j++;
answer--;
}
// since num2 can not absorb num1,
// that means we need a greater integer
// to absorb num1, so we increment
// j by 1
else {
j++;
}
}
// returning the answer
return answer;
}
// Driver Code
int main()
{
int N = 8, K = 2;
int A[] = { 2, 5, 7, 6, 9, 8, 2, 4 };
int minimum_size = minimumSize(N, K, A);
cout << minimum_size;
}
Java
// Java program for Minimize the size
// of the array by doing maximum absorptions
import java.io.*;
import java.util.Arrays;
class GFG {
// function to find the minimum size of
// the array by doing maximum absorptions
static int minimumSize(int N, int K, int A[])
{
// sorting the given array
Arrays.sort(A);
// initializing two variables i and j,
// i iterates through the first half
// of A and j iterates through the
// second half of A
int i = 0, j = (N + 1) / 2;
// variable to store minimum size of
// array after doing maximum absorptions.
// Initially, size of array is N
int answer = N;
// iterating the array through 2
// pointers(i and j)
while (i < (N + 1) / 2 && j < N) {
// num1 and num2 stores the value of
// elements at indices i and j in
// sorted array A. Obviously,
// num1<=num2
int num1 = A[i];
int num2 = A[j];
// checking if num2 can absorb num1
if (K * num1 <= num2) {
// if num1 is absorbed by num2,
// we increment i and j by 1 and
// decrement the size of array
// (stored in answer) by 1
i++;
j++;
answer--;
}
// since num2 can not absorb num1,
// that means we need a greater integer
// to absorb num1, so we increment
// j by 1
else {
j++;
}
}
// returning the answer
return answer;
}
// Driver Code
public static void main (String[] args) {
int N = 8, K = 2;
int A[] = { 2, 5, 7, 6, 9, 8, 2, 4 };
int minimum_size = minimumSize(N, K, A);
System.out.println(minimum_size);
}
}
// This code is contributed by hrithikgarg03188.
Python3
# Python3 program to implement the above approach
# function to find the minimum size of
# the array by doing maximum absorptions
def minimumSize(N, K, A):
# sorting the given array
A.sort()
# initializing two variables i and j,
# i iterates through the first half
# of A and j iterates through the
# second half of A
i = 0
j = (N + 1) // 2
# variable to store minimum size of
# array after doing maximum absorptions.
# Initially, size of array is N
answer = N
# iterating the array through 2
#pointers(i and j)
while (i < (N + 1) / 2 and j < N):
'''num1 and num2 stores the value of
elements at indices i and j in
sorted array A. Obviously,
num1<=num2'''
num1 = A[i]
num2 = A[j]
# checking if num2 can absorb num1
if K * num1 <= num2:
# if num1 is absorbed by num2,
# we increment i and j by 1 and
# decrement the size of array
# (stored in answer) by 1
i += 1
j += 1
answer -= 1
else:
# since num2 can not absorb num1,
# that means we need a greater integer
# to absorb num1, so we increment
# j by 1
j += 1
return answer
# Driver Code
N = 8
K = 2
A = [2, 5, 7, 6, 9, 8, 2, 4]
minimum_size = minimumSize(N, K, A)
print(minimum_size)
# This code is contributed by phasing17
C#
// C# program for Minimize the size
// of the array by doing maximum absorptions
using System;
using System.Collections.Generic;
class GFG
{
// function to find the minimum size of
// the array by doing maximum absorptions
static int minimumSize(int N, int K, int[] A)
{
// sorting the given array
Array.Sort(A);
// initializing two variables i and j,
// i iterates through the first half
// of A and j iterates through the
// second half of A
int i = 0;
int j = (N + 1) / 2;
// variable to store minimum size of
// array after doing maximum absorptions.
// Initially, size of array is N
int answer = N;
// iterating the array through 2
// pointers(i and j)
while ((i < (N + 1) / 2) && (j < N))
{
// num1 and num2 stores the value of
// elements at indices i and j in
// sorted array A. Obviously,
// num1<=num2
var num1 = A[i];
var num2 = A[j];
// checking if num2 can absorb num1
if ((K * num1) <= num2)
{
// if num1 is absorbed by num2,
// we increment i and j by 1 and
// decrement the size of array
// (stored in answer) by 1
i++;
j++;
answer--;
}
// since num2 can not absorb num1,
// that means we need a greater integer
// to absorb num1, so we increment
// j by 1
else
j++;
}
// returning the answer
return answer;
}
static void Main()
{
// Driver Code
var N = 8;
var K = 2;
int[] A = { 2, 5, 7, 6, 9, 8, 2, 4 };
int minimum_size = minimumSize(N, K, A);
Console.Write(minimum_size);
}
}
// This code is contributed by phasing17
Javascript
5
时间复杂度: O(N*log(N))
辅助空间: O(1)