0% found this document useful (0 votes)
12 views22 pages

Infosys DSE - 50 Questions in Java

The document provides a collection of 50 medium-level LeetCode-style problems along with their approaches, Java solutions, and time and space complexities. Each problem is accompanied by a brief description of the algorithm used to solve it, such as using HashMaps, sliding windows, or dynamic programming. The problems cover a wide range of topics including arrays, strings, linked lists, trees, and graphs.

Uploaded by

vishwasundar004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views22 pages

Infosys DSE - 50 Questions in Java

The document provides a collection of 50 medium-level LeetCode-style problems along with their approaches, Java solutions, and time and space complexities. Each problem is accompanied by a brief description of the algorithm used to solve it, such as using HashMaps, sliding windows, or dynamic programming. The problems cover a wide range of topics including arrays, strings, linked lists, trees, and graphs.

Uploaded by

vishwasundar004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Infosys DSE — 50 Medium Leet Code-style Problems (java)

Created by SYNTAX ERROR | Abhishek Rathor

Each entry: Problem → Short approach/algorithm → Java solution → Time & Space
complexity.

1. Two Sum (if unsorted)


Problem: Given array nums and target, return indices of two numbers summing to
target.
Approach: HashMap for complement lookup.

public int[] twoSum(int[] nums, int target) {


Map<Integer,Integer> m = new HashMap<>();
for(int i=0;i<nums.length;i++){
int c = target - nums[i];
if(m.containsKey(c)) return new int[]{m.get(c), i};
m.put(nums[i], i);
}
return new int[]{-1,-1};
}

Time: O(n) Space: O(n)

2. Longest Substring Without Repeating Characters


Approach: Sliding window with last index array/map.

public int lengthOfLongestSubstring(String s) {


int[] last = new int[256]; Arrays.fill(last, -1);
int res=0, start=0;
for(int i=0;i<s.length();i++){
start = Math.max(start, last[s.charAt(i)] + 1);
res = Math.max(res, i-start+1);
last[s.charAt(i)] = i;
}
return res;
}

Time: O(n) Space: O(1)

3. Add Two Numbers (linked list)


Approach: Simulate addition with carry.

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {


ListNode dummy=new ListNode(0), cur=dummy;
int carry=0;
while(l1!=null || l2!=null || carry!=0){
int s = carry + (l1!=null?l1.val:0) + (l2!=null?l2.val:0);
carry = s/10;
cur.next = new ListNode(s%10);
cur = cur.next;
if(l1!=null) l1=l1.next;
if(l2!=null) l2=l2.next;
}
return dummy.next;
}

Time: O(max(n,m)) Space: O(max(n,m))

4. Longest Palindromic Substring (center expand)


Approach: Expand from each center.

public String longestPalindrome(String s) {


if(s==null||s.length()<1) return "";
int start=0,end=0;
for(int i=0;i<s.length();i++){
int l1 = expand(s,i,i);
int l2 = expand(s,i,i+1);
int len = Math.max(l1,l2);
if(len > end-start+1){
start = i - (len-1)/2;
end = i + len/2;
}
}
return s.substring(start,end+1);
}
private int expand(String s,int l,int r){
while(l>=0 && r<s.length() && s.charAt(l)==s.charAt(r)){ l--; r++; }
return r-l-1;
}

Time: O(n^2) Space: O(1)

5. Merge Intervals
Approach: Sort by start and merge adjacent intervals.

public int[][] merge(int[][] intervals) {


if(intervals.length<=1) return intervals;
Arrays.sort(intervals,(a,b)->a[0]-b[0]);
List<int[]> res=new ArrayList<>();
int[] cur=intervals[0];
for(int i=1;i<intervals.length;i++){
if(intervals[i][0] <= cur[1]) cur[1] = Math.max(cur[1],
intervals[i][1]);
else { res.add(cur); cur=intervals[i]; }
}
res.add(cur);
return res.toArray(new int[res.size()][]);
}

Time: O(n log n) Space: O(n)

6. Search in Rotated Sorted Array


Approach: Modified binary search to choose half.

public int search(int[] nums, int target) {


int l=0,r=nums.length-1;
while(l<=r){
int m=(l+r)/2;
if(nums[m]==target) return m;
if(nums[l]<=nums[m]){
if(target>=nums[l] && target<nums[m]) r=m-1;
else l=m+1;
} else {
if(target>nums[m] && target<=nums[r]) l=m+1;
else r=m-1;
}
}
return -1;
}

Time: O(log n) Space: O(1)

7. Top K Frequent Elements


Approach: Frequency map + min-heap of size k.

