DSA Java Questions and Answers
DSA Java Questions and Answers
1. Two Sum
Find indices of two numbers that add up to a target.
Java Solution:
// HashMap approach - O(n)
import [Link].*;
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < [Link]; i++) {
int complement = target - nums[i];
if ([Link](complement)) {
return new int[]{[Link](complement), i};
}
[Link](nums[i], i);
}
return new int[]{}; // not found
}
Explanation: Use a HashMap to store value→index. For each number check if complement exists
— O(n) time, O(n) space.
Java Solution:
public int maxSubArray(int[] nums) {
int maxSoFar = nums[0], curr = nums[0];
for (int i = 1; i < [Link]; i++) {
curr = [Link](nums[i], curr + nums[i]);
maxSoFar = [Link](maxSoFar, curr);
}
return maxSoFar;
}
Explanation: Keep current running sum; reset when it becomes worse than starting at current
element.
3. Move Zeroes
Move all zeros to the end while maintaining relative order.
Java Solution:
public void moveZeroes(int[] nums) {
int j = 0;
for (int i = 0; i < [Link]; i++) {
if (nums[i] != 0) nums[j++] = nums[i];
}
while (j < [Link]) nums[j++] = 0;
}
Java Solution:
public int maxProfit(int[] prices) {
int minPrice = Integer.MAX_VALUE, maxProfit = 0;
for (int p : prices) {
minPrice = [Link](minPrice, p);
maxProfit = [Link](maxProfit, p - minPrice);
}
return maxProfit;
}
Explanation: Track minimum price seen so far and compute profit at each step.
Java Solution:
public int findDuplicate(int[] nums) {
int tortoise = nums[0], hare = nums[0];
do {
tortoise = nums[tortoise];
hare = nums[nums[hare]];
} while (tortoise != hare);
hare = nums[0];
while (tortoise != hare) {
tortoise = nums[tortoise];
hare = nums[hare];
}
return hare;
}
Explanation: Treat array as linked list with cycle. Use Floyd's cycle detection.
6. Merge Intervals
Merge overlapping intervals.
Java Solution:
import [Link].*;
public int[][] merge(int[][] intervals) {
if ([Link] <= 1) return intervals;
[Link](intervals, [Link](a -> a[0]));
List<int[]> res = new ArrayList<>();
int[] cur = intervals[0];
for (int i = 1; i < [Link]; i++) {
if (intervals[i][0] <= cur[1]) {
cur[1] = [Link](cur[1], intervals[i][1]);
} else {
[Link](cur);
cur = intervals[i];
}
}
[Link](cur);
return [Link](new int[[Link]()][]);
}
Explanation: Sort by start, then merge overlapping by comparing current end with next start.
7. Rotate Array
Rotate array to the right by k steps.
Java Solution:
public void rotate(int[] nums, int k) {
k %= [Link];
reverse(nums, 0, [Link]-1);
reverse(nums, 0, k-1);
reverse(nums, k, [Link]-1);
}
private void reverse(int[] a, int i, int j) {
while (i < j) {
int t = a[i]; a[i++] = a[j]; a[j--] = t;
}
}
Explanation: Reverse whole array, then reverse first k and remaining elements.
Java Solution:
public String reverseWords(String s) {
String[] parts = [Link]().split("\s+");
[Link]([Link](parts));
return [Link](" ", parts);
}
Explanation: Split on whitespace, reverse array of words, join with single space.
Complexity: Time: O(n), Space: O(n)
9. Valid Palindrome
Check if string is palindrome ignoring non-alphanumerics and case.
Java Solution:
public boolean isPalindrome(String s) {
int i = 0, j = [Link]()-1;
while (i < j) {
while (i < j && )) i++;
while (i < j && )) j--;
if ([Link]([Link](i++)) != [Link]([Link](j--)))
return false;
}
return true;
}
Java Solution:
public int lengthOfLongestSubstring(String s) {
int[] last = new int[256];
[Link](last, -1);
int start = 0, maxLen = 0;
for (int i = 0; i < [Link](); i++) {
start = [Link](start, last[[Link](i)] + 1);
maxLen = [Link](maxLen, i - start + 1);
last[[Link](i)] = i;
}
return maxLen;
}
Explanation: Use sliding window and store last seen index for characters.
Java Solution:
class ListNode { int val; ListNode next; ListNode(int v){val=v;} }
public ListNode reverseList(ListNode head) {
ListNode prev = null, cur = head;
while (cur != null) {
ListNode next = [Link];
[Link] = prev;
prev = cur;
cur = next;
}
return prev;
}
Java Solution:
public boolean hasCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && [Link] != null) {
slow = [Link];
fast = [Link];
if (slow == fast) return true;
}
return false;
}
Explanation: Use slow and fast pointers; if they meet, there's a cycle.
Java Solution:
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0), tail = dummy;
while (l1 != null && l2 != null) {
if ([Link] < [Link]) { [Link] = l1; l1 = [Link]; }
else { [Link] = l2; l2 = [Link]; }
tail = [Link];
}
[Link] = (l1 != null) ? l1 : l2;
return [Link];
}
Java Solution:
public ListNode middleNode(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && [Link] != null) {
slow = [Link];
fast = [Link];
}
return slow;
}
Explanation: Fast moves twice as fast; when fast reaches end, slow is middle.
Java Solution:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0); [Link] = head;
ListNode first = dummy, second = dummy;
for (int i = 0; i <= n; i++) first = [Link];
while (first != null) { first = [Link]; second = [Link]; }
[Link] = [Link];
return [Link];
}
Explanation: Use two pointers with gap n to find predecessor of target node.
Java Solution:
public boolean isValid(String s) {
Deque<Character> st = new ArrayDeque<>();
for (char c : [Link]()) {
if (c=='('||c=='{'||c=='[') [Link](c);
else {
if ([Link]()) return false;
char t = [Link]();
if ((c==')'&&t!='(')||(c=='}'&&t!='{')||(c==']'&&t!='[')) return false;
}
}
return [Link]();
}
Java Solution:
class MinStack {
private Deque<Integer> stack = new ArrayDeque<>();
private Deque<Integer> mins = new ArrayDeque<>();
public void push(int x) {
[Link](x);
if ([Link]() || x <= [Link]()) [Link](x);
}
public void pop() {
int x = [Link]();
if (x == [Link]()) [Link]();
}
public int top() { return [Link](); }
public int getMin() { return [Link](); }
}
Java Solution:
public int[] nextGreaterElements(int[] nums) {
int n = [Link]; int[] res = new int[n];
[Link](res, -1);
Deque<Integer> st = new ArrayDeque<>();
for (int i = 0; i < 2*n; i++) {
int num = nums[i % n];
while (![Link]() && nums[[Link]()] < num) res[[Link]()] = num;
if (i < n) [Link](i);
}
return res;
}
Java Solution:
class TreeNode { int val; TreeNode left, right; TreeNode(int v){val=v;} }
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Deque<TreeNode> st = new ArrayDeque<>();
TreeNode cur = root;
while (cur != null || ![Link]()) {
while (cur != null) { [Link](cur); cur = [Link]; }
cur = [Link]();
[Link]([Link]);
cur = [Link];
}
return res;
}
Explanation: Use stack to simulate recursion: go left deep, process, then go right.
Java Solution:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
Queue<TreeNode> q = new LinkedList<>(); [Link](root);
while (![Link]()) {
int sz = [Link]();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < sz; i++) {
TreeNode n = [Link]();
[Link]([Link]);
if ([Link] != null) [Link]([Link]);
if ([Link] != null) [Link]([Link]);
}
[Link](level);
}
return res;
}
Java Solution:
public int maxDepth(TreeNode root) {
if (root == null) return 0;
return 1 + [Link](maxDepth([Link]), maxDepth([Link]));
}
Java Solution:
public boolean isBalanced(TreeNode root) {
return height(root) != -1;
}
private int height(TreeNode node) {
if (node == null) return 0;
int lh = height([Link]);
if (lh == -1) return -1;
int rh = height([Link]);
if (rh == -1) return -1;
if ([Link](lh - rh) > 1) return -1;
return 1 + [Link](lh, rh);
}
Java Solution:
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (root != null) {
if ([Link] < [Link] && [Link] < [Link]) root = [Link];
else if ([Link] > [Link] && [Link] > [Link]) root = [Link];
else return root;
}
return null;
}
Explanation: Use BST property to move left or right until split point.
Java Solution:
public boolean isValidBST(TreeNode root) {
return helper(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
private boolean helper(TreeNode node, long low, long high) {
if (node == null) return true;
if ([Link] <= low || [Link] >= high) return false;
return helper([Link], low, [Link]) && helper([Link], [Link], high);
}
Java Solution:
public int diameterOfBinaryTree(TreeNode root) {
int[] res = new int[1];
depth(root, res);
return res[0];
}
private int depth(TreeNode node, int[] res) {
if (node == null) return 0;
int L = depth([Link], res);
int R = depth([Link], res);
res[0] = [Link](res[0], L + R);
return 1 + [Link](L, R);
}
Explanation: At each node, diameter may pass through it = left depth + right depth.
Java Solution:
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
backtrack(0, nums, new ArrayList<>(), res);
return res;
}
private void backtrack(int idx, int[] nums, List<Integer> cur, List<List<Integer>>
res) {
if (idx == [Link]) { [Link](new ArrayList<>(cur)); return; }
// exclude
backtrack(idx+1, nums, cur, res);
// include
[Link](nums[idx]);
backtrack(idx+1, nums, cur, res);
[Link]([Link]()-1);
}
27. Permutations
Generate all permutations of array.
Java Solution:
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
back(nums, 0, res);
return res;
}
private void back(int[] a, int i, List<List<Integer>> res) {
if (i == [Link]) {
List<Integer> cur = new ArrayList<>();
for (int v : a) [Link](v);
[Link](cur);
return;
}
for (int j = i; j < [Link]; j++) {
swap(a, i, j);
back(a, i+1, res);
swap(a, i, j);
}
}
private void swap(int[] a, int i, int j){ int t=a[i]; a[i]=a[j]; a[j]=t; }
28. N-Queens
Place n queens so none attack each other.
Java Solution:
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<>();
int[] cols = new int[n];
place(res, cols, 0, n);
return res;
}
private void place(List<List<String>> res, int[] cols, int row, int n) {
if (row == n) { [Link](build(cols)); return; }
for (int c = 0; c < n; c++) {
if (valid(cols, row, c)) {
cols[row] = c;
place(res, cols, row+1, n);
}
}
}
private boolean valid(int[] cols, int row, int col) {
for (int r = 0; r < row; r++) {
if (cols[r] == col || [Link](cols[r]-col) == row-r) return false;
}
return true;
}
private List<String> build(int[] cols) {
List<String> board = new ArrayList<>();
for (int r = 0; r < [Link]; r++) {
char[] row = new char[[Link]];
[Link](row, '.');
row[cols[r]] = 'Q';
[Link](new String(row));
}
return board;
}
Java Solution:
public boolean solveSudoku(char[][] board) {
return solve(board);
}
private boolean solve(char[][] b) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (b[i][j] == '.') {
for (char c = '1'; c <= '9'; c++) {
if (isValid(b, i, j, c)) {
b[i][j] = c;
if (solve(b)) return true;
b[i][j] = '.';
}
}
return false;
}
}
}
return true;
}
private boolean isValid(char[][] b, int r, int c, char ch) {
for (int i = 0; i < 9; i++) {
if (b[r][i] == ch || b[i][c] == ch) return false;
if (b[(r/3)*3 + i/3][(c/3)*3 + i%3] == ch) return false;
}
return true;
}
Java Solution:
public int binarySearch(int[] a, int target) {
int l = 0, r = [Link]-1;
while (l <= r) {
int m = l + (r-l)/2;
if (a[m] == target) return m;
else if (a[m] < target) l = m+1;
else r = m-1;
}
return -1;
}
Java Solution:
public void mergeSort(int[] a) {
if ([Link] < 2) return;
int mid = [Link]/2;
int[] l = [Link](a,0,mid);
int[] r = [Link](a,mid,[Link]);
mergeSort(l); mergeSort(r);
merge(a, l, r);
}
private void merge(int[] a, int[] l, int[] r) {
int i=0,j=0,k=0;
while (i<[Link] && j<[Link]) a[k++] = (l[i]<=r[j])?l[i++]:r[j++];
while (i<[Link]) a[k++] = l[i++];
while (j<[Link]) a[k++] = r[j++];
}
Java Solution:
public void quickSort(int[] a) { quickSort(a,0,[Link]-1); }
private void quickSort(int[] a, int l, int r) {
if (l >= r) return;
int p = partition(a, l, r);
quickSort(a, l, p-1);
quickSort(a, p+1, r);
}
private int partition(int[] a, int l, int r) {
int pivot = a[r], i = l;
for (int j = l; j < r; j++) {
if (a[j] < pivot) { int t=a[i]; a[i++]=a[j]; a[j]=t; }
}
int t=a[i]; a[i]=a[r]; a[r]=t;
return i;
}
Explanation: Partition around pivot then recursively sort partitions. Average O(n log n).
Complexity: Time: Avg O(n log n), Worst O(n^2), Space: O(log n)
Java Solution:
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
for (int n : nums) {
[Link](n);
if ([Link]() > k) [Link]();
}
return [Link]();
}
Explanation: Maintain min-heap of size k; top is kth largest.
Java Solution:
public int search(int[] a, int target) {
int l=0, r=[Link]-1;
while (l<=r) {
int m=(l+r)/2;
if (a[m]==target) return m;
if (a[l] <= a[m]) {
if (target>=a[l] && target<a[m]) r=m-1;
else l=m+1;
} else {
if (target>a[m] && target<=a[r]) l=m+1;
else r=m-1;
}
}
return -1;
}
Java Solution:
public int lengthOfLIS(int[] nums) {
int[] tails = new int[[Link]];
int size = 0;
for (int x : nums) {
int i = [Link](tails, 0, size, x);
if (i < 0) i = - (i+1);
tails[i] = x;
if (i == size) size++;
}
return size;
}
Java Solution:
public int lcs(String A, String B) {
int n=[Link](), m=[Link]();
int[][] dp = new int[n+1][m+1];
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++)
if ([Link](i-1)==[Link](j-1)) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=[Link](dp[i-1][j], dp[i][j-1]);
return dp[n][m];
}
Java Solution:
public int minDistance(String A, String B) {
int n=[Link](), m=[Link]();
int[][] dp = new int[n+1][m+1];
for (int i=0;i<=n;i++) dp[i][0]=i;
for (int j=0;j<=m;j++) dp[0][j]=j;
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) {
if ([Link](i-1)==[Link](j-1)) dp[i][j]=dp[i-1][j-1];
else dp[i][j]=1+[Link](dp[i-1][j-1], [Link](dp[i-1][j], dp[i][j-1]));
}
return dp[n][m];
}
Java Solution:
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
[Link](dp, amount+1);
dp[0]=0;
for (int c : coins) for (int i=c; i<=amount; i++)
dp[i] = [Link](dp[i], dp[i-c]+1);
return dp[amount] > amount ? -1 : dp[amount];
}
Java Solution:
public int numIslands(char[][] grid) {
int m=[Link], n=grid[0].length; int count=0;
for (int i=0;i<m;i++) for (int j=0;j<n;j++) {
if (grid[i][j]=='1') { dfs(grid,i,j); count++; }
}
return count;
}
private void dfs(char[][] g, int i, int j) {
if (i<0 || j<0 || i>=[Link] || j>=g[0].length || g[i][j]=='0') return;
g[i][j]='0';
dfs(g,i+1,j); dfs(g,i-1,j); dfs(g,i,j+1); dfs(g,i,j-1);
}
Explanation: DFS to mark visited land cells; increment count for new islands.
Java Solution:
class Node { public int val; public List<Node> neighbors; Node(int v){val=v;
neighbors=new ArrayList<>();} }
public Node cloneGraph(Node node) {
if (node==null) return null;
Map<Node, Node> map = new HashMap<>();
Queue<Node> q = new LinkedList<>(); [Link](node);
[Link](node, new Node([Link]));
while (![Link]()) {
Node cur = [Link]();
for (Node nei : [Link]) {
if () { [Link](nei, new Node([Link])); [Link](nei); }
[Link](cur).[Link]([Link](nei));
}
}
return [Link](node);
}
Java Solution:
public int[] topoSort(int n, int[][] edges) {
List<Integer>[] g = new List[n]; for (int i=0;i<n;i++) g[i]=new ArrayList<>();
int[] indeg = new int[n];
for (int[] e: edges) { g[e[0]].add(e[1]); indeg[e[1]]++; }
Queue<Integer> q = new LinkedList<>();
for (int i=0;i<n;i++) if (indeg[i]==0) [Link](i);
int[] res = new int[n]; int idx=0;
while (![Link]()) {
int u = [Link](); res[idx++] = u;
for (int v: g[u]) if (--indeg[v]==0) [Link](v);
}
if (idx != n) return new int[]{}; // cycle
return res;
}
Java Solution:
public int[] dijkstra(List<int[]>[] graph, int src) {
int n = [Link];
int[] dist = new int[n]; [Link](dist, Integer.MAX_VALUE);
dist[src]=0;
PriorityQueue<int[]> pq = new PriorityQueue<>([Link](a->a[1]));
[Link](new int[]{src,0});
while (![Link]()) {
int[] cur = [Link](); int u=cur[0], d=cur[1];
if (d>dist[u]) continue;
for (int[] e: graph[u]) {
int v=e[0], w=e[1];
if (dist[v] > dist[u]+w) {
dist[v] = dist[u]+w;
[Link](new int[]{v, dist[v]});
}
}
}
return dist;
}
Explanation: Use priority queue; relax edges when shorter paths found.
Java Solution:
public boolean hasCycle(int n, List<Integer>[] g) {
int[] vis = new int[n]; // 0 unvisited, 1 visiting, 2 visited
for (int i=0;i<n;i++) if (vis[i]==0 && dfs(i,g,vis)) return true;
return false;
}
private boolean dfs(int u, List<Integer>[] g, int[] vis) {
vis[u]=1;
for (int v: g[u]) {
if (vis[v]==1) return true;
if (vis[v]==0 && dfs(v,g,vis)) return true;
}
vis[u]=2; return false;
}
Explanation: Use three-state visitation to detect back-edges indicating cycles.
Java Solution:
public boolean exist(char[][] board, String word) {
int m=[Link], n=board[0].length;
for (int i=0;i<m;i++) for (int j=0;j<n;j++)
if (dfs(board, i, j, word, 0)) return true;
return false;
}
private boolean dfs(char[][] b, int i, int j, String w, int idx) {
if (idx == [Link]()) return true;
if (i<0||j<0||i>=[Link]||j>=b[0].length||b[i][j]!=[Link](idx)) return false;
char tmp=b[i][j]; b[i][j]='#';
boolean found = dfs(b,i+1,j,w,idx+1) || dfs(b,i-1,j,w,idx+1)
|| dfs(b,i,j+1,w,idx+1) || dfs(b,i,j-1,w,idx+1);
b[i][j]=tmp;
return found;
}
Java Solution:
public int[] maxSlidingWindow(int[] nums, int k) {
if ([Link]==0) return new int[0];
Deque<Integer> dq = new ArrayDeque<>();
int[] res = new int[[Link] - k + 1]; int ri=0;
for (int i=0;i<[Link];i++) {
while (![Link]() && [Link]() < i-k+1) [Link]();
while (![Link]() && nums[[Link]()] < nums[i]) [Link]();
[Link](i);
if (i >= k-1) res[ri++] = nums[[Link]()];
}
return res;
}
Java Solution:
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> pq = new PriorityQueue<>([Link](a->[Link]));
for (ListNode ln: lists) if (ln!=null) [Link](ln);
ListNode dummy=new ListNode(0), tail=dummy;
while (![Link]()) {
ListNode n = [Link]();
[Link] = n; tail = [Link];
if ([Link]!=null) [Link]([Link]);
}
return [Link];
}
Explanation: Use min-heap of current heads of lists; poll smallest and push next.
Java Solution:
public int kthSmallest(TreeNode root, int k) {
Deque<TreeNode> st = new ArrayDeque<>();
TreeNode cur = root;
while (cur != null || ![Link]()) {
while (cur != null) { [Link](cur); cur = [Link]; }
cur = [Link]();
if (--k == 0) return [Link];
cur = [Link];
}
return -1;
}
Java Solution:
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
build(root, sb);
return [Link]();
}
private void build(TreeNode node, StringBuilder sb) {
if (node==null) { [Link]("#,"); return; }
[Link]([Link]).append(',');
build([Link], sb); build([Link], sb);
}
public TreeNode deserialize(String data) {
Queue<String> q = new LinkedList<>([Link]([Link](",")));
return buildTree(q);
}
private TreeNode buildTree(Queue<String> q) {
String s = [Link]();
if ([Link]("#")) return null;
TreeNode node = new TreeNode([Link](s));
[Link] = buildTree(q); [Link] = buildTree(q);
return node;
}
Java Solution:
class LRUCache {
private int cap; private Map<Integer,Integer> map; private
LinkedHashMap<Integer,Integer> cache;
public LRUCache(int capacity) {
[Link] = capacity;
cache = new LinkedHashMap<>(capacity, 0.75f, true);
}
public int get(int key) { return [Link](key, -1); }
public void put(int key, int value) {
[Link](key, value);
if ([Link]() > cap) {
Iterator<Integer> it = [Link]().iterator(); [Link](); [Link]();
}
}
}
Explanation: Use LinkedHashMap with access-order to maintain LRU; evict oldest entry when over
capacity.
Java Solution:
// Outline: binary search on partition in smaller array.
// Full implementation is longer; key idea: partition arrays so left halves contain
half elements.
Explanation: Binary search on partition index ensuring all left <= all right; compute median from
partition edges.
Java Solution:
public int characterReplacement(String s, int k) {
int[] count = new int[26];
int maxCount = 0, start = 0, res = 0;
for (int end=0; end<[Link](); end++) {
maxCount = [Link](maxCount, ++count[[Link](end)-'A']);
while (end - start + 1 - maxCount > k) {
count[[Link](start)-'A']--; start++;
}
res = [Link](res, end - start + 1);
}
return res;
}
Explanation: Sliding window with tracking of most frequent char in window; shrink when more than
k replacements needed.
Java Solution:
public int maxProduct(int[] a) {
int imax = a[0], imin = a[0], ans = a[0];
for (int i=1;i<[Link];i++) {
if (a[i] < 0) { int t = imax; imax = imin; imin = t; }
imax = [Link](a[i], imax * a[i]);
imin = [Link](a[i], imin * a[i]);
ans = [Link](ans, imax);
}
return ans;
}
Explanation: Track max and min products ending at current position because negative flips sign.