├── FirstBada.java ├── OBS.java ├── greedycont ├── BinarySearchBuiltInDemo.java ├── IndianCoinChange.java └── Busy.java ├── StringBasedDp ├── MaximumLengthOfRepeatedSubarray.java ├── LPSubstring.java ├── MaxDotProduct.java ├── UncrossedLines.java ├── MaxDelToMakeSorted.java ├── MinDeletionsAndInsertions.java ├── Lis.java ├── LCSubsequence.java ├── EditDistance.java └── WiggleSubsequence.java ├── FibonacciBasedDp ├── ClimbingStairs.java ├── HouseRobber.java ├── SumFactors.java └── MinCostClimbingStairs.java ├── HouseRobber2 ├── Naive.java └── TopDown.java ├── HR.java ├── MoreDp ├── AllPAlindromicSubsequences.java ├── PredictTheWinner.java └── EarnAndDelete.java ├── FormMinNumber.java ├── Maximum Profit In Job Scheduling ├── Naive.java └── NaiveCached.java ├── HouseRobber3 ├── Naive.java ├── BottomUp.java └── NaiveCached.java ├── Number Of Islands ├── DFSSol.java └── BFSSol.java ├── Max Area Of Island ├── DFS.java └── BFS.java ├── AggCow.java ├── GraphProblems ├── Floodfill.java └── NumberOfClosedIslands.java ├── NQueen2 ├── BookAlloc.java ├── LIS.java ├── WallsAndGatesApproaches ├── DFS.java └── MutliEndBFS.java ├── UncrossedLines.java ├── Unique Binary Search Trees ii ├── DAndC.java └── Cached.java ├── RainWaterTrapping.java ├── Longest Increasing Path In Matix ├── Naive.java └── NaiveCached.java ├── README.md ├── KnightGoogleInterviewDp ├── KnightProbability.java └── KnightDialer.java ├── class25 ├── AlienDictionary.java ├── CourseSchedule.java └── Graph.java └── Graph.java /FirstBada.java: -------------------------------------------------------------------------------- 1 | /* The isBadVersion API is defined in the parent class VersionControl. 2 | boolean isBadVersion(int version); */ 3 | 4 | public class Solution extends VersionControl { 5 | public int firstBadVersion(int n) { 6 | int l = 0, r = n; 7 | 8 | while(r > l + 1) { 9 | int mid = l + (r - l) / 2; 10 | 11 | if(isBadVersion(mid)) { 12 | r = mid; 13 | } else { 14 | l = mid; 15 | } 16 | } 17 | 18 | return r; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /OBS.java: -------------------------------------------------------------------------------- 1 | 2 | import java.util.*; 3 | 4 | public class Main { 5 | 6 | public static long sol(int n, long[] dp) { 7 | 8 | if(n == 1) { 9 | return 2; 10 | } 11 | 12 | if(n == 2) { 13 | return 3; 14 | } 15 | 16 | if(dp[n] != -1) { 17 | return dp[n]; 18 | } 19 | long c1 = sol(n - 1, dp); 20 | long c2 = sol(n - 2, dp); 21 | 22 | return dp[n] = c1 + c2; 23 | } 24 | public static void main(String[] args) { 25 | // TODO Auto-generated method stub 26 | Scanner sc = new Scanner(System.in); 27 | int t = sc.nextInt(); 28 | 29 | while(t-- != 0) { 30 | 31 | int n = sc.nextInt(); 32 | long[] dp = new long[n + 1]; 33 | Arrays.fill(dp, -1); 34 | System.out.println(sol(n, dp)); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /greedycont/BinarySearchBuiltInDemo.java: -------------------------------------------------------------------------------- 1 | package com.chitkara.greedycont; 2 | 3 | import java.util.Arrays; 4 | 5 | public class BinarySearchBuiltInDemo { 6 | 7 | public static void main(String[] args) { 8 | // TODO Auto-generated method stub 9 | 10 | int[] arr = {1, 2, 5, 10, 20, 50}; 11 | 12 | int search = 15; 13 | 14 | int ind = Arrays.binarySearch(arr, search); 15 | System.out.println(ind); 16 | ind = Math.abs(ind) - 1; 17 | int searchSeSmaller = arr[ind]; 18 | System.out.println(searchSeSmaller); 19 | 20 | /* 21 | If element not present 22 | ind = -(search ki expected position) - 1 23 | 24 | immediate small element than searched el 25 | abs(ind) - 2 26 | 27 | immediate larger element 28 | abs(ind) - 1 29 | */ 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /StringBasedDp/MaximumLengthOfRepeatedSubarray.java: -------------------------------------------------------------------------------- 1 | //Time Complexity - O(2 ^ n) 2 | //Space Complexity - O(n + m) 3 | class Solution { 4 | public int findLength(int[] A, int[] B) { 5 | return findLength(A, B, A.length, B.length); 6 | } 7 | 8 | private int findLength(int[] A, int[] B, int n, int m) { 9 | 10 | 11 | if(n == 0 || m == 0) { 12 | return 0; 13 | } 14 | 15 | int c1 = 0, c2 = 0, c3 = 0; 16 | if(A[n - 1] == B[m - 1]) { 17 | c1 = findLength(A, B, n - 1, m - 1) + 1; 18 | } else { 19 | c2 = findLength(A, B, n - 1, m); 20 | c3 = findLength(A, B, n, m - 1); 21 | } 22 | 23 | return Math.max(c1, Math.max(c2, c3)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /FibonacciBasedDp/ClimbingStairs.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | //Bottom Up 4 | Time Complexity - O(n) 5 | Space Complexity - O(n) 6 | class Solution { 7 | public int climbStairs(int n) { 8 | int[] dp = new int[n + 1]; 9 | Arrays.fill(dp, -1); 10 | 11 | dp[0] = 1; 12 | dp[1] = 1; 13 | 14 | for(int i = 2; i <= n; i++) { 15 | dp[i] = dp[i - 1] + dp[i - 2]; 16 | } 17 | 18 | return dp[n]; 19 | } 20 | } 21 | 22 | //Space Optimized 23 | Time Complexity - O(n) 24 | Space Complexity - O(1) 25 | class Solution { 26 | public int climbStairs(int n) { 27 | int a = 1, b = 1; 28 | 29 | for(int i = 2; i <= n; i++) { 30 | int temp = a + b; 31 | a = b; 32 | b = temp; 33 | } 34 | 35 | return b; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /HouseRobber2/Naive.java: -------------------------------------------------------------------------------- 1 | class Naive { 2 | public int rob(int[] nums) { 3 | if(nums.length == 0) { 4 | return 0; 5 | } 6 | 7 | if(nums.length == 1) { 8 | return nums[0]; 9 | } 10 | return rob(nums, 0, false); 11 | } 12 | 13 | public int rob(int[] nums, int i, boolean isTaken) { 14 | 15 | if(i >= nums.length) { 16 | return 0; 17 | } 18 | int a = 0; 19 | if(i == 0) { 20 | a = nums[i] + rob(nums, i + 2, true); 21 | } else if(i == nums.length - 1) { 22 | if(!isTaken) 23 | a = nums[i] + rob(nums, i + 2, isTaken); 24 | } else { 25 | a = nums[i] + rob(nums, i + 2, isTaken); 26 | } 27 | 28 | int b = rob(nums, i + 1, isTaken); 29 | return Math.max(a, b); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /HR.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int deleteAndEarn(int[] nums) { 3 | int maxNum = Integer.MIN_VALUE; 4 | 5 | for(int el : nums) { 6 | maxNum = Math.max(maxNum, el); 7 | } 8 | 9 | int[] ha = new int[maxNum + 1]; 10 | for(int el : nums) { 11 | ha[el] += el; 12 | } 13 | 14 | int[] dp = new int[ha.length + 1]; 15 | Arrays.fill(dp, -1); 16 | return rob(ha, 0, ha.length, dp); 17 | } 18 | 19 | public int rob(int[] nums, int curr, int n, int[] dp) { 20 | 21 | if(curr >= n) { 22 | return 0; 23 | } 24 | 25 | if(dp[curr] != -1) { 26 | return dp[curr]; 27 | } 28 | 29 | int c1 = rob(nums, curr + 1, n, dp); 30 | int c2 = nums[curr] + rob(nums, curr + 2, n, dp); 31 | 32 | return dp[curr] = Math.max(c1, c2); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /StringBasedDp/LPSubstring.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int longestPalindromeSubseq(String s) { 3 | int[][] dp = new int[s.length()][s.length()]; 4 | for(int[] row : dp) { 5 | Arrays.fill(row, -1); 6 | } 7 | 8 | return lps(s, 0, s.length() - 1, dp); 9 | } 10 | 11 | private int lps(String s, int si, int ei, int[][] dp) { 12 | 13 | if(si > ei) { 14 | return 0; 15 | } 16 | 17 | if(si == ei) { 18 | return 1; 19 | } 20 | 21 | if(dp[si][ei] != -1) { 22 | return dp[si][ei]; 23 | } 24 | 25 | if(s.charAt(si) == s.charAt(ei)) { 26 | return 2 + lps(s, si + 1, ei - 1, dp); 27 | } 28 | 29 | int c1 = lps(s, si + 1, ei, dp); 30 | int c2 = lps(s, si, ei - 1, dp); 31 | 32 | return dp[si][ei] = Math.max(c1, c2); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MoreDp/AllPAlindromicSubsequences.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | public class Main { 3 | public static void main(String args[]) { 4 | int[][] dp = new int[4][4]; 5 | for(int[] row : dp) { 6 | Arrays.fill(row, -1); 7 | } 8 | 9 | System.out.println(numPalSubs("aaaa", 0, 3, dp)); 10 | } 11 | 12 | public static int numPalSubs(String s, int si, int ei, int[][] dp) { 13 | if(si > ei) { 14 | return 0; 15 | } 16 | 17 | if(si == ei) { 18 | return 1; 19 | } 20 | 21 | if(dp[si][ei] != -1) { 22 | return dp[si][ei]; 23 | } 24 | 25 | if(s.charAt(si) != s.charAt(ei)) { 26 | return dp[si][ei] = numPalSubs(s, si + 1, ei, dp) + numPalSubs(s, si, ei - 1, dp) - numPalSubs(s, si + 1, ei - 1, dp); 27 | } else { 28 | return dp[si][ei] = numPalSubs(s, si + 1, ei, dp) + numPalSubs(s, si, ei - 1, dp) + 1; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /FormMinNumber.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | import java.util.Stack; 3 | 4 | public class Tester { 5 | 6 | public static void solution(String num) { 7 | 8 | StringBuilder sb = new StringBuilder(); 9 | for (char c : num.toCharArray()) { 10 | if (Character.getNumericValue(c) % 2 == 0) { 11 | sb.append('I'); 12 | } else { 13 | sb.append('D'); 14 | } 15 | } 16 | 17 | String conv = sb.toString(); 18 | 19 | Stack st = new Stack<>(); 20 | 21 | for (int i = 0; i <= conv.length(); i++) { 22 | st.push(i + 1); 23 | 24 | if (i == conv.length() || conv.charAt(i) == 'I') { 25 | while (!st.isEmpty()) { 26 | System.out.print(st.pop()); 27 | } 28 | } 29 | } 30 | System.out.println(); 31 | } 32 | 33 | public static void main(String[] args) { 34 | // TODO Auto-generated method stub 35 | Scanner sc = new Scanner(System.in); 36 | int t = sc.nextInt(); 37 | while (t-- > 0) { 38 | String str = sc.next(); 39 | solution(str); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Maximum Profit In Job Scheduling/Naive.java: -------------------------------------------------------------------------------- 1 | class Naive { 2 | public int jobScheduling(int[] startTime, int[] endTime, int[] profit) { 3 | int[][] jobs = new int[startTime.length][3]; 4 | 5 | for(int i = 0; i < startTime.length; i++) { 6 | jobs[i] = new int[]{startTime[i], endTime[i], profit[i]}; 7 | } 8 | 9 | Arrays.sort(jobs, (a, b) -> (a[0] - b[0])); 10 | return maxProfit(jobs, 0, startTime.length); 11 | 12 | } 13 | 14 | public int maxProfit(int[][] jobs, int curr, int n) { 15 | 16 | if(curr == n) { 17 | return 0; 18 | } 19 | int c1 = maxProfit(jobs, curr + 1, n); 20 | int c2 = jobs[curr][2]; 21 | 22 | for(int i = curr + 1; i < n; i++) { 23 | if(jobs[curr][1] <= jobs[i][0]) { 24 | c2 += maxProfit(jobs, i, n); 25 | break; 26 | } 27 | } 28 | 29 | return Math.max(c1, c2); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /HouseRobber3/Naive.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class Naive { 17 | public int rob(TreeNode root) { 18 | return Math.max(rob(root, false), rob(root, true)); 19 | } 20 | 21 | private int rob(TreeNode root, boolean canRob) { 22 | 23 | if(root == null) { 24 | return 0; 25 | } 26 | 27 | if(canRob) { 28 | return root.val + rob(root.left, false) + rob(root.right, false); 29 | } else { 30 | return Math.max(rob(root.left, false), rob(root.left, true)) + Math.max(rob(root.right, false), rob(root.right, true)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /StringBasedDp/MaxDotProduct.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxDotProduct(int[] nums1, int[] nums2) { 3 | int n = nums1.length, m = nums2.length; 4 | int[][] cache = new int[n + 1][m + 1]; 5 | for(int[] row : cache) { 6 | Arrays.fill(row, -1); 7 | } 8 | return maxDotProduct(nums1, nums2, n, m, cache); 9 | } 10 | 11 | private int maxDotProduct(int[] nums1, int[] nums2, int n, int m, int[][] cache) { 12 | 13 | if(n == 0 || m == 0) { 14 | return -10000000; 15 | } 16 | 17 | if(cache[n][m] != -1) { 18 | return cache[n][m]; 19 | } 20 | 21 | int c1 = nums1[n - 1] * nums2[m - 1] + maxDotProduct(nums1, nums2, n - 1, m - 1, cache); 22 | int c2 = maxDotProduct(nums1, nums2, n - 1, m, cache); 23 | int c3= maxDotProduct(nums1, nums2, n, m - 1, cache); 24 | 25 | return cache[n][m] = Math.max(Math.max(nums1[n - 1] * nums2[m - 1], c1), Math.max(c2, c3)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /StringBasedDp/UncrossedLines.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxUncrossedLines(int[] A, int[] B) { 3 | int n = A.length, m = B.length; 4 | int[][] dp = new int[n + 1][m + 1]; 5 | for(int[] row : dp) { 6 | Arrays.fill(row, -1); 7 | } 8 | 9 | dp[0][0] = 0; 10 | 11 | for(int i = 0; i <= n; i++) { 12 | dp[i][0] = 0; 13 | } 14 | 15 | for(int j = 0; j <= m; j++) { 16 | dp[0][j] = 0; 17 | } 18 | 19 | for(int i = 1; i <= n; i++) { 20 | for(int j = 1; j <= m; j++) { 21 | if(A[i - 1] == B[j - 1]) { 22 | dp[i][j] = 1 + dp[i - 1][j - 1]; 23 | } else { 24 | int c1 = dp[i - 1][j]; 25 | int c2 = dp[i][j - 1]; 26 | 27 | dp[i][j] = Math.max(c1, c2); 28 | } 29 | } 30 | } 31 | 32 | return dp[n][m]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /greedycont/IndianCoinChange.java: -------------------------------------------------------------------------------- 1 | package com.chitkara.greedycont; 2 | 3 | import java.util.Arrays; 4 | 5 | public class IndianCoinChange { 6 | 7 | // amount = 39 8 | private static int minCoinsCount(int[] denominations, int amount) { 9 | // TODO Auto-generated method stub 10 | int count = 0; 11 | 12 | while (amount > 0) { 13 | int idx = Arrays.binarySearch(denominations, amount); // 39, idx -> -6 14 | System.out.println(idx); 15 | 16 | if (idx < 0) { // ki amount array mein ni mila 17 | // amount se choti value nikalo 18 | idx = Math.abs(idx) - 2; // idx -> 4 19 | } 20 | 21 | amount = amount - denominations[idx]; // amounnt = 39 - 20 = 19 22 | count++; // coins = 1 23 | } 24 | return count; 25 | } 26 | 27 | public static void main(String[] args) { 28 | // TODO Auto-generated method stub 29 | int[] denominations = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 2000 }; 30 | 31 | // Arrays.sort(denominations); 32 | System.out.println("min coins hai " + minCoinsCount(denominations, 50)); 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Number Of Islands/DFSSol.java: -------------------------------------------------------------------------------- 1 | class DFSSol { 2 | public int numIslands(char[][] grid) { 3 | int n = grid.length; 4 | 5 | 6 | if(n == 0 || grid[0].length == 0) { 7 | return 0; 8 | } 9 | 10 | int m = grid[0].length; 11 | int count = 0; 12 | for(int i = 0; i < n; i++) { 13 | for(int j = 0; j < m; j++) { 14 | if(grid[i][j] == '1') { 15 | count++; 16 | 17 | DFS(grid, i, j); 18 | } 19 | } 20 | } 21 | 22 | return count; 23 | } 24 | 25 | private void DFS(char[][] grid, int i, int j) { 26 | 27 | if(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == '0') { 28 | return; 29 | } 30 | 31 | grid[i][j] = '0'; 32 | DFS(grid, i + 1, j); 33 | DFS(grid, i - 1, j); 34 | DFS(grid, i, j - 1); 35 | DFS(grid, i, j + 1); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /HouseRobber3/BottomUp.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class BottomnUp { 17 | public int rob(TreeNode root) { 18 | int[] ans = robHelp(root); 19 | return Math.max(ans[0], ans[1]); 20 | } 21 | 22 | private int[] robHelp(TreeNode root) { 23 | 24 | if(root == null) { 25 | return new int[2]; 26 | } 27 | 28 | int[] left = robHelp(root.left); 29 | int[] right = robHelp(root.right); 30 | 31 | int[] ans = new int[2]; 32 | 33 | ans[0] = root.val + left[1] + right[1]; 34 | ans[1] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]); 35 | 36 | return ans; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Max Area Of Island/DFS.java: -------------------------------------------------------------------------------- 1 | class DFS { 2 | public int maxAreaOfIsland(int[][] grid) { 3 | int n = grid.length, m = grid[0].length; 4 | 5 | int maxArea = 0; 6 | for(int i = 0; i < n; i++) { 7 | for(int j = 0; j < m; j++) { 8 | if(grid[i][j] == 1) { 9 | int recAns = maxAreaOfIsland(grid, i, j, n, m); 10 | maxArea = Math.max(recAns, maxArea); 11 | } 12 | } 13 | } 14 | 15 | return maxArea; 16 | } 17 | 18 | private int maxAreaOfIsland(int[][] grid, int i, int j, int n, int m) { 19 | 20 | if(i < 0 || j < 0 || i >= n || j >= m || grid[i][j] == 0) { 21 | return 0; 22 | } 23 | 24 | grid[i][j] = 0; 25 | int a1 = maxAreaOfIsland(grid, i + 1, j, n, m); 26 | int a2 = maxAreaOfIsland(grid, i - 1, j, n, m); 27 | int a3 = maxAreaOfIsland(grid, i, j - 1, n, m); 28 | int a4 = maxAreaOfIsland(grid, i, j + 1, n, m); 29 | 30 | return 1 + a1 + a2 + a3 + a4; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /AggCow.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Main { 4 | 5 | private static boolean isPossible(int[] stalls, int dis, int c) { 6 | // TODO Auto-generated method stub 7 | int prev = stalls[0]; 8 | int numC = 1; 9 | 10 | for(int i = 1; i < stalls.length; i++) { 11 | 12 | if(c == numC) { 13 | return true; 14 | } 15 | int curr = stalls[i]; 16 | if(curr - prev >= dis) { 17 | numC++; 18 | prev = curr; 19 | } 20 | } 21 | 22 | return false; 23 | } 24 | 25 | public static void main(String[] args) { 26 | // TODO Auto-generated method stub 27 | 28 | Scanner s = new Scanner(System.in); 29 | int n = s.nextInt(); 30 | int c = s.nextInt(); 31 | 32 | int[] stalls = new int[n]; 33 | 34 | for(int i = 0; i < n; i++) { 35 | stalls[i] = s.nextInt(); 36 | } 37 | 38 | Arrays.sort(stalls); 39 | 40 | int l = 0, r = stalls[n - 1] - stalls[0]; 41 | 42 | while(r > l + 1) { 43 | 44 | int mid = (l + r) / 2; 45 | if(isPossible(stalls, mid, c)) { 46 | l = mid; 47 | } else { 48 | r = mid; 49 | } 50 | } 51 | 52 | System.out.println(l); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /FibonacciBasedDp/HouseRobber.java: -------------------------------------------------------------------------------- 1 | //Bottom Up 2 | Time Complexity - O(n) 3 | Space Complexity - O(n) 4 | class Solution { 5 | public int rob(int[] nums) { 6 | int n = nums.length; 7 | if(n == 0) { 8 | return 0; 9 | } 10 | int[] cache = new int[n + 1]; 11 | 12 | cache[0] = 0; 13 | cache[1] = nums[0]; 14 | 15 | for(int i = 2; i <= n; i++) { 16 | cache[i] = Math.max(cache[i - 2] + nums[i - 1], cache[i - 1]); 17 | } 18 | 19 | return cache[n]; 20 | } 21 | } 22 | 23 | //Space Optimised solution 24 | Time Complexity - O(n) 25 | Space Complexity - O(1) 26 | class Solution { 27 | public int rob(int[] nums) { 28 | int n = nums.length; 29 | if(n == 0) { 30 | return 0; 31 | } 32 | int[] cache = new int[n + 1]; 33 | 34 | int a = 0, b = nums[0]; 35 | 36 | for(int i = 2; i <= n; i++) { 37 | int temp = Math.max(nums[i - 1] + a, b); 38 | a = b; 39 | b = temp; 40 | } 41 | 42 | return b; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /GraphProblems/Floodfill.java: -------------------------------------------------------------------------------- 1 | class Floodfill { 2 | public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { 3 | 4 | int color = image[sr][sc ]; 5 | 6 | if(color == newColor) { 7 | return image; 8 | } 9 | 10 | int n = image.length; 11 | int m = image[0].length; 12 | 13 | int[] dx = {0, 0, 1, -1}; 14 | int[] dy = {1, -1, 0, 0}; 15 | 16 | Queue bfs = new LinkedList<>(); 17 | 18 | bfs.add(new int[]{sr, sc}); 19 | image[sr][sc] = newColor; 20 | 21 | while(!bfs.isEmpty()) { 22 | int[] pair = bfs.poll(); 23 | 24 | for(int k = 0; k < 4; k++) { 25 | int x = pair[0] + dx[k]; 26 | int y = pair[1] + dy[k]; 27 | 28 | if(x >= 0 && y >= 0 && x < n && y < m && image[x][y] == color) { 29 | image[x][y] = newColor; 30 | bfs.add(new int[]{x, y}); 31 | } 32 | } 33 | } 34 | 35 | return image; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /HouseRobber2/TopDown.java: -------------------------------------------------------------------------------- 1 | class TopDown { 2 | public int rob(int[] nums) { 3 | if(nums.length == 0) { 4 | return 0; 5 | } 6 | 7 | if(nums.length == 1) { 8 | return nums[0]; 9 | } 10 | 11 | int[][] dp = new int[2][nums.length + 1]; 12 | for(int[] row : dp) 13 | Arrays.fill(row, - 1); 14 | return rob(nums, 0, 0, dp); 15 | } 16 | 17 | public int rob(int[] nums, int i, int isTaken, int[][] dp) { 18 | 19 | if(i >= nums.length) { 20 | return 0; 21 | } 22 | 23 | if(dp[isTaken][i] != -1) { 24 | return dp[isTaken][i]; 25 | } 26 | int a = 0; 27 | if(i == 0) { 28 | a = nums[i] + rob(nums, i + 2, 1, dp); 29 | } else if(i == nums.length - 1) { 30 | if(isTaken == 0) 31 | a = nums[i] + rob(nums, i + 2, isTaken, dp); 32 | } else { 33 | a = nums[i] + rob(nums, i + 2, isTaken, dp); 34 | } 35 | 36 | int b = rob(nums, i + 1, isTaken, dp); 37 | return dp[isTaken][i] = Math.max(a, b); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /NQueen2: -------------------------------------------------------------------------------- 1 | class Solution { 2 | 3 | static int count; 4 | public int totalNQueens(int n) { 5 | count = 0; 6 | place(new int[n][n], 0, n); 7 | return count; 8 | } 9 | 10 | private static boolean canPlace(int[][] arr, int cr, int cc, int n) { 11 | // TODO Auto-generated method stub 12 | 13 | for (int row = 0; row < cr; row++) { 14 | if (arr[row][cc] == 1) { 15 | return false; 16 | } 17 | } 18 | 19 | int row = cr; 20 | int col = cc; 21 | 22 | while (row >= 0 && col >= 0) { 23 | if (arr[row][col] == 1) { 24 | return false; 25 | } 26 | row--; 27 | col--; 28 | } 29 | 30 | row = cr; 31 | col = cc; 32 | 33 | while (row >= 0 && col < n) { 34 | if (arr[row][col] == 1) { 35 | return false; 36 | } 37 | row--; 38 | col++; 39 | } 40 | 41 | return true; 42 | } 43 | 44 | public static void place(int[][] arr, int cr, int n) { 45 | 46 | 47 | if (cr == n) { 48 | count++; 49 | 50 | return; 51 | } 52 | 53 | for (int cc = 0; cc < n; cc++) { 54 | if (canPlace(arr, cr, cc, n)) { 55 | arr[cr][cc] = 1; 56 | place(arr, cr + 1, n); 57 | arr[cr][cc] = 0; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /BookAlloc.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class Main { 4 | 5 | private static boolean isValid(int[] pages, int mid, int st) { 6 | // TODO Auto-generated method stub 7 | int num = 1; 8 | int numP = 0; 9 | 10 | int i = 0; 11 | while(i < pages.length) { 12 | 13 | if(numP + pages[i] <= mid) { 14 | numP += pages[i]; 15 | i++; 16 | } else { 17 | numP = 0; 18 | num++; 19 | } 20 | 21 | if(num > st) { 22 | return false; 23 | } 24 | } 25 | 26 | return true; 27 | } 28 | public static void main(String[] args) { 29 | // TODO Auto-generated method stub 30 | Scanner s = new Scanner(System.in); 31 | 32 | int t = s.nextInt(); 33 | 34 | while (t-- != 0) { 35 | int n = s.nextInt(); 36 | int st = s.nextInt(); 37 | 38 | int[] pages = new int[n]; 39 | int sum = 0; 40 | for (int i = 0; i < n; i++) { 41 | pages[i] = s.nextInt(); 42 | sum += pages[i]; 43 | } 44 | 45 | int l = 0, r = sum; 46 | 47 | while(r > l + 1) { 48 | int mid = l + (r - l) / 2; 49 | 50 | if(isValid(pages, mid, st)) { 51 | r = mid; 52 | } else { 53 | l = mid; 54 | } 55 | } 56 | 57 | System.out.println(r); 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /Maximum Profit In Job Scheduling/NaiveCached.java: -------------------------------------------------------------------------------- 1 | class NaiveCached { 2 | public int jobScheduling(int[] startTime, int[] endTime, int[] profit) { 3 | int[][] jobs = new int[startTime.length][3]; 4 | 5 | for(int i = 0; i < startTime.length; i++) { 6 | jobs[i] = new int[]{startTime[i], endTime[i], profit[i]}; 7 | } 8 | 9 | Arrays.sort(jobs, (a, b) -> (a[0] - b[0])); 10 | int[] dp = new int[startTime.length + 1]; 11 | Arrays.fill(dp, -1); 12 | return maxProfit(jobs, 0, startTime.length, dp); 13 | 14 | } 15 | 16 | public int maxProfit(int[][] jobs, int curr, int n, int[] dp) { 17 | 18 | if(curr == n) { 19 | return 0; 20 | } 21 | 22 | if(dp[curr] != -1) { 23 | return dp[curr]; 24 | } 25 | int c1 = maxProfit(jobs, curr + 1, n, dp); 26 | int c2 = jobs[curr][2]; 27 | 28 | for(int i = curr + 1; i < n; i++) { 29 | if(jobs[curr][1] <= jobs[i][0]) { 30 | c2 += maxProfit(jobs, i, n, dp); 31 | break; 32 | } 33 | } 34 | 35 | return dp[curr] = Math.max(c1, c2); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LIS.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public static void main(String[] args) { 3 | 4 | Scanner sc = new Scanner(System.in); 5 | int n = sc.nextInt(); 6 | int[] v = new int[n]; 7 | for (int i = 0; i < n; ++i) { 8 | v[i] = sc.nextInt(); 9 | } 10 | 11 | System.out.println(lengthOfLIS(v)); 12 | } 13 | public int lengthOfLIS(int[] nums) { 14 | int[][] dp = new int[nums.length + 1][nums.length + 1]; 15 | 16 | for(int[] row : dp) { 17 | Arrays.fill(row, -1); 18 | } 19 | return lengthOfLIS(nums, 0, nums.length, -1, dp); 20 | } 21 | 22 | public int lengthOfLIS(int[] nums, int curr, int n, int pi, int[][] dp) { 23 | 24 | if(curr == n) { 25 | return 0; 26 | } 27 | 28 | if(dp[curr][pi + 1] != -1) { 29 | return dp[curr][pi + 1]; 30 | } 31 | 32 | int c1 = 0, c2 = 0; 33 | if(pi == -1 || nums[curr] > nums[pi]) { 34 | c1 = 1 + lengthOfLIS(nums, curr + 1, n, curr, dp); 35 | } 36 | 37 | c2 = lengthOfLIS(nums, curr + 1, n, pi, dp); 38 | 39 | return dp[curr][pi + 1] = Math.max(c1, c2); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /StringBasedDp/MaxDelToMakeSorted.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | class Main { 3 | public static int lengthOfLIS(int[] nums) { 4 | // Map cache = new HashMap<>(); 5 | int[][] cache = new int[nums.length + 1][nums.length + 1]; 6 | for(int[] row : cache) { 7 | Arrays.fill(row, -1); 8 | } 9 | return lengthOfLIS(nums, nums.length - 1, -1, cache); 10 | } 11 | 12 | private static int lengthOfLIS(int[] nums, int ci, int pi, int[][] cache) { 13 | 14 | if(ci < 0) { 15 | return 0; 16 | } 17 | 18 | if(cache[ci][pi + 1] != -1) { 19 | return cache[ci][pi + 1]; 20 | } 21 | 22 | int c1 = 0; 23 | if(pi == -1 || nums[ci] < nums[pi]) { 24 | c1 = 1 + lengthOfLIS(nums, ci - 1, ci, cache); 25 | } 26 | 27 | int c2 = lengthOfLIS(nums, ci - 1, pi, cache); 28 | return cache[ci][pi + 1] = Math.max(c1, c2); 29 | } 30 | 31 | public static void main(String[] args) { 32 | int[] arr = {3, 2, 1, 0}; 33 | //Subtract the length of LIS from array length, those are the minimum deletions to make sequence sorted 34 | System.out.println(arr.length - lengthOfLIS(arr)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /WallsAndGatesApproaches/DFS.java: -------------------------------------------------------------------------------- 1 | public class DFS { 2 | /** 3 | * @param rooms: m x n 2D grid 4 | * @return: nothing 5 | */ 6 | 7 | public void wallsAndGates(int[][] rooms) { 8 | // write your code here 9 | for(int i = 0; i < rooms.length; i++) { 10 | for(int j = 0; j < rooms[0].length; j++) { 11 | if(rooms[i][j] == 0) { 12 | wallsAndGatesDfs(rooms, i, j, new int[rooms.length][rooms[0].length], 0); 13 | } 14 | } 15 | } 16 | } 17 | 18 | public void wallsAndGatesDfs(int[][] rooms, int sx, int sy, int vis[][], int dis) { 19 | 20 | if(sx < 0 || sy < 0 || sx >= rooms.length || sy >=rooms[0].length || vis[sx][sy] == 1) { 21 | return; 22 | } 23 | 24 | if(rooms[sx][sy] == -1) { 25 | return; 26 | } 27 | 28 | if(dis < rooms[sx][sy]) { 29 | rooms[sx][sy] = dis; 30 | } 31 | 32 | 33 | 34 | vis[sx][sy] = 1; 35 | wallsAndGatesDfs(rooms, sx, sy + 1, vis, dis + 1); 36 | wallsAndGatesDfs(rooms, sx + 1, sy, vis, dis + 1); 37 | wallsAndGatesDfs(rooms, sx - 1, sy, vis, dis + 1); 38 | wallsAndGatesDfs(rooms, sx, sy - 1, vis, dis + 1); 39 | vis[sx][sy] = 0; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /WallsAndGatesApproaches/MutliEndBFS.java: -------------------------------------------------------------------------------- 1 | public class MutliEndBfs { 2 | /** 3 | * @param rooms: m x n 2D grid 4 | * @return: nothing 5 | */ 6 | 7 | public static int dx[] = {0, 0, 1, -1}; 8 | public static int dy[] = {1, -1, 0, 0}; 9 | public static int INF = 2147483647; 10 | public void wallsAndGates(int[][] rooms) { 11 | // write your code here 12 | Queue bfs = new LinkedList<>(); 13 | for(int i = 0; i < rooms.length; i++) { 14 | for(int j = 0; j < rooms[0].length; j++) { 15 | if(rooms[i][j] == 0) 16 | bfs.add(new int[]{i, j}); 17 | } 18 | } 19 | 20 | wallsAndGatesBfs(rooms, bfs); 21 | } 22 | 23 | public void wallsAndGatesBfs(int[][] rooms, Queue bfs) { 24 | while(!bfs.isEmpty()) { 25 | int[] disArr = bfs.remove(); 26 | int disx = disArr[0]; 27 | int disy = disArr[1]; 28 | 29 | for(int k = 0; k < 4; k++) { 30 | int x = disx + dx[k]; 31 | int y = disy + dy[k]; 32 | 33 | if(x >= 0 && x < rooms.length && y >= 0 && y < rooms[0].length && rooms[x][y] == INF) { 34 | bfs.add(new int[]{x, y}); 35 | rooms[x][y] = rooms[disx][disy] + 1; 36 | } 37 | } 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /StringBasedDp/MinDeletionsAndInsertions.java: -------------------------------------------------------------------------------- 1 | //Time Complexity - O(n ^ 2) 2 | import java.util.*; 3 | class Main { 4 | public static int longestCommonSubsequence(String text1, String text2) { 5 | 6 | int[][] cache = new int[text1.length() + 1][text2.length() + 1]; 7 | for(int[] row : cache) 8 | Arrays.fill(row, -1); 9 | 10 | cache[0][0] = 0; 11 | 12 | for(int i = 0; i <= text1.length(); i++) { 13 | cache[i][0] = 0; 14 | } 15 | 16 | for(int j = 0; j <= text2.length(); j++) { 17 | cache[0][j] = 0; 18 | } 19 | 20 | for(int i = 1; i <= text1.length(); i++) { 21 | for(int j = 1; j <= text2.length(); j++) { 22 | if(text1.charAt(i - 1) == text2.charAt(j - 1)) { 23 | cache[i][j] = 1 + cache[i - 1][j - 1]; 24 | } else { 25 | int c1 = cache[i - 1][j]; 26 | int c2 = cache[i][j - 1]; 27 | 28 | cache[i][j] = Math.max(c1, c2); 29 | } 30 | } 31 | } 32 | return cache[text1.length()][text2.length()]; 33 | } 34 | 35 | public static void main(String[] args) { 36 | int lcsLength = longestCommonSubsequence("passport", "ppsspt"); 37 | 38 | System.out.println((8 - lcsLength) + " deletions and " + (6 - lcsLength) + " insertions "); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Max Area Of Island/BFS.java: -------------------------------------------------------------------------------- 1 | class BFS { 2 | static int[] dx = {0, 0, 1, -1}; 3 | static int[] dy = {1, -1, 0, 0}; 4 | public int maxAreaOfIsland(int[][] grid) { 5 | 6 | int n = grid.length, m = grid[0].length; 7 | 8 | int maxAns = 0; 9 | for(int i = 0; i < n; i++) { 10 | for(int j = 0; j < m; j++) { 11 | if(grid[i][j] == 1) { 12 | maxAns = Math.max(maxAns, bfs(grid, i, j)); 13 | } 14 | } 15 | } 16 | return maxAns; 17 | } 18 | 19 | public boolean isSafe(int[][] grid, int i, int j) { 20 | 21 | int n = grid.length, m = grid[0].length; 22 | return i >= 0 && j >= 0 && i < n && j < m && grid[i][j] == 1; 23 | } 24 | 25 | public int bfs(int[][] grid, int i, int j) { 26 | Queue q = new LinkedList<>(); 27 | q.add(new int[]{i, j}); 28 | grid[i][j] = 0; 29 | int area = 0; 30 | while(!q.isEmpty()) { 31 | int[] pair = q.poll(); 32 | area++; 33 | 34 | for(int k = 0; k < 4; k++) { 35 | int x = pair[0] + dx[k]; 36 | int y = pair[1] + dy[k]; 37 | 38 | if(isSafe(grid, x, y)) { 39 | q.add(new int[]{x, y}); 40 | grid[x][y] = 0; 41 | } 42 | } 43 | } 44 | return area; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Number Of Islands/BFSSol.java: -------------------------------------------------------------------------------- 1 | class BFSSol { 2 | static int[] dx = {0, 0, -1, 1}; 3 | static int[] dy = {1, -1, 0, 0}; 4 | 5 | public int numIslands(char[][] grid) { 6 | if(grid.length == 0 || grid[0].length == 0) { 7 | return 0; 8 | } 9 | 10 | 11 | int count = 0; 12 | for(int i = 0; i < grid.length; i++) { 13 | for(int j = 0; j < grid[0].length; j++) { 14 | if(grid[i][j] == '1') { 15 | count++; 16 | BFS(grid, i, j); 17 | } 18 | } 19 | } 20 | 21 | return count; 22 | } 23 | 24 | private boolean isSafe(char[][] grid, int i, int j) { 25 | 26 | return i >= 0 && j >= 0 && i < grid.length && j < grid[0].length && grid[i][j] == '1'; 27 | } 28 | private void BFS(char[][] grid, int i, int j) { 29 | Queue bfs = new LinkedList<>(); 30 | 31 | bfs.add(new int[]{i, j}); 32 | grid[i][j] = '0'; 33 | 34 | while(!bfs.isEmpty()) { 35 | int[] pair = bfs.poll(); 36 | 37 | for(int k = 0; k < 4; k++) { 38 | int x = pair[0] + dx[k]; 39 | int y = pair[1] + dy[k]; 40 | 41 | if(isSafe(grid, x, y)) { 42 | grid[x][y] = '0'; 43 | bfs.add(new int[]{x, y}); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /FibonacciBasedDp/SumFactors.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | public class Main { 3 | 4 | //Recursive 5 | Time Complexity - O(3 ^ n) 6 | 7 | public static int sumFact(int n) { 8 | if(n == 0) { 9 | return 1; 10 | } 11 | 12 | if(n < 0) { 13 | return 0; 14 | } 15 | 16 | int c1 = sumFact(n - 1); 17 | int c2 = sumFact(n - 3); 18 | int c3 = sumFact(n - 4); 19 | 20 | return c1 + c2 + c3; 21 | } 22 | 23 | //Top Down 24 | Time Complexity - O(n) 25 | Space Complexity - O(n) 26 | public static int sumFactCached(int n, int[] dp) { 27 | if(n == 0) { 28 | return 1; 29 | } 30 | 31 | if(n < 0) { 32 | return 0; 33 | } 34 | 35 | if(dp[n] != -1) { 36 | return dp[n]; 37 | } 38 | 39 | int c1 = sumFact(n - 1); 40 | int c2 = sumFact(n - 3); 41 | int c3 = sumFact(n - 4); 42 | 43 | return dp[n] = c1 + c2 + c3; 44 | } 45 | 46 | //Bottom Up 47 | Time Complexity - O(n) 48 | Space Complexity - O(n) 49 | public static int sumFactBu(int n, int[] dp) { 50 | dp[0] = 1; 51 | dp[1] = 1; 52 | dp[2] = 1; 53 | dp[3] = 2; 54 | for(int i = 4; i <= n; i++) { 55 | dp[i] = dp[i - 1] + dp[i - 3] + dp[i - 4]; 56 | } 57 | 58 | return dp[n]; 59 | } 60 | public static void main(String args[]) { 61 | int[] dp = new int[11]; 62 | Arrays.fill(dp, -1); 63 | System.out.println(sumFactBu(10, dp)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /GraphProblems/NumberOfClosedIslands.java: -------------------------------------------------------------------------------- 1 | class NumberOfClosedIslands { 2 | public int closedIsland(int[][] grid) { 3 | int n = grid.length; 4 | int m = grid[0].length; 5 | 6 | int closedCount = 0; 7 | for(int i = 0; i < n; i++) { 8 | for(int j = 0; j < m; j++) { 9 | if(grid[i][j] == 0) { 10 | if(bFS(i, j, grid)) { 11 | closedCount++; 12 | } 13 | } 14 | } 15 | } 16 | 17 | return closedCount; 18 | } 19 | 20 | public boolean bFS(int i, int j, int[][] grid) { 21 | 22 | int[] dx = {0, 0, 1, -1}; 23 | int[] dy = {1, -1, 0, 0}; 24 | 25 | Queue bfs = new LinkedList<>(); 26 | bfs.add(new int[]{i, j}); 27 | grid[i][j] = 1; 28 | 29 | boolean isClosed = true; 30 | while(!bfs.isEmpty()) { 31 | int[] pair = bfs.poll(); 32 | 33 | for(int k = 0; k < 4; k++) { 34 | int x = pair[0] + dx[k]; 35 | int y = pair[1] + dy[k]; 36 | 37 | if(x >= 0 && y >= 0 && x < grid.length && y < grid[0].length) { 38 | if(grid[x][y] == 0) { 39 | grid[x][y] = 1; 40 | bfs.add(new int[]{x, y}); 41 | } 42 | } else { 43 | isClosed = false; 44 | } 45 | } 46 | } 47 | return isClosed; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /HouseRobber3/NaiveCached.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class NaiveCached { 17 | Map cacheTaken = new HashMap<>(); 18 | Map cacheNotTaken = new HashMap<>(); 19 | public int rob(TreeNode root) { 20 | 21 | return Math.max(rob(root, false), rob(root, true)); 22 | } 23 | 24 | private int rob(TreeNode root, boolean canRob) { 25 | 26 | if(root == null) { 27 | return 0; 28 | } 29 | 30 | if(canRob && cacheTaken.containsKey(root)) { 31 | return cacheTaken.get(root); 32 | } 33 | 34 | if(!canRob && cacheNotTaken.containsKey(root)) { 35 | return cacheNotTaken.get(root); 36 | } 37 | 38 | int a1 = 0, a2 = 0; 39 | if(canRob) { 40 | a1 = root.val + rob(root.left, false) + rob(root.right, false); 41 | cacheTaken.put(root, a1); 42 | return a1; 43 | } else { 44 | a2 = Math.max(rob(root.left, false), rob(root.left, true)) + Math.max(rob(root.right, false), rob(root.right, true)); 45 | cacheNotTaken.put(root, a2); 46 | return a2; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /UncrossedLines.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Scanner; 3 | 4 | public class LCS { 5 | 6 | public static int lCS(String s1, String s2, int l1, int l2) { 7 | 8 | if (l1 == 0 || l2 == 0) { 9 | return 0; 10 | } 11 | if (s1.charAt(l1 - 1) == s2.charAt(l2 - 1)) { 12 | return 1 + lCS(s1, s2, l1 - 1, l2 - 1); 13 | } else { 14 | int c1 = lCS(s1, s2, l1 - 1, l2); 15 | int c2 = lCS(s1, s2, l1, l2 - 1); 16 | 17 | return Math.max(c1, c2); 18 | } 19 | } 20 | 21 | public static int uCL(int[] s1, int[] s2, int l1, int l2, int[][] dp) { 22 | 23 | if (l1 == 0 || l2 == 0) { 24 | return 0; 25 | } 26 | 27 | if(dp[l1][l2] != -1) { 28 | return dp[l1][l2]; 29 | } 30 | 31 | if (s1[l1 - 1] == s2[l2 - 1]) { 32 | return dp[l1][l2] = 1 + uCL(s1, s2, l1 - 1, l2 - 1, dp); 33 | } else { 34 | int c1 = uCL(s1, s2, l1 - 1, l2, dp); 35 | int c2 = uCL(s1, s2, l1, l2 - 1, dp); 36 | 37 | return dp[l1][l2] = Math.max(c1, c2); 38 | } 39 | } 40 | 41 | public static void main(String[] args) { 42 | // TODO Auto-generated method stub 43 | Scanner s = new Scanner(System.in); 44 | int N = s.nextInt(); 45 | int M = s.nextInt(); 46 | 47 | int[] X = new int[N]; 48 | int[] Y = new int[M]; 49 | 50 | int[][] dp = new int[X.length + 1][Y.length + 1]; 51 | 52 | for(int[] row : dp) { 53 | Arrays.fill(row, -1); 54 | } 55 | for(int i = 0; i < N; i++) { 56 | X[i] = s.nextInt(); 57 | } 58 | 59 | for(int i = 0; i < M; i++) { 60 | Y[i] = s.nextInt(); 61 | } 62 | 63 | System.out.println(uCL(X, Y, X.length, Y.length, dp)); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /StringBasedDp/Lis.java: -------------------------------------------------------------------------------- 1 | //Recursive 2 | Time Complexity - O(2 ^ n) 3 | class Solution { 4 | public int lengthOfLIS(int[] nums) { 5 | return lengthOfLIS(nums, nums.length - 1, -1); 6 | } 7 | 8 | private int lengthOfLIS(int[] nums, int ci, int pi) { 9 | 10 | if(ci < 0) { 11 | return 0; 12 | } 13 | 14 | int c1 = 0; 15 | if(pi == -1 || nums[ci] < nums[pi]) { 16 | c1 = 1 + lengthOfLIS(nums, ci - 1, ci); 17 | } 18 | 19 | int c2 = lengthOfLIS(nums, ci - 1, pi); 20 | return Math.max(c1, c2); 21 | } 22 | } 23 | 24 | //Top Down 25 | Time Complexity - O(n ^ 2) 26 | class Solution { 27 | public int lengthOfLIS(int[] nums) { 28 | // Map cache = new HashMap<>(); 29 | int[][] cache = new int[nums.length + 1][nums.length + 1]; 30 | for(int[] row : cache) { 31 | Arrays.fill(row, -1); 32 | } 33 | return lengthOfLIS(nums, nums.length - 1, -1, cache); 34 | } 35 | 36 | private int lengthOfLIS(int[] nums, int ci, int pi, int[][] cache) { 37 | 38 | if(ci < 0) { 39 | return 0; 40 | } 41 | 42 | if(cache[ci][pi + 1] != -1) { 43 | return cache[ci][pi + 1]; 44 | } 45 | 46 | int c1 = 0; 47 | if(pi == -1 || nums[ci] < nums[pi]) { 48 | c1 = 1 + lengthOfLIS(nums, ci - 1, ci, cache); 49 | } 50 | 51 | int c2 = lengthOfLIS(nums, ci - 1, pi, cache); 52 | return cache[ci][pi + 1] = Math.max(c1, c2); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Unique Binary Search Trees ii/DAndC.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class DAndC { 17 | public List generateTrees(int n) { 18 | List ans = new ArrayList<>(); 19 | if(n == 0) { 20 | return ans; 21 | } 22 | return generateTrees(1, n); 23 | } 24 | 25 | private List generateTrees(int start, int end) { 26 | List ans = new ArrayList<>(); 27 | if(start > end) { 28 | ans.add(null); 29 | return ans; 30 | } 31 | 32 | if(start == end) { 33 | ans.add(new TreeNode(start)); 34 | return ans; 35 | } 36 | 37 | for(int i = start; i <= end; i++) { 38 | List leftSubtree = generateTrees(start, i - 1); 39 | List rightSubtree = generateTrees(i + 1, end); 40 | 41 | for(TreeNode leftC : leftSubtree) { 42 | for(TreeNode rightC : rightSubtree) { 43 | TreeNode root = new TreeNode(i); 44 | root.left = leftC; 45 | root.right = rightC; 46 | 47 | ans.add(root); 48 | } 49 | } 50 | } 51 | return ans; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /RainWaterTrapping.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int trap(int[] height) { 3 | int len = height.length; 4 | if(len == 0) return 0; 5 | int[] maxleft = new int[len]; 6 | int[] maxright = new int[len]; 7 | int max = Integer.MIN_VALUE; 8 | for(int i=0;i max){ 10 | max = height[i]; 11 | } 12 | maxleft[i] = max; 13 | } 14 | max = Integer.MIN_VALUE; 15 | for(int i=len-1;i>=0;i--){ 16 | if(height[i] > max){ 17 | max = height[i]; 18 | } 19 | maxright[i] = max; 20 | } 21 | int ret = 0; 22 | for(int i=0;i maxAns) { 25 | maxAns = ans; 26 | } 27 | } 28 | } 29 | 30 | return maxAns; 31 | } 32 | 33 | private int DFS(int[][] matrix, int i, int j, int prev, boolean[][] visited, int[][] longestP) { 34 | 35 | if(i < 0 || i == matrix.length || j < 0 || j == matrix[0].length || visited[i][j] == true || prev >= matrix[i][j]) { 36 | return 0; 37 | } 38 | 39 | 40 | // if(longestP[i][j] > 0) { 41 | // return longestP[i][j]; 42 | // } 43 | 44 | visited[i][j] = true; 45 | int top = DFS(matrix, i - 1, j, matrix[i][j], visited, longestP); 46 | int bottom = DFS(matrix, i + 1, j, matrix[i][j], visited, longestP); 47 | int right = DFS(matrix, i, j + 1, matrix[i][j], visited, longestP); 48 | int left = DFS(matrix, i, j - 1, matrix[i][j], visited, longestP); 49 | int path = 1 + Math.max(Math.max(top, bottom), Math.max(right, left)); 50 | longestP[i][j] = path; 51 | visited[i][j] = false; 52 | return path; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /greedycont/Busy.java: -------------------------------------------------------------------------------- 1 | package com.chitkara.greedycont; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | import java.util.Scanner; 8 | 9 | //Activity Selection Problem/Job Scheduling 10 | public class Busy { 11 | 12 | static class Pair { 13 | int start; 14 | int end; 15 | 16 | public Pair(int start, int end) { 17 | this.start = start; 18 | this.end = end; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | // TODO Auto-generated method stub 24 | return "start is " + start + " end is " + end; 25 | } 26 | } 27 | 28 | public static void main(String[] args) { 29 | Scanner s = new Scanner(System.in); 30 | 31 | int t = s.nextInt(); 32 | 33 | // for(int i = 0; i < t; i++) 34 | while (t-- != 0) { 35 | int n = s.nextInt(); 36 | 37 | List activities = new ArrayList<>(); 38 | 39 | for (int i = 0; i < n; i++) { 40 | int start = s.nextInt(); 41 | int end = s.nextInt(); 42 | 43 | activities.add(new Pair(start, end)); 44 | } 45 | 46 | //System.out.println(activities); 47 | 48 | // Sort on the basis of inc order of end time 49 | 50 | Collections.sort(activities, new Comparator() { 51 | 52 | @Override 53 | public int compare(Pair o1, Pair o2) { // this -> o1, other -> o2 54 | // TODO Auto-generated method stub 55 | return o1.end - o2.end; 56 | } 57 | 58 | }); 59 | 60 | System.out.println(activities); 61 | 62 | //Choose first activity 63 | int count = 1; 64 | int currEnd = activities.get(0).end; //e1 65 | 66 | //Check for other activities 67 | for(int i = 1; i < activities.size(); i++) { 68 | int st = activities.get(i).start; //ith ka start nikala or s2 69 | 70 | if(st >= currEnd) { 71 | //chunlo ith ko 72 | count++; 73 | currEnd = activities.get(i).end; 74 | } 75 | 76 | } 77 | 78 | System.out.println(count); 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /StringBasedDp/LCSubsequence.java: -------------------------------------------------------------------------------- 1 | //Recursive 2 | Time Complexity - O(2 ^ n) 3 | Space Complexity - O(n + m) 4 | class Solution { 5 | public int longestCommonSubsequence(String text1, String text2) { 6 | 7 | return lCS(text1, text2, text1.length(), text2.length()); 8 | } 9 | 10 | private int lCS(String s1, String s2, int n, int m) { 11 | 12 | if(n == 0 || m == 0) { 13 | return 0; 14 | } 15 | 16 | 17 | int c1 = 0; 18 | int c2 = 0; 19 | if(s1.charAt(n - 1) == s2.charAt(m - 1)) { 20 | return 1 + lCS(s1, s2, n - 1, m - 1); 21 | } else { 22 | c1 = lCS(s1, s2, n - 1, m); 23 | c2 = lCS(s1, s2, n, m - 1); 24 | return Math.max(c1, c2); 25 | } 26 | } 27 | } 28 | 29 | //Bottom Up 30 | Time Complexity - O(n ^ 2) 31 | Space Complexity - O(n ^ 2) 32 | class Solution { 33 | public int longestCommonSubsequence(String text1, String text2) { 34 | 35 | int[][] cache = new int[text1.length() + 1][text2.length() + 1]; 36 | for(int[] row : cache) 37 | Arrays.fill(row, -1); 38 | 39 | cache[0][0] = 0; 40 | 41 | for(int i = 0; i <= text1.length(); i++) { 42 | cache[i][0] = 0; 43 | } 44 | 45 | for(int j = 0; j <= text2.length(); j++) { 46 | cache[0][j] = 0; 47 | } 48 | 49 | for(int i = 1; i <= text1.length(); i++) { 50 | for(int j = 1; j <= text2.length(); j++) { 51 | if(text1.charAt(i - 1) == text2.charAt(j - 1)) { 52 | cache[i][j] = 1 + cache[i - 1][j - 1]; 53 | } else { 54 | int c1 = cache[i - 1][j]; 55 | int c2 = cache[i][j - 1]; 56 | 57 | cache[i][j] = Math.max(c1, c2); 58 | } 59 | } 60 | } 61 | return cache[text1.length()][text2.length()]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 100-days-of-algo 2 | 100 days of algorithm challenges
3 | - [x] Walls And Gates 4 | - [x] House Robber 3 5 | - [x] House Robber 2 6 | - [x] Maximum Profit In Job Scheduling 7 | - [x] Stone Game 3 8 | - [x] Longest Increasing Path In Matrix 9 | - [x] Word Ladder 10 | - [x] Unique BST 2 11 | - [x] Max Area Of Island 12 | - [x] Number Of Island 13 | - [x] Number Of Distinct Islands 14 | - [x] All Nodes Distance K in Binary Tree 15 | - [x] Flood Fill 16 | - [x] Number Of Closed Islands 17 | # Fibonacci Based Problems dp - 1 18 | - [x] Given a number ‘n’, implement a method to count how many possible ways there are to express ‘n’ as the sum of 1, 3, or 4. 19 | - [x] 198. House Robber 20 | - [x] 70. Climbing Stairs 21 | - [x] 45. Jump Game II 22 | - [x] 746. Min Cost Climbing Stairs 23 | 24 | # String Dp Problems dp - 2 25 | - [x] 72. Edit Distance 26 | - [x] 376. Wiggle Subsequence 27 | - [x] 1143. Longest Common Subsequence 28 | - [x] Longest Common Substring 29 | - [x] 718. Maximum Length of Repeated Subarray(Longest Common Substring Variation) 30 | 31 | # More String Dp Problems dp - 3 32 | - [x] Longest Increasing Subsequence 33 | - [x] Minimum Deletions To Make Sequence Sorted(complete LIS pattern). 34 | - [x] Minimum Deletions And Insertions To Make Two Strings Equal(complete LCS pattern) 35 | 36 | # More String DP Problems dp - 4 37 | - [x] 1035. Uncrossed Lines (LCS variant) 38 | - [x] 1458. Max Dot Product of Two Subsequences (LCS variant) 39 | - [x] 516. Longest Palindromic Subsequence 40 | 41 | # More DP Problems(Asked By Google) dp - 5 42 | - [x] 688. Knight Probability in Chessboard 43 | - [x] 935. Knight Dialer(Very Similar To 688, follows similar template) 44 | 45 | # dp - 6 46 | - [x] All palindromic subsequences 47 | - [x] 740. Delete and Earn (House Robber Variant) 48 | - [x] 486. Predict the Winner (Min - Max Variant) 49 | 50 | # More Dynamic Programming dp - 7 51 | - [x] 1092. Shortest Common Supersequence(Hard) 52 | - [x] 446. Arithmetic Slices(Medium) 53 | - [x] 877. Stone Game(Medium) (Min - Max Variant) 54 | -------------------------------------------------------------------------------- /Unique Binary Search Trees ii/Cached.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class Cached { 17 | public List generateTrees(int n) { 18 | List ans = new ArrayList<>(); 19 | if(n == 0) { 20 | return ans; 21 | } 22 | return generateTrees(1, n, new HashMap<>()); 23 | } 24 | 25 | private List generateTrees(int start, int end, Map> cache) { 26 | List ans = new ArrayList<>(); 27 | if(start > end) { 28 | ans.add(null); 29 | return ans; 30 | } 31 | 32 | if(start == end) { 33 | ans.add(new TreeNode(start)); 34 | return ans; 35 | } 36 | 37 | StringBuilder sb = new StringBuilder(); 38 | sb.append(start); 39 | sb.append(" "); 40 | sb.append(end); 41 | 42 | if(cache.containsKey(sb)) { 43 | return cache.get(sb); 44 | } 45 | 46 | for(int i = start; i <= end; i++) { 47 | List leftSubtree = generateTrees(start, i - 1, cache); 48 | List rightSubtree = generateTrees(i + 1, end, cache); 49 | 50 | for(TreeNode leftC : leftSubtree) { 51 | for(TreeNode rightC : rightSubtree) { 52 | TreeNode root = new TreeNode(i); 53 | root.left = leftC; 54 | root.right = rightC; 55 | 56 | ans.add(root); 57 | } 58 | } 59 | } 60 | cache.put(sb,ans); 61 | return ans; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Longest Increasing Path In Matix/NaiveCached.java: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | public int longestIncreasingPath(int[][] matrix) { 4 | 5 | int n = matrix.length; 6 | if(n == 0) { 7 | return 0; 8 | } 9 | int m = matrix[0].length; 10 | 11 | if(m == 0) { 12 | return 0; 13 | } 14 | 15 | boolean[][] vis = new boolean[n][m]; 16 | int[][] longestP = new int[n][m]; 17 | 18 | int maxAns = Integer.MIN_VALUE; 19 | for(int i = 0; i < matrix.length; i++) { 20 | for(int j = 0; j < matrix[i].length; j++) { 21 | 22 | int ans = DFS(matrix, i, j, -1, vis, longestP); 23 | if(ans > maxAns) { 24 | maxAns = ans; 25 | } 26 | } 27 | } 28 | 29 | 30 | return maxAns; 31 | } 32 | 33 | private int DFS(int[][] matrix, int i, int j, int prev, boolean[][] visited, int[][] longestP) { 34 | 35 | if(i < 0 || i == matrix.length || j < 0 || j == matrix[0].length || visited[i][j] == true || prev >= matrix[i][j]) { 36 | return 0; 37 | } 38 | 39 | 40 | if(longestP[i][j] > 0) { 41 | return longestP[i][j]; 42 | } 43 | 44 | visited[i][j] = true; 45 | 46 | for(int i = 0; i < matrix.length; i++) { 47 | for(int j = 0; j < matrix[i].length; j++) { 48 | int top = 49 | } 50 | } 51 | int top = DFS(matrix, i - 1, j, matrix[i][j], visited, longestP); 52 | int bottom = DFS(matrix, i + 1, j, matrix[i][j], visited, longestP); 53 | int right = DFS(matrix, i, j + 1, matrix[i][j], visited, longestP); 54 | int left = DFS(matrix, i, j - 1, matrix[i][j], visited, longestP); 55 | int path = 1 + Math.max(Math.max(top, bottom), Math.max(right, left)); 56 | longestP[i][j] = path; 57 | visited[i][j] = false; 58 | return path; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /KnightGoogleInterviewDp/KnightProbability.java: -------------------------------------------------------------------------------- 1 | //Recursive O(8 ^ n) 2 | class Solution { 3 | 4 | int[] dirx = {1, -1, 1, -1, -2, -2, 2, 2}; 5 | int[] diry = {2, 2, -2, -2, 1, -1, 1, -1}; 6 | public double knightProbability(int N, int K, int r, int c) { 7 | if(r < 0 || c < 0 || r > N - 1 || c > N - 1) { 8 | return 0; 9 | } 10 | 11 | if(K == 0) { 12 | return 1; 13 | } 14 | 15 | double probab = 0; 16 | for(int i = 0; i < 8; i++) { 17 | probab += knightProbability(N, K - 1, r + dirx[i], c + diry[i]); 18 | } 19 | 20 | return probab * 0.125; 21 | } 22 | } 23 | 24 | //Dp O(n ^ 3) 25 | class Solution { 26 | 27 | int[] dirx = {1, -1, 1, -1, -2, -2, 2, 2}; 28 | int[] diry = {2, 2, -2, -2, 1, -1, 1, -1}; 29 | public double knightProbability(int N, int K, int r, int c) { 30 | Map dp = new HashMap<>(); 31 | 32 | return knightProbability(N, K, r, c, dp); 33 | } 34 | 35 | public String keyGenerator(int k, int r, int c) { 36 | 37 | StringBuilder sb = new StringBuilder(); 38 | sb.append(k); 39 | sb.append("|"); 40 | sb.append(r); 41 | sb.append("|"); 42 | sb.append(c); 43 | 44 | return sb.toString(); 45 | } 46 | public double knightProbability(int N, int K, int r, int c, Map dp) { 47 | if(r < 0 || c < 0 || r > N - 1 || c > N - 1) { 48 | return 0; 49 | } 50 | 51 | if(K == 0) { 52 | return 1; 53 | } 54 | 55 | String key = keyGenerator(K, r, c); 56 | if(dp.containsKey(key)) { 57 | return dp.get(key); 58 | } 59 | 60 | 61 | double probab = 0; 62 | for(int i = 0; i < 8; i++) { 63 | probab += knightProbability(N, K - 1, r + dirx[i], c + diry[i], dp); 64 | } 65 | 66 | dp.put(key, probab * 0.125); 67 | return probab * 0.125; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /StringBasedDp/EditDistance.java: -------------------------------------------------------------------------------- 1 | //Recursive 2 | Time Complexity - O(3 ^ n) 3 | Space Complexity - O(n + m) recursive stack space 4 | class Solution { 5 | public int minDistance(String word1, String word2) { 6 | 7 | return minDistance(word1, word2, word1.length(), word2.length()); 8 | } 9 | 10 | private int minDistance(String word1, String word2, int n, int m) { 11 | 12 | if(n == 0 && m == 0) { 13 | return 0; 14 | } 15 | 16 | if(n == 0) { 17 | return m; 18 | } 19 | 20 | if(m == 0) { 21 | return n; 22 | } 23 | 24 | if(word1.charAt(n - 1) == word2.charAt(m - 1)) { 25 | return minDistance(word1, word2, n - 1, m - 1); 26 | } else { 27 | int c1 = minDistance(word1, word2, n - 1, m); //deletion 28 | int c2 = minDistance(word1, word2, n, m - 1); //insertion 29 | int c3 = minDistance(word1, word2, n - 1, m - 1); //replace 30 | 31 | return 1 + Math.min(c1, Math.min(c2, c3)); 32 | } 33 | } 34 | } 35 | 36 | //Bottom Up 37 | Time Complexity - O(n ^ 2) 38 | Space Complexity - O(n ^ 2) 39 | class Solution { 40 | public int minDistance(String word1, String word2) { 41 | 42 | int[][] dp = new int[word1.length() + 1][word2.length() + 1]; 43 | 44 | dp[0][0] = 0; 45 | 46 | for(int j = 0; j <= word2.length(); j++) { 47 | dp[0][j] = j; 48 | } 49 | 50 | for(int i = 0; i <= word1.length(); i++) { 51 | dp[i][0] = i; 52 | } 53 | 54 | for(int i = 1; i <= word1.length(); i++) { 55 | for(int j = 1; j <= word2.length(); j++) { 56 | if(word1.charAt(i - 1) == word2.charAt(j - 1)) { 57 | dp[i][j] = dp[i - 1][j - 1]; 58 | } else { 59 | dp[i][j] = 1 + Math.min(dp[i - 1][j], Math.min(dp[i][j - 1], dp[i - 1][j - 1])); 60 | } 61 | } 62 | } 63 | 64 | return dp[word1.length()][word2.length()]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /StringBasedDp/WiggleSubsequence.java: -------------------------------------------------------------------------------- 1 | //Time Complexity - O(2 ^ n) 2 | class Solution { 3 | public int wiggleMaxLength(int[] nums) { 4 | return Math.max(wiggleHelper(nums, -1, 0, true), wiggleHelper(nums, -1, 0, false)); 5 | } 6 | 7 | private int wiggleHelper(int[] nums, int pi, int ci, boolean isAsc) { 8 | 9 | if(ci >= nums.length) { 10 | return 0; 11 | } 12 | 13 | int c1 = 0; 14 | if(isAsc) { 15 | if(pi == -1 || nums[pi] < nums[ci]) { 16 | c1 = 1 + wiggleHelper(nums, ci, ci + 1, !isAsc); 17 | } 18 | } else { 19 | if(pi == -1 || nums[pi] > nums[ci]) { 20 | c1 = 1 + wiggleHelper(nums, ci, ci + 1, !isAsc); 21 | } 22 | } 23 | 24 | int c2 = wiggleHelper(nums, ci, ci + 1, isAsc); 25 | return Math.max(c1, c2); 26 | } 27 | } 28 | 29 | //Time Complexity - O(n ^ 2) 30 | class Solution { 31 | boolean isAsc; 32 | public int wiggleMaxLeng+th(int[] nums) { 33 | Map cache1 = new HashMap<>(); 34 | Map cache2 = new HashMap<>(); 35 | return Math.max(wiggleHelper(nums, -1, 0, true, cache1), wiggleHelper(nums, -1, 0, false, cache2)); 36 | } 37 | 38 | private int wiggleHelper(int[] nums, int pi, int ci, boolean isAsc, Map cache) { 39 | 40 | if(ci >= nums.length) { 41 | return 0; 42 | } 43 | 44 | String key = pi + "|" + ci + "|" + isAsc; 45 | if(cache.containsKey(key)) { 46 | return cache.get(key); 47 | } 48 | 49 | int c1 = 0; 50 | if(isAsc) { 51 | if(pi == -1 || nums[pi] < nums[ci]) { 52 | c1 = 1 + wiggleHelper(nums, ci, ci + 1, !isAsc, cache); 53 | } 54 | } else { 55 | if(pi == -1 || nums[pi] > nums[ci]) { 56 | c1 = 1 + wiggleHelper(nums, ci, ci + 1, !isAsc, cache); 57 | } 58 | } 59 | 60 | int c2 = wiggleHelper(nums, ci, ci + 1, isAsc, cache); 61 | cache.put(key, Math.max(c1, c2)); 62 | return Math.max(c1, c2); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /FibonacciBasedDp/MinCostClimbingStairs.java: -------------------------------------------------------------------------------- 1 | //Top Down 2 | Time Complexity - O(n) 3 | Space Complexity - O(n) 4 | class Solution { 5 | public int minCostClimbingStairs(int[] cost) { 6 | int n = cost.length; 7 | int[] dp = new int[n + 1]; 8 | Arrays.fill(dp, -1); 9 | return Math.min(minCost(cost, n, dp), minCost(cost, n - 1, dp)); 10 | } 11 | 12 | private int minCost(int[] cost, int n, int[] dp) { 13 | 14 | if(n == 1 || n == 2) { 15 | return cost[n - 1]; 16 | } 17 | if(dp[n] != -1) { 18 | return dp[n]; 19 | } 20 | 21 | int c1 = minCost(cost, n - 1, dp); 22 | int c2 = minCost(cost, n - 2, dp); 23 | return dp[n] = cost[n - 1] + Math.min(c1, c2); 24 | } 25 | } 26 | 27 | //Bottom Up 28 | Time Complexity - O(n) 29 | Space Complexity - O(n) 30 | class Solution { 31 | public int minCostClimbingStairs(int[] cost) { 32 | int n = cost.length; 33 | int[] dp1 = new int[n + 1]; 34 | int[] dp2 = new int[n + 1]; 35 | Arrays.fill(dp1, -1); 36 | Arrays.fill(dp2, -1); 37 | return Math.min(minCost(cost, n, dp1), minCost(cost, n - 1, dp2)); 38 | } 39 | 40 | private int minCost(int[] cost, int n, int[] dp) { 41 | 42 | if(n == 1 || n == 2) { 43 | dp[n] = cost[n - 1]; 44 | } 45 | 46 | dp[1] = cost[0]; 47 | dp[2] = cost[1]; 48 | 49 | for(int i = 3; i <= n; i++) { 50 | dp[i] = cost[i - 1] + Math.min(dp[i - 1], dp[i - 2]); 51 | } 52 | 53 | return dp[n]; 54 | } 55 | } 56 | 57 | //Space Optimsed 58 | Time Complexity - O(n) 59 | Space Complexity - O(1) 60 | class Solution { 61 | public int minCostClimbingStairs(int[] cost) { 62 | int n = cost.length; 63 | return Math.min(minCost(cost, n), minCost(cost, n - 1)); 64 | } 65 | 66 | private int minCost(int[] cost, int n) { 67 | 68 | 69 | int a = cost[0]; 70 | int b = cost[1]; 71 | 72 | for(int i = 3; i <= n; i++) { 73 | int temp = cost[i - 1] + Math.min(a, b); 74 | a = b; 75 | b = temp; 76 | } 77 | 78 | return b; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /MoreDp/PredictTheWinner.java: -------------------------------------------------------------------------------- 1 | //Recursive Time Complexity - O(2 ^ n) 2 | //Run time - 25 ms 3 | 4 | class Solution { 5 | public boolean PredictTheWinner(int[] nums) { 6 | 7 | int totalSum = 0; 8 | 9 | for(int num : nums) { 10 | totalSum += num; 11 | } 12 | 13 | int winP = winnings(nums, 0, nums.length - 1); 14 | 15 | if(totalSum - winP <= winP) { 16 | return true; 17 | } else { 18 | return false; 19 | } 20 | } 21 | 22 | private int winnings(int[] nums, int i, int j) { 23 | 24 | if(i == j) { 25 | return nums[i]; 26 | } 27 | 28 | if(j == i + 1) { 29 | return Math.max(nums[i], nums[j]); 30 | } 31 | 32 | int c1 = nums[i] + Math.min(winnings(nums, i + 1, j - 1), winnings(nums, i + 2, j)); 33 | int c2 = nums[j] + Math.min(winnings(nums, i, j - 2), winnings(nums, i + 1, j - 1)); 34 | 35 | return Math.max(c1, c2); 36 | } 37 | } 38 | 39 | //Top Down/Caching Dp Time Complexity - O(n ^ 2) 40 | //Runtime - 0ms 41 | class Solution { 42 | public boolean PredictTheWinner(int[] nums) { 43 | 44 | int totalSum = 0; 45 | 46 | for(int num : nums) { 47 | totalSum += num; 48 | } 49 | 50 | int[][] dp = new int[nums.length][nums.length]; 51 | for(int[] row : dp) { 52 | Arrays.fill(row, -1); 53 | } 54 | 55 | int winP = winnings(nums, 0, nums.length - 1, dp); 56 | 57 | if(totalSum - winP <= winP) { 58 | return true; 59 | } else { 60 | return false; 61 | } 62 | } 63 | 64 | private int winnings(int[] nums, int i, int j, int[][] dp) { 65 | 66 | if(i == j) { 67 | return nums[i]; 68 | } 69 | 70 | if(j == i + 1) { 71 | return Math.max(nums[i], nums[j]); 72 | } 73 | 74 | if(dp[i][j] != -1) { 75 | return dp[i][j]; 76 | } 77 | 78 | int c1 = nums[i] + Math.min(winnings(nums, i + 1, j - 1, dp), winnings(nums, i + 2, j, dp)); 79 | int c2 = nums[j] + Math.min(winnings(nums, i, j - 2, dp), winnings(nums, i + 1, j - 1, dp)); 80 | 81 | return dp[i][j] = Math.max(c1, c2); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /KnightGoogleInterviewDp/KnightDialer.java: -------------------------------------------------------------------------------- 1 | // Recursive O(8 ^ n) 2 | class Solution { 3 | 4 | int[] dirx = {1, -1, 1, -1, -2, -2, 2, 2}; 5 | int[] diry = {2, 2, -2, -2, 1, -1, 1, -1}; 6 | public int knightDialer(int n) { 7 | 8 | int nums = 0; 9 | for(int r = 0; r < 4; r++) { 10 | for(int c = 0; c < 3; c++) { 11 | nums += knightDialer(n - 1, r, c); 12 | } 13 | } 14 | 15 | return nums; 16 | } 17 | 18 | private int knightDialer(int n, int i, int j) { 19 | if(i < 0 || j < 0 || (i == 3 && j == 0) || (i == 3 && j == 2) || i > 3 || j > 2) { 20 | return 0; 21 | } 22 | 23 | if(n == 0) { 24 | return 1; 25 | } 26 | 27 | int moves = 0; 28 | for(int l = 0; l < 8; l++) { 29 | moves += knightDialer(n - 1, i + dirx[l], j + diry[l]); 30 | } 31 | 32 | return moves; 33 | } 34 | } 35 | 36 | // Dp Cached 37 | class Solution { 38 | 39 | int[] dirx = {1, -1, 1, -1, -2, -2, 2, 2}; 40 | int[] diry = {2, 2, -2, -2, 1, -1, 1, -1}; 41 | public int knightDialer(int n) { 42 | 43 | Map dp = new HashMap<>(); 44 | int nums = 0; 45 | for(int r = 0; r < 4; r++) { 46 | for(int c = 0; c < 3; c++) { 47 | if((r == 3 && c == 0) || (r == 3 && c == 2)) { 48 | 49 | } else { 50 | nums = (nums + knightDialer(n - 1, r, c, dp)) % 1000000007; 51 | } 52 | } 53 | } 54 | 55 | return nums; 56 | } 57 | 58 | public String keyGenerator(int k, int r, int c) { 59 | 60 | StringBuilder sb = new StringBuilder(); 61 | sb.append(k); 62 | sb.append("|"); 63 | sb.append(r); 64 | sb.append("|"); 65 | sb.append(c); 66 | 67 | return sb.toString(); 68 | } 69 | 70 | private int knightDialer(int n, int i, int j, Map dp) { 71 | if(i < 0 || j < 0 || (i == 3 && j == 0) || (i == 3 && j == 2) || i > 3 || j > 2) { 72 | return 0; 73 | } 74 | 75 | if(n == 0) { 76 | return 1; 77 | } 78 | 79 | String key = keyGenerator(n, i, j); 80 | if(dp.containsKey(key)) { 81 | return dp.get(key); 82 | } 83 | 84 | int moves = 0; 85 | for(int l = 0; l < 8; l++) { 86 | moves = (moves + knightDialer(n - 1, i + dirx[l], j + diry[l], dp)) % 1000000007; 87 | } 88 | 89 | dp.put(key, moves); 90 | return moves; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /class25/AlienDictionary.java: -------------------------------------------------------------------------------- 1 | package class25; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Queue; 10 | 11 | public class AlienDictionary { 12 | 13 | static class Graph { 14 | 15 | Map> adjL; 16 | 17 | int v; 18 | public Graph(int v) { 19 | this.adjL = new HashMap<>(); 20 | this.v = v; 21 | } 22 | 23 | private void addEdge(String[] dict, int n, int k) { 24 | // TODO Auto-generated method stub 25 | 26 | for (int i = 0; i < n - 1; i++) { 27 | String x = dict[i]; 28 | String y = dict[i + 1]; 29 | 30 | int j = 0; 31 | 32 | while (j < Math.min(x.length(), y.length())) { 33 | 34 | if (x.charAt(j) != y.charAt(j)) { 35 | List neighbourL = this.adjL.getOrDefault(x.charAt(j), new ArrayList<>()); 36 | neighbourL.add(y.charAt(j)); 37 | this.adjL.put(x.charAt(j), neighbourL); 38 | break; 39 | } 40 | 41 | j++; 42 | } 43 | } 44 | } 45 | 46 | private int[] indegree() { 47 | // TODO Auto-generated method stub 48 | int[] indegree = new int[this.v]; 49 | 50 | for(List neighbourL : this.adjL.values()) { 51 | for(char c : neighbourL) { 52 | indegree[c - 'a']++; 53 | } 54 | } 55 | 56 | System.out.println(Arrays.toString(indegree)); 57 | return indegree; 58 | } 59 | 60 | private void topologicalSorting() { 61 | // TODO Auto-generated method stub 62 | 63 | Queue bfs = new LinkedList<>(); 64 | int[] indegree = this.indegree(); 65 | for(int i = 0; i < indegree.length; i++) { 66 | if(indegree[i] == 0) { 67 | bfs.add((char)(i + 'a')); 68 | } 69 | } 70 | 71 | while(!bfs.isEmpty()) { 72 | char front = bfs.poll(); 73 | 74 | System.out.print(front + " "); 75 | 76 | for(char neighbour : this.adjL.getOrDefault(front, new ArrayList<>())) { 77 | indegree[neighbour - 'a']--; 78 | 79 | if(indegree[neighbour - 'a'] == 0) { 80 | bfs.add(neighbour); 81 | } 82 | } 83 | } 84 | } 85 | private void display() { 86 | // TODO Auto-generated method stub 87 | 88 | for (var entry : this.adjL.entrySet()) { 89 | System.out.println(entry.getKey() + " -> " + entry.getValue()); 90 | } 91 | } 92 | 93 | } 94 | 95 | public static void main(String[] args) { 96 | int n = 5; 97 | int k = 4; 98 | Graph g = new Graph(k); 99 | String[] s = { "baa", "abcd", "abca", "cab", "cad" }; 100 | 101 | 102 | g.addEdge(s, n, k); 103 | g.display(); 104 | g.indegree(); 105 | g.topologicalSorting(); 106 | 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /MoreDp/EarnAndDelete.java: -------------------------------------------------------------------------------- 1 | //Memoized Dp 2 | class Solution { 3 | public int deleteAndEarn(int[] nums) { 4 | 5 | if(nums.length == 0) { 6 | return 0; 7 | } 8 | 9 | int maxNum = Integer.MIN_VALUE; 10 | 11 | for(int num : nums) { 12 | maxNum = Math.max(maxNum, num); 13 | } 14 | 15 | int[] freq = new int[maxNum + 1]; 16 | int[] dp = new int[maxNum + 2]; 17 | Arrays.fill(dp, -1); 18 | for(int num : nums) { 19 | freq[num] += num; 20 | } 21 | 22 | for(int num : freq) { 23 | System.out.print(num + " "); 24 | } 25 | 26 | return deleteAndEarn(freq, 0, maxNum + 1, dp); 27 | } 28 | 29 | private int deleteAndEarn(int[] freq, int i, int n, int[] dp) { 30 | 31 | if(i >= n) { 32 | return 0; 33 | 34 | } 35 | 36 | if(dp[i] != -1) { 37 | return dp[i]; 38 | } 39 | 40 | return dp[i] = Math.max(deleteAndEarn(freq, i + 1, n, dp), freq[i] + deleteAndEarn(freq, i + 2, n, dp)); 41 | } 42 | } 43 | 44 | //Bottom Up Extra Space 45 | class Solution { 46 | public int deleteAndEarn(int[] nums) { 47 | 48 | if(nums.length == 0) { 49 | return 0; 50 | } 51 | 52 | int maxNum = Integer.MIN_VALUE; 53 | 54 | for(int num : nums) { 55 | maxNum = Math.max(maxNum, num); 56 | } 57 | 58 | int[] freq = new int[maxNum + 1]; 59 | int[] dp = new int[maxNum + 2]; 60 | Arrays.fill(dp, -1); 61 | for(int num : nums) { 62 | freq[num] += num; 63 | } 64 | 65 | dp[0] = 0; 66 | dp[1] = freq[0]; 67 | 68 | for(int i = 2; i <= maxNum + 1; i++) { 69 | dp[i] = Math.max(dp[i - 1], freq[i - 1] + dp[i - 2]); 70 | } 71 | 72 | 73 | 74 | return dp[maxNum + 1]; 75 | } 76 | } 77 | 78 | //Bottom Up Constant Space 79 | class Solution { 80 | public int deleteAndEarn(int[] nums) { 81 | 82 | if(nums.length == 0) { 83 | return 0; 84 | } 85 | 86 | int maxNum = Integer.MIN_VALUE; 87 | 88 | for(int num : nums) { 89 | maxNum = Math.max(maxNum, num); 90 | } 91 | 92 | int[] freq = new int[maxNum + 1]; 93 | int[] dp = new int[maxNum + 2]; 94 | Arrays.fill(dp, -1); 95 | for(int num : nums) { 96 | freq[num] += num; 97 | } 98 | 99 | int a = 0; 100 | int b = freq[0]; 101 | 102 | int temp = 0; 103 | for(int i = 2; i <= maxNum + 1; i++) { 104 | temp = Math.max(b, freq[i - 1] + a); 105 | a = b; 106 | b = temp; 107 | } 108 | return temp; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /class25/CourseSchedule.java: -------------------------------------------------------------------------------- 1 | package class25; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Queue; 11 | import java.util.Set; 12 | 13 | public class CourseSchedule { 14 | 15 | static class Graph { 16 | 17 | // vertex - list of neighbours to that vertex 18 | Map> adjList; 19 | 20 | int numV; 21 | 22 | public Graph(int numV) { 23 | adjList = new HashMap<>(); 24 | this.numV = numV; 25 | } 26 | 27 | // u and v mein add edge 28 | // isBidir = true -> undirected edge, false -> directed edge 29 | private void addEdge(int u, int v, boolean isBidir) { 30 | // TODO Auto-generated method stub 31 | 32 | // u -> v edge 1 -> 2 33 | 34 | // 1 ki neighbour list 35 | List uNeighbour = this.adjList.getOrDefault(u, new ArrayList<>()); 36 | uNeighbour.add(v); 37 | this.adjList.put(u, uNeighbour); 38 | 39 | if (isBidir) { 40 | // v -> u edge 2 -> 1 41 | 42 | // 2 ki neighbour list 43 | List vNeighbour = this.adjList.getOrDefault(v, new ArrayList<>()); 44 | 45 | // 2 ka neighbour 1 46 | vNeighbour.add(u); 47 | 48 | this.adjList.put(v, vNeighbour); 49 | } 50 | 51 | } 52 | 53 | private void display() { 54 | // TODO Auto-generated method stub 55 | 56 | for (Map.Entry> entry : this.adjList.entrySet()) { 57 | int vertex = entry.getKey(); 58 | List neighbourList = entry.getValue(); 59 | System.out.println(vertex + " -> " + neighbourList); 60 | } 61 | } 62 | 63 | private int[] indegree() { 64 | // TODO Auto-generated method stub 65 | 66 | int[] indegree = new int[numV]; 67 | 68 | for (List neighbourList : this.adjList.values()) { 69 | 70 | for (int neighbour : neighbourList) { 71 | indegree[neighbour]++; 72 | } 73 | } 74 | 75 | System.out.println(Arrays.toString(indegree)); 76 | return indegree; 77 | } 78 | 79 | private void topologicalSorting() { 80 | // TODO Auto-generated method stub 81 | Queue bfs = new LinkedList<>(); 82 | int[] indegree = indegree(); 83 | 84 | for (int vertex = 0; vertex < numV; vertex++) { 85 | if (indegree[vertex] == 0) { 86 | bfs.add(vertex); 87 | } 88 | } 89 | 90 | while (!bfs.isEmpty()) { 91 | int frontV = bfs.poll(); 92 | 93 | System.out.print(frontV + " "); 94 | 95 | List neighbourList = this.adjList.getOrDefault(frontV, new ArrayList<>()); 96 | 97 | for (int neighbour : neighbourList) { 98 | indegree[neighbour]--; 99 | 100 | if (indegree[neighbour] == 0) { 101 | bfs.add(neighbour); 102 | } 103 | } 104 | } 105 | 106 | // System.out.println(bfs); 107 | } 108 | 109 | } 110 | 111 | public static void main(String[] args) { 112 | // TODO Auto-generated method stub 113 | 114 | Graph g = new Graph(4); 115 | 116 | int[][] courses = { { 1, 0 }, { 2, 0 }, { 3, 1 }, { 3, 2 } }; 117 | 118 | for (int i = 0; i < courses.length; i++) { 119 | g.addEdge(courses[i][1], courses[i][0], false); 120 | } 121 | g.display(); 122 | g.topologicalSorting(); 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Graph.java: -------------------------------------------------------------------------------- 1 | package class25; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Queue; 10 | import java.util.Set; 11 | 12 | //adjacency list implementation 13 | public class Graph { 14 | 15 | // vertex - list of neighbours to that vertex 16 | Map> adjList; 17 | int v; 18 | 19 | public Graph(int v) { 20 | adjList = new HashMap<>(); 21 | this.v = v; 22 | } 23 | 24 | // u and v mein add edge 25 | // isBidir = true -> undirected edge, false -> directed edge 26 | private void addEdge(int u, int v, boolean isBidir) { 27 | // TODO Auto-generated method stub 28 | 29 | // u -> v edge 1 -> 2 30 | 31 | // 1 ki neighbour list 32 | List uNeighbour = this.adjList.getOrDefault(u, new ArrayList<>()); 33 | uNeighbour.add(v); 34 | this.adjList.put(u, uNeighbour); 35 | 36 | if (isBidir) { 37 | // v -> u edge 2 -> 1 38 | 39 | // 2 ki neighbour list 40 | List vNeighbour = this.adjList.getOrDefault(v, new ArrayList<>()); 41 | 42 | // 2 ka neighbour 1 43 | vNeighbour.add(u); 44 | 45 | this.adjList.put(v, vNeighbour); 46 | } 47 | 48 | } 49 | 50 | private void display() { 51 | // TODO Auto-generated method stub 52 | 53 | for (Map.Entry> entry : this.adjList.entrySet()) { 54 | int vertex = entry.getKey(); 55 | List neighbourList = entry.getValue(); 56 | System.out.println(vertex + " -> " + neighbourList); 57 | } 58 | } 59 | 60 | private void bFS(int src) { 61 | // TODO Auto-generated method stub 62 | 63 | Queue bfs = new LinkedList<>(); 64 | 65 | bfs.add(src); 66 | Set vis = new HashSet<>(); 67 | vis.add(src); 68 | 69 | while (!bfs.isEmpty()) { 70 | int front = bfs.poll(); // vertex - 1 71 | System.out.print(front + " "); 72 | 73 | List neighbourList = this.adjList.get(front); // [2, 4] 74 | 75 | for (int neighbour : neighbourList) { 76 | if (!vis.contains(neighbour)) { 77 | bfs.add(neighbour); 78 | vis.add(neighbour); 79 | } 80 | } 81 | } 82 | } 83 | 84 | private void sSSP(int src) { 85 | // TODO Auto-generated method stub 86 | 87 | Queue bfs = new LinkedList<>(); 88 | 89 | bfs.add(src); 90 | Map dis = new HashMap<>(); // vertex - distance from source 91 | for (int vertex : adjList.keySet()) { 92 | dis.put(vertex, Integer.MAX_VALUE); 93 | } 94 | dis.put(src, 0); 95 | 96 | while (!bfs.isEmpty()) { 97 | int front = bfs.poll(); // vertex - 4 98 | // System.out.print(front + " "); 99 | 100 | List neighbourList = this.adjList.get(front); // [1, 3] 101 | 102 | for (int neighbour : neighbourList) { 103 | if (dis.get(neighbour) == Integer.MAX_VALUE) { // agar neigbhour infinite distance pr hai source se, so 104 | // it is unvisited 105 | bfs.add(neighbour); 106 | int distance = dis.get(front) + 1; // 4 ka distance + 1 = 0 + 1 = 1; 107 | dis.put(neighbour, distance); 108 | System.out.println("distance of " + neighbour + " from source " + src + " is " + distance); 109 | } 110 | } 111 | } 112 | } 113 | 114 | private int[] indegree() { 115 | // TODO Auto-generated method stub 116 | 117 | int[] indegree = new int[v]; 118 | 119 | for (List l : adjList.values()) { 120 | for (int e : l) { 121 | indegree[e]++; 122 | } 123 | } 124 | 125 | return indegree; 126 | } 127 | 128 | private void topologicalSorting() { 129 | // TODO Auto-generated method stub 130 | 131 | int[] indegree = indegree(); 132 | 133 | Queue bfs = new LinkedList<>(); 134 | 135 | for (int i = 0; i < indegree.length; i++) { 136 | if (indegree[i] == 0) { 137 | bfs.add(i); 138 | } 139 | } 140 | 141 | while (!bfs.isEmpty()) { 142 | int front = bfs.poll(); 143 | 144 | System.out.print(front + " "); 145 | List neigbourList = adjList.getOrDefault(front, new ArrayList<>()); 146 | 147 | for (int neighbour : neigbourList) { 148 | 149 | indegree[neighbour]--; 150 | 151 | if (indegree[neighbour] == 0) { 152 | bfs.add(neighbour); 153 | } 154 | } 155 | } 156 | } 157 | 158 | private void helper(int src, Set visited) { 159 | // TODO Auto-generated method stub 160 | 161 | System.out.print(src + " "); 162 | visited.add(src); 163 | 164 | for(int e : adjList.get(src)) { 165 | if(!visited.contains(e)) { 166 | helper(e, visited); 167 | } 168 | } 169 | 170 | } 171 | 172 | private void dFS(int src) { 173 | // TODO Auto-generated method stub 174 | Set visited = new HashSet<>(); 175 | 176 | helper(src, visited); 177 | } 178 | 179 | private void connectedComponents() { 180 | // TODO Auto-generated method stub 181 | 182 | Set visited = new HashSet<>(); 183 | int count = 1; 184 | for(int vertex : adjList.keySet()) { 185 | if(!visited.contains(vertex)) { 186 | System.out.print("Connected Component " + count + " -> "); 187 | helper(vertex, visited); 188 | count++; 189 | System.out.println(); 190 | } 191 | } 192 | } 193 | 194 | public static void main(String[] args) { 195 | // TODO Auto-generated method stub 196 | 197 | Graph g = new Graph(7); 198 | 199 | g.addEdge(1, 2, true); 200 | g.addEdge(1, 4, true); 201 | g.addEdge(2, 3, true); 202 | g.addEdge(3, 4, true); 203 | g.addEdge(3, 5, true); 204 | g.addEdge(5, 6, true); 205 | 206 | g.addEdge(7, 7, false); 207 | g.addEdge(8, 8, false); 208 | 209 | // g.addEdge(0, 1, false); 210 | // g.addEdge(0, 2, false); 211 | // g.addEdge(2, 3, false); 212 | // g.addEdge(2, 4, false); 213 | // g.addEdge(3, 1, false); 214 | // g.addEdge(4, 6, false); 215 | // g.addEdge(5, 3, false); 216 | // g.addEdge(5, 6, false); 217 | g.display(); 218 | // g.top 219 | //topologicalSorting(); 220 | g.connectedComponents(); 221 | //g.dFS(1); 222 | // g.sSSP(4); 223 | } 224 | 225 | } 226 | -------------------------------------------------------------------------------- /class25/Graph.java: -------------------------------------------------------------------------------- 1 | package class25; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.Queue; 11 | import java.util.Set; 12 | 13 | //adjacency list implementation 14 | public class Graph { 15 | 16 | // vertex - list of neighbours to that vertex 17 | Map> adjList; 18 | 19 | int numV; 20 | public Graph(int numV) { 21 | adjList = new HashMap<>(); 22 | this.numV = numV; 23 | } 24 | 25 | // u and v mein add edge 26 | // isBidir = true -> undirected edge, false -> directed edge 27 | private void addEdge(int u, int v, boolean isBidir) { 28 | // TODO Auto-generated method stub 29 | 30 | // u -> v edge 1 -> 2 31 | 32 | // 1 ki neighbour list 33 | List uNeighbour = this.adjList.getOrDefault(u, new ArrayList<>()); 34 | uNeighbour.add(v); 35 | this.adjList.put(u, uNeighbour); 36 | 37 | if (isBidir) { 38 | // v -> u edge 2 -> 1 39 | 40 | // 2 ki neighbour list 41 | List vNeighbour = this.adjList.getOrDefault(v, new ArrayList<>()); 42 | 43 | // 2 ka neighbour 1 44 | vNeighbour.add(u); 45 | 46 | this.adjList.put(v, vNeighbour); 47 | } 48 | 49 | } 50 | 51 | private void display() { 52 | // TODO Auto-generated method stub 53 | 54 | for (Map.Entry> entry : this.adjList.entrySet()) { 55 | int vertex = entry.getKey(); 56 | List neighbourList = entry.getValue(); 57 | System.out.println(vertex + " -> " + neighbourList); 58 | } 59 | } 60 | 61 | private void bFS(int src) { 62 | // TODO Auto-generated method stub 63 | 64 | Queue bfs = new LinkedList<>(); 65 | 66 | bfs.add(src); 67 | Set vis = new HashSet<>(); 68 | vis.add(src); 69 | 70 | while (!bfs.isEmpty()) { 71 | int front = bfs.poll(); // vertex - 1 72 | System.out.print(front + " "); 73 | 74 | List neighbourList = this.adjList.get(front); // [2, 4] 75 | 76 | for (int neighbour : neighbourList) { 77 | if (!vis.contains(neighbour)) { 78 | bfs.add(neighbour); 79 | vis.add(neighbour); 80 | } 81 | } 82 | } 83 | } 84 | 85 | private void sSSP(int src) { 86 | // TODO Auto-generated method stub 87 | 88 | Queue bfs = new LinkedList<>(); 89 | 90 | bfs.add(src); 91 | Map dis = new HashMap<>(); // vertex - distance from source 92 | for (int vertex : adjList.keySet()) { 93 | dis.put(vertex, Integer.MAX_VALUE); 94 | } 95 | dis.put(src, 0); 96 | 97 | while (!bfs.isEmpty()) { 98 | int front = bfs.poll(); // vertex - 4 99 | // System.out.print(front + " "); 100 | 101 | List neighbourList = this.adjList.get(front); // [1, 3] 102 | 103 | for (int neighbour : neighbourList) { 104 | if (dis.get(neighbour) == Integer.MAX_VALUE) { // agar neigbhour infinite distance pr hai source se, so 105 | // it is unvisited 106 | bfs.add(neighbour); 107 | int distance = dis.get(front) + 1; // 4 ka distance + 1 = 0 + 1 = 1; 108 | dis.put(neighbour, distance); 109 | System.out.println("distance of " + neighbour + " from source " + src + " is " + distance); 110 | } 111 | } 112 | } 113 | } 114 | 115 | private void dfsHelper(int src, Set vis) { 116 | // TODO Auto-generated method stub 117 | System.out.print(src + " "); 118 | vis.add(src); 119 | 120 | List neighbourList = this.adjList.get(src); 121 | 122 | for(int neighbour : neighbourList) { 123 | if(!vis.contains(neighbour)) { 124 | dfsHelper(neighbour, vis); 125 | } 126 | } 127 | } 128 | 129 | private void dfs(int src) { 130 | // TODO Auto-generated method stub 131 | 132 | Set vis = new HashSet<>(); 133 | dfsHelper(src, vis); 134 | } 135 | 136 | private void connectedComponents() { 137 | // TODO Auto-generated method stub 138 | Set vis = new HashSet<>(); 139 | 140 | int count = 1; 141 | for(int vertex : this.adjList.keySet()) { 142 | if(!vis.contains(vertex)) { 143 | System.out.print("connected component " + count + " -> "); 144 | dfsHelper(vertex, vis); 145 | System.out.println(); 146 | count++; 147 | } 148 | 149 | } 150 | 151 | } 152 | 153 | private int[] indegree() { 154 | // TODO Auto-generated method stub 155 | 156 | int[] indegree = new int[numV]; 157 | 158 | for(List neighbourList : this.adjList.values()) { 159 | 160 | for(int neighbour : neighbourList) { 161 | indegree[neighbour]++; 162 | } 163 | } 164 | 165 | System.out.println(Arrays.toString(indegree)); 166 | return indegree; 167 | } 168 | 169 | private void topologicalSorting() { 170 | // TODO Auto-generated method stub 171 | Queue bfs = new LinkedList<>(); 172 | int[] indegree = indegree(); 173 | 174 | for(int vertex = 0; vertex < numV; vertex++) { 175 | if(indegree[vertex] == 0) { 176 | bfs.add(vertex); 177 | } 178 | } 179 | 180 | while(!bfs.isEmpty()) { 181 | int frontV = bfs.poll(); 182 | 183 | System.out.print(frontV + " "); 184 | 185 | List neighbourList = this.adjList.getOrDefault(frontV, new ArrayList<>()); 186 | 187 | for(int neighbour : neighbourList) { 188 | indegree[neighbour]--; 189 | 190 | if(indegree[neighbour] == 0) { 191 | bfs.add(neighbour); 192 | } 193 | } 194 | } 195 | 196 | //System.out.println(bfs); 197 | } 198 | public static void main(String[] args) { 199 | // TODO Auto-generated method stub 200 | 201 | Graph g = new Graph(4); 202 | 203 | // g.addEdge(1, 2, true); 204 | // g.addEdge(1, 4, true); 205 | // g.addEdge(2, 3, true); 206 | // g.addEdge(3, 4, true); 207 | // g.addEdge(3, 5, true); 208 | // g.addEdge(5, 6, true); 209 | // g.addEdge(7, 8, true); 210 | // g.addEdge(9, 9, false); 211 | 212 | //g.dfs(1); 213 | //g.connectedComponents(); 214 | // g.addEdge(0, 1, false); 215 | // g.addEdge(0, 2, false); 216 | // g.addEdge(2, 3, false); 217 | // g.addEdge(2, 4, false); 218 | // g.addEdge(3, 1, false); 219 | // g.addEdge(4, 6, false); 220 | // g.addEdge(5, 3, false); 221 | // g.addEdge(5, 6, false); 222 | // g.display(); 223 | // g.indegree(); 224 | // g.topologicalSorting(); 225 | 226 | int[][] courses = {{1, 0}, {2, 0}, {3, 1}, {3, 2}}; 227 | 228 | for(int i= 0; i < courses.length; i++) { 229 | g.addEdge(courses[i][1], courses[i][0], false); 230 | } 231 | g.display(); 232 | g.topologicalSorting(); 233 | 234 | } 235 | 236 | } 237 | --------------------------------------------------------------------------------