要在给定数组中完成的最小删除操作,使得每对总和都是 2 的幂
给定一个由N个整数组成的数组arr[] ,任务是找到应该删除的最小元素数,使得对于每个剩余的元素arr[i] ,存在另一个元素arr[j],(i!=j )使得arr[i]和arr[j]的和是2的幂。如果在任意数量的删除之后,不存在这样的对,则打印 -1。
例子:
Input: arr[] ={1, 2, 3, 4, 5, 6}, N = 6
Output: 1
Explanation:
Removing 4 is sufficient as, for the remaining elements there exist an element such that their sum is a power of 2:
- For 1, there exists 3 such that (1+3=4) is a power of 2.
- For 2, there exists 6 such that (2+6=8) is a power of 2.
- For 3, there exists 1 such that (3+1=4) is a power of 2.
- For 5, there exists 3 such that (5+3=8) is a power of 2.
- For 6, there exists 2 such that (6+2=8) is a power of 2.
Input: A={1, 5, 10, 25, 50}, N=5
Output: -1
方法:这个想法是使用按位运算运算符和映射来跟踪每个元素的频率。请按照以下步骤解决问题:
- 将变量ans初始化为0 ,以存储要删除的元素的数量。
- 计算arr[]中所有元素的频率,并将它们存储在地图中,例如mp 。
- 从0 迭代到 N-1 ,对于每个当前索引i,执行以下操作:
- 将变量 say flag初始化为0 。
- 从0到 30迭代,对于每个当前索引j ,执行以下操作:
- 如果2 j和arr[i]的差值等于arr[i],并且arr [i] 的频率大于1 ,则增加flag并中断。
- 否则,如果2 j和arr[i]之差的频率大于0 ,则递增flag并中断。
- 如果标志仍然是0 ,则递增ans,因为需要删除当前元素。
- 最后,完成上述步骤后,将移除元素的计数打印为ans中得到的值,如果小于等于N,则打印-1。
以下是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate the minimum
// number of elements to be removed
// satisfying the conditions
int minimumDeletions(int arr[], int N)
{
// Stores the final answer
int ans = 0;
// Map to store frequency
// of each element
map mp;
// Traverse the array arr[]
for (int i = 0; i < N; i++)
mp[arr[i]]++;
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
// Stores whether current
// element needs to be
// removed or not
int flag = 0;
// Iterate over the range
// [0, 30]
for (int j = 0; j < 31; j++) {
// Stores 2^j
int pw = (1 << j);
// If 2^j -arr[i] equals
// to the arr[i]
if (pw - arr[i] == arr[i]) {
// If count of arr[i]
// is greater than 1
if (mp[arr[i]] > 1) {
flag = 1;
break;
}
}
// Else if count of 2^j-arr[i]
// is greater than 0
else if (mp[pw - arr[i]] > 0) {
flag = 1;
break;
}
}
// If flag is 0
if (flag == 0)
ans++;
}
// Return ans
return ans == N ? -1 : ans;
}
// Driver Code
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int N = sizeof(arr) / sizeof(arr[0]);
cout << minimumDeletions(arr, N) << endl;
int arr1[] = { 1, 5, 10, 25, 50 };
N = sizeof(arr) / sizeof(arr[0]);
cout << minimumDeletions(arr1, N) << endl;
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to calculate the minimum
// number of elements to be removed
// satisfying the conditions
static int minimumDeletions(int []arr, int N)
{
// Stores the final answer
int ans = 0;
// Map to store frequency
// of each element
Map mp = new HashMap();
// Traverse the array arr[]
for (int i = 0; i < N; i++){
if(mp.containsKey(arr[i]))
mp.put(arr[i],mp.get(arr[i]) + 1);
else
mp.put(arr[i],1);
}
// Traverse the array arr[]
for (int i = 0; i < N; i++)
{
// Stores whether current
// element needs to be
// removed or not
int flag = 0;
// Iterate over the range
// [0, 30]
for (int j = 0; j < 31; j++) {
// Stores 2^j
int pw = (1 << j);
// If 2^j -arr[i] equals
// to the arr[i]
if (pw - arr[i] == arr[i]) {
// If count of arr[i]
// is greater than 1
if (mp.containsKey(arr[i]) && mp.get(arr[i]) > 1) {
flag = 1;
break;
}
}
// Else if count of 2^j-arr[i]
// is greater than 0
else if (mp.containsKey(pw - arr[i]) && mp.get(pw - arr[i]) > 0) {
flag = 1;
break;
}
}
// If flag is 0
if (flag == 0)
ans++;
}
// Return ans
if(ans == N)
return -1;
else
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int N = arr.length;
System.out.println(minimumDeletions(arr, N));
int arr1[] = { 1, 5, 10, 25, 50 };
N = arr1.length;
System.out.print(minimumDeletions(arr1, N));
}
}
// This code is contributed by ShubhamSingh10
Python3
# Py program for the above approach
# Function to calculate the minimum
# number of elements to be removed
# satisfying the conditions
def minimumDeletions(arr, N):
# Stores the final answer
ans = 0
# Map to store frequency
# of each element
mp = {}
# Traverse the array arr[]
for i in arr:
mp[i] = mp.get(i,0)+1
# Traverse the array arr[]
for i in range(N):
# Stores whether current
# element needs to be
# removed or not
flag = 0
# Iterate over the range
# [0, 30]
for j in range(31):
# Stores 2^j
pw = (1 << j)
# If 2^j -arr[i] equals
# to the arr[i]
if i >= len(arr):
break
if (pw - arr[i] == arr[i]):
# If count of arr[i]
# is greater than 1
if (mp[arr[i]] > 1):
flag = 1
break
# Else if count of 2^j-arr[i]
# is greater than 0
elif (((pw - arr[i]) in mp) and mp[pw - arr[i]] > 0):
flag = 1
break
# If flag is 0
if (flag == 0):
ans += 1
# Return ans
return -1 if ans == N else ans
# Driver Code
if __name__ == '__main__':
arr= [1, 2, 3, 4, 5, 6]
N = len(arr)
print (minimumDeletions(arr, N))
arr1= [1, 5, 10, 25, 50]
N = len(arr)
print (minimumDeletions(arr1, N))
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to calculate the minimum
// number of elements to be removed
// satisfying the conditions
static int minimumDeletions(int []arr, int N)
{
// Stores the final answer
int ans = 0;
// Map to store frequency
// of each element
Dictionary mp = new Dictionary();
// Traverse the array arr[]
for (int i = 0; i < N; i++){
if(mp.ContainsKey(arr[i]))
mp[arr[i]] += 1;
else
mp.Add(arr[i],1);
}
// Traverse the array arr[]
for (int i = 0; i < N; i++)
{
// Stores whether current
// element needs to be
// removed or not
int flag = 0;
// Iterate over the range
// [0, 30]
for (int j = 0; j < 31; j++) {
// Stores 2^j
int pw = (1 << j);
// If 2^j -arr[i] equals
// to the arr[i]
if (pw - arr[i] == arr[i]) {
// If count of arr[i]
// is greater than 1
if (mp.ContainsKey(arr[i]) && mp[arr[i]] > 1) {
flag = 1;
break;
}
}
// Else if count of 2^j-arr[i]
// is greater than 0
else if (mp.ContainsKey(pw - arr[i]) && mp[pw - arr[i]] > 0) {
flag = 1;
break;
}
}
// If flag is 0
if (flag == 0)
ans++;
}
// Return ans
if(ans == N)
return -1;
else
return ans;
}
// Driver Code
public static void Main()
{
int []arr = { 1, 2, 3, 4, 5, 6 };
int N = arr.Length;
Console.WriteLine(minimumDeletions(arr, N));
int []arr1 = { 1, 5, 10, 25, 50 };
N = arr1.Length;
Console.Write(minimumDeletions(arr1, N));
}
}
// This code is contributed by SURENDRA_GANGWAR.
Javascript
输出:
1
-1
时间复杂度: O(30*N)
辅助空间: O(1)