You are given a 2D integer array intervals[][] of length n and integer k, where each intervals[i] = [start, end] represents a closed interval (i.e., all integers from start to end, inclusive). An integer is called Powerful if it appears in at least k intervals. Find the maximum Powerful Integer. If no such integer exists, return -1.
Examples:
Input: intervals[][] = [[1,3], [4,6], [3,4]], k = 2
Output: 4
Explanation: Integers 3 and 4 appear in 2 intervals. The maximum is 4Input: intervals[][] = [[1,4], [12,45], [3,8], [10,12]], k = 3
Output: -1
Explanation: No integer appears in at least 3 intervals
Table of Content
[Naive Approach] Frequency Counting with Full Range Traversal
The idea is to use a frequency array to count how many times each integer appears across all intervals. For every interval [start, end], each number in that range is incremented in the array. After processing all intervals, the frequency array is scanned to find the maximum integer that appears at least `k` times. If no such integer exists, -1 is returned.
This brute-force approach ensures correctness but is not efficient for large ranges due to its high time and space complexity.
#include <iostream>
#include <vector>
using namespace std;
int powerfulInteger(vector<vector<int>>& intervals, int k) {
int ma = intervals[0][1];
int n = intervals.size();
for(int i=0;i<n;++i){
ma=max(ma,intervals[i][1]);
}
vector<int> count(ma+1);
// Count occurrences of each
// integer in the intervals
for (int i = 0; i < n; i++) {
for (int j = intervals[i][0]; j <= intervals[i][1]; j++) {
count[j]++;
}
}
int ans = -1;
// Find the maximum integer
// with frequency >= k
for (int i = 1; i <= ma; i++) {
if (count[i] >= k) {
ans = i;
}
}
return ans;
}
int main() {
vector<vector<int>> intervals = {{1, 3}, {4, 6}, {3, 4}};
int k = 2;
int result = powerfulInteger(intervals, k);
cout << result << endl;
return 0;
}
public class GfG {
public static int powerfulInteger(int[][] intervals, int k) {
int ma = intervals[0][1];
int n = intervals.length;
for (int i = 0; i < n; i++) {
ma = Math.max(ma, intervals[i][1]);
}
int[] count = new int[ma + 1];
// Count occurrences of each
// integer in the intervals
for (int i = 0; i < intervals.length; i++) {
int start = intervals[i][0];
int end = intervals[i][1];
for (int j = start; j <= end; j++) {
count[j]++;
}
}
int ans = -1;
// Find the maximum integer
// with frequency >= k
for (int i = 1; i <= ma; i++) {
if (count[i] >= k) {
ans = i;
}
}
return ans;
}
public static void main(String[] args) {
int[][] intervals = {
{1, 3},
{4, 6},
{3, 4}
};
int k = 2;
int result = powerfulInteger(intervals, k);
System.out.println(result);
}
}
def powerfulInteger(intervals, k):
n = len(intervals)
ma = intervals[0][1]
# Find the maximum endpoint
for i in range(n):
ma = max(ma, intervals[i][1])
count = [0] * (ma + 1)
# Count how many times each number
# appears across all intervals
for start, end in intervals:
for j in range(start, end + 1):
count[j] += 1
ans = -1
# Find the maximum number with at least k appearances
for i in range(1, ma + 1):
if count[i] >= k:
ans = i
return ans
if __name__ == "__main__":
intervals = [
[1, 3],
[4, 6],
[3, 4]
]
k = 2
result = powerfulInteger(intervals, k)
print(result)
using System;
class GfG
{
public static int powerfulInteger(int[,] intervals, int k)
{
int n = intervals.GetLength(0);
int ma = intervals[0, 1];
for (int i = 0; i < n; i++) {
ma = Math.Max(ma, intervals[i , 1]);
}
int[] count = new int[ma + 1];
// Count occurrences of each
// integer in the intervals
for (int i = 0; i < n; i++)
{
int start = intervals[i, 0];
int end = intervals[i, 1];
for (int j = start; j <= end; j++)
{
count[j]++;
}
}
int ans = -1;
// Find the maximum integer
// with frequency >= k
for (int i = 1; i <= ma; i++)
{
if (count[i] >= k)
{
ans = i;
}
}
return ans;
}
static void Main(string[] args)
{
int[,] intervals = {
{ 1, 3 },
{ 4, 6 },
{ 3, 4 }
};
int k = 2;
int result = powerfulInteger(intervals, k);
Console.WriteLine(result);
}
}
function powerfulInteger(intervals, k) {
let ma = intervals[0][1];
for (let i = 0; i < intervals.length; i++) {
ma = Math.max(ma, intervals[i][1]);
}
let count = new Array(ma + 1).fill(0);
// Count occurrences of each
// integer in the intervals
for (let i = 0; i < intervals.length; i++) {
const [start, end] = intervals[i];
for (let j = start; j <= end; j++) {
count[j]++;
}
}
let ans = -1;
// Find the maximum integer
// with frequency >= k
for (let i = 1; i <= ma; i++) {
if (count[i] >= k) {
ans = i;
}
}
return ans;
}
// Driver Code
const intervals = [
[1, 3],
[4, 6],
[3, 4]
];
const k = 2;
const result = powerfulInteger(intervals, k);
console.log(result);
Output
4
Time Complexity: O(n * m ), where m is maximum endpoint among all intervals
Auxiliary Space: O(m), where m is the maximum endpoint among all intervals
[Expected Approach] Using Sweep Line - O(n log(n)) Time and O(n) Space
The idea is to use the sweep line or difference array technique to efficiently count how many intervals cover each integer, without iterating through every number in every interval. For each interval, we increment the count at the start point and decrement the count just after the end point. Then, we traverse the sorted map keys while maintaining a running sum (prefix sum) of the interval overlaps. If this running count is at least
k, we update the answer to the current integer (or one less if the count drops belowk). This allows us to find the maximum powerful integer in an optimized way.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int powerfulInteger(vector<vector<int>>& intervals, int k) {
map<int, int> mpp;
// Mark interval start and
// end+1 with +1 and -1 respectively
for (auto& x : intervals) {
mpp[x[0]] += 1;
mpp[x[1] + 1] -= 1;
}
int ans = -1;
int temp = 0;
// Traverse the map (sorted keys) and
// track frequency using prefix sum
for (auto& x : mpp) {
if (mpp[x.first] >= 0) {
temp += mpp[x.first];
if (temp >= k) {
ans = x.first;
}
} else {
if (temp >= k) {
ans = x.first - 1;
}
temp += mpp[x.first];
}
}
return ans;
}
int main() {
vector<vector<int>> intervals = {
{1, 3},
{4, 6},
{3, 4}
};
int k = 2;
int result = powerfulInteger(intervals, k);
cout << result << endl;
return 0;
}
import java.util.TreeMap;
import java.util.Map;
public class GfG {
public static int powerfulInteger(int[][] intervals, int k) {
TreeMap<Integer, Integer> map = new TreeMap<>();
// Mark interval start and
// end+1 with +1 and -1 respectively
for (int i = 0; i < intervals.length; i++) {
int start = intervals[i][0];
int end = intervals[i][1];
map.put(start, map.getOrDefault(start, 0) + 1);
map.put(end + 1, map.getOrDefault(end + 1, 0) - 1);
}
int ans = -1;
int temp = 0;
// Traverse the map (sorted keys) and
// track frequency using prefix sum
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
int point = entry.getKey();
int delta = entry.getValue();
if (delta >= 0) {
temp += delta;
if (temp >= k) {
ans = point;
}
} else {
if (temp >= k) {
ans = point - 1;
}
temp += delta;
}
}
return ans;
}
public static void main(String[] args) {
int[][] intervals = {
{1, 3},
{4, 6},
{3, 4}
};
int k = 2;
int result = powerfulInteger(intervals, k);
System.out.println(result);
}
}
def powerfulInteger(intervals, k):
mpp = {}
# Mark interval start and
# end+1 with +1 and -1 respectively
for start, end in intervals:
mpp[start] = mpp.get(start, 0) + 1
mpp[end + 1] = mpp.get(end + 1, 0) - 1
ans = -1
temp = 0
# Traverse the map (sorted keys) and
# track frequency using prefix sum
for point in sorted(mpp):
delta = mpp[point]
if delta >= 0:
temp += delta
if temp >= k:
ans = point
else:
if temp >= k:
ans = point - 1
temp += delta
return ans
if __name__ == "__main__":
intervals = [
[1, 3],
[4, 6],
[3, 4]
]
k = 2
result = powerfulInteger(intervals, k)
print(result)
using System;
using System.Collections.Generic;
class GfG
{
public static int powerfulInteger(int[,] intervals, int k)
{
SortedDictionary<int, int> map = new SortedDictionary<int, int>();
int n = intervals.GetLength(0);
// Mark interval start and
// end+1 with +1 and -1 respectively
for (int i = 0; i < n; i++)
{
int start = intervals[i, 0];
int end = intervals[i, 1];
if (!map.ContainsKey(start))
map[start] = 0;
map[start] += 1;
if (!map.ContainsKey(end + 1))
map[end + 1] = 0;
map[end + 1] -= 1;
}
int ans = -1;
int temp = 0;
// Traverse the map (sorted keys) and
// track frequency using prefix sum
foreach (var kvp in map)
{
int point = kvp.Key;
int delta = kvp.Value;
if (delta >= 0)
{
temp += delta;
if (temp >= k)
ans = point;
}
else
{
if (temp >= k)
ans = point - 1;
temp += delta;
}
}
return ans;
}
static void Main(string[] args)
{
int[,] intervals = {
{ 1, 3 },
{ 4, 6 },
{ 3, 4 }
};
int k = 2;
int result = powerfulInteger(intervals, k);
Console.WriteLine(result);
}
}
function powerfulInteger(intervals, k) {
const map = new Map();
// Mark interval start and
// end+1 with +1 and -1 respectively
for (const [start, end] of intervals) {
map.set(start, (map.get(start) || 0) + 1);
map.set(end + 1, (map.get(end + 1) || 0) - 1);
}
// Traverse the map (sorted keys) and
// track frequency using prefix sum
const sortedKeys = Array.from(map.keys()).sort((a, b) => a - b);
let temp = 0;
let ans = -1;
for (const point of sortedKeys) {
const delta = map.get(point);
if (delta >= 0) {
temp += delta;
if (temp >= k) {
ans = point;
}
} else {
if (temp >= k) {
ans = point - 1;
}
temp += delta;
}
}
return ans;
}
// Driver Code
const intervals = [
[1, 3],
[4, 6],
[3, 4]
];
const k = 2;
const result = powerfulInteger(intervals, k);
console.log(result);
Output
4