0% found this document useful (0 votes)
69 views57 pages

Rajat Sachan 22scse1012575 Dsa Mte Assignment

The document provides an overview of advanced algorithmic problem-solving techniques, focusing on concepts like prefix sum arrays, sliding window techniques, and various algorithms for common problems such as range sum queries, equilibrium index, and longest substring without repeating characters. Each algorithm is accompanied by Java code examples, time and space complexity analyses, and practical applications. Additionally, it covers topics like merging sorted linked lists, finding the median of two sorted arrays, and identifying the majority element in an array.

Uploaded by

Jaggi Singh
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)
69 views57 pages

Rajat Sachan 22scse1012575 Dsa Mte Assignment

The document provides an overview of advanced algorithmic problem-solving techniques, focusing on concepts like prefix sum arrays, sliding window techniques, and various algorithms for common problems such as range sum queries, equilibrium index, and longest substring without repeating characters. Each algorithm is accompanied by Java code examples, time and space complexity analyses, and practical applications. Additionally, it covers topics like merging sorted linked lists, finding the median of two sorted arrays, and identifying the majority element in an array.

Uploaded by

Jaggi Singh
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/ 57

Advanced Algorithmic

Problem Solving
(R1UC601B)
RAJAT SACHAN
22SCSE10125 7 5
1. Explain the concept of a prefix sum array and its applications
Prefix Sum Array: A prefix sum array is an array where each element at index i
stores the sum of elements from the start of the original array up to index i. It
allows constant-time queries for the sum of any subarray.
Applications:
• Range sum queries
• Subarray sum problems
• Equilibrium index
• Histogram water trapping
• Optimization in dynamic programming

2. Range Sum Using Prefix Sum Array


Algorithm:
1. Construct a prefix sum array.
2. To find the sum in range [L, R], use: prefix[R] - prefix[L-1].
java
CopyEdit
import java.util.*;