public int[] topKFrequent(int[] nums, int k) {


Map<Integer,Integer> m=new HashMap<>();
for(int n:nums) m.put(n,m.getOrDefault(n,0)+1);
PriorityQueue<Integer> pq = new PriorityQueue<>((a,b)->m.get(a)-
m.get(b));
for(int key: m.keySet()){
pq.offer(key);
if(pq.size()>k) pq.poll();
}
int[] res=new int[k];
for(int i=k-1;i>=0;i--) res[i]=pq.poll();
return res;
}

Time: O(n log k) Space: O(n)

8. Kth Smallest Element in a BST


Approach: Inorder traversal (iterative or recursive).

public int kthSmallest(TreeNode root, int k) {


Deque<TreeNode> st=new ArrayDeque<>();
TreeNode cur=root;
while(cur!=null || !st.isEmpty()){
while(cur!=null){ st.push(cur); cur=cur.left; }
cur = st.pop();
if(--k==0) return cur.val;
cur = cur.right;
}
return -1;
}

Time: O(h + k) Space: O(h)

9. Word Break
Approach: DP boolean reachable array.

public boolean wordBreak(String s, List<String> wordDict) {


Set<String> set=new HashSet<>(wordDict);
boolean[] dp=new boolean[s.length()+1];
dp[0]=true;
for(int i=1;i<=s.length();i++){
for(int j=0;j<i;j++){
if(dp[j] && set.contains(s.substring(j,i))){ dp[i]=true;
break;}
}
}
return dp[s.length()];
}

Time: O(n^2 * L) (L substring cost) Space: O(n)

10. Number of Islands


Approach: DFS/BFS to mark visited cells.

public int numIslands(char[][] grid) {


if(grid==null||grid.length==0) return 0;
int m=grid.length,n=grid[0].length, count=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]=='1'){ count++; dfs(grid,i,j); }
}
}
return count;
}
private void dfs(char[][] g,int i,int j){
if(i<0||j<0||i>=g.length||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);
}

Time: O(mn) Space: O(mn) recursion


11. Course Schedule (detect cycle in directed graph)
Approach: Topological sort / DFS cycle detection.

public boolean canFinish(int numCourses, int[][] prerequisites) {


List<Integer>[] g = new List[numCourses];
for(int i=0;i<numCourses;i++) g[i]=new ArrayList<>();
int[] indeg=new int[numCourses];
for(int[] p:prerequisites){ g[p[1]].add(p[0]); indeg[p[0]]++; }
Queue<Integer> q=new LinkedList<>();
for(int i=0;i<numCourses;i++) if(indeg[i]==0) q.offer(i);
int cnt=0;
while(!q.isEmpty()){
int u=q.poll(); cnt++;
for(int v:g[u]) if(--indeg[v]==0) q.offer(v);
}
return cnt==numCourses;
}

Time: O(V+E) Space: O(V+E)

12. Course Schedule II (topological order)


Approach: Kahn’s algorithm output ordering.

public int[] findOrder(int numCourses, int[][] prerequisites) {


List<Integer>[] g = new List[numCourses];
for(int i=0;i<numCourses;i++) g[i]=new ArrayList<>();
int[] indeg = new int[numCourses];
for(int[] p:prerequisites){ g[p[1]].add(p[0]); indeg[p[0]]++; }
Queue<Integer> q = new LinkedList<>();
for(int i=0;i<numCourses;i++) if(indeg[i]==0) q.offer(i);
int idx=0; int[] res=new int[numCourses];
while(!q.isEmpty()){
int u=q.poll(); res[idx++]=u;
for(int v:g[u]) if(--indeg[v]==0) q.offer(v);
}
return idx==numCourses?res:new int[0];
}

Time: O(V+E) Space: O(V+E)

13. Binary Tree Level Order Traversal


Approach: BFS using queue.

public List<List<Integer>> levelOrder(TreeNode root) {


List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
Queue<TreeNode> q=new LinkedList<>(); q.offer(root);
while(!q.isEmpty()){
int sz=q.size(); List<Integer> level=new ArrayList<>();
for(int i=0;i<sz;i++){
TreeNode n=q.poll(); level.add(n.val);
if(n.left!=null) q.offer(n.left);
if(n.right!=null) q.offer(n.right);
}
res.add(level);
}
return res;
}

Time: O(n) Space: O(n)

14. Serialize and Deserialize Binary Tree


Approach: Preorder with null markers and queue during deserialization.

