Advanced Java Data Structure & Concurrency Problems
1) Two Sum using HashMap
Given an array of integers and a target value, find the indices of two numbers such that they
add up to the target.
The function should return immediately after finding the first such pair.
Code:
import [Link].*;
public class TwoSum {
public static int[] twoSum(int[] a, int target) {
Map<Integer, Integer> idx = new HashMap<>();
for (int i = 0; i < [Link]; i++) {
int need = target - a[i];
if ([Link](need)) return new int[]{[Link](need), i};
[Link](a[i], i);
}
return new int[0];
}
public static void main(String[] args) {
int[] result = twoSum(new int[]{2,7,11,15}, 9);
[Link]([Link](result)); // [0, 1]
}
}
Complexity: Time: O(n), Space: O(n)
2) Group Anagrams using HashMap
Group words that are anagrams of each other. Two words are anagrams if they contain the
same characters with the same frequency.
Code:
import [Link].*;
public class GroupAnagrams {
public static List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String s : strs) {
char[] ch = [Link]();
[Link](ch);
String key = new String(ch);
[Link](key, k -> new ArrayList<>()).add(s);
}
return new ArrayList<>([Link]());
}
public static void main(String[] args) {
String[] words = {"eat", "tea", "tan", "ate", "nat", "bat"};
[Link](groupAnagrams(words));
}
}
Complexity: Time: O(n * m log m), Space: O(n * m)
3) Top-K Frequent Elements using MinHeap
Find the k most frequent elements from an array.
Use a HashMap to count frequencies and a MinHeap to maintain the top k.
Code:
import [Link].*;
public class TopKFrequent {
public static int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> freq = new HashMap<>();
for (int x : nums) [Link](x, 1, Integer::sum);
PriorityQueue<int[]> pq = new PriorityQueue<>([Link](a -> a[1]));
for (var e : [Link]()) {
[Link](new int[]{[Link](), [Link]()});
if ([Link]() > k) [Link]();
}
int[] ans = new int[[Link]()];
for (int i = [Link]() - 1; i >= 0; i--) ans[i] = [Link]()[0];
return ans;
}
public static void main(String[] args) {
int[] result = topKFrequent(new int[]{1,1,1,2,2,3}, 2);
[Link]([Link](result)); // [1, 2]
}
}
Complexity: Time: O(n log k), Space: O(n)
4) LRU Cache using LinkedHashMap
Design a Least Recently Used (LRU) cache supporting O(1) get and put operations.
Use LinkedHashMap with accessOrder set to true.
Code:
import [Link].*;
class LRUCache extends LinkedHashMap<Integer, Integer> {
private final int cap;
LRUCache(int capacity) {
super(capacity, 0.75f, true);
[Link] = capacity;
}
public int get(int key) { return [Link](key, -1); }
public void put(int key, int value) { [Link](key, value); }
@Override
protected boolean removeEldestEntry([Link]<Integer,Integer> e) {
return size() > cap;
}
public static void main(String[] args) {
LRUCache cache = new LRUCache(2);
[Link](1, 1);
[Link](2, 2);
[Link]([Link](1)); // 1
[Link](3, 3);
[Link]([Link](2)); // -1
}
}
Complexity: Time: O(1), Space: O(capacity)
5) Thread-Safe Singleton
Implement a singleton that is lazily initialized and thread-safe using double-checked
locking.
Code:
public class Singleton {
private static volatile Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized ([Link]) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
Singleton s1 = [Link]();
Singleton s2 = [Link]();
[Link](s1 == s2); // true
}
}
Complexity: Time: O(1), Space: O(1)