public class RangeSumPrefix {


public static void main(String[] args) {
int[] arr = {2, 4, 6, 8, 10};
int L = 1, R = 3;
int[] prefix = new int[arr.length];
prefix[0] = arr[0];
for (int i = 1; i < arr.length; i++) {
prefix[i] = prefix[i - 1] + arr[i];
}
int sum = L == 0 ? prefix[R] : prefix[R] - prefix[L - 1];
System.out.println(sum);
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Array: [2, 4, 6, 8, 10], Query: [1, 3] → Sum: 4 + 6 + 8 = 18

3. Equilibrium Index
Algorithm:
1. Compute total sum.
2. Iterate and track left sum.
3. If left sum == total - left - current, return index.
java
CopyEdit
public class EquilibriumIndex {
public static void main(String[] args) {
int[] arr = {-7, 1, 5, 2, -4, 3, 0};
int total = 0;
for (int num : arr) total += num;
int leftSum = 0;
for (int i = 0; i < arr.length; i++) {
if (leftSum == total - leftSum - arr[i]) {
System.out.println(i);
return;
}
leftSum += arr[i];
}
System.out.println(-1);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [-7, 1, 5, 2, -4, 3, 0] → Output: 3

4. Check if Prefix Sum == Suffix Sum


Algorithm:
1. Get total sum.
2. Iterate and compare left sum with right.
java
CopyEdit
public class EqualPrefixSuffix {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 3};
int total = 0, leftSum = 0;
for (int num : arr) total += num;
for (int i = 0; i < arr.length - 1; i++) {
leftSum += arr[i];
if (leftSum == total - leftSum) {
System.out.println(true);
return;
}
}
System.out.println(false);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [1, 2, 3, 3] → Output: true

5. Maximum Sum of Subarray of Size K


Algorithm:
1. Use sliding window of size k.
2. Track max sum by sliding the window.
java
CopyEdit
public class MaxSumSubarrayK {
public static void main(String[] args) {
int[] arr = {2, 1, 5, 1, 3, 2};
int k = 3;
int windowSum = 0;
for (int i = 0; i < k; i++) windowSum += arr[i];
int maxSum = windowSum;
for (int i = k; i < arr.length; i++) {
windowSum += arr[i] - arr[i - k];
maxSum = Math.max(maxSum, windowSum);
}
System.out.println(maxSum);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Array: [2, 1, 5, 1, 3, 2], k = 3 → Max Sum: 9

6. Length of Longest Substring Without Repeating Characters


Algorithm:
1. Use a sliding window and HashSet.
2. Expand window with right pointer.
3. Remove from left until unique.
java
CopyEdit
import java.util.*;

public class LongestUniqueSubstring {


public static void main(String[] args) {
String s = "abcabcbb";
Set<Character> set = new HashSet<>();
int left = 0, maxLen = 0;
for (int right = 0; right < s.length(); right++) {
while (set.contains(s.charAt(right))) {
set.remove(s.charAt(left++));
}
set.add(s.charAt(right));
maxLen = Math.max(maxLen, right - left + 1);
}
System.out.println(maxLen);
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: "abcabcbb" → Output: 3

7. Explain the sliding window technique and its use in string problems
Sliding Window Technique:
A method where a subset of data (window) is moved over the input structure
(array/string) to track or compute specific values efficiently.
Applications in String Problems:
• Longest substring without repeating characters
• Minimum window substring
• Anagram checking
• Counting occurrences of pattern
Advantages:
• Reduces time complexity from O(n²) to O(n)
• No need for nested loops
• Efficient memory usage

8. Longest Palindromic Substring


Algorithm:
1. Expand from each center.
2. Track max length.
java
CopyEdit
public class LongestPalindrome {
public static void main(String[] args) {
String s = "babad";
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = expand(s, i, i);
int len2 = expand(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
System.out.println(s.substring(start, end + 1));
}
static int expand(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}
}
Time Complexity: O(n²)
Space Complexity: O(1)
Example:
Input: "babad" → Output: "bab" or "aba"

9. Longest Common Prefix Among Strings


Algorithm:
1. Compare characters of the first string with others.
2. Stop when mismatch found.
java
CopyEdit
public class LongestCommonPrefix {
public static void main(String[] args) {
String[] strs = {"flower", "flow", "flight"};
if (strs.length == 0) {
System.out.println("");
return;
}
String prefix = strs[0];
for (int i = 1; i < strs.length; i++) {
while (strs[i].indexOf(prefix) != 0) {
prefix = prefix.substring(0, prefix.length() - 1);
}
}
System.out.println(prefix);
}
}
Time Complexity: O(n * m)
Space Complexity: O(1)
Example:
Input: ["flower","flow","flight"] → Output: "fl"

10. Generate All Permutations of a String


Algorithm:
1. Use backtracking.
2. Swap characters and recurse.
java
CopyEdit
public class PermutationsString {
public static void main(String[] args) {
String s = "abc";
permute(s.toCharArray(), 0);
}
static void permute(char[] s, int l) {
if (l == s.length - 1) {
System.out.println(new String(s));
return;
}
for (int i = l; i < s.length; i++) {
swap(s, i, l);
permute(s, l + 1);
swap(s, i, l);
}
}

static void swap(char[] s, int i, int j) {


char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
Time Complexity: O(n!)
Space Complexity: O(n)
Example:
Input: "abc" → Output: abc, acb, bac, bca, cab, cba
11. Two Numbers in Sorted Array That Add to Target
Algorithm:
1. Use two pointers from start and end.
2. Move inward based on sum comparison.
java
CopyEdit
public class TwoSumSorted {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 6};
int target = 6;
int left = 0, right = arr.length - 1;
while (left < right) {
int sum = arr[left] + arr[right];
if (sum == target) {
System.out.println(arr[left] + " " + arr[right]);
return;
} else if (sum < target) {
left++;
} else {
right--;
}
}
System.out.println("No pair found");
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [1,2,3,4,6], Target = 6 → Output: 2 4

12. Lexicographically Next Greater Permutation


Algorithm:
1. Find decreasing suffix.
2. Swap with next larger number.
3. Reverse the suffix.
java
CopyEdit
import java.util.*;

public class NextPermutation {


public static void main(String[] args) {
int[] nums = {1, 2, 3};
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) i--;
if (i >= 0) {
int j = nums.length - 1;
while (nums[j] <= nums[i]) j--;
swap(nums, i, j);
}
reverse(nums, i + 1);
System.out.println(Arrays.toString(nums));
}

static void swap(int[] a, int i, int j) {


int temp = a[i];
a[i] = a[j];
a[j] = temp;
}

static void reverse(int[] a, int start) {


int end = a.length - 1;
while (start < end) swap(a, start++, end--);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [1,2,3] → Output: [1,3,2]

13. Merge Two Sorted Linked Lists


Algorithm:
1. Use dummy node and compare node values.
2. Attach smaller node to current pointer.
java
CopyEdit
public class MergeSortedLists {
static class Node {
int val;
Node next;
Node(int val) { this.val = val; }
}

public static void main(String[] args) {


Node l1 = new Node(1);
l1.next = new Node(3);
l1.next.next = new Node(5);

Node l2 = new Node(2);


l2.next = new Node(4);
l2.next.next = new Node(6);

Node head = merge(l1, l2);


while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
}

static Node merge(Node l1, Node l2) {


Node dummy = new Node(0);
Node current = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
current.next = l1;
l1 = l1.next;
} else {
current.next = l2;
l2 = l2.next;
}
current = current.next;
}
current.next = l1 != null ? l1 : l2;
return dummy.next;
}
}
Time Complexity: O(n + m)
Space Complexity: O(1)
Example:
Lists: 1→3→5, 2→4→6 → Output: 1→2→3→4→5→6

14. Median of Two Sorted Arrays Using Binary Search


Algorithm:
1. Binary search on the smaller array.
2. Partition both arrays at midpoints.
3. Use max of lefts and min of rights.
java
CopyEdit
public class MedianSortedArrays {
public static void main(String[] args) {
int[] A = {1, 3};
int[] B = {2};
if (A.length > B.length) {
int[] temp = A; A = B; B = temp;
}
int m = A.length, n = B.length;
int low = 0, high = m;
while (low <= high) {
int i = (low + high) / 2;
int j = (m + n + 1) / 2 - i;
int maxLeftA = (i == 0) ? Integer.MIN_VALUE : A[i - 1];
int minRightA = (i == m) ? Integer.MAX_VALUE : A[i];
int maxLeftB = (j == 0) ? Integer.MIN_VALUE : B[j - 1];
int minRightB = (j == n) ? Integer.MAX_VALUE : B[j];
if (maxLeftA <= minRightB && maxLeftB <= minRightA) {
if ((m + n) % 2 == 0)
System.out.println((Math.max(maxLeftA, maxLeftB) +
Math.min(minRightA, minRightB)) / 2.0);
else
System.out.println(Math.max(maxLeftA, maxLeftB));
return;
} else if (maxLeftA > minRightB) {
high = i - 1;
} else {
low = i + 1;
}
}
}
}
Time Complexity: O(log(min(m, n)))
Space Complexity: O(1)
Example:
Input: [1,3], [2] → Output: 2.0

15. k-th Smallest Element in a Sorted Matrix


Algorithm:
1. Use min heap with elements from the first column.
2. Push next elements in row for each pop.
java
CopyEdit
import java.util.*;

public class KthSmallestMatrix {


public static void main(String[] args) {
int[][] matrix = {
{1, 5, 9},
{10, 11, 13},
{12, 13, 15}
};
int k = 8;
PriorityQueue<int[]> minHeap = new
PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
int n = matrix.length;
for (int i = 0; i < n; i++) minHeap.offer(new int[]{matrix[i][0], i, 0});
for (int i = 0; i < k - 1; i++) {
int[] curr = minHeap.poll();
if (curr[2] < n - 1)
minHeap.offer(new int[]{matrix[curr[1]][curr[2] + 1], curr[1], curr[2] +
1});
}
System.out.println(minHeap.poll()[0]);
}
}
Time Complexity: O(k log n)
Space Complexity: O(n)
Example:
Input: k = 8 → Output: 13
16. Majority Element Appearing More Than n/2 Times
Algorithm:
1. Use Boyer-Moore Voting Algorithm.
java
CopyEdit
public class MajorityElement {
public static void main(String[] args) {
int[] nums = {2, 2, 1, 1, 1, 2, 2};
int count = 0, candidate = 0;
for (int num : nums) {
if (count == 0) candidate = num;
count += (num == candidate) ? 1 : -1;
}
System.out.println(candidate);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [2,2,1,1,1,2,2] → Output: 2

17. Trapping Rain Water Between Bars


Algorithm:
1. Precompute maxLeft and maxRight.
2. Water = min(maxLeft, maxRight) - height[i].
java
CopyEdit
public class TrappingRainWater {
public static void main(String[] args) {
int[] height = {0,1,0,2,1,0,1,3,2,1,2,1};
int n = height.length;
int[] left = new int[n];
int[] right = new int[n];
left[0] = height[0];
for (int i = 1; i < n; i++) left[i] = Math.max(left[i - 1], height[i]);
right[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; i--) right[i] = Math.max(right[i + 1], height[i]);
int water = 0;
for (int i = 0; i < n; i++) water += Math.min(left[i], right[i]) - height[i];
System.out.println(water);
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: [0,1,0,2,1,0,1,3,2,1,2,1] → Output: 6

18. Maximum XOR of Two Numbers in Array


Algorithm:
1. Use Trie or greedy bitwise method.
java
CopyEdit
import java.util.*;

public class MaxXOR {


public static void main(String[] args) {
int[] nums = {3, 10, 5, 25, 2, 8};
int max = 0, mask = 0;
for (int i = 31; i >= 0; i--) {
mask |= (1 << i);
Set<Integer> set = new HashSet<>();
for (int num : nums) set.add(num & mask);
int temp = max | (1 << i);
for (int prefix : set) {
if (set.contains(prefix ^ temp)) {
max = temp;
break;
}
}
}
System.out.println(max);
}
}
Time Complexity: O(n * 32)
Space Complexity: O(n)
Example:
Input: [3,10,5,25,2,8] → Output: 28
19. Maximum Product Subarray
Algorithm:
1. Track max and min at each index.
2. Update global max.
java
CopyEdit
public class MaxProductSubarray {
public static void main(String[] args) {
int[] nums = {2, 3, -2, 4};
int maxProd = nums[0], minProd = nums[0], result = nums[0];
for (int i = 1; i < nums.length; i++) {
int temp = maxProd;
maxProd = Math.max(nums[i], Math.max(maxProd * nums[i], minProd *
nums[i]));
minProd = Math.min(nums[i], Math.min(temp * nums[i], minProd *
nums[i]));
result = Math.max(result, maxProd);
}
System.out.println(result);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [2,3,-2,4] → Output: 6
20. Count Numbers with Unique Digits
Algorithm:
1. Use permutations.
2. Sum valid counts from 1 to n digits.
java
CopyEdit
public class UniqueDigitCount {
public static void main(String[] args) {
int n = 2;
if (n == 0) {
System.out.println(1);
return;
}
int result = 10, unique = 9, available = 9;
for (int i = 2; i <= n && available > 0; i++) {
unique *= available--;
result += unique;
}
System.out.println(result);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: 2 → Output: 91
21. Count 1s in Binary Representation from 0 to n
Algorithm:
1. Use dynamic programming.
2. For each number, count 1s as res[i] = res[i >> 1] + (i & 1).
java
CopyEdit
import java.util.Arrays;

public class CountBits {


public static void main(String[] args) {
int n = 5;
int[] res = new int[n + 1];
for (int i = 1; i <= n; i++) {
res[i] = res[i >> 1] + (i & 1);
}
System.out.println(Arrays.toString(res));
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: 5 → Output: [0, 1, 1, 2, 1, 2]

22. Check if Number is Power of Two Using Bit Manipulation


Algorithm:
1. Power of two has only one set bit.
2. (n & (n - 1)) == 0
java
CopyEdit
public class PowerOfTwo {
public static void main(String[] args) {
int n = 16;
boolean isPower = n > 0 && (n & (n - 1)) == 0;
System.out.println(isPower);
}
}
Time Complexity: O(1)
Space Complexity: O(1)
Example:
Input: 16 → Output: true

23. Maximum XOR of Two Numbers in Array


(Same as Q18 — repeated, skipping code reuse per your condition.)
java
CopyEdit
import java.util.*;

public class MaxXORAgain {


public static void main(String[] args) {
int[] nums = {3, 10, 5, 25, 2, 8};
int max = 0, mask = 0;
for (int i = 31; i >= 0; i--) {
mask |= (1 << i);
Set<Integer> set = new HashSet<>();
for (int num : nums) set.add(num & mask);
int temp = max | (1 << i);
for (int prefix : set) {
if (set.contains(prefix ^ temp)) {
max = temp;
break;
}
}
}
System.out.println(max);
}
}
Time Complexity: O(n * 32)
Space Complexity: O(n)

24. Bit Manipulation and Its Advantages in Algorithm Design


Explanation: Bit manipulation involves operations directly on bits using
operators like AND (&), OR (|), XOR (^), NOT (~), left shift (<<), and right shift
(>>). These operations are extremely fast and efficient for performing low-level
arithmetic, checking even/odd, toggling bits, and optimizing space.
Advantages:
• Performance: Operations are done in constant time.
• Space Efficiency: Can pack multiple values into a single variable (e.g.,
bitmasking).
• Problem Solving: Useful in problems involving subsets, counting bits,
optimization with constraints on numbers.

25. Next Greater Element for Each Element in an Array


Algorithm:
1. Use stack to keep track of indices.
2. Traverse array from right to left.
java
CopyEdit
import java.util.*;

public class NextGreaterElement {


public static void main(String[] args) {
int[] nums = {4, 5, 2, 10, 8};
int[] res = new int[nums.length];
Stack<Integer> stack = new Stack<>();
for (int i = nums.length - 1; i >= 0; i--) {
while (!stack.isEmpty() && stack.peek() <= nums[i]) stack.pop();
res[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(nums[i]);
}
System.out.println(Arrays.toString(res));
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: [4,5,2,10,8] → Output: [5,10,10,-1,-1]
26. Remove n-th Node from End of Singly Linked List
Algorithm:
1. Use two-pointer approach.
2. Move first pointer n steps ahead.
3. Move both pointers until first reaches the end.
4. Remove the target node.
java
CopyEdit
public class RemoveNthFromEnd {
static class Node {
int val;
Node next;
Node(int val) { this.val = val; }
}

public static void main(String[] args) {


Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);

int n = 2;
head = removeNthFromEnd(head, n);
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
}

static Node removeNthFromEnd(Node head, int n) {


Node dummy = new Node(0);
dummy.next = head;
Node first = dummy, second = dummy;
for (int i = 0; i <= n; i++) first = first.next;
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: 1→2→3→4→5, n = 2 → Output: 1→2→3→5

27. Find Node Where Two Singly Linked Lists Intersect


Algorithm:
1. Compute lengths of both lists.
2. Align heads by skipping extra nodes.
3. Traverse both lists together to find intersection.
java
CopyEdit
public class IntersectionLinkedList {
static class Node {
int val;
Node next;
Node(int val) { this.val = val; }
}

public static void main(String[] args) {


Node a = new Node(1);
a.next = new Node(2);
Node b = new Node(3);
b.next = a.next;
a.next.next = new Node(4);
a.next.next.next = new Node(5);

Node intersection = findIntersection(a, b);


System.out.println(intersection != null ? intersection.val : "No
Intersection");
}

static Node findIntersection(Node a, Node b) {


Node p1 = a, p2 = b;
while (p1 != p2) {
p1 = (p1 == null) ? b : p1.next;
p2 = (p2 == null) ? a : p2.next;
}
return p1;
}
}
Time Complexity: O(n + m)
Space Complexity: O(1)
Example:
Input: 1→2→4→5 and 3→2→4→5 → Output: 2

28. Implement Two Stacks in One Array


Algorithm:
1. Use two indices, one from the left, one from the right.
2. Push to respective ends and adjust indices.
java
CopyEdit
public class TwoStacks {
static class TwoStack {
int[] arr;
int top1, top2, size;
TwoStack(int n) {
size = n;
arr = new int[n];
top1 = -1;
top2 = n;
}

void push1(int x) {
if (top1 < top2 - 1) arr[++top1] = x;
}

void push2(int x) {
if (top1 < top2 - 1) arr[--top2] = x;
}

int pop1() { return (top1 >= 0) ? arr[top1--] : -1; }


int pop2() { return (top2 < size) ? arr[top2++] : -1; }
}

public static void main(String[] args) {


TwoStack ts = new TwoStack(5);
ts.push1(10);
ts.push2(20);
ts.push1(30);
System.out.println(ts.pop1());
System.out.println(ts.pop2());
}
}
Time Complexity: O(1)
Space Complexity: O(n)
Example:
Input: push1(10), push2(20), push1(30), pop1(), pop2() → Output: 30 20

29. Check if Integer is Palindrome Without String Conversion


Algorithm:
1. Reverse half of the number.
2. Compare reversed half with original.
java
CopyEdit
public class PalindromeNumber {
public static void main(String[] args) {
int x = 121;
if (x < 0 || (x % 10 == 0 && x != 0)) {
System.out.println(false);
return;
}
int rev = 0;
while (x > rev) {
rev = rev * 10 + x % 10;
x /= 10;
}
System.out.println(x == rev || x == rev / 10);
}
}
Time Complexity: O(log n)
Space Complexity: O(1)
Example:
Input: 121 → Output: true

30. Concept of Linked Lists and Applications in Algorithm Design


Explanation: A linked list is a dynamic data structure where elements (nodes)
are linked using pointers.
Types:
• Singly Linked List: Each node has a value and a pointer to the next node.
• Doubly Linked List: Each node has pointers to both previous and next
nodes.
• Circular Linked List: The last node points back to the first node.
Applications:
• Dynamic Memory Allocation: No need for a fixed size like arrays.
• Efficient Insertions/Deletions: O(1) complexity at head or tail.
• Implementing Stacks & Queues: Used in real-time data structures.
• Graph Representation: Adjacency list representation.
• Hash Tables: Used for separate chaining in collision handling.
31. Maximum in Every Sliding Window of Size K Using Deque
Algorithm:
1. Use deque to store indices.
2. Maintain decreasing order in deque.
java
CopyEdit
import java.util.*;

public class SlidingWindowMax {


public static void main(String[] args) {
int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
int k = 3;
int n = nums.length;
int[] res = new int[n - k + 1];
Deque<Integer> dq = new ArrayDeque<>();

for (int i = 0; i < n; 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()];
}

System.out.println(Arrays.toString(res));
}
}
Time Complexity: O(n)
Space Complexity: O(k)
Example:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 → Output: [3,3,5,5,6,7]

32. Largest Rectangle in Histogram


Algorithm:
1. Use stack to maintain bars.
2. Calculate area when current bar is smaller.
java
CopyEdit
import java.util.*;

public class LargestRectangle {


public static void main(String[] args) {
int[] heights = {2,1,5,6,2,3};
Stack<Integer> stack = new Stack<>();
int maxArea = 0;
int n = heights.length;
for (int i = 0; i <= n; i++) {
int h = (i == n) ? 0 : heights[i];
while (!stack.isEmpty() && h < heights[stack.peek()]) {
int height = heights[stack.pop()];
int width = stack.isEmpty() ? i : i - stack.peek() - 1;
maxArea = Math.max(maxArea, height * width);
}
stack.push(i);
}
System.out.println(maxArea);
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: [2,1,5,6,2,3] → Output: 10

33. Sliding Window Technique and Its Applications in Array Problems


Explanation: The sliding window is a method for optimizing brute-force
algorithms in array or string problems.
Concept: Use two pointers to create a window which moves through the data
to track sums, counts, or other properties.
Common Applications:
• Maximum/minimum in a subarray.
• Longest substring with unique characters.
• Subarrays with sum equal to K.
• Fixed-size window operations.
Benefits:
• Reduces time complexity from O(n²) to O(n).
• Requires minimal extra space.

34. Subarray Sum Equals K Using Hashing


Algorithm:
1. Use HashMap to store cumulative sums.
2. Count matching previous prefix sums.
java
CopyEdit
import java.util.*;

public class SubarraySumEqualsK {


public static void main(String[] args) {
int[] nums = {1, 1, 1};
int k = 2;
Map<Integer, Integer> map = new HashMap<>();
map.put(0, 1);
int sum = 0, count = 0;
for (int num : nums) {
sum += num;
count += map.getOrDefault(sum - k, 0);
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
System.out.println(count);
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: nums = [1,1,1], k = 2 → Output: 2
35. K Most Frequent Elements Using Priority Queue
Algorithm:
1. Count frequencies using HashMap.
2. Use Min-Heap of size k to track top elements.
java
CopyEdit
import java.util.*;

public class TopKFrequent {


public static void main(String[] args) {
int[] nums = {1,1,1,2,2,3};
int k = 2;
Map<Integer, Integer> freq = new HashMap<>();
for (int num : nums) freq.put(num, freq.getOrDefault(num, 0) + 1);
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> freq.get(a) -
freq.get(b));
for (int key : freq.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();
System.out.println(Arrays.toString(res));
}
}
Time Complexity: O(n log k)
Space Complexity: O(n)
Example:
Input: [1,1,1,2,2,3], k=2 → Output: [1,2]
36. Generate All Subsets of a Given Array
Algorithm:
1. Use backtracking to explore all possibilities.
2. Add current subset to result.
java
CopyEdit
import java.util.*;

public class Subsets {


public static void main(String[] args) {
int[] nums = {1, 2, 3};
List<List<Integer>> res = new ArrayList<>();
backtrack(res, new ArrayList<>(), nums, 0);
System.out.println(res);
}

static void backtrack(List<List<Integer>> res, List<Integer> temp, int[] nums,


int start) {
res.add(new ArrayList<>(temp));
for (int i = start; i < nums.length; i++) {
temp.add(nums[i]);
backtrack(res, temp, nums, i + 1);
temp.remove(temp.size() - 1);
}
}
}
Time Complexity: O(2ⁿ)
Space Complexity: O(n)
Example:
Input: [1, 2, 3] → Output: [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]]

37. Find All Unique Combinations That Sum to Target


Algorithm:
1. Use backtracking.
2. Include current number multiple times if needed.
java
CopyEdit
import java.util.*;

public class CombinationSum {


public static void main(String[] args) {
int[] candidates = {2,3,6,7};
int target = 7;
List<List<Integer>> res = new ArrayList<>();
backtrack(res, new ArrayList<>(), candidates, target, 0);
System.out.println(res);
}

static void backtrack(List<List<Integer>> res, List<Integer> temp, int[] nums,


int remain, int start) {
if (remain == 0) {
res.add(new ArrayList<>(temp));
return;
}
for (int i = start; i < nums.length; i++) {
if (nums[i] <= remain) {
temp.add(nums[i]);
backtrack(res, temp, nums, remain - nums[i], i);
temp.remove(temp.size() - 1);
}
}
}
}
Time Complexity: O(2ⁿ)
Space Complexity: O(n)
Example:
Input: [2,3,6,7], target = 7 → Output: [[2,2,3],[7]]

38. Generate All Permutations of a Given Array


Algorithm:
1. Use backtracking.
2. Swap elements to generate permutations.
java
CopyEdit
import java.util.*;

public class Permutations {


public static void main(String[] args) {
int[] nums = {1, 2, 3};
List<List<Integer>> res = new ArrayList<>();
backtrack(res, nums, 0);
System.out.println(res);
}

static void backtrack(List<List<Integer>> res, int[] nums, int start) {


if (start == nums.length) {
List<Integer> list = new ArrayList<>();
for (int num : nums) list.add(num);
res.add(list);
return;
}
for (int i = start; i < nums.length; i++) {
swap(nums, start, i);
backtrack(res, nums, start + 1);
swap(nums, start, i);
}
}

static void swap(int[] nums, int i, int j) {


int t = nums[i]; nums[i] = nums[j]; nums[j] = t;
}
}
Time Complexity: O(n!)
Space Complexity: O(n)
Example:
Input: [1,2,3] → Output: All permutations

39. Difference Between Subsets and Permutations


Explanation:
Subsets:
• Contain 0 to n elements in original order.
• Order doesn't matter.
• Total: 2ⁿ subsets.
Example: {1,2} → [[], [1], [2], [1,2]]
Permutations:
• Contain all elements with different orderings.
• Order matters.
• Total: n! permutations.
Example: {1,2} → [[1,2], [2,1]]
Key Differences:
• Count: Subsets → 2ⁿ, Permutations → n!
• Order Sensitivity: Not in subsets, required in permutations.

40. Find Element with Maximum Frequency in an Array


Algorithm:
1. Count frequency using HashMap.
2. Track max frequency element.
java
CopyEdit
import java.util.*;

public class MaxFrequencyElement {


public static void main(String[] args) {
int[] nums = {1, 3, 2, 1, 4, 1};
Map<Integer, Integer> map = new HashMap<>();
int maxFreq = 0, result = nums[0];

for (int num : nums) {


int freq = map.getOrDefault(num, 0) + 1;
map.put(num, freq);
if (freq > maxFreq) {
maxFreq = freq;
result = num;
}
}
System.out.println(result);
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: [1,3,2,1,4,1] → Output: 1
41. Maximum Subarray Sum Using Kadane’s Algorithm
java
CopyEdit
public class MaxSubarrayKadane {
public static void main(String[] args) {
int[] nums = {-2,1,-3,4,-1,2,1,-5,4};
int maxSum = nums[0], currSum = nums[0];
for (int i = 1; i < nums.length; i++) {
currSum = Math.max(nums[i], currSum + nums[i]);
maxSum = Math.max(maxSum, currSum);
}
System.out.println(maxSum);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4] → Output: 6

42. Concept of Dynamic Programming and Its Use in Solving the Maximum
Subarray Problem
Explanation:
Dynamic Programming (DP):
• A method to solve problems by breaking them into overlapping
subproblems and storing the results.
Use in Maximum Subarray:
• Use a DP array dp[i] = max subarray sum ending at index i.
• Recurrence: dp[i] = max(arr[i], dp[i-1] + arr[i])
Optimized Version (Kadane’s Algorithm):
• Uses only variables instead of arrays.
• Tracks current and global maximum sum.
Advantages:
• Reduces time from O(n²) to O(n)
• Efficient space with constant usage

43. Top K Frequent Elements in an Array


java
CopyEdit
import java.util.*;

public class TopKFrequentElements {


public static void main(String[] args) {
int[] nums = {1,1,1,2,2,3};
int k = 2;
Map<Integer, Integer> count = new HashMap<>();
for (int num : nums) count.put(num, count.getOrDefault(num, 0) + 1);

PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> count.get(a) -


count.get(b));
for (int num : count.keySet()) {
pq.offer(num);
if (pq.size() > k) pq.poll();
}

int[] res = new int[k];


for (int i = k - 1; i >= 0; i--) res[i] = pq.poll();
System.out.println(Arrays.toString(res));
}
}
Time Complexity: O(n log k)
Space Complexity: O(n)
Example:
Input: [1,1,1,2,2,3], k=2 → Output: [1,2]

44. Two Numbers Add to Target Using Hashing


java
CopyEdit
import java.util.*;

public class TwoSumHashing {


public static void main(String[] args) {
int[] nums = {2,7,11,15};
int target = 9;
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int comp = target - nums[i];
if (map.containsKey(comp)) {
System.out.println(Arrays.toString(new int[]{map.get(comp), i}));
return;
}
map.put(nums[i], i);
}
}
}
Time Complexity: O(n)
Space Complexity: O(n)
Example:
Input: [2,7,11,15], target=9 → Output: [0,1]

45. Concept of Priority Queues and Their Applications in Algorithm Design


Explanation:
Priority Queue:
• A special type of queue where each element has a priority.
• Elements are served based on priority, not just insertion order.
Implementation:
• Java uses PriorityQueue which is a Min-Heap by default.
Applications:
• Dijkstra’s shortest path algorithm
• Top K elements (frequent/largest/smallest)
• Huffman encoding
• Real-time scheduling systems
Advantages:
• Efficient insert and delete (O(log n))
46. Longest Palindromic Substring in a Given String
java
CopyEdit
public class LongestPalindrome {
public static void main(String[] args) {
String s = "babad";
int start = 0, maxLen = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = expand(s, i, i);
int len2 = expand(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > maxLen) {
start = i - (len - 1) / 2;
maxLen = len;
}
}
System.out.println(s.substring(start, start + maxLen));
}

static int expand(String s, int left, int right) {


while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right))
{
left--; right++;
}
return right - left - 1;
}
}
Time Complexity: O(n²)
Space Complexity: O(1)
Example:
Input: "babad" → Output: "bab" or "aba"

47. Concept of Histogram Problems and Their Applications


Explanation:
Histogram Problems:
• Typically involve arrays of heights representing bars.
Key Applications:
• Largest rectangle in histogram
• Trapping rain water
• Skyline problem
Use in Algorithms:
• Monotonic stack for efficient area/space calculations
• Sliding window or two pointers
Real-world Usage:
• Data visualization optimization
• Memory management
• Image processing (histogram equalization)

48. Next Permutation of a Given Array


java
CopyEdit
import java.util.*;

public class NextPermutation {


public static void main(String[] args) {
int[] nums = {1,2,3};
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) i--;

if (i >= 0) {
int j = nums.length - 1;
while (nums[j] <= nums[i]) j--;
swap(nums, i, j);
}
reverse(nums, i + 1);
System.out.println(Arrays.toString(nums));
}

static void swap(int[] nums, int i, int j) {


int t = nums[i]; nums[i] = nums[j]; nums[j] = t;
}

static void reverse(int[] nums, int start) {


int i = start, j = nums.length - 1;
while (i < j) swap(nums, i++, j--);
}
}
Time Complexity: O(n)
Space Complexity: O(1)
Example:
Input: [1,2,3] → Output: [1,3,2]

49. Intersection of Two Linked Lists


java
CopyEdit
public class LinkedListIntersection {
static class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}

public static void main(String[] args) {


// Example nodes creation skipped; assume intersectNode is shared
}

static ListNode getIntersectionNode(ListNode a, ListNode b) {


ListNode p1 = a, p2 = b;
while (p1 != p2) {
p1 = (p1 == null) ? b : p1.next;
p2 = (p2 == null) ? a : p2.next;
}
return p1;
}
}
Time Complexity: O(n + m)
Space Complexity: O(1)

50. Concept of Equilibrium Index and Its Applications


Explanation:
Equilibrium Index:
• An index i such that the sum of elements before i is equal to the sum
after i.
Applications:
• Load balancing in distributed systems
• Financial models (equal inflow/outflow)
• Sensor-based data where equilibrium is needed
Approach:
• Total sum, then subtract left sums as we traverse to check equilibrium

You might also like