public String serialize(TreeNode root) {


StringBuilder sb=new StringBuilder();
build(root,sb);
return sb.toString();
}
private void build(TreeNode r,StringBuilder sb){
if(r==null){ sb.append("X,"); return; }
sb.append(r.val).append(",");
build(r.left,sb); build(r.right,sb);
}
public TreeNode deserialize(String data){
Queue<String> q=new LinkedList<>(Arrays.asList(data.split(",")));
return buildTree(q);
}
private TreeNode buildTree(Queue<String> q){
String v=q.poll();
if(v.equals("X")) return null;
TreeNode node=new TreeNode(Integer.parseInt(v));
node.left = buildTree(q); node.right = buildTree(q);
return node;
}

Time: O(n) Space: O(n)

15. LRU Cache


Approach: HashMap + Doubly linked list. (Compact single-class implementation)

class LRUCache {
private int cap;
private Map<Integer,Node> map;
private Node head, tail;
class Node{ int k,v; Node prev,next; Node(int k,int
v){this.k=k;this.v=v;} }
public LRUCache(int capacity){
this.cap=capacity; map=new HashMap<>();
head=new Node(0,0); tail=new Node(0,0);
head.next=tail; tail.prev=head;
}
public int get(int key){
if(!map.containsKey(key)) return -1;
Node n=map.get(key); remove(n); insertFront(n); return n.v;
}
public void put(int key,int value){
if(map.containsKey(key)){ remove(map.get(key)); map.remove(key); }
if(map.size()==cap){ map.remove(tail.prev.k); remove(tail.prev); }
Node n=new Node(key,value); insertFront(n); map.put(key,n);
}
private void remove(Node n){ n.prev.next = n.next; n.next.prev =
n.prev; }
private void insertFront(Node n){ n.next=head.next; head.next.prev=n;
head.next=n; n.prev=head; }
}

Time: O(1) per op Space: O(capacity)

16. K Closest Points to Origin


Approach: Use max-heap of size k or Quickselect.

public int[][] kClosest(int[][] points, int k) {


PriorityQueue<int[]> pq = new PriorityQueue<>((a,b)-
>(b[0]*b[0]+b[1]*b[1])-(a[0]*a[0]+a[1]*a[1]));
for(int[] p:points){
pq.offer(p);
if(pq.size()>k) pq.poll();
}
int[][] res=new int[k][2];
for(int i=k-1;i>=0;i--) res[i]=pq.poll();
return res;
}

Time: O(n log k) Space: O(k)

17. Minimum Window Substring


Approach: Sliding window with counts for target; expand right until all matched,
shrink left to minimize.

public String minWindow(String s, String t) {


if(s.length()==0 || t.length()==0) return "";
int[] need=new int[128];
for(char c:t.toCharArray()) need[c]++;
int required=t.length(), l=0, minLen=Integer.MAX_VALUE, start=0;
for(int r=0;r<s.length();r++){
if(need[s.charAt(r)]-- > 0) required--;
while(required==0){
if(r-l+1 < minLen){ minLen = r-l+1; start=l; }
if(++need[s.charAt(l++)] > 0) required++;
}
}
return minLen==Integer.MAX_VALUE?"":s.substring(start,start+minLen);
}

Time: O(n) Space: O(1)


18. Word Ladder (shortest transformation length)
Approach: BFS on word graph with one-letter transformations; precompute generic
forms.

public int ladderLength(String begin, String end, List<String> wordList) {


Set<String> dict = new HashSet<>(wordList);
if(!dict.contains(end)) return 0;
Queue<String> q=new LinkedList<>();
q.offer(begin);
Set<String> vis=new HashSet<>(); vis.add(begin);
int lvl=1;
while(!q.isEmpty()){
int sz=q.size();
for(int i=0;i<sz;i++){
String cur=q.poll();
char[] a=cur.toCharArray();
for(int j=0;j<a.length;j++){
char old=a[j];
for(char c='a';c<='z';c++){
a[j]=c; String nxt=new String(a);
if(nxt.equals(end)) return lvl+1;
if(dict.contains(nxt) && !vis.contains(nxt)){
vis.add(nxt); q.offer(nxt); }
}
a[j]=old;
}
}
lvl++;
}
return 0;
}

Time: O(M * 26 * L) (M words, L length) Space: O(M)

19. Trapping Rain Water


Approach: Two-pointer with leftMax/rightMax.

public int trap(int[] h) {


int l=0,r=h.length-1, leftMax=0,rightMax=0,res=0;
while(l<r){
if(h[l] < h[r]){
leftMax=Math.max(leftMax,h[l]);
res += leftMax - h[l++];
} else {
rightMax=Math.max(rightMax,h[r]);
res += rightMax - h[r--];
}
}
return res;
}

Time: O(n) Space: O(1)


