Given an array A[]. For each element A[i], We need to find the maximum value A[j] (where j ≠ i) that satisfies the condition A[j] ≤ 2*A[i].
If no such value exists for a particular index i, store -1 for that index. Finally, return an array where each position contains the result corresponding to A[i].
Examples:
Input: A[] = [95, 73, 36, 83, 79, 74, 27, 5]
Output: [83, 95, 27, 95, 95, 95,36, -1]
Explanation:
For 95, the largest allowed value is 2 × 95 = 190. The largest number ≤ 190 other than 95 itself is 83.
For 36, the allowed limit is 72. The largest number ≤ 72 is 27, so answer is 27.
For 5, allowed limit is 10, and no element ≤ 10 except itself exists → -1.Input: A[] = [54, 56, 96]
Output: [96, 96, 56]
Explanation:
For 54, allowed limit is 108. The largest number ≤ 108 other than 54 is 96.
For 96, allowed limit is 192. The largest number ≤ 192 other than 96 is 56.
Table of Content
[Naive Approach]Brute Force - O(n*n) Time and O(1) Space
The idea is to process each element A[i] in the array individually and examine all other elements A[j] to find the largest value that satisfies the given conditions. For every element A[i], we first compute a limit as 2 × A[i]. Then, we scan through all elements in the array and consider only those A[j] where the index j ≠ i and the value A[j] ≤ limit. Among all such valid elements, we select the maximum value and store it as the answer for the current index
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends
vector<int> largestValue(vector<int> &A) {
int n = A.size();
vector<int> ans(n);
// Iterate over each element in the array
for (int i = 0; i < n; i++) {
// Maximum allowed value for A[j] for current A[i]
int limit = 2 * A[i];
int best = -1;
// Check all other elements in the array
for (int j = 0; j < n; j++) {
// Skip the same element and check if it is within the limit
if (i != j && A[j] <= limit) {
best = max(best, A[j]);
}
}
ans[i] = best;
}
return ans;
}
//Driver Code Starts
int main() {
vector<int> A = {95, 73, 36, 83, 79, 74, 27, 5};
vector<int> result = largestValue(A);
for (auto x : result) cout << x << " ";
cout << endl;
}
//Driver Code Ends
//Driver Code Starts
import java.util.Arrays;
public class GFG {
//Driver Code Ends
static int[] largestValue(int[] A) {
int n = A.length;
int[] ans = new int[n];
// Iterate over each element in the array
for (int i = 0; i < n; i++) {
// Maximum allowed value for A[j] for current A[i]
int limit = 2 * A[i];
int best = -1;
// Check all other elements in the array
for (int j = 0; j < n; j++) {
// Skip the same element and check if it is within the limit
if (i != j && A[j] <= limit) {
best = Math.max(best, A[j]);
}
}
ans[i] = best;
}
return ans;
}
//Driver Code Starts
public static void main(String[] args) {
int[] A = {95, 73, 36, 83, 79, 74, 27, 5};
int[] result = largestValue(A);
for (int x : result) System.out.print(x + " ");
System.out.println();
}
}
//Driver Code Ends
#Driver Code Starts
#Driver Code Ends
def largestValue(A):
n = len(A)
ans = [0] * n
# Iterate over each element in the array
for i in range(n):
# Maximum allowed value for A[j] for current A[i]
limit = 2 * A[i]
best = -1
# Check all other elements in the array
for j in range(n):
# Skip the same element and check if it is within the limit
if i != j and A[j] <= limit:
best = max(best, A[j])
ans[i] = best
return ans
#Driver Code Starts
if __name__ == "__main__":
A = [95, 73, 36, 83, 79, 74, 27, 5]
result = largestValue(A)
print(*result)
#Driver Code Ends
using System;
class GFG {
static int[] largestValue(int[] A) {
int n = A.Length;
int[] ans = new int[n];
// Iterate over each element in the array
for (int i = 0; i < n; i++) {
// Maximum allowed value for A[j] for current A[i]
int limit = 2 * A[i];
int best = -1;
// Check all other elements in the array
for (int j = 0; j < n; j++) {
// Skip the same element and check if it is within the limit
if (i != j && A[j] <= limit) {
best = Math.Max(best, A[j]);
}
}
ans[i] = best;
}
return ans;
}
static void Main() {
int[] A = {95, 73, 36, 83, 79, 74, 27, 5};
int[] result = largestValue(A);
foreach (int x in result) Console.Write(x + " ");
Console.WriteLine();
}
}
function largestValue(A) {
const n = A.length;
const ans = new Array(n);
// Iterate over each element in the array
for (let i = 0; i < n; i++) {
// Maximum allowed value for A[j] for current A[i]
const limit = 2 * A[i];
let best = -1;
// Check all other elements in the array
for (let j = 0; j < n; j++) {
// Skip the same element and check if it is within the limit
if (i !== j && A[j] <= limit) {
best = Math.max(best, A[j]);
}
}
ans[i] = best;
}
return ans;
}
//Driver Code Starts
//Driver Code
const A = [95, 73, 36, 83, 79, 74, 27, 5];
const result = largestValue(A);
console.log(result.join(" "));
//Driver Code Ends
Output
83 95 27 95 95 95 36 -1
[Optimal Approach] Sorting + Binary Search - O(n log n) Time and O(n) Space
The main idea of this approach is to efficiently find, for each element, the largest value in the array that is at most twice its value. By sorting the array, we know the order of all elements, which allows us to quickly identify suitable candidates without checking every element. However, sorting changes the original indices, so we cannot directly use the sorted positions as answers. To handle this, we always compare the value itself and, if the largest candidate equals the current element, we consider the next smaller element in the sorted array to ensure we select a different element. If no valid element exists, we return -1.
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//Driver Code Ends
vector<int> largestValue(vector<int> &A) {
int n = A.size();
// Make a copy and sort it
vector<int> sortedA = A;
sort(sortedA.begin(), sortedA.end());
vector<int> ans(n);
for (int i = 0; i < n; i++) {
// Maximum allowed value
int limit = 2 * A[i];
int idx = upper_bound(sortedA.begin(), sortedA.end(), limit) - sortedA.begin();
// Step back to get the largest value ≤ limit
idx--;
if (idx < 0) {
// No element ≤ limit found
ans[i] = -1;
continue;
}
if (sortedA[idx] == A[i]) {
// If largest candidate equals A[i], pick previous element to maintain i != j
int prev = idx - 1;
if (prev >= 0) ans[i] = sortedA[prev];
else ans[i] = -1;
} else {
ans[i] = sortedA[idx];
}
}
return ans;
}
//Driver Code Starts
int main() {
vector<int> A = {95, 73, 36, 83, 79, 74, 27, 5};
vector<int> result = largestValue(A);
for (auto x : result) cout << x << " ";
cout << endl;
}
//Driver Code Ends
//Driver Code Starts
import java.util.Arrays;
public class GFG {
//Driver Code Ends
static int[] largestValue(int[] A) {
int n = A.length;
// Make a copy and sort it
int[] sortedA = Arrays.copyOf(A, n);
Arrays.sort(sortedA);
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
// Maximum allowed value
int limit = 2 * A[i];
int idx = Arrays.binarySearch(sortedA, limit);
if (idx < 0) idx = -idx - 2; // Get largest value ≤ limit
// Step back to get the largest value ≤ limit
if (idx < 0) {
// No element ≤ limit found
ans[i] = -1;
continue;
}
if (sortedA[idx] == A[i]) {
// If largest candidate equals A[i], pick previous element to maintain i != j
int prev = idx - 1;
if (prev >= 0) ans[i] = sortedA[prev];
else ans[i] = -1;
} else {
ans[i] = sortedA[idx];
}
}
return ans;
}
//Driver Code Starts
public static void main(String[] args) {
int[] A = {95, 73, 36, 83, 79, 74, 27, 5};
int[] result = largestValue(A);
for (int x : result) System.out.print(x + " ");
System.out.println();
}
}
//Driver Code Ends
def largestValue(A):
n = len(A)
# Make a copy and sort it
sortedA = sorted(A)
ans = [0] * n
for i in range(n):
# Maximum allowed value
limit = 2 * A[i]
# Step back to get the largest value ≤ limit
idx = -1
for j in range(n):
if sortedA[j] <= limit:
idx = j
else:
break
if idx == -1:
# No element ≤ limit found
ans[i] = -1
continue
if sortedA[idx] == A[i]:
# If largest candidate equals A[i], pick previous element to maintain i != j
prev = idx - 1
if prev >= 0:
ans[i] = sortedA[prev]
else:
ans[i] = -1
else:
ans[i] = sortedA[idx]
return ans
#Driver Code Starts
if __name__ == "__main__":
A = [95, 73, 36, 83, 79, 74, 27, 5]
result = largestValue(A)
print(*result)
#Driver Code Ends
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int[] largestValue(int[] A) {
int n = A.Length;
// Make a copy and sort it
int[] sortedA = new int[n];
Array.Copy(A, sortedA, n);
Array.Sort(sortedA);
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
// Maximum allowed value
int limit = 2 * A[i];
// Step back to get the largest value ≤ limit
int idx = -1;
for (int j = 0; j < n; j++) {
if (sortedA[j] <= limit) idx = j;
else break;
}
if (idx == -1) {
// No element ≤ limit found
ans[i] = -1;
continue;
}
if (sortedA[idx] == A[i]) {
// If largest candidate equals A[i], pick previous element to maintain i != j
int prev = idx - 1;
ans[i] = prev >= 0 ? sortedA[prev] : -1;
} else {
ans[i] = sortedA[idx];
}
}
return ans;
}
//Driver Code Starts
static void Main() {
int[] A = {95, 73, 36, 83, 79, 74, 27, 5};
int[] result = largestValue(A);
foreach (int x in result) Console.Write(x + " ");
Console.WriteLine();
}
}
//Driver Code Ends
function largestValue(A) {
const n = A.length;
// Make a copy and sort it
const sortedA = [...A].sort((a, b) => a - b);
const ans = new Array(n);
for (let i = 0; i < n; i++) {
// Maximum allowed value
const limit = 2 * A[i];
// Step back to get the largest value ≤ limit
let idx = -1;
for (let j = 0; j < n; j++) {
if (sortedA[j] <= limit) idx = j;
else break;
}
if (idx === -1) {
// No element ≤ limit found
ans[i] = -1;
continue;
}
if (sortedA[idx] === A[i]) {
// If largest candidate equals A[i], pick previous element to maintain i != j
const prev = idx - 1;
ans[i] = prev >= 0 ? sortedA[prev] : -1;
} else {
ans[i] = sortedA[idx];
}
}
return ans;
}
//Driver Code Starts
//Driver Code
const A = [95, 73, 36, 83, 79, 74, 27, 5];
const result = largestValue(A);
console.log(result.join(" "));
//Driver Code Ends
Output
83 95 27 95 95 95 36 -1