Given two arrays a[] and b[] of size n. The task is to create an array the same size using the elements from both the arrays such that the new array formed contains n greatest but unique elements of both the arrays. The order of elements should follow the below rules.
- All elements of second array appear before first array.
- The order of appearance of elements is kept same in output as in input.
Examples:
Input: a[] = [2, 4, 3] , b[] = [5, 6, 1]
Output: 5 6 4
Explanation: As 5, 6 and 4 are maximum elements from two arrays giving second array higher priority. Order of elements is same in output as in input.Input: a[] = [7, 4, 8, 0, 1] , b[] = [9, 10, 2, 3, 6]
Output: 9 10 6 7 8
Explanation: As 10, 9, 8, 7 and 6 are maximum elements from two arrays giving second array higher priority. Order of elements is same in output as in input.
Table of Content
Using Sorting - O(n log n) Time and O(n) Space
The idea is to merge both arrays and sort the merged array in decreasing order. Then store the
nlargest unique elements using a hash set. Finally, traversebfirst andanext, and add elements toansonly if they are among the selected elements and are not already added. This maintains the required order and gives the maximum unique elements.
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
using namespace std;
vector<int> maximizeArray(vector<int> &a, vector<int> &b)
{
int n = a.size();
// merge both arrays
vector<int> merged;
for (int x : a)
merged.push_back(x);
for (int x : b)
merged.push_back(x);
// sort in decreasing order
sort(merged.begin(), merged.end(), greater<int>());
// pick n largest unique elements
unordered_set<int> hash;
int i = 0;
while (i < merged.size() && hash.size() < n)
{
hash.insert(merged[i]);
i++;
}
// maintain order (b first then a)
vector<int> ans;
unordered_set<int> used;
// b first
for (int x : b)
{
if (hash.count(x) && !used.count(x))
{
ans.push_back(x);
used.insert(x);
}
}
// then a
for (int x : a)
{
if (hash.count(x) && !used.count(x))
{
ans.push_back(x);
used.insert(x);
}
}
return ans;
}
// Driver Code
int main()
{
vector<int> a = {7, 4, 8, 0, 1};
vector<int> b = {9, 10, 2, 3, 6};
vector<int> ans = maximizeArray(a, b);
for (int x : ans)
{
cout << x << " ";
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Function to compare integers for qsort
int compare(const void *a, const void *b) {
return (*(int*)b - *(int*)a);
}
int main() {
int a[] = {7, 4, 8, 0, 1};
int b[] = {9, 10, 2, 3, 6};
int n = sizeof(a) / sizeof(a[0]);
int m = sizeof(b) / sizeof(b[0]);
int merged[n + m];
// merge both arrays
memcpy(merged, a, n * sizeof(int));
memcpy(merged + n, b, m * sizeof(int));
// sort in decreasing order
qsort(merged, n + m, sizeof(int), compare);
// pick n largest unique elements
int hash[100] = {0};
int i = 0;
int count = 0;
while (i < n + m && count < n) {
if (hash[merged[i]] == 0) {
hash[merged[i]] = 1;
count++;
}
i++;
}
// maintain order (b first then a)
int ans[n];
int used[100] = {0};
int j = 0;
// b first
for (i = 0; i < m; i++) {
if (hash[b[i]] &&!used[b[i]]) {
ans[j++] = b[i];
used[b[i]] = 1;
}
}
// then a
for (i = 0; i < n; i++) {
if (hash[a[i]] && !used[a[i]]) {
ans[j++] = a[i];
used[a[i]] = 1;
}
}
// Print the result
for (i = 0; i < n; i++) {
printf("%d ", ans[i]);
}
return 0;
}
import java.util.*;
public class GfG {
public static List<Integer> maximizeArray(int[] a, int[] b) {
int n = a.length;
// merge both arrays
List<Integer> merged = new ArrayList<>();
for (int x : a)
merged.add(x);
for (int x : b)
merged.add(x);
// sort in decreasing order
merged.sort((x, y) -> y - x);
// pick n largest unique elements
Set<Integer> hash = new HashSet<>();
int i = 0;
while (i < merged.size() && hash.size() < n) {
hash.add(merged.get(i));
i++;
}
// maintain order (b first then a)
List<Integer> ans = new ArrayList<>();
Set<Integer> used = new HashSet<>();
// b first
for (int x : b) {
if (hash.contains(x) &&!used.contains(x)) {
ans.add(x);
used.add(x);
}
}
// then a
for (int x : a) {
if (hash.contains(x) &&!used.contains(x)) {
ans.add(x);
used.add(x);
}
}
return ans;
}
public static void main(String[] args) {
int[] a = {7, 4, 8, 0, 1};
int[] b = {9, 10, 2, 3, 6};
List<Integer> ans = maximizeArray(a, b);
for (int x : ans) {
System.out.print(x + " ");
}
}
}
def maximizeArray(a, b):
n = len(a)
# merge both arrays
merged = a + b
# sort in decreasing order
merged.sort(reverse=True)
# pick n largest unique elements
hash = set()
i = 0
while i < len(merged) and len(hash) < n:
hash.add(merged[i])
i += 1
# maintain order (b first then a)
ans = []
used = set()
# b first
for x in b:
if x in hash and x not in used:
ans.append(x)
used.add(x)
# then a
for x in a:
if x in hash and x not in used:
ans.append(x)
used.add(x)
return ans
# Driver Code
if __name__ == '__main__':
a = [7, 4, 8, 0, 1]
b = [9, 10, 2, 3, 6]
ans = maximizeArray(a, b)
for x in ans:
print(x, end=' ')
using System;
using System.Collections.Generic;
using System.Linq;
public class GfG
{
public static List<int> MaximizeArray(List<int> a, List<int> b)
{
int n = a.Count;
// merge both arrays
List<int> merged = new List<int>(a);
merged.AddRange(b);
// sort in decreasing order
merged.Sort();
merged.Reverse();
// pick n largest unique elements
HashSet<int> hash = new HashSet<int>();
int i = 0;
while (i < merged.Count && hash.Count < n)
{
hash.Add(merged[i]);
i++;
}
// maintain order (b first then a)
List<int> ans = new List<int>();
HashSet<int> used = new HashSet<int>();
// b first
foreach (int x in b)
{
if (hash.Contains(x) && !used.Contains(x))
{
ans.Add(x);
used.Add(x);
}
}
// then a
foreach (int x in a)
{
if (hash.Contains(x) &&!used.Contains(x))
{
ans.Add(x);
used.Add(x);
}
}
return ans;
}
public static void Main()
{
List<int> a = new List<int> { 7, 4, 8, 0, 1 };
List<int> b = new List<int> { 9, 10, 2, 3, 6 };
List<int> ans = MaximizeArray(a, b);
foreach (int x in ans)
{
Console.Write(x + " ");
}
}
}
function maximizeArray(a, b) {
let n = a.length;
// merge both arrays
let merged = a.concat(b);
// sort in decreasing order
merged.sort((x, y) => y - x);
// pick n largest unique elements
let hash = new Set();
let i = 0;
while (i < merged.length && hash.size < n) {
hash.add(merged[i]);
i++;
}
// maintain order (b first then a)
let ans = [];
let used = new Set();
// b first
for (let x of b) {
if (hash.has(x) &&!used.has(x)) {
ans.push(x);
used.add(x);
}
}
// then a
for (let x of a) {
if (hash.has(x) &&!used.has(x)) {
ans.push(x);
used.add(x);
}
}
return ans;
}
// Driver Code
let a = [7, 4, 8, 0, 1];
let b = [9, 10, 2, 3, 6];
let ans = maximizeArray(a, b);
for (let x of ans) {
process.stdout.write(x + ' ');
}
Output
9 10 6 7 8
Time Complexity: O(n log n)
Auxiliary Space: O(n)
Using Priority Queue - O(n log n) Time and O(n) Space
The idea is to use a max heap to store all elements of both arrays so that the largest elements can be accessed efficiently. Then store the
nlargest unique elements in a hash set. Finally, traversebfirst andanext, and add elements toansonly if they belong to the selected elements and are not already added. This maintains the required order and gives the maximum unique elements.
#include <iostream>
#include <queue>
#include <unordered_set>
#include <vector>
using namespace std;
// Function to maximize array elements
vector<int> maximizeArray(vector<int> &a, vector<int> &b)
{
int n = a.size();
// Max heap
priority_queue<int> pq;
// Insert elements of both arrays
for (int x : a)
pq.push(x);
for (int x : b)
pq.push(x);
// Store n largest unique elements
unordered_set<int> hash;
while (!pq.empty() && hash.size() < n)
{
int top = pq.top();
pq.pop();
hash.insert(top);
}
vector<int> ans;
// To avoid duplicates in answer
unordered_set<int> used;
// Store elements of b first
for (int x : b)
{
if (hash.count(x) && !used.count(x))
{
ans.push_back(x);
used.insert(x);
}
}
// Store elements of a next
for (int x : a)
{
if (hash.count(x) && !used.count(x))
{
ans.push_back(x);
used.insert(x);
}
}
return ans;
}
// Driver Code
int main()
{
vector<int> a = {7, 4, 8, 0, 1};
vector<int> b = {9, 10, 2, 3, 6};
vector<int> ans = maximizeArray(a, b);
for (int x : ans)
{
cout << x << " ";
}
return 0;
}
import java.util.*;
public class GfG {
// Function to maximize array elements
public static ArrayList<Integer> maximizeArray(int[] a, int[] b) {
int n = a.length;
// Max heap
PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);
// Insert elements of both arrays
for (int x : a)
pq.add(x);
for (int x : b)
pq.add(x);
// Store n largest unique elements
Set<Integer> hash = new HashSet<>();
while (!pq.isEmpty() && hash.size() < n) {
int top = pq.poll();
hash.add(top);
}
ArrayList<Integer> ans = new ArrayList<>();
// To avoid duplicates in answer
Set<Integer> used = new HashSet<>();
// Store elements of b first
for (int x : b) {
if (hash.contains(x) &&!used.contains(x)) {
ans.add(x);
used.add(x);
}
}
// Store elements of a next
for (int x : a) {
if (hash.contains(x) &&!used.contains(x)) {
ans.add(x);
used.add(x);
}
}
return ans;
}
// Driver Code
public static void main(String[] args) {
int[] a = {7, 4, 8, 0, 1};
int[] b = {9, 10, 2, 3, 6};
ArrayList<Integer> ans = maximizeArray(a, b);
for (int x : ans) {
System.out.print(x + " ");
}
}
}
from heapq import *
# Function to maximize array elements
def maximizeArray(a, b):
n = len(a)
# Max heap
pq = []
# Insert elements of both arrays
for x in a:
heappush(pq, -x)
for x in b:
heappush(pq, -x)
# Store n largest unique elements
hash = set()
while pq and len(hash) < n:
top = -heappop(pq)
hash.add(top)
ans = []
# To avoid duplicates in answer
used = set()
# Store elements of b first
for x in b:
if x in hash and x not in used:
ans.append(x)
used.add(x)
# Store elements of a next
for x in a:
if x in hash and x not in used:
ans.append(x)
used.add(x)
return ans
# Driver Code
if __name__ == "__main__":
a = [7, 4, 8, 0, 1]
b = [9, 10, 2, 3, 6]
ans = maximizeArray(a, b)
for x in ans:
print(x, end=" ")
using System;
using System.Collections.Generic;
class GfG
{
// Function to maximize array elements
public List<int> maximizeArray(int[] a, int[] b)
{
int n = a.Length;
// Max heap using SortedSet
PriorityQueue<int, int> pq = new PriorityQueue<int, int>();
// Insert elements of both arrays
foreach (int x in a)
{
pq.Enqueue(x, -x);
}
foreach (int x in b)
{
pq.Enqueue(x, -x);
}
// Store n largest unique elements
HashSet<int> hash = new HashSet<int>();
while (pq.Count > 0 && hash.Count < n)
{
int top = pq.Dequeue();
hash.Add(top);
}
List<int> ans = new List<int>();
// To avoid duplicates in answer
HashSet<int> used = new HashSet<int>();
// Store elements of b first
foreach (int x in b)
{
if (hash.Contains(x) && !used.Contains(x))
{
ans.Add(x);
used.Add(x);
}
}
// Store elements of a next
foreach (int x in a)
{
if (hash.Contains(x) && !used.Contains(x))
{
ans.Add(x);
used.Add(x);
}
}
return ans;
}
static void Main()
{
int[] a = { 7, 4, 8, 0, 1 };
int[] b = { 9, 10, 2, 3, 6 };
GfG obj = new GfG();
List<int> ans = obj.maximizeArray(a, b);
foreach (int x in ans)
{
Console.Write(x + " ");
}
}
}
function maximizeArray(a, b) {
let n = a.length;
// Max heap
let pq = new MaxHeap();
// Insert elements of both arrays
for (let x of a) {
pq.push(x);
}
for (let x of b) {
pq.push(x);
}
// Store n largest unique elements
let hash = new Set();
while (!pq.isEmpty() && hash.size < n) {
let top = pq.pop();
hash.add(top);
}
let ans = [];
// To avoid duplicates in answer
let used = new Set();
// Store elements of b first
for (let x of b) {
if (hash.has(x) &&!used.has(x)) {
ans.push(x);
used.add(x);
}
}
// Store elements of a next
for (let x of a) {
if (hash.has(x) &&!used.has(x)) {
ans.push(x);
used.add(x);
}
}
return ans;
}
// MaxHeap class
class MaxHeap {
constructor() {
this.heap = [];
}
push(val) {
this.heap.push(val);
this.#bubbleUp(this.heap.length - 1);
}
pop() {
if (this.heap.length === 1) return this.heap.pop();
let max = this.heap[0];
this.heap[0] = this.heap.pop();
this.#sinkDown(0);
return max;
}
isEmpty() {
return this.heap.length === 0;
}
#bubbleUp(index) {
while (index > 0) {
let parentIndex = Math.floor((index - 1) / 2);
if (this.heap[index] <= this.heap[parentIndex]) break;
[this.heap[index], this.heap[parentIndex]] = [this.heap[parentIndex], this.heap[index]];
index = parentIndex;
}
}
#sinkDown(index) {
let length = this.heap.length;
let leftChildIndex, rightChildIndex, largestIndex;
while (true) {
leftChildIndex = 2 * index + 1;
rightChildIndex = 2 * index + 2;
largestIndex = index;
if (leftChildIndex < length && this.heap[leftChildIndex] > this.heap[largestIndex]) {
largestIndex = leftChildIndex;
}
if (rightChildIndex < length && this.heap[rightChildIndex] > this.heap[largestIndex]) {
largestIndex = rightChildIndex;
}
if (largestIndex === index) break;
[this.heap[index], this.heap[largestIndex]] = [this.heap[largestIndex], this.heap[index]];
index = largestIndex;
}
}
}
// Driver Code
let a = [7, 4, 8, 0, 1];
let b = [9, 10, 2, 3, 6];
let ans = maximizeArray(a, b);
ans.forEach(x => console.log(x));
Output
9 10 6 7 8
Time Complexity: O(n log n)
Auxiliary Space: O(n)