20. Find Median from Data Stream
Approach: Two heaps (max-heap low, min-heap high).

class MedianFinder {
PriorityQueue<Integer> lo = new
PriorityQueue<>(Collections.reverseOrder());
PriorityQueue<Integer> hi = new PriorityQueue<>();
public void addNum(int num) {
lo.offer(num);
hi.offer(lo.poll());
if(lo.size() < hi.size()) lo.offer(hi.poll());
}
public double findMedian() {
if(lo.size()>hi.size()) return lo.peek();
return (lo.peek()+hi.peek())/2.0;
}
}

Time: O(log n) per add Space: O(n)

21. Coin Change (min coins)


Approach: DP bottom-up for min coins.

public int coinChange(int[] coins, int amount) {


int[] dp = new int[amount+1];
Arrays.fill(dp, amount+1);
dp[0]=0;
for(int i=1;i<=amount;i++){
for(int c:coins) if(c<=i) dp[i] = Math.min(dp[i], dp[i-c]+1);
}
return dp[amount]>amount?-1:dp[amount];
}

Time: O(amount * nCoins) Space: O(amount)

22. Subarray Sum Equals K


Approach: Prefix sum with hashmap counts.

public int subarraySum(int[] nums, int k) {


Map<Integer,Integer> m=new HashMap<>(); m.put(0,1);
int sum=0,res=0;
for(int n:nums){
sum+=n;
if(m.containsKey(sum-k)) res+=m.get(sum-k);
m.put(sum, m.getOrDefault(sum,0)+1);
}
return res;
}

Time: O(n) Space: O(n)


23. Minimum Path Sum (grid)
Approach: DP in-place or 1D DP.

public int minPathSum(int[][] grid) {


int m=grid.length,n=grid[0].length;
for(int i=1;i<m;i++) grid[i][0]+=grid[i-1][0];
for(int j=1;j<n;j++) grid[0][j]+=grid[0][j-1];
for(int i=1;i<m;i++)
for(int j=1;j<n;j++)
grid[i][j]+=Math.min(grid[i-1][j], grid[i][j-1]);
return grid[m-1][n-1];
}

Time: O(mn) Space: O(1)

24. Unique Paths II (with obstacles)


Approach: DP with obstacle checks.

public int uniquePathsWithObstacles(int[][] obs) {


int m=obs.length,n=obs[0].length;
if(obs[0][0]==1) return 0;
obs[0][0]=1;
for(int i=1;i<m;i++) obs[i][0] = (obs[i][0]==0?obs[i-1][0]:0);
for(int j=1;j<n;j++) obs[0][j] = (obs[0][j]==0?obs[0][j-1]:0);
for(int i=1;i<m;i++)
for(int j=1;j<n;j++)
obs[i][j] = (obs[i][j]==0? obs[i-1][j]+obs[i][j-1] : 0);
return obs[m-1][n-1];
}

Time: O(mn) Space: O(1)

25. Maximum Product Subarray


Approach: Track max and min ending here because of negatives.

public int maxProduct(int[] nums) {


int res = nums[0], curMax = nums[0], curMin = nums[0];
for(int i=1;i<nums.length;i++){
if(nums[i]<0){
int t=curMax; curMax=curMin; curMin=t;
}
curMax = Math.max(nums[i], curMax*nums[i]);
curMin = Math.min(nums[i], curMin*nums[i]);
res = Math.max(res, curMax);
}
return res;
}

Time: O(n) Space: O(1)


26. Search a 2D Matrix II
Approach: Start from top-right and eliminate row/col each step.

public boolean searchMatrix(int[][] matrix, int target) {


int m=matrix.length, n=matrix[0].length;
int r=0,c=n-1;
while(r<m && c>=0){
if(matrix[r][c]==target) return true;
else if(matrix[r][c] > target) c--;
else r++;
}
return false;
}

Time: O(m+n) Space: O(1)

27. Reverse Nodes in k-Group (linked list)


Approach: Iterative reversing in groups with dummy head.

public ListNode reverseKGroup(ListNode head, int k) {


ListNode dummy=new ListNode(0); dummy.next=head;
ListNode prev=dummy;
while(true){
ListNode kth = prev;
for(int i=0;i<k && kth!=null;i++) kth=kth.next;
if(kth==null) break;
ListNode nextGroup = kth.next;
// reverse [prev.next .. kth]
ListNode cur = prev.next, prevNode = nextGroup;
while(cur!=nextGroup){
ListNode tmp = cur.next;
cur.next = prevNode;
prevNode = cur;
cur = tmp;
}
ListNode tmp = prev.next;
prev.next = kth;
prev = tmp;
}
return dummy.next;
}

Time: O(n) Space: O(1)

28. Clone Graph


Approach: BFS/DFS with hashmap of original->copy.

public Node cloneGraph(Node node) {


if(node==null) return null;
Map<Node,Node> map=new HashMap<>();
Queue<Node> q=new LinkedList<>();
q.offer(node);
map.put(node, new Node(node.val, new ArrayList<>()));
while(!q.isEmpty()){
Node cur=q.poll();
for(Node nei: cur.neighbors){
if(!map.containsKey(nei)){
map.put(nei, new Node(nei.val, new ArrayList<>()));
q.offer(nei);
}
map.get(cur).neighbors.add(map.get(nei));
}
}
return map.get(node);
}

Time: O(N+E) Space: O(N)

29. Binary Tree Right Side View


Approach: BFS level order, take last element of each level.

public List<Integer> rightSideView(TreeNode root) {


List<Integer> res=new ArrayList<>();
if(root==null) return res;
Queue<TreeNode> q=new LinkedList<>(); q.offer(root);
while(!q.isEmpty()){
int sz=q.size();
for(int i=0;i<sz;i++){
TreeNode n=q.poll();
if(i==sz-1) res.add(n.val);
if(n.left!=null) q.offer(n.left);
if(n.right!=null) q.offer(n.right);
}
}
return res;
}

Time: O(n) Space: O(n)

30. Find Peak Element


Approach: Binary search leveraging neighbor comparisons.

public int findPeakElement(int[] nums) {


int l=0,r=nums.length-1;
while(l<r){
int m=(l+r)/2;
if(nums[m] < nums[m+1]) l=m+1;
else r=m;
}
return l;
}

Time: O(log n) Space: O(1)


31. House Robber II (circle)
Approach: Two runs of linear DP excluding first or last.

public int rob(int[] nums) {


if(nums.length==1) return nums[0];
return Math.max(robLinear(nums,0,nums.length-2),
robLinear(nums,1,nums.length-1));
}
private int robLinear(int[] a,int l,int r){
int incl=0, excl=0;
for(int i=l;i<=r;i++){
int n = Math.max(incl, excl+a[i]);
excl = incl;
incl = n;
}
return incl;
}

Time: O(n) Space: O(1)

32. Binary Tree Zigzag Level Order Traversal


Approach: BFS with level parity flip or deque.

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {


List<List<Integer>> res=new ArrayList<>();
if(root==null) return res;
Queue<TreeNode> q=new LinkedList<>(); q.offer(root);
boolean leftToRight=true;
while(!q.isEmpty()){
int sz=q.size(); LinkedList<Integer> level=new LinkedList<>();
for(int i=0;i<sz;i++){
TreeNode n=q.poll();
if(leftToRight) level.addLast(n.val); else
level.addFirst(n.val);
if(n.left!=null) q.offer(n.left);
if(n.right!=null) q.offer(n.right);
}
res.add(level); leftToRight=!leftToRight;
}
return res;
}

Time: O(n) Space: O(n)

33. Minimum Height Trees


Approach: Topological trimming (peeling leaves).

public List<Integer> findMinHeightTrees(int n, int[][] edges) {


if(n==1) return Collections.singletonList(0);
List<Set<Integer>> g = new ArrayList<>();
for(int i=0;i<n;i++) g.add(new HashSet<>());
for(int[] e:edges){ g.get(e[0]).add(e[1]); g.get(e[1]).add(e[0]); }
List<Integer> leaves=new ArrayList<>();
for(int i=0;i<n;i++) if(g.get(i).size()==1) leaves.add(i);
int remaining = n;
while(remaining>2){
remaining -= leaves.size();
List<Integer> newLeaves = new ArrayList<>();
for(int leaf: leaves){
int nei = g.get(leaf).iterator().next();
g.get(nei).remove(leaf);
if(g.get(nei).size()==1) newLeaves.add(nei);
}
leaves = newLeaves;
}
return leaves;
}

Time: O(n) Space: O(n)

34. Binary Tree Maximum Path Sum


Approach: DFS returning max gain, track global max.

int maxSum = Integer.MIN_VALUE;


public int maxPathSum(TreeNode root) {
dfs(root);
return maxSum;
}
private int dfs(TreeNode node){
if(node==null) return 0;
int left = Math.max(0, dfs(node.left));
int right = Math.max(0, dfs(node.right));
maxSum = Math.max(maxSum, node.val + left + right);
return node.val + Math.max(left,right);
}

Time: O(n) Space: O(h)

35. Count of Smaller Numbers After Self


Approach: Binary Indexed Tree (Fenwick) or merge sort with indices. (Use BIT)

public List<Integer> countSmaller(int[] nums) {


int n=nums.length;
int[] sorted = Arrays.copyOf(nums,n);
Arrays.sort(sorted);
Map<Integer,Integer> rank=new HashMap<>();
int r=1;
for(int v: sorted) if(!rank.containsKey(v)) rank.put(v, r++);
Fenwick bit = new Fenwick(r+1);
List<Integer> res = new ArrayList<>();
for(int i=n-1;i>=0;i--){
int rk = rank.get(nums[i]);
res.add(bit.query(rk-1));
bit.update(rk,1);
}
Collections.reverse(res);
return res;
}
class Fenwick {
int[] f;
Fenwick(int n){ f=new int[n]; }
void update(int i,int delta){ for(;i<f.length;i+=i&-i) f[i]+=delta; }
int query(int i){ int s=0; for(;i>0;i-=i&-i) s+=f[i]; return s; }
}

Time: O(n log n) Space: O(n)

36. Longest Consecutive Sequence


Approach: HashSet and expand from starts.

public int longestConsecutive(int[] nums) {


Set<Integer> s=new HashSet<>();
for(int n:nums) s.add(n);
int best=0;
for(int n:nums){
if(!s.contains(n-1)){
int cur=n,len=1;
while(s.contains(++cur)) len++;
best=Math.max(best,len);
}
}
return best;
}

Time: O(n) Space: O(n)

37. Subsets II (unique subsets with duplicates)


Approach: Sort and backtrack skipping duplicates.

public List<List<Integer>> subsetsWithDup(int[] nums) {


Arrays.sort(nums);
List<List<Integer>> res=new ArrayList<>();
backtrack(nums,0,new ArrayList<>(),res);
return res;
}
private void backtrack(int[] nums,int idx,List<Integer>
cur,List<List<Integer>> res){
res.add(new ArrayList<>(cur));
for(int i=idx;i<nums.length;i++){
if(i>idx && nums[i]==nums[i-1]) continue;
cur.add(nums[i]);
backtrack(nums,i+1,cur,res);
cur.remove(cur.size()-1);
}
}

Time: O(2^n) Space: O(n)


38. Word Search (board)
Approach: Backtracking DFS with visited marking.

public boolean exist(char[][] board, String word) {


int m=board.length, n=board[0].length;
for(int i=0;i<m;i++) for(int j=0;j<n;j++)
if(dfs(board,word,0,i,j)) return true;
return false;
}
private boolean dfs(char[][] b,String w,int idx,int i,int j){
if(idx==w.length()) return true;
if(i<0||j<0||i>=b.length||j>=b[0].length||b[i][j]!=w.charAt(idx))
return false;
char c=b[i][j]; b[i][j]='#';
boolean found = dfs(b,w,idx+1,i+1,j) || dfs(b,w,idx+1,i-1,j) ||
dfs(b,w,idx+1,i,j+1) || dfs(b,w,idx+1,i,j-1);
b[i][j]=c;
return found;
}

Time: O(mn4^L) Space: O(L)

39. Letter Combinations of a Phone Number


Approach: Backtracking using digit-to-letters map.

public List<String> letterCombinations(String digits) {


List<String> res=new ArrayList<>();
if(digits.length()==0) return res;
String[] map = {"","",
"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
back(digits,0,new StringBuilder(),res,map);
return res;
}
private void back(String d,int idx,StringBuilder sb,List<String>
res,String[] map){
if(idx==d.length()){ res.add(sb.toString()); return; }
for(char c: map[d.charAt(idx)-'0'].toCharArray()){
sb.append(c);
back(d,idx+1,sb,res,map);
sb.deleteCharAt(sb.length()-1);
}
}

Time: O(4^L * L) Space: O(L)

40. Combination Sum (unique combos)


Approach: Backtracking with candidates sorted and reuse allowed.

public List<List<Integer>> combinationSum(int[] candidates, int target) {


List<List<Integer>> res=new ArrayList<>();
Arrays.sort(candidates);
back(candidates,0,target,new ArrayList<>(),res);
return res;
}
private void back(int[] c,int idx,int t,List<Integer>
cur,List<List<Integer>> res){
if(t==0){ res.add(new ArrayList<>(cur)); return; }
for(int i=idx;i<c.length && c[i]<=t;i++){
cur.add(c[i]);
back(c,i,t-c[i],cur,res);
cur.remove(cur.size()-1);
}
}

Time: Exponential Space: O(target/minCandidate)

41. Basic Calculator II ( + - * / )


Approach: Single pass with stack or tracking last number.

public int calculate(String s) {


if(s==null) return 0;
s = s.replaceAll(" ","") + "+";
int cur=0, last=0, res=0;
char op='+';
for(int i=0;i<s.length();i++){
char c=s.charAt(i);
if(Character.isDigit(c)) cur = cur*10 + (c-'0');
else {
if(op=='+'){ res+=last; last=cur; }
else if(op=='-'){ res+=last; last=-cur; }
else if(op=='*'){ last = last * cur; }
else if(op=='/'){ last = last / cur; }
op = c; cur=0;
}
}
return res+last;
}

Time: O(n) Space: O(1) (ignoring string operations)

42. Binary Search Tree Iterator


Approach: Controlled inorder with stack.

class BSTIterator {
Deque<TreeNode> st = new ArrayDeque<>();
public BSTIterator(TreeNode root){
pushLeft(root);
}
private void pushLeft(TreeNode r){ while(r!=null){ st.push(r);
r=r.left; } }
public int next(){
TreeNode n=st.pop();
pushLeft(n.right);
return n.val;
}
public boolean hasNext(){ return !st.isEmpty(); }
}

Time: next amortized O(1) Space: O(h)

43. Find Kth Largest Element in an Array


Approach: Quickselect or min-heap. (Quickselect shown)

public int findKthLargest(int[] nums, int k) {


return quickSelect(nums, 0, nums.length-1, nums.length-k);
}
private int quickSelect(int[] a,int l,int r,int k){
if(l==r) return a[l];
int p = partition(a,l,r);
if(k==p) return a[k];
else if(k < p) return quickSelect(a,l,p-1,k);
else return quickSelect(a,p+1,r,k);
}
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){ swap(a,i,j); i++; }
}
swap(a,i,r);
return i;
}
private void swap(int[] a,int i,int j){ int t=a[i]; a[i]=a[j]; a[j]=t;}

Time: Average O(n) Space: O(1)

44. Maximal Rectangle (in binary matrix)


Approach: Treat each row as histogram and compute largest rectangle per row (stack).

public int maximalRectangle(char[][] matrix) {


if(matrix.length==0) return 0;
int m=matrix.length, n=matrix[0].length;
int[] h=new int[n];
int max=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++) h[j] = matrix[i][j]=='1' ? h[j]+1 : 0;
max = Math.max(max, largestRectangleArea(h));
}
return max;
}
private int largestRectangleArea(int[] h){
Deque<Integer> st=new ArrayDeque<>(); st.push(-1);
int max=0;
for(int i=0;i<h.length;i++){
while(st.peek()!=-1 && h[i] <= h[st.peek()]) max = Math.max(max,
h[st.pop()] * (i - st.peek() -1));
st.push(i);
}
while(st.peek()!=-1) max = Math.max(max, h[st.pop()] * (h.length -
st.peek() -1));
return max;
}

Time: O(mn) Space: O(n)

45. Alien Dictionary (topological order of chars)


Approach: Build graph of precedence from adjacent words, topological sort, detect
cycle.

public String alienOrder(String[] words) {


Map<Character,Set<Character>> g=new HashMap<>();
Map<Character,Integer> indeg=new HashMap<>();
for(String w:words) for(char c:w.toCharArray()){ g.putIfAbsent(c,new
HashSet<>()); indeg.putIfAbsent(c,0); }
for(int i=0;i<words.length-1;i++){
String w1=words[i], w2=words[i+1];
int len = Math.min(w1.length(), w2.length()), j=0;
while(j<len && w1.charAt(j)==w2.charAt(j)) j++;
if(j<len){
char c1=w1.charAt(j), c2=w2.charAt(j);
if(!g.get(c1).contains(c2)){ g.get(c1).add(c2); indeg.put(c2,
indeg.get(c2)+1); }
} else if(w1.length() > w2.length()) return "";
}
Queue<Character> q=new LinkedList<>();
for(char c: indeg.keySet()) if(indeg.get(c)==0) q.offer(c);
StringBuilder sb=new StringBuilder();
while(!q.isEmpty()){
char c=q.poll(); sb.append(c);
for(char nei: g.get(c)){
indeg.put(nei, indeg.get(nei)-1);
if(indeg.get(nei)==0) q.offer(nei);
}
}
if(sb.length() != indeg.size()) return "";
return sb.toString();
}

Time: O(V+E) Space: O(V+E)

46. Word Ladder II (all shortest sequences)


Approach: BFS to build graph of levels then backtrack from end to start (bidirectional
variant optional).
(Compact outline — implementation is long; here's a concise BFS + DFS
backtracking solution)

public List<List<String>> findLadders(String begin, String end,


List<String> wordList) {
Set<String> dict = new HashSet<>(wordList);
List<List<String>> res = new ArrayList<>();
if(!dict.contains(end)) return res;
Map<String,List<String>> tree = new HashMap<>();
Set<String> level = new HashSet<>(); level.add(begin);
boolean found=false;
while(!level.isEmpty() && !found){
Set<String> next = new HashSet<>();
for(String s: level) dict.remove(s);
for(String s: level){
char[] arr=s.toCharArray();
for(int i=0;i<arr.length;i++){
char old = arr[i];
for(char c='a';c<='z';c++){
arr[i]=c; String ns = new String(arr);
if(!dict.contains(ns)) continue;
tree.computeIfAbsent(s, k-> new ArrayList<>()).add(ns);
if(ns.equals(end)) found=true;
next.add(ns);
}
arr[i]=old;
}
}
level = next;
}
if(found){
LinkedList<String> path=new LinkedList<>();
path.add(begin);
dfsBuild(begin, end, tree, path, res);
}
return res;
}
private void dfsBuild(String cur,String end, Map<String,List<String>> tree,
LinkedList<String> path, List<List<String>> res){
if(cur.equals(end)){ res.add(new ArrayList<>(path)); return; }
if(!tree.containsKey(cur)) return;
for(String nxt: tree.get(cur)){
path.add(nxt);
dfsBuild(nxt,end,tree,path,res);
path.removeLast();
}
}

Time: High — depends on branching; Space: O(N * L)

47. Find All Anagrams in a String


Approach: Sliding window frequency arrays.

public List<Integer> findAnagrams(String s, String p) {


List<Integer> res=new ArrayList<>();
if(s.length() < p.length()) return res;
int[] sCount=new int[26], pCount=new int[26];
for(int i=0;i<p.length();i++){ sCount[s.charAt(i)-'a']++;
pCount[p.charAt(i)-'a']++; }
if(Arrays.equals(sCount,pCount)) res.add(0);
for(int i=p.length(); i<s.length(); i++){
sCount[s.charAt(i)-'a']++;
sCount[s.charAt(i-p.length())-'a']--;
if(Arrays.equals(sCount,pCount)) res.add(i-p.length()+1);
}
return res;
}
Time: O(n*26) ~ O(n) Space: O(1)

48. Insert Interval


Approach: Add non-overlapping intervals, merge when overlapping.

public int[][] insert(int[][] intervals, int[] newInterval) {


List<int[]> res=new ArrayList<>();
int i=0;
while(i<intervals.length && intervals[i][1] < newInterval[0])
res.add(intervals[i++]);
while(i<intervals.length && intervals[i][0] <= newInterval[1]){
newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
i++;
}
res.add(newInterval);
while(i<intervals.length) res.add(intervals[i++]);
return res.toArray(new int[res.size()][]);
}

Time: O(n) Space: O(n)

49. Binary Search Tree From Preorder


Approach: Reconstruct BST using bounds (index pointer).

int idx;
public TreeNode bstFromPreorder(int[] preorder) {
idx=0;
return helper(preorder, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
private TreeNode helper(int[] a, int lo, int hi){
if(idx==a.length) return null;
int val = a[idx];
if(val < lo || val > hi) return null;
idx++;
TreeNode root = new TreeNode(val);
root.left = helper(a, lo, val);
root.right = helper(a, val, hi);
return root;
}

Time: O(n) Space: O(h)

50. Sliding Window Maximum


Approach: Deque storing indices of potential max in decreasing order.

public int[] maxSlidingWindow(int[] nums, int k) {


if(nums==null||k<=0) return new int[0];
int n=nums.length; int[] res=new int[n-k+1];
Deque<Integer> dq = new ArrayDeque<>();
for(int i=0;i<nums.length;i++){
while(!dq.isEmpty() && dq.peek() < i-k+1) dq.poll();
while(!dq.isEmpty() && nums[dq.peekLast()] < nums[i])
dq.pollLast();
dq.offer(i);
if(i>=k-1) res[i-k+1] = nums[dq.peek()];
}
return res;
}

Time: O(n) Space: O(k)

� About the Author


SYNTAX ERROR | Abhishek Rathor

Helping students crack their dream placements! �

Connect with me:

• � Instagram: @code.abhii07
• � YouTube: SYNTAX ERROR

� Youve Got This! All The Best! �


"Success is where preparation meets opportunity. You've prepared well - now go seize your
opportunity!"

Sure! Let’s continue adding more Infosys DSE-relevant medium-level LeetCode problems
with full Java solutions.

You might also like