diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5a83bd5..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.classpath b/.classpath deleted file mode 100644 index 51a8bba..0000000 --- a/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/.gitignore b/.gitignore index ab31b20..6fd6edf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ *.class +.DS_Store +.classpath +.project +AmazonProblems.iml +*.json diff --git a/.project b/.project deleted file mode 100644 index cd4a1be..0000000 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - AmazonProblems - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 3a21537..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/AmazonProblems.iml b/AmazonProblems.iml deleted file mode 100644 index ea1542a..0000000 --- a/AmazonProblems.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index 67688a5..0000000 Binary files a/src/.DS_Store and /dev/null differ diff --git a/src/geeksforgeeks/.vscode/UrlEncode.java b/src/geeksforgeeks/.vscode/UrlEncode.java new file mode 100644 index 0000000..e69de29 diff --git a/src/geeksforgeeks/.vscode/launch.json b/src/geeksforgeeks/.vscode/launch.json new file mode 100644 index 0000000..4ef3738 --- /dev/null +++ b/src/geeksforgeeks/.vscode/launch.json @@ -0,0 +1,178 @@ +{ + "configurations": [ + { + "type": "java", + "name": "CodeLens (Launch) - LongestUniqueSubstring", + "request": "launch", + "mainClass": "geeksforgeeks.LongestUniqueSubstring" + }, + { + "type": "java", + "name": "CodeLens (Launch) - DesignTicTacToe", + "request": "launch", + "mainClass": "geeksforgeeks.DesignTicTacToe" + }, + { + "type": "java", + "name": "CodeLens (Launch) - RomanToInteger", + "request": "launch", + "mainClass": "geeksforgeeks.RomanToInteger" + }, + { + "type": "java", + "name": "CodeLens (Launch) - MaxProductString", + "request": "launch", + "mainClass": "geeksforgeeks.MaxProductString" + }, + { + "type": "java", + "name": "CodeLens (Launch) - ReorganiseString", + "request": "launch", + "mainClass": "geeksforgeeks.ReorganiseString" + }, + { + "type": "java", + "name": "CodeLens (Launch) - ValidParentheses", + "request": "launch", + "mainClass": "geeksforgeeks.ValidParentheses" + }, + { + "type": "java", + "name": "CodeLens (Launch) - TwoSumClosestToZero", + "request": "launch", + "mainClass": "geeksforgeeks.TwoSumClosestToZero" + }, + { + "type": "java", + "name": "CodeLens (Launch) - TrailingZeroes", + "request": "launch", + "mainClass": "geeksforgeeks.TrailingZeroes" + }, + { + "type": "java", + "name": "CodeLens (Launch) - SpiralMatrix", + "request": "launch", + "mainClass": "geeksforgeeks.SpiralMatrix" + }, + { + "type": "java", + "name": "CodeLens (Launch) - SnakeAndLadder", + "request": "launch", + "mainClass": "geeksforgeeks.SnakeAndLadder" + }, + { + "type": "java", + "name": "CodeLens (Launch) - SerializeAndDeserialize", + "request": "launch", + "mainClass": "geeksforgeeks.SerializeAndDeserialize" + }, + { + "type": "java", + "name": "CodeLens (Launch) - JumpsToReachEnd", + "request": "launch", + "mainClass": "geeksforgeeks.JumpsToReachEnd" + }, + { + "type": "java", + "name": "CodeLens (Launch) - ReorderLogs", + "request": "launch", + "mainClass": "geeksforgeeks.ReorderLogs" + }, + { + "type": "java", + "name": "CodeLens (Launch) - QueensAttackKing", + "request": "launch", + "mainClass": "geeksforgeeks.QueensAttackKing" + }, + { + "type": "java", + "name": "CodeLens (Launch) - ProductExceptSelf", + "request": "launch", + "mainClass": "geeksforgeeks.ProductExceptSelf" + }, + { + "type": "java", + "name": "CodeLens (Launch) - PrisonAfterNDays", + "request": "launch", + "mainClass": "geeksforgeeks.PrisonAfterNDays" + }, + { + "type": "java", + "name": "CodeLens (Launch) - PrintParenthesis", + "request": "launch", + "mainClass": "geeksforgeeks.PrintParenthesis" + }, + { + "type": "java", + "name": "CodeLens (Launch) - NextGreaterNumber", + "request": "launch", + "mainClass": "geeksforgeeks.NextGreaterNumber" + }, + { + "type": "java", + "name": "CodeLens (Launch) - MinimumSwapSortArray", + "request": "launch", + "mainClass": "geeksforgeeks.MinimumSwapSortArray" + }, + { + "type": "java", + "name": "CodeLens (Launch) - MinimumDistanceBetweenTwoNumbers", + "request": "launch", + "mainClass": "geeksforgeeks.MinimumDistanceBetweenTwoNumbers" + }, + { + "type": "java", + "name": "CodeLens (Launch) - MaximumSubstringWithKDistinctChar", + "request": "launch", + "mainClass": "geeksforgeeks.MaximumSubstringWithKDistinctChar" + }, + { + "type": "java", + "name": "CodeLens (Launch) - MajorityVoting", + "request": "launch", + "mainClass": "geeksforgeeks.MajorityVoting" + }, + { + "type": "java", + "name": "CodeLens (Launch) - CountDistinctKSubString", + "request": "launch", + "mainClass": "geeksforgeeks.CountDistinctKSubString" + }, + { + "type": "java", + "name": "CodeLens (Launch) - UrlEncode", + "request": "launch", + "mainClass": "geeksforgeeks.UrlEncode" + }, + { + "type": "java", + "name": "CodeLens (Launch) - FirstMissingPositive", + "request": "launch", + "mainClass": "geeksforgeeks.FirstMissingPositive" + }, + { + "type": "java", + "name": "CodeLens (Launch) - MergeIntervals", + "request": "launch", + "mainClass": "geeksforgeeks.MergeIntervals" + }, + { + "type": "java", + "name": "CodeLens (Launch) - InorderSuccessorPredecessor", + "request": "launch", + "mainClass": "geeksforgeeks.InorderSuccessorPredecessor" + }, + { + "type": "java", + "name": "CodeLens (Launch) - PalindromePartion", + "request": "launch", + "mainClass": "geeksforgeeks.PalindromePartion" + }, + { + "type": "java", + "name": "CodeLens (Launch) - MobileKeyPadCombinations", + "request": "launch", + "mainClass": "geeksforgeeks.MobileKeyPadCombinations" + } + ] +} \ No newline at end of file diff --git a/src/geeksforgeeks/.vscode/settings.json b/src/geeksforgeeks/.vscode/settings.json new file mode 100644 index 0000000..2666eac --- /dev/null +++ b/src/geeksforgeeks/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "files.exclude": { + "**/.classpath": true, + "**/.project": true, + "**/.settings": true, + "**/.factorypath": true + }, + "explorer.sortOrder": "modified" +} \ No newline at end of file diff --git a/src/geeksforgeeks/AdvantageShuffle.java b/src/geeksforgeeks/AdvantageShuffle.java new file mode 100644 index 0000000..6319ff8 --- /dev/null +++ b/src/geeksforgeeks/AdvantageShuffle.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +// the advantage of A with respect to B is the number of indices i for which A[i] > B[i]. + +// Return any permutation of A that maximizes its advantage with respect to B. +//Input: A = [12,24,8,32], B = [13,25,32,11] +//Output: [24,32,8,12] +// Input: A = [2,7,11,15], B = [1,10,4,11] +// Output: [2,11,7,15] +public class AdvantageShuffle { + public int[] advantageCount(int[] A, int[] B) { + Arrays.sort(A); + + PriorityQueue pq= new PriorityQueue<>((a,b)->Integer.compare(b[0],a[0])); + for(int i=0;ival){ // if polled element is lesser thar A[hi], put A[hi] at index of + // queued elements index, means, equal to B's current index we are putting + // a value greater that B's in result arrays + result[index]=A[hi--]; + }else{ + result[index]=A[lo++]; + } + } + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/AircraftOptimization.java b/src/geeksforgeeks/AircraftOptimization.java index ad49b7f..ef0eb40 100644 --- a/src/geeksforgeeks/AircraftOptimization.java +++ b/src/geeksforgeeks/AircraftOptimization.java @@ -7,56 +7,67 @@ import java.util.List; /** - * https://leetcode.com/discuss/interview-question/318918/Amazon-or-Online-Assessment-2019-or-Optimal-Aircraft-Utilization - * * https://leetcode.com/discuss/interview-question/373202 + * Given 2 lists a and b. Each element is a pair of integers where the first integer represents the unique id and the second integer represents a value. + * Your task is to find an element from a and an element form b such that the sum of their values is less or equal to target and as close to target as possible. + * Return a list of ids of selected elements. If no pair is possible, return an empty list. + * + * a = [[1, 2], [2, 4], [3, 6]] + b = [[1, 2]] + target = 7 + + Output: [[2, 1]] + + Explanation: + There are only three combinations [1, 1], [2, 1], and [3, 1], which have a total sum of 4, 6 and 8, respectively. + Since 6 is the largest sum that does not exceed 7, [2, 1] is the optimal pair. */ public class AircraftOptimization { - public List> calculateOptimalRoute(final List> forwardList, - final List> returnList, int capacity) { - - Collections.sort(forwardList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); - Collections.sort(returnList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); - - int max = 0; - int i = 0; - int j = returnList.size() - 1; - - List> result = null; - while (i < forwardList.size() && j >= 0) { - int currentSum = forwardList.get(i).get(1) + returnList.get(j).get(1); - - if (currentSum > max && currentSum <= capacity) { - max = forwardList.get(i).get(1) + returnList.get(j).get(1); - // Initializing new list - result = new LinkedList<>(); - result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); - i++; - } else if (forwardList.get(i).get(1) + returnList.get(j).get(1) == max) { - // no need to reset result list - result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); - i++; - } else { - j--; - } - } - return result; - } - - public static void main(String[] args) { - AircraftOptimization aircraft = new AircraftOptimization(); - List> returnList = new ArrayList<>(); - returnList.add(new ArrayList(Arrays.asList(1, 2000))); - returnList.add(new ArrayList(Arrays.asList(2, 3000))); - returnList.add(new ArrayList(Arrays.asList(3, 4000))); - returnList.add(new ArrayList(Arrays.asList(4, 5000))); - List> forwardList = new ArrayList<>(); - forwardList.add(new ArrayList(Arrays.asList(1, 3000))); - forwardList.add(new ArrayList(Arrays.asList(2, 5000))); - forwardList.add(new ArrayList(Arrays.asList(3, 7000))); - forwardList.add(new ArrayList(Arrays.asList(4, 10000))); - List> calculateOptimalRoute = aircraft.calculateOptimalRoute(forwardList, returnList, 10000); - System.out.println(calculateOptimalRoute); - } + public List> calculateOptimalRoute(final List> forwardList, + final List> returnList, int capacity) { + + Collections.sort(forwardList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); + Collections.sort(returnList, (o1, o2) -> Integer.compare(o1.get(1), o2.get(1))); + + int max = 0; + int i = 0; + int j = returnList.size() - 1; + + List> result = null; + while (i < forwardList.size() && j >= 0) { + int currentSum = forwardList.get(i).get(1) + returnList.get(j).get(1); + + if (currentSum > max && currentSum <= capacity) { + max = forwardList.get(i).get(1) + returnList.get(j).get(1); + // Initializing new list + result = new LinkedList<>(); + result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); + i++; + } else if (forwardList.get(i).get(1) + returnList.get(j).get(1) == max) { + // no need to reset result list + result.add(new ArrayList<>(Arrays.asList(forwardList.get(i).get(0), returnList.get(j).get(0)))); + i++; + } else { + j--; + } + } + return result; + } + + public static void main(String[] args) { + AircraftOptimization aircraft = new AircraftOptimization(); + List> returnList = new ArrayList<>(); + returnList.add(new ArrayList(Arrays.asList(1, 2000))); + returnList.add(new ArrayList(Arrays.asList(2, 3000))); + returnList.add(new ArrayList(Arrays.asList(3, 4000))); + returnList.add(new ArrayList(Arrays.asList(4, 5000))); + List> forwardList = new ArrayList<>(); + forwardList.add(new ArrayList(Arrays.asList(1, 3000))); + forwardList.add(new ArrayList(Arrays.asList(2, 5000))); + forwardList.add(new ArrayList(Arrays.asList(3, 7000))); + forwardList.add(new ArrayList(Arrays.asList(4, 10000))); + List> calculateOptimalRoute = aircraft.calculateOptimalRoute(forwardList, returnList, 10000); + System.out.println(calculateOptimalRoute); + } } diff --git a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java index c8e4d68..28f12b7 100644 --- a/src/geeksforgeeks/AlternateOddAndEvenNumbers.java +++ b/src/geeksforgeeks/AlternateOddAndEvenNumbers.java @@ -3,38 +3,41 @@ // (0, 2, 4,..) and negative numbers at odd indexes (1, 3, // 5, ..) +import java.util.Arrays; + +/** + * https://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/ + * An array contains both positive and negative numbers in random order. + * Rearrange the array elements so that positive and negative numbers are placed alternatively. + * If there are more positive numbers they appear at the end of the array. + * If there are more negative numbers, they too appear in the end of the array. + * [-1, 2, -3, 4, 5, 6, -7, 8, 9] + * output [9, -7, 8, -3, 5, -1, 2, 4, 6] or[4, -3, 5, -1, 6, -7, 2, 8, 9] + */ class AlternateOddAndEvenNumbers { - // The main function that rearranges elements of given - // array. It puts positive elements at even indexes (0, - // 2, ..) and negative numbers at odd indexes (1, 3, ..). static void rearrange(int arr[], int n) { - // The following few lines are similar to partition - // process of QuickSort. The idea is to consider 0 - // as pivot and divide the array around it. - int i = -1, temp = 0; + //-1, 2, -3, 4, 5, 6, -7, 8, 9 + int i = 0, temp = 0; for (int j = 0; j < n; j++) { if (arr[j] < 0) { - i++; temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; + i++; } } + // we have seggregated positive and negative elements + System.out.println(Arrays.toString(arr)); + int pos = i , neg = 0; + // pos indicates start of positive integer, neg starts from 0; - // Now all positive numbers are at end and negative numbers at - // the beginning of array. Initialize indexes for starting point - // of positive and negative numbers to be swapped - int pos = i + 1, neg = 0; - - // Increment the negative index by 2 and positive index by 1, i.e., - // swap every alternate negative number with next positive number while (pos < n && neg < pos && arr[neg] < 0) { temp = arr[neg]; arr[neg] = arr[pos]; arr[pos] = temp; pos++; - neg += 2; + neg += 2; // need to skip next element as output should be alternative } } @@ -44,7 +47,7 @@ static void printArray(int arr[], int n) { } public static void main(String[] args) { - int arr[] = {-1, 2, -3, 4, 5, 6, -7, 8, 9}; + int arr[] = { -1, 2, -3, 4, 5, 6, -7, 8, 9 }; int n = arr.length; rearrange(arr, n); System.out.println("Array after rearranging: "); diff --git a/src/geeksforgeeks/AngleOfClock.java b/src/geeksforgeeks/AngleOfClock.java new file mode 100644 index 0000000..874caef --- /dev/null +++ b/src/geeksforgeeks/AngleOfClock.java @@ -0,0 +1,15 @@ +package geeksforgeeks; + +public class AngleOfClock { + public double angleClock(int hours, int minutes) { + // every hour is 30* (360/12) because 12 hrs in clock + // every min is 6* (360/60) because 60 mins per hr + // we take mod of 12 because 12th hr needs to be 0* + double hour= (double) (hours%12 + (double)minutes/60)*30; + double min= minutes*6; + double absAngle= Math.abs(hour-min); + if(absAngle>180) absAngle= 360-absAngle; // this is because when time is 0.02 the angel will be 358 + + return absAngle; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ArrangeInQueue.java b/src/geeksforgeeks/ArrangeInQueue.java new file mode 100644 index 0000000..a0a3054 --- /dev/null +++ b/src/geeksforgeeks/ArrangeInQueue.java @@ -0,0 +1,27 @@ +package geeksforgeeks; + +// Input: +// [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] + +// Output: +// [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] +public class ArrangeInQueue { + +// 1. Sort people by their height, shortest to tallest +// 2. Iterate and put each person to the correct position +// 2.a When placing the shortest person, all person to his left will be taller or equal height, since you are iterating in height sorted array, so put it at a index equal to its k value +// 2.b When placing the next shortest person, find a position, where count of positions to the left unoccupied plus the ones where same height person is placed, is equal to its k value +// 2.c Keep repeating + public int[][] reconstructQueue(int[][] people) { + List result= new ArrayList<>(); + Arrays.sort(people,(a,b)->{ + if(a[0]==b[0]) return a[1]-b[1]; + return b[0]-a[0]; + }); + + for(int[] x: people){ + result.add(x[1],x); + } + return result.toArray(new int[people.length][2]); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/BasicCalculator.java b/src/geeksforgeeks/BasicCalculator.java new file mode 100644 index 0000000..75a5f7f --- /dev/null +++ b/src/geeksforgeeks/BasicCalculator.java @@ -0,0 +1,56 @@ +package geeksforgeeks; + +// Input: "(1+(4+5+2)-3)+(6+8)" +// Output: 23 +public class BasicCalculator { + + public int calculate(String s) { + if(s==null || s.length()==0) return -1; + Deque deque= new ArrayDeque<>(); + int sign=1; + int number=0; + int result=0; + // let's take an edge case 2-(5-6)=3; + // at i=0 number=2 + // i=1 char ='-' update with prev seen sign res=sign*number reset number we are looking for next operand + //i=2 char='(' and sign is '-', push prev result and sign and reset result for calclating + // subproblem inside braces + // i=3 update number to 5 + // i=4 char ='-' update result as sign*number = 5 reset number and sign =-1 + //i=5 update number to 6 + // i=6 char=')' update result with existing number(res=5=> 5+(-1*6)) and sign inside the braces + // then pop, which is last seen sign outside brace=> -1 and pop again to get result outside brace + // add all to result; + + for(int i=0;i queue = new LinkedList<>(); + if(root == null) return false; + queue.add(root); + int depthY = -1; + int depthX = -2; + int level = 0; + while(!queue.isEmpty()){ + int size = queue.size(); + for(int i = 0 ; i < size ; i++){ + TreeNode node = queue.remove(); + // eagerly checking if both vales are of same parent + if(node.left != null && node.right != null){ + if(node.left.val == x && node.right.val == y) return false; + if(node.left.val == y && node.right.val == x) return false; + } + //now checking if any of x or y matches with current node and records the level + if(node.val == x) depthX = level; + if(node.val == y) depthY = level; + if(node.left != null) queue.add(node.left); + if(node.right != null) queue.add(node.right); + } + level++; + } + return depthX == depthY; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/BitonicSearch.java b/src/geeksforgeeks/BitonicSearch.java index 7e22457..ce5e156 100644 --- a/src/geeksforgeeks/BitonicSearch.java +++ b/src/geeksforgeeks/BitonicSearch.java @@ -33,6 +33,22 @@ static int descendingBinarySearch(int arr[], int low, int high, int key) { return -1; } + // instead of writing two methods, we can write a method which contains order aganostic + // binary search, which compares the first and last element at first and inside while + // if ascending add below + // if (arr[mid] > key) { + // high = mid - 1; + // } else { + // low = mid + 1; + // } + //else if decending + // if (arr[mid] < key) { + // high = mid - 1; + // } else { + // low = mid + 1; + // } + + // -3,1,-2,-3,-4,-5,-6 static int findBitonicPoint(int arr[], int n, int l, int r) { int mid = ((r + l) / 2) + l; @@ -67,7 +83,7 @@ static int searchBitonic(int arr[], int n, int key, int index) { } public static void main(String args[]) { - int arr[] = {-3, 3, 9, 8, 20, 17, 5, 3, 1}; + int arr[] = { -3, 3, 9, 8, 20, 17, 5, 3, 1 }; int key = 3; int n = arr.length; int l = 0; diff --git a/src/geeksforgeeks/BoatsToSave.java b/src/geeksforgeeks/BoatsToSave.java new file mode 100644 index 0000000..1b495a5 --- /dev/null +++ b/src/geeksforgeeks/BoatsToSave.java @@ -0,0 +1,25 @@ +package geeksforgeeks; +class BoatsToSave { + public int numRescueBoats(int[] people, int limit) { + if(people.length==0 || limit==0) return 0; + + Arrays.sort(people); + + int i=0; + int j=people.length-1; + int res=0; + while(i<=j){ + if(people[i]+people[j]<=limit){ + res++; + i++; + j--; + }else{ + res++; + j--;// neglecting people with more weight + } + + } + + return res; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/BuyAndSellStockAnytime.java b/src/geeksforgeeks/BuyAndSellStockAnytime.java new file mode 100644 index 0000000..a3a6e46 --- /dev/null +++ b/src/geeksforgeeks/BuyAndSellStockAnytime.java @@ -0,0 +1,23 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + */ +public class BuyAndSellStockAnytime { + + public int maxProfit(int[] prices) { + int total = 0; + for (int i = 0; i < prices.length - 1; i++) { + if (prices[i + 1] > prices[i]) { + total += prices[i + 1] - prices[i]; + } + } + return total; + } + + public static void main(String[] args) { + BuyAndSellStockAnytime stock = new BuyAndSellStockAnytime(); + int[] arr = { 7, 1, 5, 6, 4 }; + System.out.println(stock.maxProfit(arr)); + } +} diff --git a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java index 88c31ec..02e5d09 100644 --- a/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java +++ b/src/geeksforgeeks/BuyAndSellStockAtMostTwice.java @@ -4,51 +4,6 @@ * https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-twice/ */ class BuyAndSellStockAtMostTwice { - // { 2, 30, 15, 10, 8, 25, 80 }; - // 78,72,72,72,72,55 - // - static int maxProfit(int price[], int n) { - - int profit[] = new int[n]; - /* - * Get the maximum profit with only one transaction allowed. After this loop, - * profit[i] contains maximum profit from price[i..n-1] using at most one trans. - */ - int max_price = price[n - 1]; - for (int i = n - 2; i >= 0; i--) { - // max_price has maximum of price[i..n-1] - if (price[i] > max_price) - max_price = price[i]; - - // we can get profit[i] by taking maximum of: - // a) previous maximum, i.e., profit[i+1] - // b) profit by buying at price[i] and selling at - // max_price - profit[i] = Math.max(profit[i + 1], max_price - price[i]); - } - - /* - * Get the maximum profit with two transactions allowed After this loop, - * profit[n-1] contains the result - */ - int min_price = price[0]; - for (int i = 1; i < n; i++) { - // min_price is minimum price in price[0..i] - if (price[i] < min_price) - min_price = price[i]; - - // Maximum profit is maximum of: - // a) previous maximum, i.e., profit[i-1] - // b) (Buy, Sell) at (min_price, price[i]) and add - // profit of other trans. stored in profit[i] - profit[i] = Math.max(profit[i - 1], profit[i] + (price[i] - min_price)); - - //1->28+72 - // - - } - return profit[n - 1]; - } public static void main(String args[]) { int price[] = { 2, 30, 15, 10, 8, 25, 80 }; @@ -56,4 +11,40 @@ public static void main(String args[]) { System.out.println("Maximum Profit = " + maxProfit(price, n)); } + /** + * the idea is when we find a profit which is from + * i to n, we can break it in to i to k, k+1 to n + * in this manner at each point we can calculate profit from + * (left min element to current element) and (current element to right max element) + * the second part of the above eq can be acieved by coming from right to left + * for input [3,3,5,0,0,3,1,4] + * profit from l->r [0,0,2,2,2,3,3,4] + * profit from r->l [4,4,4,4,4,3,3,0] + * this simply states that at index 2 if we come from left the profit is 2 + * and we can initiate another transaction to obtain another profit + */ + public int maxProfit(int[] prices) { + int ans = 0; + if (prices.length == 0 || prices.length == 1) + return ans; + int[] p = new int[prices.length]; + int minBuy = prices[0]; + int maxProfit = 0; + for (int i=1;i=0;i--) { + maxSell = Math.max(maxSell, prices[i]); + maxProfit = Math.max(maxProfit, maxSell - prices[i]); + p[i] += maxProfit; + ans = Math.max(p[i], ans); + } + return ans; + } + } diff --git a/src/geeksforgeeks/Candy.java b/src/geeksforgeeks/Candy.java index 2bf6b7d..8405771 100644 --- a/src/geeksforgeeks/Candy.java +++ b/src/geeksforgeeks/Candy.java @@ -4,29 +4,43 @@ /** * https://www.hackerrank.com/challenges/candies/problem + * Alice wants to give at least 1 candy to each child. + * If two children sit next to each other, then + * the one with the higher rating must get more candies than neighbour (left and right). + * Alice wants to minimize the total number of candies she must buy. + +For example, assume her students' ratings are [4, 6, 4, 5, 6, 2]. +She gives the students candy in the following minimal amounts: [1, 2, 1, 2, 3, 1]. She must buy a minimum of 10 candies. */ class Candy { // 2, 4, 2, 6, 1, 7, 8, 3, 2, 1 // 1, 2, 1, 2, 1, 2, 3, 1, 1, 1 - // 1,2,4,3,2,1 + // 1, 2, 4, 3, 2, 1 int candy(int[] ratings) { int size = ratings.length; - if (size <= 1) + if (size <= 1) { return size; + } + // ideally we should maintain 2 arrays 1)L->R 2) R->L + // then iterate both and check max b/w 2 items as result for each index + // we optimise it further for extra space and for loop int[] num = new int[size]; Arrays.fill(num, 1); - // left to righ + // left to right for (int i = 1; i < size; i++) { - if (ratings[i] > ratings[i - 1]) + if (ratings[i] > ratings[i - 1]) { num[i] = num[i - 1] + 1; + } } // right to left for (int i = size - 1; i > 0; i--) { - if (ratings[i - 1] > ratings[i]) + if (ratings[i - 1] > ratings[i]) { + // check curr index + 1 or existing value num[i - 1] = Math.max(num[i] + 1, num[i - 1]); + } } int result = 0; for (int i = 0; i < size; i++) { @@ -38,7 +52,7 @@ int candy(int[] ratings) { public static void main(String[] args) { Candy candy = new Candy(); - int[] ratings = {2, 4, 2, 6, 1, 7, 8, 9, 2, 1}; + int[] ratings = { 2, 4, 2, 6, 1, 7, 8, 9, 2, 1 }; System.out.println(candy.candy(ratings)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/CelebrityProblem.java b/src/geeksforgeeks/CelebrityProblem.java new file mode 100644 index 0000000..01ac872 --- /dev/null +++ b/src/geeksforgeeks/CelebrityProblem.java @@ -0,0 +1,29 @@ +package geeksforgeeks; + +public class CelebrityProblem { + /** + * @param n a party with n people + * + * @return the celebrity's label or -1 + */ + public int findCelebrity(int n) { + int candidate = 0; + for (int i = 1; i < n; i++) { + if (knows(candidate, i)) { + candidate = i; + } + } + + for (int i = 0; i < n; i++) { + if (i != candidate && (knows(candidate, i) || !knows(i, candidate))) { + return -1; + } + } + + return candidate; + } + + public boolean knows(int candidate, int i) { + return false; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/CheckPalindromePermutation.java b/src/geeksforgeeks/CheckPalindromePermutation.java new file mode 100644 index 0000000..cd68680 --- /dev/null +++ b/src/geeksforgeeks/CheckPalindromePermutation.java @@ -0,0 +1,32 @@ +package geeksforgeeks; + +/** + * Given a string, determine if a permutation of the string could form a palindrome. + * Input: "code" + * Output: false + * Input: "carerac" + Output: true + */ +public class CheckPalindromePermutation { + // If a string with an even length is a palindrome, every character in the string must always occur an even number of times. + // If the string with an odd length is a palindrome, every character except one of the characters must always occur an even number of times. + // Thus, in case of a palindrome, the number of characters with odd number of occurrences can't exceed 1 + + public boolean canPermutePalindrome(String s) { + if(s==null || s.length()==0) return false; + int[] cache= new int[128]; + + for(char ch: s.toCharArray()){ + cache[ch]++; + } + + int oddCOunt=0; + + for(int i=0;i<128;i++){ + oddCOunt+= cache[i]%2; + if(oddCOunt>1) return false; + } + + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/CheckPermutationContains.java b/src/geeksforgeeks/CheckPermutationContains.java new file mode 100644 index 0000000..84699aa --- /dev/null +++ b/src/geeksforgeeks/CheckPermutationContains.java @@ -0,0 +1,42 @@ +package geeksforgeeks; + +/** + * Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. + * In other words, one of the first string's permutations is the substring of the second string. + * Input:s1= "ab" s2 = "eidboaoo" + Output: False + */ +public class CheckPermutationContains { + + // How do we know string p is a permutation of string s? Easy, each character in p is in s too. + // So we can abstract all permutation strings of s to a map (Character -> Count). i.e. abba -> {a:2, b:2}. + // Since there are only 26 lower case letters in this problem, we can just use an array to represent the map. + // How do we know string s2 contains a permutation of s1? We just need to create a sliding window with length of s1, move from beginning to the end of s2. + // When a character moves in from right of the window, we subtract 1 to that character count from the map. + // When a character moves out from left of the window, we add 1 to that character count. + // So once we see all zeros in the map, meaning equal numbers of every characters between s1 and the substring in the sliding window, we know the answer is true. + public boolean checkInclusion(String s1, String s2) { + if(s1.length()==0 || s2.length()==0) return false; + int[] cache= new int[26]; + for(char s: s1.toCharArray()){ + cache[s-'a']++; + } + + int right=0; + + while(right=s1.length()) cache[s2.charAt(right-s1.length())-'a']++; + if(allZero(cache)) return true; + right++; + } + return false; + } + + public boolean allZero(int[] cache){ + for(int i=0;i<26;i++){ + if(cache[i]>0) return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/CloneGraph.java b/src/geeksforgeeks/CloneGraph.java new file mode 100644 index 0000000..4594889 --- /dev/null +++ b/src/geeksforgeeks/CloneGraph.java @@ -0,0 +1,53 @@ +package geeksforgeeks; +/* +// Definition for a Node. +class Node { + public int val; + public List neighbors; + + public Node() { + val = 0; + neighbors = new ArrayList(); + } + + public Node(int _val) { + val = _val; + neighbors = new ArrayList(); + } + + public Node(int _val, ArrayList _neighbors) { + val = _val; + neighbors = _neighbors; + } +} +*/ +class Solution { + public Node cloneGraph(Node node) { + if(node==null) return node; + + Map map= new HashMap<>(); + + Queue queue= new ArrayDeque<>(); + queue.offer(node); + map.put(node,new Node(node.val)); + + while(!queue.isEmpty()){ + Node current= queue.poll(); + + for(Node neighbors: current.neighbors){ + if(!map.containsKey(neighbors)){ + Node neighborClone= new Node(neighbors.val); + map.put(neighbors,neighborClone); + queue.offer(neighbors); + } + + map.get(current).neighbors.add(map.get(neighbors)); + } + } + + return map.get(node); + + } + + +} \ No newline at end of file diff --git a/src/geeksforgeeks/ClosestNumbers.java b/src/geeksforgeeks/ClosestNumbers.java index e9f4efc..ae55108 100644 --- a/src/geeksforgeeks/ClosestNumbers.java +++ b/src/geeksforgeeks/ClosestNumbers.java @@ -6,28 +6,42 @@ /** * https://www.geeksforgeeks.org/closest-numbers-list-unsorted-integers/ + * Given a list of distinct unsorted integers, + * find the pair of elements that have the smallest absolute difference between them? + * If there are multiple pairs, find them all. + * Input : arr[] = {10, 50, 12, 100} +Output : (10, 12) +The closest elements are 10 and 12 + +Input : arr[] = {5, 4, 3, 2} +Output : (2, 3), (3, 4), (4, 5) */ public class ClosestNumbers { public static void main(String[] args) { //10, 50, 12, 100 - int[] arr = new int[]{5, 4, 3, 2}; + int[] arr = new int[] { 10, 50, 12, 100 }; + int n = arr.length; + if (n <= 1) { + return; + } + + // Sort array elements Arrays.sort(arr); - Map map = new HashMap<>(); + // Compare differences of adjacent + // pairs to find the minimum difference. + int minDiff = arr[1] - arr[0]; + for (int i = 2; i < n; i++) + minDiff = Math.min(minDiff, arr[i] - arr[i - 1]); - for (int i = 0; i < arr.length - 1; i++) { - map.put(arr[i] + "-" + arr[i + 1], arr[i + 1] - arr[i]); - } - int min = arr[1] - arr[0]; - for (Map.Entry m : map.entrySet()) { - if (min > m.getValue()) - min = m.getValue(); - } - - for (Map.Entry ma : map.entrySet()) { - if (ma.getValue().equals(min)) - System.out.println(ma.getKey()); + // Traverse array again and print all pairs + // with difference as minDiff. + for (int i = 1; i < n; i++) { + if ((arr[i] - arr[i - 1]) == minDiff) { + System.out.print("(" + arr[i - 1] + ", " + arr[i] + "),"); + } } } + } diff --git a/src/geeksforgeeks/CombinationIterator.java b/src/geeksforgeeks/CombinationIterator.java new file mode 100644 index 0000000..05a9095 --- /dev/null +++ b/src/geeksforgeeks/CombinationIterator.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +// CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator. + +// iterator.next(); // returns "ab" +// iterator.hasNext(); // returns true +// iterator.next(); // returns "ac" +// iterator.hasNext(); // returns true +// iterator.next(); // returns "bc" +// iterator.hasNext(); // returns false +public class CombinationIterator { + Deque deque; + boolean[] visited; + public CombinationIterator(String characters, int combinationLength) { + deque= new ArrayDeque<>(); + visited= new boolean[characters.length()]; + generateCombinations(characters,deque, new StringBuilder(), combinationLength, 0, visited); + } + + public String next() { + if(hasNext()) return deque.poll(); + + return ""; + } + + public boolean hasNext() { + return !deque.isEmpty(); + } + + public void generateCombinations(String characters, Deque deque,StringBuilder sb, int limit, int start, boolean[] visited){ + + if(sb.length()==limit){ + deque.offer(new String(sb.toString())); + return; + } + + for(int i=start; i end) return null; + + TreeNode node = new TreeNode(preorder[start]); + int i; + for(i=start;i<=end;i++) { + if(preorder[i] > node.val) + break; + } + + node.left = helper(preorder, start+1, i-1); + node.right = helper(preorder, i, end); + return node; + + + + } public static TreeNode bstFromPreorder(int[] preorder) { if (preorder == null || preorder.length == 0) { @@ -17,6 +41,7 @@ public static TreeNode bstFromPreorder(int[] preorder) { Stack stack = new Stack<>(); TreeNode root = new TreeNode(preorder[0]); stack.push(root); + //8, 3, 1, 6, 4, 7, 10, 14, 13 for (int i = 1; i < preorder.length; i++) { TreeNode node = new TreeNode(preorder[i]); if (preorder[i] < stack.peek().val) { diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java new file mode 100644 index 0000000..cf7aed9 --- /dev/null +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPostorder.java @@ -0,0 +1,28 @@ +package geeksforgeeks; + +public class ConstructTreeFromInorderAndPostorder { + // idea is same as iorder preorder, but we take postOrder[lastIndex] as root; + public TreeNode buildTree(int[] inorder, int[] postorder) { + if(inorder==null || postorder==null) return null; + Map map= new HashMap(); + for(int i=0;i map){ + if(iStart>iEnd || ps>pe) return null; + + TreeNode root= new TreeNode(postorder[pend]); + int divider=map.get(root.val); + // one more change is, since we need to take last element as root + // we have to carefully pass the right index to recursive calls + // pstart, pstart+divider-iStart-1-> left subarray + //pstart+divider-iStart, pend -> right sub array + root.left= helperFn(inorder, iStart,divider-1,postorder,pstart,pstart+divider-iStart-1,map); + root.right=helperFn(inorder,divider+1,iEnd,postorder,pstart+divider-iStart,pend-1,map); + return root; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java new file mode 100644 index 0000000..1a1694c --- /dev/null +++ b/src/geeksforgeeks/ConstructTreeFromInorderAndPreorder.java @@ -0,0 +1,48 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + */ +class ConstructTreeFromInorderAndPreorder { + + // The basic idea is here: + // Say we have 2 arrays, PRE and IN. + // Preorder traversing implies that PRE[0] is the root node. + // Then we can find this PRE[0] in IN, say it's IN[5]. + // Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left + // side, IN[6] to the end is on the right side. + // Recursively doing this on subarrays, we can build a tree out of it :) + public TreeNode buildTree(int[] preorder, int[] inorder) { + Map map = new HashMap<>(); + List set = new LinkedList<>(); + + for (int i = 0; i < inorder.length; i++) { + map.put(inorder[i], i); + } + + for (int i = 0; i < preorder.length; i++) { + set.add(preorder[i]); + } + + return buildTreeUtil(map, set, 0, inorder.length - 1); + + } + + public TreeNode buildTreeUtil(Map map, List set, int start, int end) { + if (start > end) + return null; + if (set.isEmpty()) + return null; + int rootval = set.get(0); + set.remove(0); + TreeNode root = new TreeNode(rootval); + int inorderIndex = map.get(rootval); + root.left = buildTreeUtil(map, set, start, inorderIndex - 1); + root.right = buildTreeUtil(map, set, inorderIndex + 1, end); + return root; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ContainerWithMostWater.java b/src/geeksforgeeks/ContainerWithMostWater.java new file mode 100644 index 0000000..5bc747c --- /dev/null +++ b/src/geeksforgeeks/ContainerWithMostWater.java @@ -0,0 +1,36 @@ +package geeksforgeeks; + +/** + * Given n non-negative integers a1, a2, ..., an , + * where each represents a point at coordinate (i, ai). + * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). + * Find two lines, which together with x-axis forms a container, such that the container contains the most water. + + Note: You may not slant the container and n is at least 2. + Input: [1,8,6,2,5,4,8,3,7] + Output: 49 + */ +public class ContainerWithMostWater { + + public int maxArea(int[] height) { + if(height==null || height.length==0) return 0; + int i=0; + int j= height.length-1; + int result=0; + + while(iheight[j]){ // the reason we are moving lesser side is + // j-i is going to be decreasing so we need to + // maintain higher side to have max value + j--; + }else{ + i++; + } + } + return result; + } +} diff --git a/src/geeksforgeeks/ConvertXToY.java b/src/geeksforgeeks/ConvertXToY.java new file mode 100644 index 0000000..7b0f137 --- /dev/null +++ b/src/geeksforgeeks/ConvertXToY.java @@ -0,0 +1,69 @@ +package geeksforgeeks; +// Java program to find minimum +// number of steps needed to +// convert a number x into y +// with two operations allowed : +// (1) multiplication with 2 +// (2) subtraction with 1. + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + +/** + * https://www.geeksforgeeks.org/minimum-number-operation-required-convert-number-x-y/ + */ + +public class ConvertXToY { + + private static int minOperations(int src, int target) { + + Set visited = new HashSet<>(); + LinkedList queue = new LinkedList<>(); + + Steps node = new Steps(src, 0); + + queue.offer(node); + visited.add(node); + + while (!queue.isEmpty()) { + Steps temp = queue.poll(); + visited.add(temp); + + if (temp.val == target) { + return temp.steps; + } + + int mul = temp.val * 2; + int sub = temp.val - 1; + + // given constraints + if (mul > 0 && mul < 1000) { + Steps nodeMul = new Steps(mul, temp.steps + 1); + queue.offer(nodeMul); + } + if (sub > 0 && sub < 1000) { + Steps nodeSub = new Steps(sub, temp.steps + 1); + queue.offer(nodeSub); + } + } + return -1; + } + + public static void main(String[] args) { + // int x = 2, y = 5; + int x = 4, y = 7; + Steps src = new Steps(x, y); + System.out.println(minOperations(x, y)); + } +} + +class Steps { + int val; + int steps; + + public Steps(int val, int steps) { + this.val = val; + this.steps = steps; + } +} diff --git a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java b/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java index dd13894..8d99fea 100644 --- a/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java +++ b/src/geeksforgeeks/CountAllPathsFrom2DMatrix.java @@ -3,7 +3,7 @@ /*https://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/*/ class CountAllPathsFrom2DMatrix { // A Java program to count all possible paths -// from top left to bottom right + // from top left to bottom right // Returns count of possible paths to reach // cell at row number m and column number n from // the topmost leftmost cell (cell at 1, 1) @@ -13,7 +13,7 @@ static int numberOfPaths(int m, int n) { int count[][] = new int[m][n]; // Count of paths to reach any cell in - // first column is 1 + // first row is 1 for (int i = 0; i < m; i++) count[i][0] = 1; diff --git a/src/geeksforgeeks/CountAndSay.java b/src/geeksforgeeks/CountAndSay.java new file mode 100644 index 0000000..b420233 --- /dev/null +++ b/src/geeksforgeeks/CountAndSay.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + + +/** + * https://leetcode.com/problems/count-and-say/ + */ +public class CountAndSay { + public String countAndSay(int n) { + if (n <= 0) { + return "-1"; + } + String result = "1"; + + for (int i = 1; i < n; i++) { + result = build(result); + } + return result; + } + + private String build(String result) { + StringBuilder builder = new StringBuilder(); + int p = 0; + while (p < result.length()) { + char val = result.charAt(p); + int count = 0; + + while (p < result.length() && result.charAt(p) == val) { // note that p and val will be same in first run, to count single instance + p++; + count++; + } + builder.append(String.valueOf(count)); + builder.append(val); + } + return builder.toString(); + } + + public static void main(String[] args) { + CountAndSay countAndSay = new CountAndSay(); + System.out.println(countAndSay.countAndSay(4)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/CountDistinctKSubString.java b/src/geeksforgeeks/CountDistinctKSubString.java deleted file mode 100644 index 57ab9ab..0000000 --- a/src/geeksforgeeks/CountDistinctKSubString.java +++ /dev/null @@ -1,44 +0,0 @@ -package geeksforgeeks; - -// Java program to CountKSubStr number of substrings -// with exactly distinct characters in a given string - -import java.util.Arrays; - -/*https://www.geeksforgeeks.org/count-number-of-substrings-with-exactly-k-distinct-characters/*/ -public class CountDistinctKSubString { - - private int countKDist(String str, int k) { - - int result = 0; - - int n = str.length(); - - int count[] = new int[26]; - - for (int i = 0; i < n; i++) { - int distinctCount = 0; - - Arrays.fill(count, 0); - - for (int j = i; j < n; j++) { - - if (count[str.charAt(j) - 'a'] == 0) - distinctCount++; - - count[str.charAt(j) - 'a']++; - - if (distinctCount == k) - result++; - } - } - return result; - } - - public static void main(String[] args) { - CountDistinctKSubString ob = new CountDistinctKSubString(); - String ch = "pqpqs"; - int k = 2; - System.out.println("Total substrings with exactly " + k + " distinct characters : " + ob.countKDist(ch, k)); - } -} diff --git a/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java b/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java index b36b8fa..9b0310a 100644 --- a/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java +++ b/src/geeksforgeeks/CountMinimumStepsToFormDesiredInputArray.java @@ -4,7 +4,7 @@ /*https://www.geeksforgeeks.org/count-minimum-steps-get-given-desired-array/*/ // unsolved class CountMinimumStepsToFormDesiredInputArray { - static int arr[] = new int[]{16, 16, 16}; + static int arr[] = new int[] { 16, 16, 16 }; // Returns count of minimum operations to covert a // zero array to arr array with increment and @@ -25,17 +25,20 @@ static int countMinOperations(int n) { int i; // To find first odd element for (i = 0; i < n; i++) { // If odd number found - if (arr[i] % 2 == 1) + if (arr[i] % 2 == 1) { break; + } - // If 0, then increment zero_count - else if (arr[i] == 0) + // If 0, then increment zero_count + else if (arr[i] == 0) { zero_count++; + } } // All numbers are 0 - if (zero_count == n) + if (zero_count == n) { return result; + } // All numbers are even if (i == n) { @@ -59,9 +62,9 @@ else if (arr[i] == 0) public static void main(String[] args) { - System.out.println("Minimum number of steps required to \n" + - "get the given target array is " + - countMinOperations(arr.length)); + System.out.println( + "Minimum number of steps required to \n" + "get the given target array is " + countMinOperations( + arr.length)); } } diff --git a/src/geeksforgeeks/CountNumbersLessThanSelf.java b/src/geeksforgeeks/CountNumbersLessThanSelf.java new file mode 100644 index 0000000..447f314 --- /dev/null +++ b/src/geeksforgeeks/CountNumbersLessThanSelf.java @@ -0,0 +1,103 @@ +package geeksforgeeks; + +import java.util.LinkedList; +import java.util.List; + +/** + * You are given an integer array nums and you have to return a new counts array. + * The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. + * Input: [5,2,6,1] + * Output: [2,1,1,0] + */ +class CountNumbersLessThanSelf { + // Wrapper class for each and every value of the input array, +// to store the original index position of each value, before we merge sort the array + private class ArrayValWithOrigIdx { + int val; + int originalIdx; + + public ArrayValWithOrigIdx(int val, int originalIdx) { + this.val = val; + this.originalIdx = originalIdx; + } + } + + public List countSmaller(int[] nums) { + if (nums == null || nums.length == 0) return new LinkedList(); + int n = nums.length; + int[] result = new int[n]; + + ArrayValWithOrigIdx[] newNums = new ArrayValWithOrigIdx[n]; + for (int i = 0; i < n; ++i) newNums[i] = new ArrayValWithOrigIdx(nums[i], i); + + mergeSortAndCount(newNums, 0, n - 1, result); + + // notice we don't care about the sorted array after merge sort finishes. + // we only wanted the result counts, generated by running merge sort + List resultList = new LinkedList(); + for (int i : result) resultList.add(i); + return resultList; + } + + private void mergeSortAndCount(ArrayValWithOrigIdx[] nums, int start, int end, int[] result) { + if (start >= end) return; + + int mid = (start + end) / 2; + mergeSortAndCount(nums, start, mid, result); + mergeSortAndCount(nums, mid + 1, end, result); + + // left subarray start...mid + // right subarray mid+1...end + int leftPos = start; + int rightPos = mid + 1; + LinkedList merged = new LinkedList(); + int numElemsRightArrayLessThanLeftArray = 0; + while (leftPos < mid + 1 && rightPos <= end) { + if (nums[leftPos].val > nums[rightPos].val) { + // this code block is exactly what the problem is asking us for: + // a number from the right side of the original input array, is smaller + // than a number from the left side + // + // within this code block, + // nums[rightPos] is smaller than the start of the left sub-array. + // Since left sub-array is already sorted, + // nums[rightPos] must also be smaller than the entire remaining left sub-array + ++numElemsRightArrayLessThanLeftArray; + + // continue with normal merge sort, merge + merged.add(nums[rightPos]); + ++rightPos; + } else { + // a number from left side of array, is smaller than a number from + // right side of array + result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + + // Continue with normal merge sort + merged.add(nums[leftPos]); + ++leftPos; + } + } + + // part of normal merge sort, if either left or right sub-array is not empty, + // move all remaining elements into merged result + while (leftPos < mid + 1) { + result[nums[leftPos].originalIdx] += numElemsRightArrayLessThanLeftArray; + + merged.add(nums[leftPos]); + ++leftPos; + } + while (rightPos <= end) { + merged.add(nums[rightPos]); + ++rightPos; + } + + // part of normal merge sort + // copy back merged result into array + int pos = start; + for (ArrayValWithOrigIdx m : merged) { + nums[pos] = m; + ++pos; + } + } +} + diff --git a/src/geeksforgeeks/CountingInversion.java b/src/geeksforgeeks/CountingInversion.java index b381ec3..b9b678b 100644 --- a/src/geeksforgeeks/CountingInversion.java +++ b/src/geeksforgeeks/CountingInversion.java @@ -2,58 +2,61 @@ /** * https://www.geeksforgeeks.org/counting-inversions/ - * */ class CountingInversion { - static int mergeSort(int[] arr, int arrSize) { - int[] temp = new int[arrSize]; - return mergeSort(arr, temp, 0, arrSize - 1); - } - - static int mergeSort(int[] arr, int[] temp, int left, int right) { - int mid; - int invCount = 0; - if (left < right) { - mid = ((right - left) / 2) + left; - - invCount = mergeSort(arr, temp, left, mid); - invCount += mergeSort(arr, temp, mid + 1, right); - - invCount += merge(arr, temp, left, mid + 1, right); - } - return invCount; - } - - static int merge(int[] arr, int[] temp, int left, int mid, int right) { - int invCount = 0; - - int i = left; - int j = mid; - int k = left; - while ((i <= mid - 1) && (j <= right)) { - if (arr[i] <= arr[j]) { - temp[k++] = arr[i++]; - } else { - temp[k++] = arr[j++]; - - invCount = invCount + (mid - i); - } - } - - while (i <= mid - 1) - temp[k++] = arr[i++]; - while (j <= right) - temp[k++] = arr[j++]; - - for (i = left; i <= right; i++) - arr[i] = temp[i]; - - return invCount; - } - - public static void main(String[] args) { - int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; - System.out.println("Number of inversions are " + mergeSort(arr, arr.length)); - } + static int mergeSort(int[] arr, int arrSize) { + int[] temp = new int[arrSize]; + return mergeSort(arr, temp, 0, arrSize - 1); + } + + static int mergeSort(int[] arr, int[] temp, int left, int right) { + int mid; + int invCount = 0; + if (left < right) { + mid = ((right - left) / 2) + left; + + invCount = mergeSort(arr, temp, left, mid); + invCount += mergeSort(arr, temp, mid + 1, right); + + invCount += merge(arr, temp, left, mid + 1, right); + } + return invCount; + } + + static int merge(int[] arr, int[] temp, int left, int mid, int right) { + int invCount = 0; + + int i = left; + int j = mid; + int k = left; + while ((i <= mid - 1) && (j <= right)) { + if (arr[i] <= arr[j]) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + // the reason to put mid-i is take example of [1,3,5] [2,4,6] + // left is 0 and right is mid at start + // when i=1 and j=0 (value 3 and 2) we see an inversion, since + // the first part is sorted and values after i=1(3) will be greater than j=0(2) + // so we consider all elements after 3 as inversions + invCount = invCount + (mid - i); + } + } + + while (i <= mid - 1) + temp[k++] = arr[i++]; + while (j <= right) + temp[k++] = arr[j++]; + + for (i = left; i <= right; i++) + arr[i] = temp[i]; + + return invCount; + } + + public static void main(String[] args) { + int arr[] = new int[] { 4, 6, 2, 1, 9, 7 }; + System.out.println("Number of inversions are " + mergeSort(arr, arr.length)); + } } diff --git a/src/geeksforgeeks/CourseSchedule.java b/src/geeksforgeeks/CourseSchedule.java new file mode 100644 index 0000000..19d6167 --- /dev/null +++ b/src/geeksforgeeks/CourseSchedule.java @@ -0,0 +1,116 @@ +package geeksforgeeks; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; +/** + * Input: numCourses = 2, prerequisites = [[1,0]] +Output: true +Explanation: There are a total of 2 courses to take. +To take course 1 you should have finished course 0. So it is possible. + +Input: numCourses = 2, prerequisites = [[1,0],[0,1]] +Output: false +Explanation: There are a total of 2 courses to take. + To take course 1 you should have finished course 0, and to take course 0 you should + also have finished course 1. So it is impossible. + */ +class CourseSchedule { + public boolean canFinish(int numCourses, int[][] prerequisites) { + + Map> map = new HashMap<>(); // Courses that depend on the key + int[] degrees = new int[numCourses]; // # of prerequisites for course i + Queue queue = new ArrayDeque<>(); // Used to find dependants and decrease their outdegree + + for (int[] pre : prerequisites) { + List tempList = map.getOrDefault(pre[1], new ArrayList<>()); + tempList.add(pre[0]); + degrees[pre[0]]++; + map.put(pre[1], tempList); + } + + for (int i = 0; i < degrees.length; i++) { + if (degrees[i] == 0) { + queue.offer(i); + } + } + + int count = 0; + while (!queue.isEmpty()) { + int temp = queue.poll(); + if (degrees[temp] == 0) { + count++; // if cond for duplicates + } + if (!map.containsKey(temp)) { + continue; + } + for (int i : map.get(temp)) { + if (--degrees[i] == 0) { + queue.offer(i); + } + } + } + + return count == numCourses; + } + + public boolean canFinishDFS(int numCourses, int[][] prerequisites) { + // this method basically finds a back-edge between nodes + // backedge is when doing a node(A)'s dfs, it puts A to a temp state + // while traversing A's child, if any of child dosen't have anymore child it's marked as completed + // if there are children it put's the current child to temp state and visits it's children + // so when doing a dfs for a node if it encounters a temp state node rather than completed node + // then that means there's a cycle we cannot complete the course + // (T) A \ + // / / + // (T) B / + // / \ / + // (Co) C D (T) while doing DFS for D's components we encounter A, but A is still in temp state + // + ArrayList[] adjList= new ArrayList[numCourses]; + for(int i=0;i(); + } + for(int[] preReq:prerequisites){ + adjList[preReq[0]].add(preReq[1]); + } + // this visited array will maintain 3 values 0,1 and 2 + // 0-unvisited, 1-being visited and 2 visited + int[] visited= new int[numCourses]; + for(int i=0;i[] adjList, int[] visited, int vertex){ + if(visited[vertex]==1) return false; // when a node comes with being visited state, we fail it + visited[vertex]=1; + for(int adj: adjList[vertex]){ + if(!dfs(adjList, visited, adj)) return false; + } + visited[vertex]=2; // finally we set visited to true + return true; + } + // this is to get the order of course as output + public boolean dfs( List[] adjList, int[] visited, Listresult, int node){ + if(visited[node]==1) return false; + if(visited[node]==2) return true; + + visited[node]=1; + for(int adj: adjList[node]){ + if(!dfs(adjList, visited, result, adj)){ + return false; + } + } + visited[node]=2; + result.add(node); // this will keep track of which to fininsh first and last + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/DecodeString.java b/src/geeksforgeeks/DecodeString.java new file mode 100644 index 0000000..4340ebd --- /dev/null +++ b/src/geeksforgeeks/DecodeString.java @@ -0,0 +1,49 @@ +package geeksforgeeks; + +import java.util.ArrayDeque; +import java.util.Deque; + +// s = "3[a2[c]]", return "accaccacc". +// s = "2[abc]3[cd]ef", return "abcabccdcdcdef". +public class DecodeString { + public String decodeString(String s) { + if (s == null) + return ""; + + Deque count = new ArrayDeque<>(); + Deque result = new ArrayDeque<>(); + int start = 0; + StringBuilder tempResult = new StringBuilder(); + while (start < s.length()) { + // whenever we see number, we push to count queue + if (Character.isDigit(s.charAt(start))) { + int num = 0; + while (Character.isDigit(s.charAt(start))) { + num = num * 10 + s.charAt(start) - '0'; + start++; + } + count.push(num); + } else if (s.charAt(start) == '[') { + // whenever we see a open brace we push the string we have to result queue + result.push(tempResult.toString()); + tempResult = new StringBuilder(); + start++; + } else if (s.charAt(start) == ']') { + // whenever a closing brace comes, we pop the last seen count and last seen string + // and replicate that string and stores in temp result + StringBuilder sb = new StringBuilder(result.pop()); + int tempCount = count.pop(); + for (int i = 0; i < tempCount; i++) { + sb.append(tempResult); + } + tempResult = sb; + start++; + } else { + // whenever we see a char, we push to result string + tempResult.append(s.charAt(start++)); + } + } + + return tempResult.toString(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/DesignTicTacToe.java b/src/geeksforgeeks/DesignTicTacToe.java new file mode 100644 index 0000000..c0c16a0 --- /dev/null +++ b/src/geeksforgeeks/DesignTicTacToe.java @@ -0,0 +1,107 @@ +package geeksforgeeks; +/* +Design a Tic-tac-toe game that is played between two players on a n x n grid. + +You may assume the following rules: + +A move is guaranteed to be valid and is placed on an empty block. +Once a winning condition is reached, no more moves is allowed. +A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. + +Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. + +TicTacToe toe = new TicTacToe(3); + +toe.move(0, 0, 1); -> Returns 0 (no one wins) +|X| | | +| | | | // Player 1 makes a move at (0, 0). +| | | | + +toe.move(0, 2, 2); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 2 makes a move at (0, 2). +| | | | + +toe.move(2, 2, 1); -> Returns 0 (no one wins) +|X| |O| +| | | | // Player 1 makes a move at (2, 2). +| | |X| + +toe.move(1, 1, 2); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 2 makes a move at (1, 1). +| | |X| + +toe.move(2, 0, 1); -> Returns 0 (no one wins) +|X| |O| +| |O| | // Player 1 makes a move at (2, 0). +|X| |X| + +toe.move(1, 0, 2); -> Returns 0 (no one wins) +|X| |O| +|O|O| | // Player 2 makes a move at (1, 0). +|X| |X| + +toe.move(2, 1, 1); -> Returns 1 (player 1 wins) +|X| |O| +|O|O| | // Player 1 makes a move at (2, 1). +|X|X|X| + */ +public class DesignTicTacToe { + private int[] rows; + private int[] cols; + private int diagonal; + private int antiDiagonal; + + /** Initialize your data structure here. */ + public DesignTicTacToe(int n) { + rows = new int[n]; + cols = new int[n]; + } + + /** Player {player} makes a move at ({row}, {col}). + @param row The row of the board. + @param col The column of the board. + @param player The player, can be either 1 or 2. + @return The current winning condition, can be either: + 0: No one wins. + 1: Player 1 wins. + 2: Player 2 wins. */ + public int move(int row, int col, int player) { + int toAdd = player == 1 ? 1 : -1; + // if A player makes a move on 0,0 we are going to increment index posistion of row and col at 0,0 + // if B player makes a move on 0,2 we are going to decrement index posistion at row and col at 0,2 + // after that the count of row at 0 will be 0(balanced moves) like wise if a row or col has value n only + // a player can be adjudged a winner + rows[row] += toAdd; + cols[col] += toAdd; + if (row == col) { + diagonal += toAdd; + } + + if (col + row == cols.length - 1) { + antiDiagonal += toAdd; + } + + int size = rows.length; + if (Math.abs(rows[row]) == size || + Math.abs(cols[col]) == size || + Math.abs(diagonal) == size || + Math.abs(antiDiagonal) == size) { + return player; + } + + return 0; + } + + public static void main(String[] args) { + DesignTicTacToe toe=new DesignTicTacToe(3); + toe.move(0, 0, 1); + toe.move(0, 2, 2); + toe.move(2, 2, 1); + toe.move(1, 1, 2); + toe.move(2, 0, 1); + toe.move(1, 0, 2); + toe.move(2, 1, 1); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/DivideSubArrayAverage.java b/src/geeksforgeeks/DivideSubArrayAverage.java index 72ee60e..dfdfa0f 100644 --- a/src/geeksforgeeks/DivideSubArrayAverage.java +++ b/src/geeksforgeeks/DivideSubArrayAverage.java @@ -29,7 +29,7 @@ static void findSubarrays(int arr[], int n) { } public static void main(String[] args) { - int[] arr = {1, 5, 7, 2, 0}; + int[] arr = { 1, 5, 7, 2, 0 }; int n = arr.length; findSubarrays(arr, n); } diff --git a/src/geeksforgeeks/DungeonGame.java b/src/geeksforgeeks/DungeonGame.java new file mode 100644 index 0000000..7537453 --- /dev/null +++ b/src/geeksforgeeks/DungeonGame.java @@ -0,0 +1,64 @@ +package geeksforgeeks; + +// The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. +//The dungeon consists of M x N rooms laid out in a 2D grid. +//Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. + +// The knight has an initial health point represented by a positive integer. +//If at any point his health point drops to 0 or below, he dies immediately. +//Input +// |-2 -3 3 | +// |-5 -10 1 | +// |10 30 -5 | + +//output 7 + +// the trick here is to go bottom up, start from the last cell, +// inorder to reach there he should have atleast 6 as health, so that +// when he reaches -5(energy is consumed) and he's left with +1 health +// likewise if we backtrack from end to start, we'll need +7 as min initial health to +// play the game +public class DungeonGame { + public int calculateMinimumHP(int[][] dungeon) { + + int[][] dp = new int[dungeon.length][dungeon[0].length]; + + int m = dungeon.length; + int n = dungeon[0].length; + + dp[m-1][n-1] = Math.max(1, 1-dungeon[m-1][n-1]); + + // Populate the last column + for(int i=m-2;i>=0;i--){ + dp[i][n-1] = Math.max(1, dp[i+1][n-1]-dungeon[i][n-1]); + } + + // Populate the last row + for(int i=n-2;i>=0;i--){ + dp[m-1][i] = Math.max(1, dp[m-1][i+1]-dungeon[m-1][i]); + } + + // to achieve the answer, we need to setup the last row and last column + // we know to reach last cell we need 6 as energy, let's say that comes + // from cell above it, that cell's original val is +1, so we must have + // 5 energy when we reach there and adding it up, it became 6 + // the reason to put 1 on last row is, the value in that cell is 30 + // so to reach last cell from that cell, we need only 6 energy(min) + // to have 6 from +30, player should have health of -24 and player cannot + // have neg val, so we put 1 as filler + // |* * 2 | + // |* * 5 | + // |1 1 6 | + + // Populate the rest by taking max of bottom and right (reverse of down and left) + + for(int i=m-2;i>=0;i--){ + for(int j=n-2;j>=0;j--){ + dp[i][j] = Math.max(1, Math.min(dp[i+1][j], dp[i][j+1])-dungeon[i][j]); + } + } + + + return dp[0][0]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/DutchNationalFlag.java b/src/geeksforgeeks/DutchNationalFlag.java new file mode 100644 index 0000000..74c3d4f --- /dev/null +++ b/src/geeksforgeeks/DutchNationalFlag.java @@ -0,0 +1,31 @@ +package geeksforgeeks; + +class DutchNationalFlag { + public void sortColors(int[] arr) { + if (arr.length == 0) { + return; + } + int pivot = 1; + int i = 0; + int j = arr.length - 1; + int zeroPos = 0; + while (i <= j) { + if (arr[i] > pivot) { + swap(arr, i, j); + j--; + } else if (arr[i] == pivot) { + i++; + } else { + swap(arr, zeroPos, i); + zeroPos++; + i++; + } + } + } + + public void swap(int[] arr, int i, int j) { + int temp = arr[j]; + arr[j] = arr[i]; + arr[i] = temp; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/EvaluvateExpressions.java b/src/geeksforgeeks/EvaluvateExpressions.java new file mode 100644 index 0000000..3086f9b --- /dev/null +++ b/src/geeksforgeeks/EvaluvateExpressions.java @@ -0,0 +1,59 @@ +package geeksforgeeks; + +// Given a string of numbers and operators, +// return all possible results from computing all the different possible ways to group numbers +// and operators. The valid operators are +, - and *. + +// Input: "2*3-4*5" +// Output: [-34, -14, -10, -10, 10] +// Explanation: +// (2*(3-(4*5))) = -34 +// ((2*3)-(4*5)) = -14 +// ((2*(3-4))*5) = -10 +// (2*((3-4)*5)) = -10 +// (((2*3)-4)*5) = 10 +public class EvaluvateExpressions { + public List diffWaysToCompute(String input) { + if(input==null) return Collections.emptyList(); + + Map> map= new HashMap<>(); + return bfsHelper(input, map); + + } + + public List bfsHelper(String input, Map> map){ + + if(map.containsKey(input)){ + return map.get(input); + } + + List result= new ArrayList<>(); + if(!input.contains("+") && !input.contains("-") && !input.contains("*")){ + result.add(Integer.parseInt(input)); + }else{ + // Split input string into two parts and solve them recursively + // for ex input = 2*3-4 output=2,-2 + // 2* | 3-4 => this right and left expression returns a list + // 2*3| -4 => this right and left expression returns another list + for(int i=0;i firstList= bfsHelper(input.substring(0,i),map); + List secondList= bfsHelper(input.substring(i+1),map); + for(int first: firstList){ + for(int second: secondList){ + if(input.charAt(i)=='+'){ + result.add(first+second); + }else if(input.charAt(i)=='-'){ + result.add(first-second); + }else{ + result.add(first*second); + } + } + } + } + } + } + map.put(input,result); + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/EvaluvateRPN.java b/src/geeksforgeeks/EvaluvateRPN.java new file mode 100644 index 0000000..6ea7f30 --- /dev/null +++ b/src/geeksforgeeks/EvaluvateRPN.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +// Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] +// Output: 22 +// Explanation: +// ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 +// = ((10 * (6 / (12 * -11))) + 17) + 5 +// = ((10 * (6 / -132)) + 17) + 5 +// = ((10 * 0) + 17) + 5 +// = (0 + 17) + 5 +// = 17 + 5 +// = 22 +public class EvaluvateRPN { + public int reversePolishNotation(String[] tokens) { + if(tokens==null && tokens.length==0) return 0; + Deque deque= new ArrayDeque<>(); + for(String i: tokens){ + if(i.length()==1 && "+*-/".contains(i)){ + Integer second= deque.removeFirst(); + Integer first= deque.removeFirst(); + //System.out.println(first +" - "+ second +" "+i); + switch(i){ + case "+": + deque.addFirst(first+second); + break; + case "-": + deque.addFirst(first-second); + break; + case "*": + deque.addFirst(first*second); + break; + case "/": + deque.addFirst(first/second); + break; + + } + }else{ + deque.addFirst(Integer.parseInt(i)); + } + } + + return deque.removeFirst(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/FileSystem.java b/src/geeksforgeeks/FileSystem.java new file mode 100644 index 0000000..09691c5 --- /dev/null +++ b/src/geeksforgeeks/FileSystem.java @@ -0,0 +1,80 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class FileSystem { + + class Trie { + boolean isfile = false; + HashMap files = new HashMap<>(); + String content = ""; + } + + Trie root; + + public FileSystem() { + root = new Trie(); + } + + public List ls(String path) { + Trie trie = root; + List files = new ArrayList<>(); + if (!path.equals("/")) { + String[] arr = path.split("/"); + for (int i = 1; i < arr.length; i++) { + trie = trie.files.get(arr[i]); + } + if (trie.isfile) { + files.add(arr[arr.length - 1]); + return files; + } + } + List res_files = new ArrayList<>(trie.files.keySet()); + Collections.sort(res_files); + return res_files; + } + + public void mkdir(String path) { + Trie trie = root; + String[] arr = path.split("/"); + for (int i = 1; i < arr.length; i++) { + if (!trie.files.containsKey(arr[i])) { + trie.files.put(arr[i], new Trie()); + } + trie = trie.files.get(arr[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Trie trie = root; + String[] arr = filePath.split("/"); + for (int i = 1; i < arr.length - 1; i++) { + trie = trie.files.get(arr[i]); + } + if (!trie.files.containsKey(arr[arr.length - 1])) { + trie.files.put(arr[arr.length - 1], new Trie()); + } + trie = trie.files.get(arr[arr.length - 1]); + trie.isfile = true; + trie.content = trie.content + content; + } + + public String readContentFromFile(String filePath) { + Trie trie = root; + String[] arr = filePath.split("/"); + for (int i = 1; i < arr.length - 1; i++) { + trie = trie.files.get(arr[i]); + } + return trie.files.get(arr[arr.length - 1]).content; + } +} + +/** + * Your FileSystem object will be instantiated and called as such: FileSystem + * obj = new FileSystem(); List param_1 = obj.ls(path); obj.mkdir(path); + * obj.addContentToFile(filePath,content); String param_4 = + * obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/FileSystem1166.java b/src/geeksforgeeks/FileSystem1166.java new file mode 100644 index 0000000..ed1331f --- /dev/null +++ b/src/geeksforgeeks/FileSystem1166.java @@ -0,0 +1,64 @@ +package geeksforgeeks; + +import java.util.HashMap; + +/** + * You are asked to design a file system which provides two functions: + * + * createPath(path, value): Creates a new path and associates a value to it if possible and returns True. + * Returns False if the path already exists or its parent path doesn't exist. + * + * get(path): Returns the value associated with a path or returns -1 if the path doesn't exist. + * + * ["FileSystem","createPath","createPath","get","createPath","get"] + * [[],["/leet",1],["/leet/code",2],["/leet/code"],["/c/d",1],["/c"]] + * Output: + * [null,true,true,2,false,-1] + * Explanation: + * FileSystem fileSystem = new FileSystem(); + * + * fileSystem.createPath("/leet", 1); // return true + * fileSystem.createPath("/leet/code", 2); // return true + * fileSystem.get("/leet/code"); // return 2 + * fileSystem.createPath("/c/d", 1); // return false because the parent path "/c" doesn't exist. + * fileSystem.get("/c"); // return -1 because this path doesn't exist. + */ +public class FileSystem1166 { + + private HashMap m = new HashMap<>(); + + /** + * Initialization of class. + * Use a hash map to store the path and value. + */ + public FileSystem1166() { + m.put("", -1); // avoid initially when path is "/a" regarded as false + } + + /** + * Creates a new path and associates a value to it if possible and returns True. + * The valid path's parent is the path before the last "/". + * Hence, check parent and then put the path into map if it is valid. + * If the path has already exist, return false. + * + * @param path given path + * @param value given value + * @return true to create a new path with value, false if the path already exists or its parent path doesn't exist + */ + public boolean create(String path, int value) { + if (path.charAt(0) != '/') { + return false; + } + String parent = path.substring(0, path.lastIndexOf("/")); + if (!m.containsKey(parent)) { + return false; + } + + return m.putIfAbsent(path, value) == null; // if the path exist, m.putIfAbsent(path, value) will be null + } + + public int get(String path) { + return m.getOrDefault(path, -1); + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/FileSystemI.java b/src/geeksforgeeks/FileSystemI.java new file mode 100644 index 0000000..51f3e19 --- /dev/null +++ b/src/geeksforgeeks/FileSystemI.java @@ -0,0 +1,96 @@ +package geeksforgeeks; +/** + * Design an in-memory file system to simulate the following functions: + * + * ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. + * If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. + * + * mkdir: Given a directory path that does not exist, you should make a new directory according to the path. + * If the middle directories in the path don't exist either, you should create them as well. This function has void return type. + * + * addContentToFile: Given a file path and file content in string format. + * If the file doesn't exist, you need to create that file containing given content. + * If the file already exists, you need to append given content to original content. This function has void return type. + * + * readContentFromFile: Given a file path, return its content in string format. + */ +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +public class FileSystemI { + class Dir { + HashMap directory = new HashMap<>(); + HashMap files = new HashMap<>(); + } + + Dir root; + + public FileSystemI() { + root = new Dir(); + } + + + public List ls(String path) { + Dir tempRoot = root; + List files = new ArrayList<>(); + if (!path.equals("/")) { + String[] directoriesList = path.split("/"); + for (int i = 1; i < directoriesList.length - 1; i++) { + tempRoot = tempRoot.directory.get(directoriesList[i]); + } + //If the last level in the input happens to be a file name, we simply need to return the file name. + // So, we directly return the last entry in the array. + if (tempRoot.files.containsKey(directoriesList[directoriesList.length - 1])) { + files.add(directoriesList[directoriesList.length - 1]); + return files; + } else { + tempRoot = tempRoot.directory.get(directoriesList[directoriesList.length - 1]); + } + } + //If the last level entry happens to be a directory, + // we can obtain its subdirectory list from the list of keys in its hashmap. + // Similarly, we can obtain the list of files in the last directory from the keys in the corresponding hashmap. + files.addAll(new ArrayList<>(tempRoot.directory.keySet())); + files.addAll(new ArrayList<>(tempRoot.files.keySet())); + Collections.sort(files); + return files; + } + + public void mkdir(String path) { + Dir t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + t.directory.putIfAbsent(d[i], new Dir()); + t = t.directory.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.directory.get(d[i]); + } + t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); + } + + public String readContentFromFile(String filePath) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.directory.get(d[i]); + } + return t.files.get(d[d.length - 1]); + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/FindMinimumInRotatedArray.java b/src/geeksforgeeks/FindMinimumInRotatedArray.java index cafb09c..1ccb519 100644 --- a/src/geeksforgeeks/FindMinimumInRotatedArray.java +++ b/src/geeksforgeeks/FindMinimumInRotatedArray.java @@ -4,8 +4,12 @@ public class FindMinimumInRotatedArray { public static int findMin(int[] nums) { - if (nums.length == 0) return -1; - if (nums.length == 1) return nums[0]; + if (nums.length == 0) { + return -1; + } + if (nums.length == 1) { + return nums[0]; + } int start = 0; int end = nums.length - 1; while (start <= end) { @@ -14,7 +18,7 @@ public static int findMin(int[] nums) { if (nums[start] <= nums[end]) { return nums[start]; } - + // mid is compared against end, if mid is high, then the rotated part is right of mid if (nums[mid] < nums[end]) { end = mid; } else { @@ -24,9 +28,29 @@ public static int findMin(int[] nums) { return -1; } - + public int findMinWithDuplicate(int[] nums) { + if(nums.length==1) return nums[0]; + int start=0; + int end= nums.length-1; + while(startnums[end]){ + start=mid+1; + }else{ + end=mid; + } + } + + } + + return nums[start]; + } public static void main(String[] args) { - int[] arr = {7, 1, 2, 3, 4, 5, 6}; + int[] arr = { 7, 1, 2, 3, 4, 5, 6 }; findMin(arr); } } \ No newline at end of file diff --git a/src/geeksforgeeks/FindMissingNumbers.java b/src/geeksforgeeks/FindMissingNumbers.java new file mode 100644 index 0000000..a889568 --- /dev/null +++ b/src/geeksforgeeks/FindMissingNumbers.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +// Input: [2, 3, 1, 8, 2, 3, 5, 1] +// Output: 4, 6, 7 +public class FindMissingNumbers { + + //Brute Force + // Set set = new HashSet<>(); + // for (int i = 0; i < nums.length; i++) set.add(i + 1); + // for (int i = 0; i < nums.length; i++) set.remove(nums[i]); + // return new ArrayList<>(set); + public List findDisappearedNumbers(int[] nums) { + if(nums.length==0) return Collections.emptyList(); + int i=0; + // cyclic sort begins + while(i result= new ArrayList<>(); + i=0; + while(i right) { - return -1; - } - - int mid = (left + right) / 2; - if (arr[mid] == key && (mid == 0 || arr[mid - 1] != key)) { - return mid; - } else if (arr[mid] >= key) { - return findFirstOccurrence(arr, left, mid - 1, key); - } else { - return findFirstOccurrence(arr, mid + 1, right, key); - } - } - - private static int findLastOccurrence(int[] arr, int left, int right, int key) { - if (left > right) { - return 0; - } - - int mid = (left + right) / 2; - if (arr[mid] == key && (mid == right || arr[mid + 1] != key)) { - return mid; - } else if (arr[mid] <= key) { - return findLastOccurrence(arr, mid + 1, right, key); - } else { - return findLastOccurrence(arr, left, mid - 1, key); - } - } - -} diff --git a/src/geeksforgeeks/FindSmallestInteger.java b/src/geeksforgeeks/FindSmallestInteger.java index b844cc8..8c3d88b 100644 --- a/src/geeksforgeeks/FindSmallestInteger.java +++ b/src/geeksforgeeks/FindSmallestInteger.java @@ -8,27 +8,29 @@ int findSmallest(int arr[], int n) { // Traverse the array and increment 'result' if arr[i] is // smaller than or equal to 'result'. - for (int i = 0; i < n && arr[i] <= result; i++) + for (int i = 0; i < n && arr[i] <= result; i++) { + System.out.println("Result :" + result + ":: arr[" + i + "]" + arr[i]); result = result + arr[i]; + } return result; } public static void main(String[] args) { FindSmallestInteger small = new FindSmallestInteger(); - int arr1[] = {1, 3, 4, 5}; + int arr1[] = { 1, 3, 4, 5 }; int n1 = arr1.length; System.out.println(small.findSmallest(arr1, n1)); - int arr2[] = {1, 2, 6, 10, 11, 15}; + int arr2[] = { 1, 2, 6, 10, 11, 15 }; int n2 = arr2.length; System.out.println(small.findSmallest(arr2, n2)); - int arr3[] = {1, 1, 1, 1}; + int arr3[] = { 1, 1, 1, 1 }; int n3 = arr3.length; System.out.println(small.findSmallest(arr3, n3)); - int arr4[] = {1, 1, 3, 4}; + int arr4[] = { 1, 1, 3, 4 }; int n4 = arr4.length; System.out.println(small.findSmallest(arr4, n4)); diff --git a/src/geeksforgeeks/FirstAndLastOccurence.java b/src/geeksforgeeks/FirstAndLastOccurence.java new file mode 100644 index 0000000..e07a6c1 --- /dev/null +++ b/src/geeksforgeeks/FirstAndLastOccurence.java @@ -0,0 +1,36 @@ +package geeksforgeeks; + +public class FirstAndLastOccurence { + public int[] searchRange(int[] nums, int target) { + if(nums.length==0) return new int[]{-1,-1}; + int[] result= new int[2]; + result[0]=binarySearch(nums,target,false); + if(result[0]==-1){ + result[1]=-1; + return result; + } + result[1]=binarySearch(nums,target,true); + return result; + } + + public int binarySearch(int[]nums, int target, boolean findMaxIndex){ + int start=0; + int end=nums.length-1; + int key=-1; + while(start<=end){ + int mid= start + (end-start)/2; + + if(nums[mid]target){ + end=mid-1; + }else{ + key=mid; + if(findMaxIndex) start=mid+1; + else end=mid-1; + } + } + + return key; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/FirstMissingPositive.java b/src/geeksforgeeks/FirstMissingPositive.java index 67e5dfb..1efb0e7 100644 --- a/src/geeksforgeeks/FirstMissingPositive.java +++ b/src/geeksforgeeks/FirstMissingPositive.java @@ -1,56 +1,95 @@ package geeksforgeeks; +import java.awt.List; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + /** * https://leetcode.com/problems/first-missing-positive/ - * */ public class FirstMissingPositive { - public int firstMissingPositive(int[] A) { - int i = 0; - while (i < A.length) { - if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) - i++; - else if (A[A[i] - 1] != A[i]) - swap(A, i, A[i] - 1); - else - i++; - } - i = 0; - while (i < A.length && A[i] == i + 1) - i++; - return i + 1; - } - - private void swap(int[] A, int i, int j) { - int temp = A[i]; - A[i] = A[j]; - A[j] = temp; - } - - public int firstMissingPositiveWithExtraSpace(int[] nums) { - if (nums == null || nums.length == 0) - return 1; - int length = nums.length; - int[] arr = new int[length + 1]; - for (int i = 0; i < length; i++) { - if (nums[i] <= length && nums[i] > 0) { - arr[--nums[i]] = -1; - } - } - - for (int i = 0; i < arr.length; i++) { - if (arr[i] != -1) { - return ++i; - } - } - return -1; - } - - public static void main(String[] args) { - int[] arr = { 3, 4, -1, 1 }; - FirstMissingPositive fmp = new FirstMissingPositive(); - System.out.println(fmp.firstMissingPositive(arr)); - System.out.println(fmp.firstMissingPositiveWithExtraSpace(arr)); - } + public int firstMissingPositive(int[] A) { + int i = 0; + while (i < A.length) { + // same cyclic sort, as missing numbers + if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } + } + i = 0; + while (i < A.length && A[i] == i + 1) + i++; + return i + 1; + } + + private void swap(int[] A, int i, int j) { + int temp = A[i]; + A[i] = A[j]; + A[j] = temp; + } + + public int firstMissingPositiveWithExtraSpace(int[] nums) { + if (nums == null || nums.length == 0) { + return 1; + } + int length = nums.length; + int[] arr = new int[length + 1]; + for (int i = 0; i < length; i++) { + if (nums[i] <= length && nums[i] > 0) { + arr[--nums[i]] = -1; + } + } + + for (int i = 0; i < arr.length; i++) { + if (arr[i] != -1) { + return ++i; + } + } + return -1; + } + + public List findKMissingPossitiveNumber(int[] A){ + int i = 0; + while (i < A.length) { + // same cyclic sort, as missing numbers + if (A[i] == i + 1 || A[i] <= 0 || A[i] > A.length) { + i++; + } else if (A[A[i] - 1] != A[i]) { + swap(A, i, A[i] - 1); + } else { + i++; + } + } + + List missingNumber= new ArrayList<>(); + Set additionalNumber= new HashSet<>(); + + i=0; + while(i= times DLLNode[] node= new DLLNode[26]; + // first condition whenever we see a value, we need to check it in visited array + // if(visited[c-'a']== true) do nothing because already added and deleted from the list(means this is 3rd occurrence of the array) + // else if(node[c-'a']!=null) removeNode(node[c-'a']); visited[c-'a']=true; 2nd occurrence we need to remove from list and set visited value to true + // else create a node and add head if head null or add to tail means we are seeing first time and need to create an entry in list + + // this uses arraylist so remove and contains are O(N) + static void findFirstNonRepeating() { + // inDLL[x] contains pointer to a DLL node if x is present + // in DLL. If x is not present, then inDLL[x] is NULL + List inDLL = new ArrayList<>(); + + // repeated[x] is true if x is repeated two or more times. + // If x is not seen so far or x is seen only once. then + // repeated[x] is false + boolean[] repeated = new boolean[MAX_CHAR]; + + // Let us consider following stream and see the process + String stream = "geeksforgeeksandgeeksquizfor"; + for (int i = 0; i < stream.length(); i++) { + char x = stream.charAt(i); + System.out.println("Reading " + x + " from stream n"); + + // We process this character only if it has not occurred + // or occurred only once. repeated[x] is true if x is + // repeated twice or more.s + if (!repeated[x]) { + // If the character is not in DLL, then add this at + // the end of DLL. + if (!(inDLL.contains(x))) { + inDLL.add(x); + } else // Otherwise remove this character from DLL + { + inDLL.remove((Character) x); + repeated[x] = true; // Also mark it as repeated + } + } + + // Print the current first non-repeating character from + // stream + if (inDLL.size() != 0) { + System.out.print("First non-repeating character so far is "); + System.out.println(inDLL.get(0)); + } + } + } + + public static void main(String[] args) { + findFirstNonRepeating(); + } +} diff --git a/src/geeksforgeeks/FirstNonRepeatedCharacter.java b/src/geeksforgeeks/FirstNonRepeatedCharacter.java index 43a90e3..d68d349 100644 --- a/src/geeksforgeeks/FirstNonRepeatedCharacter.java +++ b/src/geeksforgeeks/FirstNonRepeatedCharacter.java @@ -1,24 +1,26 @@ package geeksforgeeks; public class FirstNonRepeatedCharacter { - public static int firstUniqChar(String s) { - int freq[] = new int[26]; - for (int i = 0; i < s.length(); i++) - freq[s.charAt(i) - 'a']++; - // loop the same string again to find first occurrence not freq array - for (int i = 0; i < s.length(); i++) - if (freq[s.charAt(i) - 'a'] == 1) - return i; - return -1; - } + public static int firstUniqChar(String s) { + int freq[] = new int[26]; + for (int i = 0; i < s.length(); i++) + freq[s.charAt(i) - 'a']++; + // loop the same string again to find first occurrence not freq array + for (int i = 0; i < s.length(); i++) + if (freq[s.charAt(i) - 'a'] == 1) { + return i; + } + return -1; + } - public static void main(String args[]) { - String str = "geeksforgeeks"; + public static void main(String args[]) { + String str = "geeksforgeeks"; - int index = firstUniqChar(str); - if (index == -1) - System.out.print("Either all characters are " + "repeating or string is empty"); - else - System.out.print("First non-repeating character" + " is " + str.charAt(index)); - } + int index = firstUniqChar(str); + if (index == -1) { + System.out.print("Either all characters are repeating or string is empty"); + } else { + System.out.print("First non-repeating character" + " is " + str.charAt(index)); + } + } } diff --git a/src/geeksforgeeks/Flatten2DVector.java b/src/geeksforgeeks/Flatten2DVector.java new file mode 100644 index 0000000..de40a3b --- /dev/null +++ b/src/geeksforgeeks/Flatten2DVector.java @@ -0,0 +1,67 @@ +package geeksforgeeks; + +import java.util.List; + +/* +Thoughts: +As hint indicates: use 2 pointers to hold position. +Use hasNext to validate (x,y) and move x. +Use next() to return (x,y) and move it(regardless of correctness, which is determined by hasNext()) + +Implement an iterator to flatten a 2d vector. + +For example, +Given 2d vector = + +[ + [1,2], + [3], + [4,5,6] +] +By calling next repeatedly until hasNext returns false, +the order of elements returned by next should be: [1,2,3,4,5,6]. +*/ +public class Flatten2DVector { + private int x; + private int y; + private List> list; + + public Flatten2DVector(List> vec2d) { + if (vec2d == null) { + return; + } + this.x = 0; + this.y = 0; + this.list = vec2d; + } + + public int next() { + int rst = list.get(x).get(y); + // when y(column) reaches end increment row(x) and reset y + if (y + 1 >= list.get(x).size()) { + y = 0; + x++; + } else { + y++; + } + return rst; + } + + public boolean hasNext() { + if (list == null) { + return false; + } + // this condition is to check for empty rows + while (x < list.size() && list.get(x).size() == 0) { + x++; + y = 0; + } + if (x >= list.size()) { + return false; + } + if (y >= list.get(x).size()) { + return false; + } + return true; + } +} diff --git a/src/geeksforgeeks/FlattenLinkedList.java b/src/geeksforgeeks/FlattenLinkedList.java index 1e2e95c..9fbbcbe 100644 --- a/src/geeksforgeeks/FlattenLinkedList.java +++ b/src/geeksforgeeks/FlattenLinkedList.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://www.techiedelight.com/flatten-linked-list/ + */ class FlattenLinkedList { Node head; @@ -19,7 +22,6 @@ public String toString() { } } - Node mergeIterative(Node a, Node b) { Node dummy = new Node(0); Node result = dummy; @@ -49,8 +51,9 @@ Node mergeIterative(Node a, Node b) { } Node flatten(Node root) { - if (root == null || root.right == null) + if (root == null || root.right == null) { return root; + } root.right = flatten(root.right); @@ -59,7 +62,6 @@ Node flatten(Node root) { return root; } - public static void main(String args[]) { flattenList(); } @@ -120,9 +122,13 @@ void printList() { } Node merge(Node a, Node b) { - if (a == null) return b; + if (a == null) { + return b; + } - if (b == null) return a; + if (b == null) { + return a; + } Node result; diff --git a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java b/src/geeksforgeeks/FlattenMultiLevelLinkedList.java index f054faa..f1db59b 100644 --- a/src/geeksforgeeks/FlattenMultiLevelLinkedList.java +++ b/src/geeksforgeeks/FlattenMultiLevelLinkedList.java @@ -4,7 +4,9 @@ class FlattenMultiLevelLinkedList { public Node flatten(Node head) { - if (head == null) return head; + if (head == null) { + return head; + } // Pointer Node p = head; while (p != null) { @@ -19,7 +21,9 @@ public Node flatten(Node head) { temp = temp.next; // Connect tail with p.next, if it is not null temp.next = p.next; - if (p.next != null) p.next.prev = temp; + if (p.next != null) { + p.next.prev = temp; + } // Connect p with p.child, and remove p.child p.next = p.child; p.child.prev = p; diff --git a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java b/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java index 1f10903..115d9b2 100644 --- a/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java +++ b/src/geeksforgeeks/FlipMaximizeZeroesSubarrayKadane.java @@ -2,23 +2,30 @@ /** * https://www.geeksforgeeks.org/maximize-number-0s-flipping-subarray/ + *

+ * Problem : flip 1's to 0's so that total no.of 0's in array is maximized */ class FlipMaximizeZeroesSubarrayKadane { public static int findMaxZeroCount(int arr[], int n) { int zeroCount = 0; - int maxSoFar = 0; - int maxEndingHere = 0; + int maxSoFar = Integer.MIN_VALUE; + int sum = 0; for (int i = 0; i < n; i++) { - if (arr[i] == 0) + if (arr[i] == 0) { zeroCount++; + } int val = (arr[i] == 1) ? 1 : -1; - maxEndingHere = Math.max(val, maxEndingHere + val); - maxSoFar = Math.max(maxSoFar, maxEndingHere); + sum = sum + val; + + if (sum < 0) { + sum = 0; + } + maxSoFar = Math.max(maxSoFar, sum); } maxSoFar = Math.max(0, maxSoFar); @@ -26,7 +33,7 @@ public static int findMaxZeroCount(int arr[], int n) { } public static void main(String[] args) { - int arr[] = {0, 1, 0, 0, 1, 1, 0}; + int arr[] = { 0, 1, 0, 0, 1, 1, 0 }; System.out.println(findMaxZeroCount(arr, arr.length)); } diff --git a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java b/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java index 535afdb..66590b7 100644 --- a/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java +++ b/src/geeksforgeeks/FlipZeroesToFormConsecutiveMaximumOnes.java @@ -30,7 +30,6 @@ public static void longestSeq(int[] A, int k) { if (A[left] == 0) { count--; } - left++; } @@ -43,13 +42,14 @@ public static void longestSeq(int[] A, int k) { } } - System.out.println("The longest sequence has length " + window + " from index " + leftIndex + " to " - + (leftIndex + window - 1)); + System.out.println( + "The longest sequence has length " + window + " from index " + leftIndex + " to " + (leftIndex + window + - 1)); } // main function public static void main(String[] args) { - int[] A = {1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0}; + int[] A = { 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0 }; int k = 1; longestSeq(A, k); diff --git a/src/geeksforgeeks/FourSum.java b/src/geeksforgeeks/FourSum.java new file mode 100644 index 0000000..96a925c --- /dev/null +++ b/src/geeksforgeeks/FourSum.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + +import java.util.HashMap; +import java.util.Map; + +/** + * https://leetcode.com/problems/4sum-ii/ + */ +public class FourSum { + + public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { + Map sums = new HashMap<>(); + int count = 0; + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < B.length; j++) { + int sum = A[i] + B[j]; + sums.put(sum, sums.getOrDefault(sum, 0) + 1); + + } + } + for (int k = 0; k < A.length; k++) { + for (int z = 0; z < C.length; z++) { + int sum = -(C[k] + D[z]); + if (sums.containsKey(sum)) { + count += sums.get(sum); + } + } + } + return count; + } + + public static void main(String[] args) { + int[] A = { 1, 2 }; + int[] B = { -2, -1 }; + int[] C = { -1, 2 }; + int[] D = { 0, 2 }; + + FourSum fs = new FourSum(); + fs.fourSumCount(A, B, C, D); + } +} diff --git a/src/geeksforgeeks/FrequencySort.java b/src/geeksforgeeks/FrequencySort.java new file mode 100644 index 0000000..a01d6cc --- /dev/null +++ b/src/geeksforgeeks/FrequencySort.java @@ -0,0 +1,34 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// sort the string by character frequency from high to low +public class FrequencySort { + // this could be easily done with priority queue but this is ref for bucket sort + public String frequencySort(String s) { + Map map = new HashMap<>(); + for (char c : s.toCharArray()) + map.put(c, map.getOrDefault(c, 0) + 1); + + List[] bucket = new List[s.length() + 1]; + + for (char key : map.keySet()) { + int frequency = map.get(key); + if (bucket[frequency] == null) bucket[frequency] = new ArrayList<>(); + bucket[frequency].add(key); + } + + StringBuilder sb = new StringBuilder(); + // since this is max frequency are iterating from last else we'd go from start + for (int pos = bucket.length - 1; pos >= 0; pos--) + if (bucket[pos] != null) + for (char c : bucket[pos]) + for (int i = 0; i < map.get(c); i++) + sb.append(c); + + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/GameOfLife.java b/src/geeksforgeeks/GameOfLife.java new file mode 100644 index 0000000..d2b6069 --- /dev/null +++ b/src/geeksforgeeks/GameOfLife.java @@ -0,0 +1,61 @@ +package geeksforgeeks; + +/** + * https://forum.letstalkalgorithms.com/t/game-of-life/516/2 + *

+ * https://leetcode.com/problems/game-of-life/ + * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article): + * + * Any live cell with fewer than two live neighbors dies, as if caused by under-population. + * Any live cell with two or three live neighbors lives on to the next generation. + * Any live cell with more than three live neighbors dies, as if by over-population.. + * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. + * + * Input: + * [ + * [0,1,0], + * [0,0,1], + * [1,1,1], + * [0,0,0] + * ] + * Output: + * [ + * [0,0,0], + * [1,0,1], + * [0,1,1], + * [0,1,0] + * ] + */ +public class GameOfLife { + + public void gameOfLife(int[][] board) { + + int[][] dir ={{1,-1},{1,0},{1,1},{0,-1},{0,1},{-1,-1},{-1,0},{-1,1}}; + int row=board.length; + int col=board[0].length; + + for(int i=0; i=row || j1>=col || i1<0 || j1<0) continue; // border conditions + + if(board[i1][j1]==1 || board[i1][j1]==2) liveCells++; + } + + if(board[i][j]==0 && liveCells==3) board[i][j]=3; //Any dead cell with exactly three live neighbors becomes a live cell + + if(board[i][j]==1 && (liveCells<2 || liveCells>3)) board[i][j]=2; //live cell with fewer than two live neighbors dies || Any live cell with more than three live neighbors dies + } + } + + for(int i=0; i generateParenthesis(int n) { + List result = new ArrayList<>(); + if (n == 0) + return result; + // initially we send empty string and target number of pairs needed + generateUtil(n, new StringBuilder(), 0, 0, result); + + return result; + } + + public void generateUtil(int n, StringBuilder paran, int open, int close, List result) { + if (close == n) { // when close reaches n, we know n pairs have been created + result.add(paran.toString()); + return; + } + + if (close < open) { // when close is less than open we add a close and proceed + paran.append(")"); + generateUtil(n, paran, open, close + 1, result); + paran.deleteCharAt(paran.length() - 1); // backtracking to remove the last seen + } + if (open < n) { + paran.append("("); + generateUtil(n, paran, open + 1, close, result); + paran.deleteCharAt(paran.length() - 1); + + } + + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/GrammarMistake.java b/src/geeksforgeeks/GrammarMistake.java new file mode 100644 index 0000000..134fb1f --- /dev/null +++ b/src/geeksforgeeks/GrammarMistake.java @@ -0,0 +1,83 @@ +package geeksforgeeks; + +/** + * https://www.geeksforgeeks.org/check-given-sentence-given-set-simple-grammer-rules/ + * A simple sentence if syntactically correct if it fulfills given rules. The following are given rules. + * + * 1. Sentence must start with a Uppercase character (e.g. Noun/ I/ We/ He etc.) + * 2. Then lowercase character follows. + * 3. There must be spaces between words. + * 4. Then the sentence must end with a full stop(.) after a word. + * 5. Two continuous spaces are not allowed. + * 6. Two continuous upper case characters are not allowed. + * 7. However, the sentence can end after an upper case character. + * + * + */ +import java.util.Arrays; +import java.util.List; + +class Main +{ + public static boolean validateSentence(char[] chars) + { + int index = 0; + if (Character.isLowerCase(chars[index])) { // 1st condition + return false; + } + + while (index < chars.length) + { + if (Character.isUpperCase(chars[index])) + { + if (Character.isUpperCase(chars[index + 1])) { // 5th condition + return false; + } + + if (index - 1 >= 0 && chars[index - 1] != ' ') { // 2nd condition + return false; + } + } + + if (chars[index] == ' ' && chars[index + 1] == ' ') { // 4th condition + return false; + } + + index++; + } + + if (chars[index - 2] == ' ' || chars[index - 1] != '.') { // 3th condition + return false; + } + + return true; + } + + public static void main(String[] args) + { + List list = Arrays.asList( + "This sentence is syntactically correct.", + + "This sentence is syntactically incorrect as two " + + "continuous spaces are not allowed.", + + "This sentence is syntactically correct Y.", + + "This sentence is syntactically incorRect as uppercase " + + "character is not allowed midway of the String.", + + "THis sentence is syntactically incorrect as lowercase " + + "character don't follow the first uppercase character.", + + "This sentence is syntactically incorrect as it doesn't " + + "end with a full stop" + ); + + System.out.println("Valid sentences are -"); + for (String sentence: list) { + if (validateSentence(sentence.toCharArray())) { + System.out.println(sentence); + } + } + } +} diff --git a/src/geeksforgeeks/GraphBiPartite.java b/src/geeksforgeeks/GraphBiPartite.java new file mode 100644 index 0000000..27da2f5 --- /dev/null +++ b/src/geeksforgeeks/GraphBiPartite.java @@ -0,0 +1,53 @@ +package geeksforgeeks; + +/** + * Recall that a graph is bipartite if we can split it's set of nodes into + * two independent subsets A and B such that every edge in the graph has one node in A and + * another node in B. + * Input: [[1,3], [0,2], [1,3], [0,2]] => 0th node connects to 1,3 .. +Output: true +Explanation: +The graph looks like this: +0----1 +| | +| | +3----2 +We can divide the vertices into two groups: {0, 2} and {1, 3}. +Input: [[1,2,3], [0,2], [0,1,3], [0,2]] +Output: false +Explanation: +The graph looks like this: +0----1 +| \ | +| \ | +3----2 +We cannot find a way to divide the set of nodes into two independent subsets. + */ +public class GraphBiPartite { + public boolean isBipartite(int[][] graph) { + int[] color= new int[graph.length]; + + for(int i=0;i> groupAnagrams(String[] strs) { + List> result= new ArrayList<>(); + + if(strs==null || strs.length==0) return result; + Map> map= new HashMap<>(); + + for(String s: strs){ + // int[] cache= new int[26]; + // for(char ch: s.toCharArray()){ + // cache[ch-'a']++; + // } + // String hash=Arrays.toString(cache); + char[] te=s.toCharArray(); + Arrays.sort(te); + String hash=new String(te); + + List list= map.getOrDefault(hash, new LinkedList<>()); + list.add(s); + map.put(hash,list); + } + + return new ArrayList(map.values()); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/HappyNumber.java b/src/geeksforgeeks/HappyNumber.java new file mode 100644 index 0000000..a8ff875 --- /dev/null +++ b/src/geeksforgeeks/HappyNumber.java @@ -0,0 +1,56 @@ +package geeksforgeeks; + +import java.util.HashSet; +import java.util.Set; + +/** + * https://leetcode.com/problems/happy-number/ + */ +class HappyNumber { + public boolean isHappy(int n) { + + Set visited = new HashSet<>(); + int sum = String.valueOf(n).chars().map(Character::getNumericValue).map(val -> val * val).sum() == 1 ? 1 : n; + while (true) { + if (sum == 1) { + return true; + } + sum = String.valueOf(sum).chars().map(Character::getNumericValue).map(val -> val * val).sum(); + if (visited.contains(sum)) { + return false; + } + + visited.add(sum); + } + } + + public int next(int n) + { + int res=0; + while (n>0) + { + int t = n % 10; + res += t*t; + n/=10; + } + return res; + } + + public boolean isHappyOpt(int n) + { + int i1=n, i2=next(n); + + while ( i2 != i1) + { + i1 = next(i1); + i2 = next(next(i2)); + } + + return i1==1; + } + + public static void main(String[] args) { + HappyNumber hn = new HappyNumber(); + System.out.println(hn.isHappy(19)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/HitCounter.java b/src/geeksforgeeks/HitCounter.java new file mode 100644 index 0000000..77d6368 --- /dev/null +++ b/src/geeksforgeeks/HitCounter.java @@ -0,0 +1,24 @@ +package geeksforgeeks; +public class HitCounter { + ArrayDeque trac; + /** Initialize your data structure here. */ + private final int FIVE_MINUTES = 300; + public HitCounter() { + trac = new ArrayDeque(); + } + + /** Record a hit. + @param timestamp - The current timestamp (in seconds granularity). */ + public void hit(int timestamp) { + trac.addLast(timestamp); + } + + /** Return the number of hits in the past 5 minutes. + @param timestamp - The current timestamp (in seconds granularity). */ + public int getHits(int timestamp) { + while(trac.size() > 0 && ( int) trac.getFirst() + FIVE_MINUTES <= timestamp) { + trac.removeFirst(); + } return trac.size(); + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/HouseRobber.java b/src/geeksforgeeks/HouseRobber.java new file mode 100644 index 0000000..b860ad0 --- /dev/null +++ b/src/geeksforgeeks/HouseRobber.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/house-robber/ + */ +public class HouseRobber { + + public int rob(int[] nums) { + if (nums.length == 0) { + return 0; + } + int incl = nums[0]; + int excl = 0; + for (int i = 1; i < nums.length; i++) { + int temp = incl; + incl = Math.max(incl, excl + nums[i]); + excl = temp; + } + return incl; + } + + public int robCircular(int[] nums) { + + if(nums.length==0) return 0; + if(nums.length==1) return nums[0]; + return Math.max(helperFn(nums,0,nums.length-2), helperFn(nums,1,nums.length-1)); + + } + + public int helperFn(int[] nums, int start, int end){ + int pre=0; int cur=0; + for(int i=start;i<=end;i++){ + int temp=Math.max(pre+nums[i],cur); + pre=cur; + cur=temp; + + } + return cur; + } + + public static void main(String[] args) { + int[] arr = { 2, 7, 9, 3, 1 }; + HouseRobber houseRobber = new HouseRobber(); + System.out.println(houseRobber.rob(arr)); + } +} diff --git a/src/geeksforgeeks/IPOMaxProfit.java b/src/geeksforgeeks/IPOMaxProfit.java new file mode 100644 index 0000000..5338d09 --- /dev/null +++ b/src/geeksforgeeks/IPOMaxProfit.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + + + +import java.util.PriorityQueue; +//https://leetcode.com/problems/ipo/ + +// Input: distinctProjToFind=2, capital=0, Profits=[1,2,3], Capital=[0,1,1]. +// Output: 4 + +// Explanation: Since your initial capital is 0, you can only start the project indexed 0. +// After finishing it you will obtain profit 1 and your capital becomes 1. +// With capital 1, you can either start the project indexed 1 or the project indexed 2. +// Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital. +// Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4. +public class IPOMaxProfit { + + // Create (capital, profit) pairs and put them into PriorityQueue pqCap. + // This PriorityQueue sort by capital increasingly. + // Keep polling pairs from pqCap until the project out of current capital capability. Put them into + // PriorityQueue pqPro which sort by profit decreasingly. + // Poll one from pqPro, it's guaranteed to be the project with max profit and within current capital capability. + //Add the profit to capital W. + //Repeat step 2 and 3 till finish k steps or no suitable project (pqPro.isEmpty()). + public int findMaximizedCapital(int steps, int initialCapital, int[] Profits, int[] Capital) { + + PriorityQueue minQueue= new PriorityQueue<>((a, b)->Integer.compare(a[0],b[0])); + PriorityQueue maxQueue= new PriorityQueue<>((a,b)->Integer.compare(b[1],a[1])); + + for(int i=0;i dirs = new HashMap < > (); + HashMap < String, String > files = new HashMap < > (); + } + Dir root; + public FileSystem() { + root = new Dir(); + } + public List < String > ls(String path) { + Dir t = root; + List < String > files = new ArrayList < > (); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + if (t.files.containsKey(d[d.length - 1])) { + files.add(d[d.length - 1]); + return files; + } else { + t = t.dirs.get(d[d.length - 1]); + } + } + files.addAll(new ArrayList < > (t.dirs.keySet())); + files.addAll(new ArrayList < > (t.files.keySet())); + Collections.sort(files); + return files; + } + + public void mkdir(String path) { + Dir t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.dirs.containsKey(d[i])) + t.dirs.put(d[i], new Dir()); + t = t.dirs.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + t.files.put(d[d.length - 1], t.files.getOrDefault(d[d.length - 1], "") + content); + } + + public String readContentFromFile(String filePath) { + Dir t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.dirs.get(d[i]); + } + return t.files.get(d[d.length - 1]); + } +} + +class FileSystem1 { + class File { + boolean isfile = false; + HashMap < String, File > files = new HashMap < > (); + String content = ""; + } + File root; + public FileSystem() { + root = new File(); + } + + public List < String > ls(String path) { + File t = root; + List < String > files = new ArrayList < > (); + if (!path.equals("/")) { + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + t = t.files.get(d[i]); + } + if (t.isfile) { + files.add(d[d.length - 1]); + return files; + } + } + List < String > res_files = new ArrayList < > (t.files.keySet()); + Collections.sort(res_files); + return res_files; + } + + public void mkdir(String path) { + File t = root; + String[] d = path.split("/"); + for (int i = 1; i < d.length; i++) { + if (!t.files.containsKey(d[i])) + t.files.put(d[i], new File()); + t = t.files.get(d[i]); + } + } + + public void addContentToFile(String filePath, String content) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + if (!t.files.containsKey(d[d.length - 1])) + t.files.put(d[d.length - 1], new File()); + t = t.files.get(d[d.length - 1]); + t.isfile = true; + t.content = t.content + content; + } + + public String readContentFromFile(String filePath) { + File t = root; + String[] d = filePath.split("/"); + for (int i = 1; i < d.length - 1; i++) { + t = t.files.get(d[i]); + } + return t.files.get(d[d.length - 1]).content; + } +} + +/** + * Your FileSystem object will be instantiated and called as such: + * FileSystem obj = new FileSystem(); + * List param_1 = obj.ls(path); + * obj.mkdir(path); + * obj.addContentToFile(filePath,content); + * String param_4 = obj.readContentFromFile(filePath); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/InOrderSuccessor.java b/src/geeksforgeeks/InOrderSuccessor.java new file mode 100644 index 0000000..d71489e --- /dev/null +++ b/src/geeksforgeeks/InOrderSuccessor.java @@ -0,0 +1,29 @@ +package geeksforgeeks; +public class InOrderSuccessor { + /* + * @param root: The root of the BST. + * @param p: You need find the successor node of p. + * @return: Successor of p. + */ + TreeNode result=null; + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root,p); + return result; + } + // Inorder traversal is obtained by going right first and follow the left path till end + // while traversing right we record the right before taking left turn, incase the left path is null + + public void helperFn(TreeNode root, TreeNode p){ + if(root==null) return; + + if(root.val>p.val){ + + result=root; + helperFn(root.left,p); + }else{ + + helperFn(root.right,p); + } + + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/InorderSuccessorPredecessor.java b/src/geeksforgeeks/InorderSuccessorPredecessor.java new file mode 100644 index 0000000..3c46754 --- /dev/null +++ b/src/geeksforgeeks/InorderSuccessorPredecessor.java @@ -0,0 +1,149 @@ +package geeksforgeeks; + +/** + * https://algorithms.tutorialhorizon.com/inorder-predecessor-and-successor-in-binary-search-tree/ + */ +public class InorderSuccessorPredecessor { + static int successor, predecessor; + + public void successorPredecessor(TNode root, int val) { + // if (root.data == val) { + // // go to the right most element in the left subtree, it will be the + // // predecessor. + // if (root.left != null) { + // TNode t = root.left; + // while (t.right != null) { + // t = t.right; + // } + // predecessor = t.data; + // } + // if (root.right != null) { + // // go to the left most element in the right subtree, it will be + // // the successor. + // TNode t = root.right; + // while (t.left != null) { + // t = t.left; + // } + // successor = t.data; + // } + // } else + if (root != null) { + if (root.data > val) { + // we make the root as successor because we might have a + // situation when value matches with the root, it wont have + // right subtree to find the successor, in that case we need + // parent to be the successor + successor = root.data; + successorPredecessor(root.left, val); + } else if (root.data < val) { + // we make the root as predecessor because we might have a + // situation when value matches with the root, it wont have + // left subtree to find the predecessor, in that case we need + // parent to be the predecessor. + predecessor = root.data; + successorPredecessor(root.right, val); + } + } + } + + public void shortSolution(TNode root, int val) { + if (root != null) { + if (root.data > val) { + // we make the root as successor because we might have a + // situation when value matches with the root, it wont have + // right subtree to find the successor, in that case we need + // parent to be the successor + successor = root.data; + successorPredecessor(root.left, val); + } else if (root.data < val) { + // we make the root as predecessor because we might have a + // situation when value matches with the root, it wont have + // left subtree to find the predecessor, in that case we need + // parent to be the predecessor. + predecessor = root.data; + successorPredecessor(root.right, val); + } + } + } + + public static void main(String args[]) { + TNode root = new TNode(25); + root.left = new TNode(15); + root.right = new TNode(40); + root.left.left = new TNode(10); + root.left.left.left = new TNode(5); + root.left.right = new TNode(18); + root.right.left = new TNode(35); + root.right.right = new TNode(45); + root.left.right.left = new TNode(19); + root.left.right.right = new TNode(20); + InorderSuccessorPredecessor i = new InorderSuccessorPredecessor(); + + // i.successorPredecessor(root, 20); +/* TNode tempSuccessor = root.right; + TNode successor = i.findSuccessor(tempSuccessor); + successor = successor==null?tempSuccessor:successor;*/ + + System.out.println("Inorder Successor of 10 is : " + successor + " and predecessor is : " + predecessor); + + } + + TreeNode result=null; + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + helperFn(root,p); + return result; + } + + public void helperFn(TreeNode root, TreeNode p){ + if(root==null) return; + + if(root.val>p.val){ + // System.out.println("greatre root"+root.val); + result=root; + helperFn(root.left,p); + }else{ + //System.out.println("smaller root"+root.val); + helperFn(root.right,p); + } + + } +} + +private TreeNode findPredecessor(TreeNode root, TreeNode node) { + TreeNode pre = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val < node.val) { + pre = cur; + cur = cur.right; + } else { + cur = cur.left; + } + } + return pre; +} +private TreeNode findSuccessor(TreeNode root, TreeNode node) { + TreeNode succ = null; + TreeNode cur = root; + while (cur != null) { + if (cur.val > node.val) { + succ = cur; + cur = cur.left; + } else { + cur = cur.right; + } + } + return succ; +} + +class TNode { + int data; + TNode left; + TNode right; + + public TNode(int data) { + this.data = data; + left = null; + right = null; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/InserstionSortList.java b/src/geeksforgeeks/InserstionSortList.java new file mode 100644 index 0000000..8ed6bf7 --- /dev/null +++ b/src/geeksforgeeks/InserstionSortList.java @@ -0,0 +1,29 @@ +package geeksforgeeks; + +public class InserstionSortList { + public ListNode insertionSortList(ListNode head) { + ListNode dummy = new ListNode(0); + ListNode prev = dummy; + + // take 1->2->3->4 + while (head != null) { + ListNode temp = head.next; // at first run temp=2, second run temp=3 + + /* Before insert, the prev is at the last node of the sorted list. + Only the last node's value is larger than the current inserting node + should we move the temp back to the head*/ + if (prev.val >= head.val) prev = dummy; + + // during second run prev= 0->1->null + while (prev.next != null && prev.next.val < head.val) { + prev = prev.next; + } // after this loop, at first run prev=0 (0->null), second run prev=1 + + head.next = prev.next; // we set 1->null // second run 2->null + prev.next = head; // 0->1 // 0->1->2 + + head = temp; // head= 2->3->4 // head= 3->4 + } + return dummy.next; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/IntegerToBinary.java b/src/geeksforgeeks/IntegerToBinary.java new file mode 100644 index 0000000..c16ffc3 --- /dev/null +++ b/src/geeksforgeeks/IntegerToBinary.java @@ -0,0 +1,38 @@ +package geeksforgeeks; + +class IntegerToBinary { + // function to convert decimal to binary + static void decToBinary(int n) { + // array to store binary number + int[] binaryNum = new int[1000]; + + // counter for binary array + int i = 0; + while (n > 0) { + // storing remainder in binary array + binaryNum[i] = n % 2; + n = n / 2; + i++; + } + + // printing binary array in reverse order + for (int j = i - 1; j >= 0; j--) + System.out.print(binaryNum[j]); + } + + public static void main(String[] args) { + int n = 4; + // decToBinary(n); + // System.out.println("Default method :" + Integer.toBinaryString(4)); + System.out.println(intToBinary(4)); + } + + public static String intToBinary(int n) { + String s = ""; + while (n > 0) { + s = ((n % 2) == 0 ? "0" : "1") + s; + n = n / 2; + } + return s; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/IntersectionOfArrays.java b/src/geeksforgeeks/IntersectionOfArrays.java new file mode 100644 index 0000000..f104dd9 --- /dev/null +++ b/src/geeksforgeeks/IntersectionOfArrays.java @@ -0,0 +1,79 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * https://leetcode.com/problems/intersection-of-two-arrays-ii/discuss/82241/AC-solution-using-Java-HashMap + *

+ * Example 1: + *

+ * Input: nums1 = [1,2,2,1], nums2 = [2,2] + * Output: [2,2] + * Example 2: + *

+ * Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] + * Output: [4,9] + */ +public class IntersectionOfArrays { + public static void main(String[] args) { + IntersectionOfArrays intersectionOfArrays = new IntersectionOfArrays(); + int[] nums1 = { 4, 4, 9, 5 }; + int[] nums2 = { 9, 4, 9, 4, 2, 3 }; + System.out.println(Arrays.toString(intersectionOfArrays.intersect(nums1, nums2))); + } + + public int[] intersect(int[] nums1, int[] nums2) { + //The first question is relatively easy, create a hashmap base on number frequency of nums1(whichever one is longer). + + // Then for every element of nums2, look upon the hashmap. If we found an intersection, deduct by 1 to avoid duplicate. + HashMap map = new HashMap<>(); + ArrayList result = new ArrayList<>(); + for (int i = 0; i < nums1.length; i++) { + map.put(nums1[i], map.getOrDefault(nums1[i], 1)); + } + + for (int i = 0; i < nums2.length; i++) { + if (map.containsKey(nums2[i]) && map.get(nums2[i]) > 0) { + result.add(nums2[i]); + map.put(nums2[i], map.get(nums2[i]) - 1); + } + } + + int[] r = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + r[i] = result.get(i); + } + + return r; + } + + //What if the given array is already sorted? How would you optimize your algorithm? + // Classic two pointer iteration, i points to nums1 and j points to nums2. + // Because a sorted array is in ascending order, so if nums1[i] > nums[j], we need to increment j, and vice versa. + // Only when nums1[i] == nums[j], we add it to the result array. Time Complexity O(max(N, M)) + public int[] intersectSorted(int[] nums1, int[] nums2) { + Arrays.sort(nums1); + Arrays.sort(nums2); + int n = nums1.length, m = nums2.length; + int i = 0, j = 0; + List list = new ArrayList<>(); + while(i < n && j < m){ + int a = nums1[i], b= nums2[j]; + if(a == b){ + list.add(a); + i++; + j++; + }else if(a < b){ + i++; + }else{ + j++; + } + } + int[] ret = new int[list.size()]; + for(int k = 0; k < list.size();k++) ret[k] = list.get(k); + return ret; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/IsEditOneDistanceAway.java b/src/geeksforgeeks/IsEditOneDistanceAway.java new file mode 100644 index 0000000..ad443e8 --- /dev/null +++ b/src/geeksforgeeks/IsEditOneDistanceAway.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +class IsEditOneDistanceAway { + static boolean isOneEdit(String first, String second) { + // if the input string are same + if (first.equals(second)) + return false; + + int len1 = first.length(); + int len2 = second.length(); + // If the length difference of the stings is more than 1, return false. + if ((len1 - len2) > 1 || (len2 - len1) > 1) { + return false; + } + int i = 0, j = 0; + int diff = 0; + while (i < len1 && j < len2) { + char f = first.charAt(i); + char s = second.charAt(j); + if (f != s) { + diff++; + if (len1 > len2) + i++; + if (len2 > len1) + j++; + if (len1 == len2) + i++; + j++; + } else { + i++; + j++; + } + if (diff > 1) { + return false; + } + } + // If the length of the string is not same. ex. "abc" and "abde" are not one + // edit distance. + if (diff == 1 && len1 != len2 && (i != len1 || j != len2)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/IsSubsequence.java b/src/geeksforgeeks/IsSubsequence.java new file mode 100644 index 0000000..53df8e0 --- /dev/null +++ b/src/geeksforgeeks/IsSubsequence.java @@ -0,0 +1,22 @@ +package geeksforgeeks; + +public class IsSubsequence { + // Input: s = "abc", t = "ahbgdc" + // Output: true + // Input: s = "axc", t = "ahbgdc" + // Output: false + public boolean isSubsequence(String s, String t) { + if(s==null || t==null) return false; + int i=0; int j=0; + + while(i queue = new ArrayDeque<>(); + queue.offer(root); + while (!queue.isEmpty()) { + Pair temp = queue.poll(); + for (int[] dir : directions) { + + int x = temp.x + dir[0]; + int y = temp.y + dir[1]; + if (isvalid(grid, x, y)) { + grid[x][y] = '0'; + queue.offer(new Pair(x, y)); + } + } + } + } + + public boolean isvalid(char[][] grid, int x, int y) { + if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == '0') { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/Islands.java b/src/geeksforgeeks/Islands.java index 948f3bb..49a8bad 100644 --- a/src/geeksforgeeks/Islands.java +++ b/src/geeksforgeeks/Islands.java @@ -11,8 +11,9 @@ class Islands { public int numIslands(int[][] grid) { int count = 0; n = grid.length; - if (n == 0) + if (n == 0) { return 0; + } m = grid[0].length; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) @@ -25,8 +26,9 @@ public int numIslands(int[][] grid) { } private void DFSMarking(int[][] grid, int i, int j) { - if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) + if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != 1) { return; + } grid[i][j] = 0; DFSMarking(grid, i + 1, j); DFSMarking(grid, i - 1, j); @@ -35,7 +37,7 @@ private void DFSMarking(int[][] grid, int i, int j) { } public static void main(String[] args) { - int M[][] = new int[][]{{1, 1, 1, 1, 0}, {1, 1, 0, 1, 0}, {1, 1, 0, 0, 0}, {0, 0, 0, 0, 0}}; + int M[][] = new int[][] { { 1, 1, 1, 1, 0 }, { 1, 1, 0, 1, 0 }, { 1, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; Islands I = new Islands(); System.out.println("Number of islands is: " + I.numIslands(M)); } diff --git a/src/geeksforgeeks/IsomorphicArray.java b/src/geeksforgeeks/IsomorphicArray.java index f0ded5e..8eacfe8 100644 --- a/src/geeksforgeeks/IsomorphicArray.java +++ b/src/geeksforgeeks/IsomorphicArray.java @@ -1,33 +1,36 @@ package geeksforgeeks; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class IsomorphicArray { public Collection> groupIsomorphicStrings(List strings) { - if (strings == null || strings.isEmpty()) + if (strings == null || strings.isEmpty()) { return Collections.EMPTY_LIST; + } Map> hashToList = new HashMap<>(); for (String string : strings) { String hash = hash(string); - if (!hashToList.containsKey(hash)) + if (!hashToList.containsKey(hash)) { hashToList.put(hash, new ArrayList<>()); + } hashToList.get(hash).add(string); } return hashToList.values(); } - + // this method returns a hash value for every string passed in + // apple = 12234 + // apply = 12234 + // dog = 123 + // cog = 123 + // romi = 1234 private String hash(String s) { - if (s.isEmpty()) + if (s.isEmpty()) { return ""; + } int count = 1; StringBuilder hash = new StringBuilder(); @@ -36,13 +39,18 @@ private String hash(String s) { for (char c : s.toCharArray()) { - if (map.containsKey(c)) - hash.append(map.get(c)); - else { + if (!map.containsKey(c)) { map.put(c, count++); - hash.append(map.get(c)); } + hash.append(map.get(c)); } + System.out.println(s +" = "+hash.toString() ); return hash.toString(); } + + public static void main(String[] args) { + Collection> result = new IsomorphicArray() + .groupIsomorphicStrings(Arrays.asList("apple", "apply", "dog", "cog", "romi")); + result.stream().forEach(System.out::println); + } } diff --git a/src/geeksforgeeks/IsomorphicString.java b/src/geeksforgeeks/IsomorphicString.java index 3fae7d5..1f41f1e 100644 --- a/src/geeksforgeeks/IsomorphicString.java +++ b/src/geeksforgeeks/IsomorphicString.java @@ -7,14 +7,16 @@ */ class IsomorphicString { static boolean isIsomorphic(String s, String t) { - int m1[] = new int[256]; - int m2[] = new int[256]; + char m1[] = new int[256]; + char m2[] = new int[256]; int n = s.length(); for (int i = 0; i < n; ++i) { // it checks the count of the character in the array ; // for 'g' -> a[103] is 2 and 'd' -> a[100] is 2 - if (m1[s.charAt(i)] != m2[t.charAt(i)]) + // if both are same both gets incremented together else return false + if (m1[s.charAt(i)] != m2[t.charAt(i)]) { return false; + } m1[s.charAt(i)] = i + 1; m2[t.charAt(i)] = i + 1; } diff --git a/src/geeksforgeeks/JumpsToReachEnd.java b/src/geeksforgeeks/JumpsToReachEnd.java new file mode 100644 index 0000000..7f305c1 --- /dev/null +++ b/src/geeksforgeeks/JumpsToReachEnd.java @@ -0,0 +1,62 @@ +package geeksforgeeks; + +import java.util.*; + +public class JumpsToReachEnd { + + public static boolean canReachEnd(List maxAdvanceSteps) { + int furthestReachSoFar = 0, lastlndex = maxAdvanceSteps.size() - 1; + + //i <= furthestReachSoFar && furthestReachSoFar < lastlndex this is the imp part of the solution + for (int i = 0; i <= furthestReachSoFar && furthestReachSoFar < lastlndex; ++i) { + // for every index store max-steps it can take and i should be + // less than maxSteps to check if it can move further + // e.x (3, 2, 0, 0, 2, 0,1) when index i is 3 maxStpes is also 3, it cannot move further + furthestReachSoFar = Math.max(furthestReachSoFar, i + maxAdvanceSteps.get(i)); + } + return furthestReachSoFar >= lastlndex; + } + + + // Given an array of non-negative integers arr, you are initially positioned at start index of the array. + // When you are at index i, you can jump to i + arr[i] or i - arr[i], + // check if you can reach to any index with value 0. + public boolean canReach(int[] arr, int start) { + // visited check included + if(start>=arr.length || start<0 || arr[start]>arr.length || arr[start]<0) return false; + if(arr[start]==0 ) return true; + arr[start]=-arr[start]; // visited marking + return canReach(arr, start+arr[start]) || canReach(arr, start-arr[start]); + + } + + public int minJump(int[] nums) { + if(nums==null || nums.length==0) return 0; + int currentMax=0; + int currentEnd=0; + int jumps=0; + + for(int i=0;i=nums.length-1){ // if the current pick solves the issue + jumps++; + break; + } + //Once the current point reaches curEnd, + //then trigger another jump, and set the new curEnd with curFarthest, + //then keep the above steps, as the following: + if(currentEnd==i){ // when the current pick of ladder reached last step + jumps++; + currentEnd=currentMax; + } + } + return jumps; + } + + public static void main(String[] args) { + + List list= Arrays.asList(new Integer[]{3,3,1,0, 2,0,1}); + System.out.println(canReachEnd(list)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/KClosestElements.java b/src/geeksforgeeks/KClosestElements.java new file mode 100644 index 0000000..6ea0cd5 --- /dev/null +++ b/src/geeksforgeeks/KClosestElements.java @@ -0,0 +1,66 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.PriorityQueue; + +/** + * Given a sorted array arr, two integers k and x, find the k closest elements to x in the array. + * Input: arr = [1,2,3,4,5], k = 4, x = 3 +Output: [1,2,3,4] + */ +public class KClosestElements { + public List findClosestElements(int[] arr, int k, int x) { + // since this is sorted array we are making use of binary search to get index of X and + // fix the range between index-K to index+K and doing normal PQ solution + int index= binarySearch(arr,x); + //if(index==-1) return Collections.emptyList(); + + int low= Math.max(0,index-k); + int high= Math.min(index+k,arr.length-1); + + PriorityQueue queue= new PriorityQueue<>((a, b)->Integer.compare(a.key,b.key)); + + for(int i=low;i<=high;i++){ + // taking abs value because question is askin closest in both signs + queue.offer(new Entry(Math.abs(arr[i]-x),i)); + } + List result= new ArrayList<>(); + int i=0; + while(i0){ + start--; + } + return start; + } +} + +class Entry{ + int key; + int value; + public Entry(int key, int value){ + this.key=key; + this.value=value; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/KmostFrequentLetters.java b/src/geeksforgeeks/KmostFrequentLetters.java new file mode 100644 index 0000000..a5d1022 --- /dev/null +++ b/src/geeksforgeeks/KmostFrequentLetters.java @@ -0,0 +1,42 @@ +package geeksforgeeks; + +import java.util.*; + +public class KmostFrequentLetters { + public static void main(String[] args) { + int k1 = 2; + String[] keywords1 = { "anacell", "cetracular", "betacellular" }; + String[] reviews1 = { "Anacell provides the best services in the city", "betacellular has awesome services", + "Best services provided by anacell, everyone should use anacell", }; + int k2 = 2; + String[] keywords2 = { "anacell", "betacellular", "cetracular", "deltacellular", "eurocell" }; + String[] reviews2 = { "I love anacell Best services; Best services provided by anacell", + "betacellular has great services", "deltacellular provides much better services than betacellular", + "cetracular is worse than anacell", "Betacellular is better than deltacellular.", }; + System.out.println(solve(k1, keywords1, reviews1)); + System.out.println(solve(k2, keywords2, reviews2)); + } + + private static List solve(int k, String[] keywords, String[] reviews) { + List res = new ArrayList<>(); + Set set = new HashSet<>(Arrays.asList(keywords)); + Map map = new HashMap<>(); + for(String r : reviews) { + String[] strs = r.split("\\W"); + Set added = new HashSet<>(); // creating a set per review to vaoid duplicate within a review + for(String s : strs) { + s = s.toLowerCase(); + if(set.contains(s) && !added.contains(s)) { + map.put(s, map.getOrDefault(s, 0) + 1); + added.add(s); + } + } + } + PriorityQueue> maxHeap = new PriorityQueue<>((a, b)->a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue()); + maxHeap.addAll(map.entrySet()); + while(!maxHeap.isEmpty() && k-- > 0) { + res.add(maxHeap.poll().getKey()); + } + return res; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/KthClosestOrigin.java b/src/geeksforgeeks/KthClosestOrigin.java index 323ebef..fb4967c 100644 --- a/src/geeksforgeeks/KthClosestOrigin.java +++ b/src/geeksforgeeks/KthClosestOrigin.java @@ -5,95 +5,98 @@ /** * https://leetcode.com/problems/k-closest-points-to-origin/solution/ - * */ class KthClosestOrigin { - static int[][] points = new int[3][2]; - - // quick select - public int[][] kClosest(int[][] points, int K) { - sort(0, points.length - 1, K); - return Arrays.copyOfRange(points, 0, K); - } - - public void sort(int i, int j, int K) { - if (i >= j) - return; - int k = new Random().nextInt(j - i + 1) + i; - swap(i, k); - - int mid = partition(i, j); - int leftLength = mid - i + 1; - if (K < leftLength) - sort(i, mid - 1, K); - else if (K > leftLength) - sort(mid + 1, j, K - leftLength); - } - - public int partition(int i, int j) { - int oi = i; - int pivot = dist(i); - i++; - - while (true) { - while (i < j && dist(i) < pivot) - i++; - while (i <= j && dist(j) > pivot) - j--; - if (i >= j) - break; - swap(i, j); - } - swap(oi, j); - return j; - } - - public int dist(int i) { - return points[i][0] * points[i][0] + points[i][1] * points[i][1]; - } - - public void swap(int i, int j) { - int t0 = points[i][0], t1 = points[i][1]; - points[i][0] = points[j][0]; - points[i][1] = points[j][1]; - points[j][0] = t0; - points[j][1] = t1; - } - - public int[][] kClosestOLogN(int[][] points, int K) { - int N = points.length; - int[] dists = new int[N]; - for (int i = 0; i < N; ++i) - dists[i] = distOLogN(points[i]); - - Arrays.sort(dists); - int distK = dists[K - 1]; - - int[][] ans = new int[K][2]; - int t = 0; - for (int i = 0; i < N; ++i) - if (distOLogN(points[i]) <= distK) - ans[t++] = points[i]; - return ans; - } - - public int distOLogN(int[] point) { - return point[0] * point[0] + point[1] * point[1]; - } - - public static void main(String[] args) { - KthClosestOrigin kth = new KthClosestOrigin(); - points[0][0] = 3; - points[0][1] = 3; - - points[1][0] = 5; - points[1][1] = -1; - - points[2][0] = 2; - points[2][1] = 4; - - // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); - System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); - } + static int[][] points = new int[3][2]; + + // quick select + public int[][] kClosest(int[][] points, int K) { + sort(0, points.length - 1, K); + return Arrays.copyOfRange(points, 0, K); + } + + public void sort(int i, int j, int K) { + if (i >= j) { + return; + } + int k = new Random().nextInt(j - i + 1) + i; + swap(i, k); + + int mid = partition(i, j); + int leftLength = mid - i + 1; + if (K < leftLength) { + sort(i, mid - 1, K); + } else if (K > leftLength) { + sort(mid + 1, j, K - leftLength); + } + } + + public int partition(int i, int j) { + int oi = i; + int pivot = dist(i); + i++; + + while (true) { + while (i < j && dist(i) < pivot) + i++; + while (i <= j && dist(j) > pivot) + j--; + if (i >= j) { + break; + } + swap(i, j); + } + swap(oi, j); + return j; + } + + public int dist(int i) { + return points[i][0] * points[i][0] + points[i][1] * points[i][1]; + } + + public void swap(int i, int j) { + int t0 = points[i][0], t1 = points[i][1]; + points[i][0] = points[j][0]; + points[i][1] = points[j][1]; + points[j][0] = t0; + points[j][1] = t1; + } + + public int[][] kClosestOLogN(int[][] points, int K) { + int N = points.length; + int[] dists = new int[N]; + for (int i = 0; i < N; ++i) + dists[i] = distOLogN(points[i]); + + Arrays.sort(dists); + int distK = dists[K - 1]; + + int[][] ans = new int[K][2]; + int t = 0; + for (int i = 0; i < N; ++i) + if (distOLogN(points[i]) <= distK) { + ans[t++] = points[i]; + } + return ans; + } + + public int distOLogN(int[] point) { + return point[0] * point[0] + point[1] * point[1]; + } + + public static void main(String[] args) { + KthClosestOrigin kth = new KthClosestOrigin(); + points[0][0] = 3; + points[0][1] = 3; + + points[1][0] = 5; + points[1][1] = -1; + + points[2][0] = 2; + points[2][1] = 4; + + // System.out.println(Arrays.deepToString(kth.kClosestOLogN(points, 1))); + System.out.println(Arrays.deepToString(kth.kClosest(points, 2))); + } } diff --git a/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java b/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java index b27bf5d..d62166f 100644 --- a/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java +++ b/src/geeksforgeeks/KthSmallestFromTwoSortedArrays.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://www.geeksforgeeks.org/k-th-element-two-sorted-arrays/ + */ class KthSmallestFromTwoSortedArrays { public static int findKth(int[] A, int i, int[] B, int j, int k) { @@ -26,14 +29,15 @@ public static int findKth(int[] A, int i, int[] B, int j, int k) { } public static void main(String[] args) { - int arr1[] = {1,6,8,9,15}; - int arr2[] = {3,5,10,14,20}; + int arr1[] = { 1, 6, 8, 9, 15 }; + int arr2[] = { 3, 5, 10, 14, 20 }; int k = 6; int ans = findKth(arr1, 0, arr2, 0, k); - if (ans == -1) + if (ans == -1) { System.out.println("Invalid query"); - else + } else { System.out.println(ans); + } } } diff --git a/src/geeksforgeeks/KthSmallestMatrix.java b/src/geeksforgeeks/KthSmallestMatrix.java index ac71a24..29bebcb 100644 --- a/src/geeksforgeeks/KthSmallestMatrix.java +++ b/src/geeksforgeeks/KthSmallestMatrix.java @@ -13,17 +13,16 @@ public static int kthSmallest(int[][] matrix, int k) { for (int i = 0; i < k - 1; i++) { Points t = pq.poll(); System.out.println(t.x); - if (t.x == n - 1) + if (t.x == n - 1) { continue; + } pq.offer(new Points(t.x + 1, t.y, matrix[t.x + 1][t.y])); } return pq.poll().val; } public static void main(String[] args) { - int[][] matrix = {{1, 2, 9}, - {3, 11, 13}, - {4, 13, 15}}; + int[][] matrix = { { 1, 2, 9 }, { 3, 11, 13 }, { 4, 13, 15 } }; int k = 4; System.out.println(kthSmallest(matrix, k)); diff --git a/src/geeksforgeeks/LIS2DMatrix.java b/src/geeksforgeeks/LIS2DMatrix.java new file mode 100644 index 0000000..5ea3e62 --- /dev/null +++ b/src/geeksforgeeks/LIS2DMatrix.java @@ -0,0 +1,52 @@ +package geeksforgeeks; + +/** + * DFS + Memoization + *

+ * Traverse all points in matrix, use every point as starting point to do dfs traversal. DFS function returns max increasing + * path after comparing four max return distance from four directions. + */ + +class LIS2DMatrix { + int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + + public int longestIncreasingPath(int[][] matrix) { + + if (matrix.length == 0) return 0; + // i+1,j, i-1,j i,j+1 i,j-1 + Integer[][] cache = new Integer[matrix.length][matrix[0].length]; + //Arrays.fill(cache,-1); + int result = 0; + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix[0].length; j++) { + result = Math.max(dfsUtil(matrix, i, j, cache, Integer.MIN_VALUE), result); + } + } + + return result; + } + + public int dfsUtil(int[][] matrix, int i, int j, Integer[][] cache, int data) { + if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || data >= matrix[i][j]) return 0; + + + if (cache[i][j] != null) return cache[i][j]; + + int max = 1; // every element is an answer to itself + + for (int[] dir : dirs) { + + int x = i + dir[0]; + int y = j + dir[1]; + + int count = 1 + dfsUtil(matrix, x, y, cache, matrix[i][j]); + max = Math.max(count, max); + } + cache[i][j] = max; + + return cache[i][j]; + + } + + +} \ No newline at end of file diff --git a/src/geeksforgeeks/LRUCache.java b/src/geeksforgeeks/LRUCache.java index a4acbc6..5c99caf 100644 --- a/src/geeksforgeeks/LRUCache.java +++ b/src/geeksforgeeks/LRUCache.java @@ -1,132 +1,118 @@ package geeksforgeeks; -/* - https://leetcode.com/problems/lru-cache/ - An adaption of the answer from user "liaison" on Leetcode. - Link: https://leetcode.com/problems/lru-cache/discuss/45911/Java-Hashtable-%2B-Double-linked-list-(with-a-touch-of-pseudo-nodes) - Revision by Benyam Ephrem (Dec. 31th 2018) - > Making variable names more conventional - > Adding more clarifying comments - > Moving code around to be more conventional - This code passes all Leetcode test cases as of Dec. 31st 2018 - Runtime: 77 ms, faster than 95.85% of Java online submissions for LRU Cache. - The video to explain this code is here: https://www.youtube.com/watch?v=S6IfqDXWa10 -*/ - -import java.util.HashMap; -import java.util.Map; - class LRUCache { - - private class DNode { + + class DLLNode{ + DLLNode prev; + DLLNode next; + int val; int key; - int value; - DNode prev; - DNode next; - } - - private Map hashtable = new HashMap<>(); - private DNode head, tail; - private int totalItemsInCache; - private int maxCapacity; - - public LRUCache(int maxCapacity) { - - totalItemsInCache = 0; - this.maxCapacity = maxCapacity; - - head = new DNode(); - head.prev = null; - - tail = new DNode(); - tail.next = null; - - head.next = tail; - tail.prev = head; - } - - public int get(int key) { - - DNode node = hashtable.get(key); - boolean itemFoundInCache = node != null; - - if (!itemFoundInCache) { - return -1; + public DLLNode(int key, int val){ + this.val=val; + this.key=key; } - - moveToHead(node); - - return node.value; } - - public void put(int key, int value) { - - DNode node = hashtable.get(key); - boolean itemFoundInCache = node != null; - - if (!itemFoundInCache) { - - DNode newNode = new DNode(); - newNode.key = key; - newNode.value = value; - - hashtable.put(key, newNode); - addNode(newNode); - - totalItemsInCache++; - - if (totalItemsInCache > maxCapacity) { - removeLRUEntryFromStructure(); + Map map; + DLLNode head; + DLLNode tail; + int capacity=0; + public LRUCache(int capacity) { + map= new HashMap<>(); + head= new DLLNode(-1,-1); + tail= new DLLNode(-1,-1); + head.next=tail; + tail.prev=head; + this.capacity=capacity; + } + + public int get(int key) { + if(!map.containsKey(key)) return -1; + DLLNode node= map.get(key); + update(node); + return node.val; + } + + public void put(int key, int value) { + if(map.containsKey(key)){ + DLLNode node= map.get(key); + node.val=value; + update(node); + }else{ + if(map.size()>=capacity){ + removeTail(); + } + DLLNode newNode= new DLLNode(key,value); + map.put(key, newNode); + + updateHead(newNode); } - - } else { - node.value = value; - moveToHead(node); + } + + public void removeTail(){ + DLLNode tailNode=tail.prev; + remove(tailNode); + map.remove(tailNode.key); + } + + public void updateHead(DLLNode node){ + node.prev = head; + node.next = head.next; + head.next.prev = node; + head.next = node; + } + + public void remove(DLLNode node){ + DLLNode next= node.next; + DLLNode prev= node.prev; + prev.next=next; + next.prev=prev; + } + public void update(DLLNode node){ + remove(node); + updateHead(node); } } - - private void removeLRUEntryFromStructure() { - DNode tail = popTail(); - hashtable.remove(tail.key); - --totalItemsInCache; - } - - private void addNode(DNode node) { - - node.prev = head; - node.next = head.next; - - head.next.prev = node; - head.next = node; - } - - private void removeNode(DNode node) { - - DNode savedPrev = node.prev; - DNode savedNext = node.next; - - savedPrev.next = savedNext; - savedNext.prev = savedPrev; - } - - private void moveToHead(DNode node) { - removeNode(node); - addNode(node); - } - - private DNode popTail() { - DNode itemBeingRemoved = tail.prev; - removeNode(itemBeingRemoved); - return itemBeingRemoved; - } - - public static void main(String[] args) { - LRUCache lru = new LRUCache(3); - lru.put(1, 1); - lru.put(2, 2); - lru.put(3, 3); - lru.put(2, 2); - lru.put(4, 4); - lru.put(2, 2); - lru.put(3, 3); + + + class LRUCache1 { + LinkedHashMap isbnToPrice; + + LRUCache(final int capacity) { + this.isbnToPrice + = new LinkedHashMap(capacity, 1f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry e) { + return this.size() > capacity; + } + }; + } + + public Integer lookup(Integer key) { + if (!isbnToPrice.containsKey(key)) { + return null; + } + return isbnToPrice.get(key); + } + + public Integer insert(Integer key, Integer value) { + // We add the value for key only if key is not present - we don’t update + // existing values. + Integer currentValue = isbnToPrice.get(key); + if (!isbnToPrice.containsKey(key)) { + isbnToPrice.put(key, value); + return currentValue; + } else { + return null; + } + } + + public Integer erase(Object key) { + return isbnToPrice.remove(key); + } + } -} + /** + * Your LRUCache object will be instantiated and called as such: + * LRUCache obj = new LRUCache(capacity); + * int param_1 = obj.get(key); + * obj.put(key,value); + */ \ No newline at end of file diff --git a/src/geeksforgeeks/LargestDivisibleSubset.java b/src/geeksforgeeks/LargestDivisibleSubset.java new file mode 100644 index 0000000..e52f5d2 --- /dev/null +++ b/src/geeksforgeeks/LargestDivisibleSubset.java @@ -0,0 +1,64 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies: + Si % Sj = 0 or Sj % Si = 0. + If there are multiple solutions, return any subset is fine. + Input: [2,3,4,6,10,8,24] + Output: [2,4,8,24] each pair's modulo is 0 + */ +public class LargestDivisibleSubset { + + /** + * if a%b==0 means a>b, if b>a then the ans is b itself + *inorder to have that we need to sort the array in increasing order + at first each val is ans to itself, then we come from last so a is higher in a%b + [2, 3, 4, 6, 8, 10, 24] + {2} {3} {4} {6} {8} {10} {24} + {8,24} + + {6,24} + + {4,8,24} + + {3,6,24} + + {2,4,8,24} + * + */ + public List largestDivisibleSubset(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + Arrays.sort(nums); + List[] result= new ArrayList[nums.length]; + + int maxLength=0; + int resIndex=-1; + List re; + + for(int i=nums.length-1;i>=0;i--){ + result[i]=new ArrayList<>(); // every element is an answer itself + re= new ArrayList<>(); + result[i].add(nums[i]); + for(int j=i+1;j re.size()){ // this is to take even if 1 element is at j position + re=result[j]; // the reason we take list is consider 4,8,24 when i is at 4 and j is 8 mod is 0 means 4%24 is also zero + } + } + } + result[i].addAll(re); + if(result[i].size()>maxLength){ + maxLength=result[i].size(); + resIndex=i; + } + } + Collections.sort(result[resIndex]); + return result[resIndex]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LargestPossibleNumber.java b/src/geeksforgeeks/LargestPossibleNumber.java index 9f349c3..398815f 100644 --- a/src/geeksforgeeks/LargestPossibleNumber.java +++ b/src/geeksforgeeks/LargestPossibleNumber.java @@ -5,9 +5,13 @@ import java.util.Comparator; import java.util.List; +/** + * https://www.geeksforgeeks.org/given-an-array-of-numbers-arrange-the-numbers-to-form-the-biggest-number/ + */ class LargestPossibleNumber { + public static void main(String[] args) { - int nums[] = {10, 68, 97, 9, 21, 12}; + int nums[] = { 10, 68, 97, 9, 21, 12 }; List numbers = Arrays.asList("10", "68", "97", "9", "21", "12"); Collections.sort(numbers, (a, b) -> (b + a).compareTo(a + b)); @@ -21,10 +25,9 @@ public String largestNumber(int[] nums) { arr[i] = String.valueOf(nums[i]); } - Arrays.sort(arr, - (a, b) -> { - return (b + a).compareTo(a + b); - }); + Arrays.sort(arr, (a, b) -> { + return (b + a).compareTo(a + b); + }); StringBuilder sb = new StringBuilder(); for (String s : arr) { @@ -36,4 +39,17 @@ public String largestNumber(int[] nums) { return sb.toString(); } + + public String largestNumber1(int[] nums) { + if(nums==null || nums.length==0) return null; + List list= new LinkedList<>(); + for(int i: nums){ + list.add(String.valueOf(i)); + } + + Collections.sort(list, (a,b)->(int)(Long.parseLong(b+a)-Long.parseLong(a+b))); + + return String.join("",list).replaceFirst("^0+(?!$)", ""); + + } } \ No newline at end of file diff --git a/src/geeksforgeeks/LargestSubArray.java b/src/geeksforgeeks/LargestSubArray.java deleted file mode 100644 index 6abddb7..0000000 --- a/src/geeksforgeeks/LargestSubArray.java +++ /dev/null @@ -1,53 +0,0 @@ -package geeksforgeeks; - -import java.util.HashMap; - -/*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/*/ -class LargestSubArray { - - int maxLen(int arr[], int n) { - - HashMap map = new HashMap<>(); - - int sum = 0; - int maxLength = 0; - int endingIndex = -1; - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == 0) ? -1 : 1; - } - - for (int i = 0; i < n; i++) { - sum += arr[i]; - if (sum == 0) { - maxLength = i + 1; - endingIndex = i; - } - - if (map.containsKey(sum)) { - if (maxLength < i - map.get(sum)) { - maxLength = i - map.get(sum); - endingIndex = i; - } - } else - map.put(sum, i); - } - - for (int i = 0; i < n; i++) { - arr[i] = (arr[i] == -1) ? 0 : 1; - } - - int start = endingIndex - maxLength + 1; - System.out.println(start + " to " + endingIndex); - - return maxLength; - } - - public static void main(String[] args) { - LargestSubArray sub = new LargestSubArray(); - int arr[] = {0, 0, 0, 1, 0, 1, 1}; - int n = arr.length; - - sub.maxLen(arr, n); - } -} diff --git a/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java b/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java new file mode 100644 index 0000000..2d5e893 --- /dev/null +++ b/src/geeksforgeeks/LargestSubArrayWithZeroesAndOnes.java @@ -0,0 +1,68 @@ +package geeksforgeeks; + +import java.util.HashMap; + +/*https://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/ + Given an array containing only 0s and 1s, find the largest subarray which contains equal no of 0s and 1s. + Expected time complexity is O(n). +*/ +class LargestSubArrayWithZeroesAndOnes { + /** + * The concept of taking cumulative sum, taking 0’s as -1 will help us in optimising the approach. + * While taking the cumulative sum, there are two cases when there can be a sub-array with equal number of 0’s and 1’s + * When cumulative sum=0, which signifies that sub-array from index (0) till present index has equal number of 0’s and 1’s. + * + * When we encounter a cumulative sum value which we have already encountered before, + * which means that sub-array from the previous index+1 till the present index has equal number of 0’s and 1’s as they give a cumulative sum of 0 . + * @param arr + * @param n + * @return + */ + int maxLen(int arr[], int n) { + + HashMap map = new HashMap<>(); + + int sum = 0; + int maxLength = 0; + int endingIndex = -1; + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == 0) ? -1 : 1; + } + + for (int i = 0; i < n; i++) { + sum += arr[i]; + + if (sum == 0) { // To handle sum=0 at last index + maxLength = i + 1; + endingIndex = i; + } + // If this sum is seen before, + // then update max_len if required + if (map.containsKey(sum)) { + if (maxLength < i - map.get(sum)) { + maxLength = i - map.get(sum); + endingIndex = i; + } + } else + map.put(sum, i); + } + + for (int i = 0; i < n; i++) { + arr[i] = (arr[i] == -1) ? 0 : 1; + } + + int start = endingIndex - maxLength + 1; + System.out.println(start + " to " + endingIndex); + + return maxLength; + } + + public static void main(String[] args) { + LargestSubArrayWithZeroesAndOnes sub = new LargestSubArrayWithZeroesAndOnes(); + int arr[] = {0, 0, 0, 1, 0, 1, 1}; + int n = arr.length; + + sub.maxLen(arr, n); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java b/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java new file mode 100644 index 0000000..f832355 --- /dev/null +++ b/src/geeksforgeeks/LengthOfLongestSubstringKDistinct.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +import java.util.HashMap; +import java.util.Map; + +public class LengthOfLongestSubstringKDistinct { + /** + * @param s: A string + * @param k: An integer + * + * @return: An integer + */ + public int lengthOfLongestSubstringKDistinct(String s, int k) { + if (s == null || k == 0) { + return 0; + } + Map map = new HashMap<>(); + + int result = 0; + int left = 0; + int right = 0; + + while (left < s.length()) { + char ch = s.charAt(left); + map.put(ch, map.getOrDefault(ch, 0) + 1); + while (map.size() > k) { + char chright = s.charAt(right); + map.put(chright, map.get(chright) - 1); + if (map.get(chright) <= 0) { + map.remove(chright); + } + right++; + } + left++; + result = Math.max(result, left - right); + } + + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LinkedListRemoveDuplicates.java b/src/geeksforgeeks/LinkedListRemoveDuplicates.java new file mode 100644 index 0000000..029e418 --- /dev/null +++ b/src/geeksforgeeks/LinkedListRemoveDuplicates.java @@ -0,0 +1,36 @@ +package geeksforgeeks; + +class LinkedListRemoveDuplicate{ + /** + * Method to remove duplicates from Linked list + * when no additional buffer is allowed. + * + * Time Complexity : O(n^2) + * Space Complexity : O(1) + * + * @param head + */ + public static void removeDuplicatesWithoutBuffer(LinkedListNode head) { + /* If head is null, stop processing */ + if (head == null) { + return; + } + /* We will need two pointers here i.e current and runner. + * When current is pointing to a node, move runner through + * rest of the list, checking for duplicates */ + LinkedListNode current = head; + while (current != null) { + /* Have runner point to current node */ + LinkedListNode runner = current; + while (runner.next != null) { + /* If it is duplicate, jump runner over the node */ + if (runner.next.data == current.data) { + runner.next = runner.next.next; + } else { + runner = runner.next; + } + } + current = current.next; + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LiveCellDeadCellGame.java b/src/geeksforgeeks/LiveCellDeadCellGame.java new file mode 100644 index 0000000..9ec83b4 --- /dev/null +++ b/src/geeksforgeeks/LiveCellDeadCellGame.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +//https://leetcode.com/problems/game-of-life/discuss/73366/Clean-O(1)-space-O(mn)-time-Java-Solution +public class LiveCellDeadCellGame { + public void gameOfLife(int[][] board) { + int[][] dir = { { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, -1 }, { 0, 1 }, { -1, -1 }, { -1, 0 }, { -1, 1 } }; + int row = board.length; + int col = board[0].length; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + int liveCells = 0; + for (int k = 0; k < dir.length; k++) { + if (i + dir[k][0] >= row || j + dir[k][1] >= col || i + dir[k][0] < 0 || j + dir[k][1] < 0) { + continue; + } + if (board[i + dir[k][0]][j + dir[k][1]] == 1 || board[i + dir[k][0]][j + dir[k][1]] == 2) { + liveCells++; + } + } + + if (board[i][j] == 0 && liveCells == 3) { + board[i][j] = 3; + } + if (board[i][j] == 1 && (liveCells < 2 || liveCells > 3)) { + board[i][j] = 2; + } + } + } + + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + board[i][j] %= 2; + } + } + + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestConsequtiveSequence.java b/src/geeksforgeeks/LongestConsequtiveSequence.java new file mode 100644 index 0000000..1eea844 --- /dev/null +++ b/src/geeksforgeeks/LongestConsequtiveSequence.java @@ -0,0 +1,71 @@ +package geeksforgeeks; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + * + * Your algorithm should run in O(n) complexity. + * Input: [100, 4, 200, 1, 3, 2] + * Output: 4 + * Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. + */ +class LongestConsequtiveSequence { + + public int longestConsecutive(int[] nums) { + if (nums.length == 0) { + return 0; + } + int max = 1; + Set set = new HashSet<>(); + for (int i : nums) { + set.add(i); + } + // have a set, go backwards and remove entries, go forward remove entries and calculate Max + // without removing entries, runtime would be too much + for (Integer i : nums) { + int num = i; + int count = 1; + // looking left; + while (set.contains(--num)) { + count++; + set.remove(num); + } + num = i; + while (set.contains(++num)) { + count++; + set.remove(num); + } + + max = Math.max(max, count); + } + + return max; + } + + public int longestConsecutiveSorting(int[] nums) { + if (nums == null || nums.length == 0) + return 0; + + Arrays.sort(nums); + + int longestStreak = 1; + int currentStreak = 1; + + for (int i = 0; i < nums.length - 1; i++) { + if (nums[i] != nums[i+1]) { // avoid duplicate + if (nums[i] + 1 == nums[i+1]) { // if increasing increase streak count else reset + currentStreak += 1; + } + else { + longestStreak = Math.max(longestStreak, currentStreak); + currentStreak = 1; + } + } + } + + return Math.max(longestStreak, currentStreak); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestRepeatCharReplace.java b/src/geeksforgeeks/LongestRepeatCharReplace.java new file mode 100644 index 0000000..4cf5039 --- /dev/null +++ b/src/geeksforgeeks/LongestRepeatCharReplace.java @@ -0,0 +1,47 @@ +package geeksforgeeks; + +// you can perform at most k operations on that string. +// In one operation, you can choose any character of the string and change it to any other uppercase English character. +// Find the length of the longest sub-string containing all repeating letters +// s = "ABAB", k = 2 +// Output: +// 4 +// Explanation: +// Replace the two 'A's with two 'B's or vice versa. +public class LongestRepeatCharReplace { + public int characterReplacement(String s, int k) { + if(s==null || s.length()==0) return 0; + + int[] cache= new int[26]; + int left=0; + int right=0; + int result=0; + int maxOccured=0; + while(right 0, then we have characters in the window that are NOT the character that occurs the most. + // end-start+1-maxCount is equal to exactly the # of characters that are NOT the character that occurs the most in that window. + //Example: For a window "xxxyz", end-start+1-maxCount would equal 2. (maxCount is 3 and there are 2 characters here, "y" and "z" that are not "x" in the window.) + // We are allowed to have at most k replacements in the window, so when end-start+1-maxCount > k, + //then there are more characters in the window than we can replace, and we need to shrink the window. + // If we have window with "xxxy" and k = 1, that's fine because end-start+1-maxCount = 1, which is not > k. maxLength gets updated to 4. + // But if we then find a "z" after, like "xxxyz", then we need to shrink the window because now end-start+1-maxCount = 2, and 2 > 1. The window becomes "xxyz". + if(right-left+1-maxOccured > k){ + char leftchr= s.charAt(left); + --cache[leftchr-'A']; + left++; + } + result=Math.max(result, right-left+1); + right++; + } + + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/LongestSpanWithSameSumArray.java b/src/geeksforgeeks/LongestSpanWithSameSumArray.java index 71fe75b..dee75cb 100644 --- a/src/geeksforgeeks/LongestSpanWithSameSumArray.java +++ b/src/geeksforgeeks/LongestSpanWithSameSumArray.java @@ -1,42 +1,69 @@ package geeksforgeeks; -import java.util.HashMap; - /*https://www.geeksforgeeks.org/longest-span-sum-two-binary-arrays/*/ class LongestSpanWithSameSumArray { static int longestCommonSum(int[] arr1, int[] arr2, int n) { - int[] arr = new int[n]; - for (int i = 0; i < n; i++) - arr[i] = arr1[i] - arr2[i]; + int maxLen = 0; + + // Initialize prefix sums of two arrays + int preSum1 = 0, preSum2 = 0; - HashMap map = new HashMap<>(); + // Create an array to store staring and ending + // indexes of all possible diff values. diff[i] + // would store starting and ending points for + // difference "i-n" - int sum = 0; - int maxLength = 0; + int diff[] = new int[2*n+1]; - for (int i = 0; i < n; i++) { + // Initialize all starting and ending values as -1. + for (int i = 0; i < diff.length; i++) { + diff[i] = -1; + } - sum += arr[i]; + // Traverse both arrays + for (int i=0; i maxLen) + maxLen = len; + } } - return maxLength; + return maxLen; } public static void main(String args[]) { /* int[] arr1 = {0, 1, 0, 1, 1, 1, 1}; int[] arr2 = {1, 1, 1, 1, 1, 0, 1};*/ - int arr1[] = {0, 1, 0, 0, 1, 1, 1, 0}; - int arr2[] = {1, 1, 1, 1, 1, 1, 0, 1}; + int arr1[] = { 0, 1, 0, 0, 1, 1, 1, 0 }; + int arr2[] = { 1, 1, 1, 1, 1, 1, 0, 1 }; //{-1,0,-1,0,0,1,0} int n = arr1.length; System.out.println(longestCommonSum(arr1, arr2, n)); diff --git a/src/geeksforgeeks/LongestSubArraySumUtmostK.java b/src/geeksforgeeks/LongestSubArraySumUtmostK.java index 43e306e..093bb04 100644 --- a/src/geeksforgeeks/LongestSubArraySumUtmostK.java +++ b/src/geeksforgeeks/LongestSubArraySumUtmostK.java @@ -6,31 +6,28 @@ // array is non-negative class LongestSubArraySumUtmostK { - public static int atMostSum(int arr[], int n, int target) { + public static int utMostSum(int arr[], int n, int target) { int sum = 0; int count = 0; int maxCount = 0; for (int i = 0; i < n; i++) { - //7 if ((sum + arr[i]) <= target) { sum += arr[i]; count++; } else if (sum != 0) { sum = sum - arr[i - count] + arr[i]; } - maxCount = Math.max(count, maxCount); } return maxCount; } public static void main(String[] args) { - int arr[] = {1, 2, 1, 0, 1, 1, 0}; + int arr[] = { 1, 2, 1, 0, 1, 1, 0 }; int n = arr.length; int k = 4; - System.out.print(atMostSum(arr, n, k)); - + System.out.print(utMostSum(arr, n, k)); } } diff --git a/src/geeksforgeeks/LongestUniqueSubstring.java b/src/geeksforgeeks/LongestUniqueSubstring.java index 289e2b0..21b6f58 100644 --- a/src/geeksforgeeks/LongestUniqueSubstring.java +++ b/src/geeksforgeeks/LongestUniqueSubstring.java @@ -5,6 +5,7 @@ /*https://leetcode.com/problems/longest-substring-without-repeating-characters/*/ public class LongestUniqueSubstring { + public static int lengthOfLongestSubstring(String s) { Map map = new HashMap<>(); int begin = 0; @@ -15,12 +16,16 @@ public static int lengthOfLongestSubstring(String s) { while (end < s.length()) { char c = s.charAt(end); map.put(c, map.getOrDefault(c, 0) + 1); - if (map.get(c) > 1) counter++; + if (map.get(c) > 1) { + counter++; + } end++; while (counter > 0) { char charTemp = s.charAt(begin); - if (map.get(charTemp) > 1) counter--; + if (map.get(charTemp) > 1) { + counter--; + } map.put(charTemp, map.get(charTemp) - 1); begin++; } @@ -28,8 +33,21 @@ public static int lengthOfLongestSubstring(String s) { } return result; } + public static int lengthOfLongestSubstringOpt(String s) { + int res = 0, n = s.length(); + int[] arr = new int[256]; + int startIndex=0; + for(int curr=0;curr next index, so that we can start from here + arr[s.charAt(curr)] = curr+1; + } + return res; + } public static void main(String[] args) { - System.out.println(lengthOfLongestSubstring("abccbcbb")); + System.out.println(lengthOfLongestSubstringOpt("pwwkew")); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MajorityVoting.java b/src/geeksforgeeks/MajorityVoting.java index d857bdb..291132a 100644 --- a/src/geeksforgeeks/MajorityVoting.java +++ b/src/geeksforgeeks/MajorityVoting.java @@ -7,24 +7,25 @@ public class MajorityVoting { public static List majorityElementII(int[] nums) { - if (nums == null || nums.length == 0) + if (nums == null || nums.length == 0) { return new ArrayList<>(); + } List result = new ArrayList<>(); - int number1 = nums[0]; - int number2 = nums[0]; + int candidate1 = nums[0]; + int candidate2 = nums[0]; int count1 = 0; int count2 = 0; int len = nums.length; for (int i = 0; i < len; i++) { - if (nums[i] == number1) + if (nums[i] == candidate1) { count1++; - else if (nums[i] == number2) + } else if (nums[i] == candidate2) { count2++; - else if (count1 == 0) { - number1 = nums[i]; + } else if (count1 == 0) { + candidate1 = nums[i]; count1 = 1; } else if (count2 == 0) { - number2 = nums[i]; + candidate2 = nums[i]; count2 = 1; } else { count1--; @@ -34,29 +35,37 @@ else if (count1 == 0) { count1 = 0; count2 = 0; for (int i = 0; i < len; i++) { - if (nums[i] == number1) + if (nums[i] == candidate1) { count1++; - else if (nums[i] == number2) + } else if (nums[i] == candidate2) { count2++; + } + } + if (count1 > len / 3) { + result.add(candidate1); + } + if (count2 > len / 3) { + result.add(candidate2); } - if (count1 > len / 3) - result.add(number1); - if (count2 > len / 3) - result.add(number2); return result; } public static int majorityElementI(int[] nums) { - int count = 0; - int candidate = 0; + int count = 1; + int candidate = nums[0]; int majority = nums.length / 2; - for (int num : nums) { - if (count == 0) { - candidate = num; + for (int i = 1; i < nums.length; i++) { + if (candidate == nums[i]) { + count++; + } else if (count == 0) { + count++; + candidate = nums[i]; + } else { + count--; } - count += (num == candidate) ? 1 : -1; } + //what if array is even and it has many elements count = 0; for (int num : nums) { if (num == candidate) { @@ -68,9 +77,10 @@ public static int majorityElementI(int[] nums) { } public static void main(String[] args) { - int[] arr = {1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2}; + int[] arr = { 1, 1, 1, 1, 1, 2, 2, 4, 4, 4, 4, 4, 2, 2 }; System.out.println(majorityElementI(arr)); System.out.println(majorityElementII(arr)); + } } diff --git a/src/geeksforgeeks/MakeAnArrayPalindrome.java b/src/geeksforgeeks/MakeAnArrayPalindrome.java index 775cb12..8234a81 100644 --- a/src/geeksforgeeks/MakeAnArrayPalindrome.java +++ b/src/geeksforgeeks/MakeAnArrayPalindrome.java @@ -34,7 +34,7 @@ else if (arr[i] > arr[j]) { } public static void main(String[] args) { - int arr[] = new int[]{1, 4, 5, 9, 1}; + int arr[] = new int[] { 1, 4, 5, 9, 1 }; System.out.println("Count of minimum operations is " + findMinOps(arr, arr.length)); } diff --git a/src/geeksforgeeks/MatrixRowWithMax1.java b/src/geeksforgeeks/MatrixRowWithMax1.java index c71f828..0a278e9 100644 --- a/src/geeksforgeeks/MatrixRowWithMax1.java +++ b/src/geeksforgeeks/MatrixRowWithMax1.java @@ -6,7 +6,7 @@ public class MatrixRowWithMax1 { public static void main(String[] args) { - int[][] mat = {{0, 0, 0, 1}, {0, 1, 1, 1}, {1, 1, 1, 1}, {0, 0, 0, 0}}; + int[][] mat = { { 0, 0, 0, 1 }, { 0, 1, 1, 1 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } }; System.out.println(rowWithMax1s(mat)); } @@ -17,8 +17,9 @@ static int rowWithMax1s(int mat[][]) { int max_row_index = 0; int j = findFirstIndex(mat[0], 0, C - 1); - if (j == -1) + if (j == -1) { j = C - 1; + } for (int i = 1; i < R; i++) { while (j >= 0 && mat[i][j] == 1) { @@ -33,14 +34,13 @@ static int findFirstIndex(int arr[], int low, int high) { if (high >= low) { int mid = low + (high - low) / 2; - if ((mid == 0 || (arr[mid - 1] == 0)) && arr[mid] == 1) + if ((mid == 0 || (arr[mid - 1] == 0)) && arr[mid] == 1) { return mid; - - else if (arr[mid] == 0) + } else if (arr[mid] == 0) { return findFirstIndex(arr, (mid + 1), high); - - else + } else { return findFirstIndex(arr, low, (mid - 1)); + } } return -1; } diff --git a/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java new file mode 100644 index 0000000..97589ed --- /dev/null +++ b/src/geeksforgeeks/MaxDistinctElementAfterKRemoval.java @@ -0,0 +1,117 @@ +package geeksforgeeks; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * Given an array arr[] containing n elements. The problem is to find maximum number of distinct elements (non-repeating) after removing k elements from the array. + * Input : arr[] = {5, 7, 5, 5, 1, 2, 2}, k = 3 + * Output : 4 + * + * Remove 2 occurrences of element 5 and + * 1 occurrence of element 2. + * + * Input : arr[] = {1, 2, 3, 4, 5, 6, 7}, k = 5 + * Output : 2 + */ +public class MaxDistinctElementAfterKRemoval { + // after removing k elements + + /** + * Create a hash table to store the frequency of each element. + * Insert frequency of each element in a max heap. + * Now, perform the following operation k times. + * Remove an element from the max heap. Decrement its value by 1. After this if element is not equal to 0, then again push the element in the max heap. + * @param arr + * @param n + * @param k + * @return + */ + static int maxDistinctNum(int[] arr, int n, int k) + { + // hash map to store + // frequency of each element + HashMap map = new HashMap<>(); + + // priority_queue 'pq' implemented as + // max heap + PriorityQueue pq = + new PriorityQueue<>(Collections.reverseOrder()); + + // storing frequency of each element in map + for (int i = 0; i < n; i++) { + map.put(arr[i], map.getOrDefault(arr[i],0)+1); + } + + // inserting frequency of each element in 'pq' + for (Map.Entry entry : map.entrySet()) { + pq.add(entry.getValue()); + } + + while (k > 0) { + // get the top element of 'pq' + int temp = pq.poll(); + + // decrement the popped element by 1 + temp--; + + // if true, then push the element in 'pq' + if (temp > 0) + pq.add(temp); + k--; + } + + // Count all those elements that appear + // once after above operations. + int res = 0; + while (pq.size() != 0) { + pq.poll(); + res++; + } + + return res; + } + + /** + * Given an array of integers arr and an integer k. Find the least number of unique integers after removing exactly k elements. + * Input: arr = [5,5,4], k = 1 + * Output: 1 + * Explanation: Remove the single 4, only 5 is left. + * + * Input: arr = [4,3,1,1,3,3,2], k = 3 + * Output: 2 + * Explanation: Remove 4, 2 and either one of the two 1s or three 3s. 1 and 3 will be left. + * @param arr + * @param k + * @return + */ + public int findLeastNumOfUniqueInts(int[] arr, int k) { + if(arr.length==0) return 0; + Map frequencyMap= new HashMap<>(); + + for(int i: arr){ + frequencyMap.put(i,frequencyMap.getOrDefault(i,0)+1); + } + + PriorityQueue maxQueue= new PriorityQueue<>(); + + for(Map.Entry entry: frequencyMap.entrySet()){ + maxQueue.offer(entry.getValue()); + } + + while(k-- >0){ + int temp= maxQueue.poll(); + temp-=1; + if(temp>0) maxQueue.offer(temp); + + } + + int result=0; + while(!maxQueue.isEmpty()){ + result++; + } + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxFreqStack.java b/src/geeksforgeeks/MaxFreqStack.java new file mode 100644 index 0000000..624051d --- /dev/null +++ b/src/geeksforgeeks/MaxFreqStack.java @@ -0,0 +1,74 @@ +package geeksforgeeks; + +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * FreqStack has two functions: + * + * push(int x), which pushes an integer x onto the stack. + * pop(), which removes and returns the most frequent element in the stack. + * If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned. + * ["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"], + * [[],[5],[7],[5],[7],[4],[5],[],[],[],[]] + * Output: [null,null,null,null,null,null,null,5,7,5,4] + * Explanation: + * After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top. Then: + * + * pop() -> returns 5, as 5 is the most frequent. + * The stack becomes [5,7,5,7,4]. + * + * pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top. + * The stack becomes [5,7,5,4]. + * + * pop() -> returns 5. + * The stack becomes [5,7,4]. + * + * pop() -> returns 4. + * The stack becomes [5,7]. + */ +public class MaxFreqStack { + + PriorityQueue maxQueue; + Map hashMap; + int sequence = 0; + + public MaxFreqStack() { + + maxQueue= new PriorityQueue<>((a,b)->{ + if(a.frequency==b.frequency){ + return Integer.compare(b.sequence,a.sequence); + } + return Integer.compare(b.frequency,a.frequency); + }); + hashMap= new HashMap<>(); + } + + public void push(int x) { + hashMap.put(x, hashMap.getOrDefault(x, 0) + 1); + maxQueue.offer(new EntryStack(x, hashMap.get(x), sequence++)); + } + + public int pop() { + EntryStack temp = maxQueue.poll(); + hashMap.put(temp.val, temp.frequency - 1); + + return temp.val; + } +} + +// 1. val = value of the number +// 2. frequency = current frequency of the number when it was pushed to the heap +// 3. sequenceNumber = a sequence number, to know what number came first +class EntryStack { + int val; + int frequency; + int sequence; + + public EntryStack(int val, int frequency, int sequence) { + this.val = val; + this.frequency = frequency; + this.sequence = sequence; + } +} diff --git a/src/geeksforgeeks/MaxHistogram.java b/src/geeksforgeeks/MaxHistogram.java new file mode 100644 index 0000000..a860ddd --- /dev/null +++ b/src/geeksforgeeks/MaxHistogram.java @@ -0,0 +1,68 @@ +package geeksforgeeks; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/largest-rectangle-in-histogram/ + */ + +public class MaxHistogram { + + //For any bar i the maximum rectangle is of width r - l - 1 + // where r - is the last coordinate of the bar to the right with height h[r] >= h[i] and + // l - is the last coordinate of the bar to the left which height h[l] >= h[i] + //So if for any i coordinate we know his utmost higher (or of the same height) neighbors to the right and to the left, + // we can easily find the largest rectangle: maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); + + //The main trick is how to effectively calculate lessFromRight and lessFromLeft arrays. + // The trivial solution is to use O(n^2) solution and for each i element + // first find his left/right neighbour in the second inner loop just iterating back or forward: + public static int largestRectangleArea(int[] height) { + if (height == null || height.length == 0) { + return 0; + } + int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current + int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current + lessFromRight[height.length - 1] = height.length; + lessFromLeft[0] = -1; + + // for example in order to lessFromLeft[i]; if height[i - 1] < height[i] then left[i] = i - 1; + // other wise we do not need to start scan from i - 1; we can start the scan from lessFromLeft[i - 1], + // because since lessFromLeft[i - 1] is the first position to the left of i - 1 that have height less than height[i - 1], + // and we know height[i - 1] >= height[i]; so lessFromLeft[i] must be at the left or at lessFromLeft[i - 1]; similar for the right array; + for (int i = 1; i < height.length; i++) { + int p = i - 1; + + while (p >= 0 && height[p] >= height[i]) { + p = lessFromLeft[p]; + } + lessFromLeft[i] = p; + } + + for (int i = height.length - 2; i >= 0; i--) { + int p = i + 1; + + while (p < height.length && height[p] >= height[i]) { + p = lessFromRight[p]; + } + lessFromRight[i] = p; + } + // after both the loop ends, this is the output of left and right + // input [2, 1, 5, 6, 2, 3] + // 0, 1, ,2 3, 4, 5 + // left [-1, -1, 1, 2, 1, 4] => indexes of elements + // right [1, 6, 4, 4, 6, 6] + int maxArea = 0; + for (int i = 0; i < height.length; i++) { + maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1)); + } + System.out.println(Arrays.toString(lessFromLeft)); + System.out.println(Arrays.toString(lessFromRight)); + return maxArea; + } + + public static void main(String[] args) { + int[] arr = new int[] { 2, 1, 5, 6, 2, 3 }; + System.out.println(largestRectangleArea(arr)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxProductString.java b/src/geeksforgeeks/MaxProductString.java new file mode 100644 index 0000000..54bb75d --- /dev/null +++ b/src/geeksforgeeks/MaxProductString.java @@ -0,0 +1,57 @@ +package geeksforgeeks; + +/** + * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) + * where the two words do not share common letters. + * You may assume that each word will contain only lower case letters + * Input: ["abcw","baz","foo","bar","xtfn","abcdef"] + * Output: 16 + * Explanation: The two words can be "abcw", "xtfn". + * + * Input: ["a","aa","aaa","aaaa"] + * Output: 0 + * Explanation: No such pair of words. + */ +public class MaxProductString { + public int maxProduct(String[] words) { + int[] checker = new int[words.length]; + int max = 0; + // populating the checker array with their respective numbers + for (int i = 0; i < checker.length; i++) { + int num = 0; + for (int j = 0; j < words[i].length(); j++) { + // we are making char index in bit to be set + // a 1->1 making first bit marked + // b 2->10 + // c 4->100 + // ab 3->11 // making first and secind marked + // ac 5->101 + // abc 7->111 + // az 33554433->10000000000000000000000001 + + num |= 1 << (words[i].charAt(j) - 'a'); + System.out.println(words[i].charAt(j)+"->"+num+ "->"+Integer.toBinaryString(num) ); + } + + checker[i] = num; + } + + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + // abcd efgd + // 11110000 -> abcd + // 00011110 -> efgd + // and-ing these two might say if even a single char is present in other + if ((checker[i] & checker[j]) == 0) //checking if the two strings have common character + max = Math.max(max, words[i].length() * words[j].length()); + } + } + System.out.println(max); + return max; + } + + + public static void main(String[] args) { + new MaxProductString().maxProduct(new String[]{"abcw", "baz", "foo", "bar", "xtfn", "abcdef"}); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaxSoldiers.java b/src/geeksforgeeks/MaxSoldiers.java new file mode 100644 index 0000000..0866e7a --- /dev/null +++ b/src/geeksforgeeks/MaxSoldiers.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +public class MaxSoldiers { + class Pair{ + int row; + int soldiers; + Pair(int row, int soldiers){ + this.row=row; + this.soldiers=soldiers; + } + } + + public int[] kWeakestRows(int[][] mat, int k) { + int[] result= new int[k]; + PriorityQueue queue= new PriorityQueue<>((a,b)->a.soldiers==b.soldiers?Integer.compare(a.row,b.row):Integer.compare(a.soldiers,b.soldiers)); + int i=0; + int soldiers=0; + for(int []rows: mat){ + int temp= binarySearchUtil(rows, 0, rows.length); + queue.offer(new Pair(i,temp)); + i++; + } + int ind=0; + while(ind map= new HashMap<>(); + Queue stack=new LinkedList(); + stack.offer(root); + map.put(root,1); // if we are assigning head as 0 then the fourmula is left=>2*n+1, right=> 2*n+2 + while(!stack.isEmpty()){ + int width= stack.size(); + int start=0; + int end=0; + for(int i=0;i 0) - previousSum += diff; - else - previousSum = diff; - - if (previousSum > maxSum) - maxSum = previousSum; + static int maxDiff(int arr[], int arr_size) { + int maxDiff = 0; + int minElement = arr[0]; + for (int i = 1; i < arr_size; i++) { + if (arr[i] - minElement > maxDiff) { + maxDiff = arr[i] - minElement; + } + if (arr[i] < minElement) { + minElement = arr[i]; + } } - return maxSum; + return maxDiff; + } + static int maxDiff1(int arr[], int arr_size) { + int maxDiff = 0; + int minElement = arr[0]; + for (int i = 1; i < arr_size; i++) { + if (arr[i] - minElement > maxDiff) { + maxDiff = arr[i] - minElement; + } + if (arr[i] < minElement) { + minElement = arr[i]; + } + } + return maxDiff; } - public static void main(String[] args) { - int arr[] = {2, 4, 1, 3, 10, 8, 5}; - int n = arr.length; - - System.out.print("Maximum difference is " + maxDiff(arr, n)); + int arr[] = { 2, 4, 1, 3, 10, 8, 5 }; + System.out.println("Maximum difference is " + maxDiff(arr, arr.length)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/MaximumGap.java b/src/geeksforgeeks/MaximumGap.java new file mode 100644 index 0000000..64342fd --- /dev/null +++ b/src/geeksforgeeks/MaximumGap.java @@ -0,0 +1,70 @@ +package geeksforgeeks; + +/** + * Given an unsorted array, find the maximum difference between the successive elements in its sorted form. +Return 0 if the array contains less than 2 elements. +Input: [3,6,9,1] +Output: 3 +Explanation: The sorted form of the array is [1,3,6,9], either + (3,6) or (6,9) has the maximum difference 3. + + +trick is to do in O(N)= > Radix sort + */ +public class MaximumGap { + // The first step is to find the maximum value in nums array, it will + // be the threshold to end while loop. + // Then use the radix sort algorithm to sort based on each digit from Least Significant Bit + // (LSB) to Most Significant Bit (MSB), that's exactly what's showing + // in the link. + // (nums[i] / exp) % 10 is used to get the digit, for each digit, basically the digit itself serves as the index to + // access the count array. Count array stores the index to access aux + // array which stores the numbers after sorting based on the current + // digit. + // Finally, find the maximum gap from sorted array. + // Time and space complexities are both O(n). (Actually time is O(10n) at worst case for Integer.MAX_VALUE 2147483647) + public int maximumGap(int[] nums) { + if (nums == null || nums.length < 2) { + return 0; + } + + // m is the maximal number in nums + int m = nums[0]; + for (int i = 1; i < nums.length; i++) { + m = Math.max(m, nums[i]); + } + + int exp = 1; // 1, 10, 100, 1000 ... + int R = 10; // 10 digits + + int[] aux = new int[nums.length]; + + while (m / exp > 0) { // Go through all digits from LSB to MSB + int[] count = new int[R]; + + for (int i = 0; i < nums.length; i++) { + count[(nums[i] / exp) % 10]++; + } + + for (int i = 1; i < count.length; i++) { + count[i] += count[i - 1]; + } + + for (int i = nums.length - 1; i >= 0; i--) { + aux[--count[(nums[i] / exp) % 10]] = nums[i]; + } + + for (int i = 0; i < nums.length; i++) { + nums[i] = aux[i]; + } + exp *= 10; + } + + int max = 0; + for (int i = 1; i < aux.length; i++) { + max = Math.max(max, aux[i] - aux[i - 1]); + } + + return max; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MaximumProductSubarray.java b/src/geeksforgeeks/MaximumProductSubarray.java new file mode 100644 index 0000000..025e49e --- /dev/null +++ b/src/geeksforgeeks/MaximumProductSubarray.java @@ -0,0 +1,63 @@ +package geeksforgeeks; + +/** + * https://www.geeksforgeeks.org/maximum-product-subarray/ + */ +public class MaximumProductSubarray { + + // 1, -2, -3, 0, 8, 7, -2 + public static int maxProductSubArray(int[] A) { + + if (A.length == 0) { + return 0; + } + + int maxHerePre = A[0]; + int minHerePre = A[0]; + int maxsofar = A[0]; + + for (int i = 1; i < A.length; i++) { + int maxHere = Math.max(Math.max(maxHerePre * A[i], minHerePre * A[i]), A[i]); + int minHere = Math.min(Math.min(maxHerePre * A[i], minHerePre * A[i]), A[i]); + maxsofar = Math.max(maxHere, maxsofar); + maxHerePre = maxHere; + minHerePre = minHere; + } + return maxsofar; + } + + public static int maxSumSubArray(int[] arr) { + + int max = Integer.MIN_VALUE; + int sum = 0; + + for (int i = 0; i < arr.length; i++) { + sum = sum + arr[i]; + if (sum < 0) { + //get i if you want to get index of subarray + sum = 0; + } + max = Math.max(sum, max); + } + return sum; + } + + public int maxSubArray(int[] nums) { + if(nums==null || nums.length==0) return 0; + + int maxHere=0; + int max=Integer.MIN_VALUE; + for(int i:nums){ + maxHere=Math.max(i,maxHere+i); + max= Math.max(maxHere, max); + } + + return max; + } + + public static void main(String[] args) { + int arr[] = { 1, -2, -3, 0, 8, 7, -2 }; + System.out.println("Maximum Sub array sum is " + maxSumSubArray(arr)); + System.out.println("Maximum Sub array product is " + maxProductSubArray(arr)); + } +} diff --git a/src/geeksforgeeks/MaximumSubarray.java b/src/geeksforgeeks/MaximumSubarray.java deleted file mode 100644 index 8d7a333..0000000 --- a/src/geeksforgeeks/MaximumSubarray.java +++ /dev/null @@ -1,45 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/maximum-product-subarray/ - */ -public class MaximumSubarray { - - public static int maxProductSubArray(int[] A) { - if (A.length == 0) { - return 0; - } - - int maxHerePre = A[0]; - int minHerePre = A[0]; - int maxsofar = A[0]; - - for (int i = 1; i < A.length; i++) { - int maxHere = Math.max(Math.max(maxHerePre * A[i], minHerePre * A[i]), A[i]); - int minHere = Math.min(Math.min(maxHerePre * A[i], minHerePre * A[i]), A[i]); - maxsofar = Math.max(maxHere, maxsofar); - maxHerePre = maxHere; - minHerePre = minHere; - } - return maxsofar; - } - - public static int maxSumSubArray(int[] nums) { - - int maxSoFar = nums[0]; - int maxEndingHere = nums[0]; - - for (int i = 1; i < nums.length; i++) { - maxEndingHere = Math.max(maxEndingHere + nums[i], nums[i]); - maxSoFar = Math.max(maxSoFar, maxEndingHere); - } - return maxSoFar; - } - - - public static void main(String[] args) { - int arr[] = {1, -2, -3, 0, 8, 7, -2}; - System.out.println("Maximum Sub array product is " + maxSumSubArray(arr)); - } - -} diff --git a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java b/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java index 12f3007..65963f7 100644 --- a/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java +++ b/src/geeksforgeeks/MaximumSubstringWithKDistinctChar.java @@ -3,10 +3,16 @@ import java.util.HashMap; import java.util.Map; +/** + * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ + *

+ * https://www.lintcode.com/problem/longest-substring-with-at-most-two-distinct-characters/description + */ public class MaximumSubstringWithKDistinctChar { public static void main(String[] args) { System.out.println(lengthOfLongestSubstringTwoDistinct("abaaaaacccddcc", 2)); + //System.out.println(lengthOfLongestSubstringKDistinct("eqgkcwGFvjjmxutystqdfhuMblWbylgjxsxgnoh", 2)); } public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { @@ -18,7 +24,9 @@ public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { while (end < s.length()) { char c = s.charAt(end); map.put(c, map.getOrDefault(c, 0) + 1); - if (map.get(c) == 1) counter++;//new char + if (map.get(c) == 1) { + counter++;//new char + } end++; while (counter > k) { char cTemp = s.charAt(start); @@ -32,4 +40,36 @@ public static int lengthOfLongestSubstringTwoDistinct(String s, int k) { } return length; } + + // improvised solution + public static int lengthOfLongestSubstringKDistinct(String s, int k) { + if (s == null || s.isEmpty()) { + return 0; + } + if (k == 0) { + return 0; + } + int start = 0; + int maxCount = 0; + int[] arr = new int[26]; + s = s.toLowerCase(); + for (int i = 0; i < s.length(); i++) { + + if (arr[s.charAt(i) - 'a'] == 0) { + k--; + } + + arr[s.charAt(i) - 'a']++; + while (k == -1) { + + arr[s.charAt(start) - 'a']--; + if (arr[s.charAt(start) - 'a'] == 0) { + k++; + } + start++; + } + maxCount = Math.max(maxCount, i - start); + } + return maxCount + 1; + } } diff --git a/src/geeksforgeeks/MaximumUnsortedSubarray.java b/src/geeksforgeeks/MaximumUnsortedSubarray.java index 8cc830a..b9a436e 100644 --- a/src/geeksforgeeks/MaximumUnsortedSubarray.java +++ b/src/geeksforgeeks/MaximumUnsortedSubarray.java @@ -4,12 +4,22 @@ import java.util.Arrays; import java.util.List; -//https://www.interviewbit.com/problems/maximum-unsorted-subarray/# +//https://leetcode.com/problems/shortest-unsorted-continuous-subarray/ +/** + * Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. + * + * You need to find the shortest such subarray and output its length. + * + * Example 1: + * Input: [2, 6, 4, 8, 10, 9, 15] + * Output: 5 + * Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. + */ public class MaximumUnsortedSubarray { - public static ArrayList subarraySort(ArrayList A) { + public static ArrayList subarraySort(final ArrayList A) { - ArrayList list = new ArrayList<>(); + final ArrayList list = new ArrayList<>(); int start = -1; int end = -1; @@ -34,7 +44,13 @@ public static ArrayList subarraySort(ArrayList A) { break; } } - + // [1, 3, 2, 0, -1, 7, 10] + // the initial finding gives you 3 and -1 however the original sort array is + // [1, -1, 0, 2, 3, 7, 10], + //The problem here is that the smallest number of our subarray is ‘-1’ + // which dictates that we need to include more numbers from the beginning of the array + // We will have a similar problem + //if the maximum of the subarray is bigger than some elements at the end of the array // find min and max in the range [start, end] int min = A.get(start); int max = A.get(start); @@ -63,11 +79,12 @@ public static ArrayList subarraySort(ArrayList A) { return list; } - public static void main(String[] args) { + public static void main(final String[] args) { //1, 1, 10, 10, 15, 10, 15, 10,10, 15, 10, 15 - //(1, 3, 2, 4, 5))); + //(1, 3, 2, 4, 5); //4, 15, 4, 4, 15, 18, 20 - List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); + //2, 6, 1, 8, 10, 9, 15 + final List result = subarraySort(new ArrayList<>(Arrays.asList(4, 15, 4, 4, 15, 18, 20))); result.stream().forEach(System.out::println); } } diff --git a/src/geeksforgeeks/MedianOfKWindow.java b/src/geeksforgeeks/MedianOfKWindow.java new file mode 100644 index 0000000..2e3ad95 --- /dev/null +++ b/src/geeksforgeeks/MedianOfKWindow.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +public class MedianOfKWindow { + public double[] medianSlidingWindow(int[] nums, int k) { + MedianQueue medianHeap= new MedianQueue(); + + double[] result= new double[nums.length-k+1]; + + int resultIndex=0; + + for( int i=0;i minQueue= new PriorityQueue<>(); + PriorityQueue maxQueue= new PriorityQueue<>(Collections.reverseOrder()); + + public void offer(int x){ + maxQueue.offer(x); + minQueue.offer(maxQueue.poll()); + if(maxQueue.size() minQueue.size() ? maxQueue.peek() : ((long)maxQueue.peek() + minQueue.peek()) * 0.5; + } + public int size(){ + return minQueue.size() + maxQueue.size(); + } + + public boolean remove(int x){ + return minQueue.remove(x) || maxQueue.remove(x); + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MedianOfRunningIntegers.java b/src/geeksforgeeks/MedianOfRunningIntegers.java index cef851b..d9f05ca 100644 --- a/src/geeksforgeeks/MedianOfRunningIntegers.java +++ b/src/geeksforgeeks/MedianOfRunningIntegers.java @@ -3,11 +3,20 @@ import java.util.Collections; import java.util.PriorityQueue; +/** + * https://leetcode.com/problems/find-median-from-data-stream/ + */ public class MedianOfRunningIntegers { PriorityQueue min = new PriorityQueue<>(); PriorityQueue max = new PriorityQueue<>(Collections.reverseOrder()); + // 6,8,1,4,9,2,3,5 + // median is a middle element in sorted array + // in a sorted array if we choose a point the immediate left to that point is maxLeft (max of all left) + // the immediate right to that point is minRight (min of all right) + // to mimic that here the right(max) values are stored in min heap + // the left(min) values are stored in maxheap public void addNum(int num) { max.offer(num); min.offer(max.poll()); @@ -17,15 +26,16 @@ public void addNum(int num) { } public double findMedian() { - if (max.size() == min.size()) + if (max.size() == min.size()) { return (max.peek() + min.peek()) / 2.0; - else + } else { return max.peek(); + } } public static void main(String[] args) { MedianOfRunningIntegers median = new MedianOfRunningIntegers(); - int A[] = {5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4}; + int A[] = { 5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4 }; for (int num : A) { median.addNum(num); System.out.println(median.findMedian()); diff --git a/src/geeksforgeeks/MedianOfTwoSortedArrays.java b/src/geeksforgeeks/MedianOfTwoSortedArrays.java new file mode 100644 index 0000000..7eae057 --- /dev/null +++ b/src/geeksforgeeks/MedianOfTwoSortedArrays.java @@ -0,0 +1,57 @@ +package geeksforgeeks; + +/** + * https://github.com/mission-peace/interview/blob/master/src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java + */ +public class MedianOfTwoSortedArrays { + + public double findMedianSortedArrays(int input1[], int input2[]) { + //if input1 length is greater than switch them so that input1 is smaller than input2. + if (input1.length > input2.length) { + return findMedianSortedArrays(input2, input1); + } + int x = input1.length; + int y = input2.length; + + int low = 0; + int high = x; + while (low <= high) { + int partitionX = (low + high) / 2; + int partitionY = (x + y + 1) / 2 - partitionX; + + //if partitionX is 0 it means nothing is there on left side. Use -INF for maxLeftX + //if partitionX is length of input then there is nothing on right side. Use +INF for minRightX + int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1]; + int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX]; + + int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1]; + int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY]; + + if (maxLeftX <= minRightY && maxLeftY <= minRightX) { + //We have partitioned array at correct place + // Now get max of left elements and min of right elements to get the median in case of even length combined array size + // or get max of left for odd length combined array size. + if ((x + y) % 2 == 0) { + return ((double) Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY)) / 2; + } else { + return Math.max(maxLeftX, maxLeftY); + } + } else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side. + high = partitionX - 1; + } else { //we are too far on left side for partitionX. Go on right side. + low = partitionX + 1; + } + } + + //Only we we can come here is if input arrays were not sorted. Throw in that scenario. + throw new IllegalArgumentException(); + } + + public static void main(String[] args) { + int[] x = { 1, 3, 8, 9, 15, 17 }; + int[] y = { 7, 11, 18, 19, 21, 25 }; + // 1,3,7,8,9,11,15,18,19,21,25 + MedianOfTwoSortedArrays mm = new MedianOfTwoSortedArrays(); + System.out.println(mm.findMedianSortedArrays(x, y)); + } +} diff --git a/src/geeksforgeeks/MeetingRoomsII.java b/src/geeksforgeeks/MeetingRoomsII.java new file mode 100644 index 0000000..bdab7a8 --- /dev/null +++ b/src/geeksforgeeks/MeetingRoomsII.java @@ -0,0 +1,66 @@ +package geeksforgeeks; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +/** + * https://www.lintcode.com/problem/meeting-rooms-ii/ + */ + +public class MeetingRoomsII { + /** + * @param intervals: an array of meeting time intervals + * + * @return: the minimum number of conference rooms required + */ + // [(0,30),(5,10),(15,20)] + public int minMeetingRooms(List intervals) { + if (intervals == null || intervals.size() == 0) { + return -1; + } + + Collections.sort(intervals, Comparator.comparingInt(a -> a.start)); + + PriorityQueue queue = new PriorityQueue<>(); + queue.offer(intervals.get(0).end); + for (int i = 1; i < intervals.size(); i++) { + Interval temp = intervals.get(i); + if (queue.peek() <= temp.start) { + queue.poll(); + } + queue.offer(temp.end); + } + + return queue.size(); + + } + + // Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]] + // Output: [[3,4]] + + public List employeeFreeTime(List> schedule) { + PriorityQueue que = new PriorityQueue<>((a, b) -> a.start - b.start); + + for (List list : schedule) { + for (Interval i : list) { + que.add(i); + } + } + + List rt = new ArrayList<>(); + int max = -1; + while (!que.isEmpty()) { + Interval top = que.poll(); + if (max != -1 && top.start > max) { + rt.add(new Interval(max, top.start)); + } + max = Math.max(max, top.end); + } + + return rt; + } + + +} diff --git a/src/geeksforgeeks/MergeIntervalIntersection.java b/src/geeksforgeeks/MergeIntervalIntersection.java new file mode 100644 index 0000000..a17ee6f --- /dev/null +++ b/src/geeksforgeeks/MergeIntervalIntersection.java @@ -0,0 +1,39 @@ +package geeksforgeeks; + +/** + * +Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted order. +Return the intersection of these two interval lists. + +Input: A = [[0,2],[5,10],[13,23],[24,25]], B = [[1,5],[8,12],[15,24],[25,26]] +Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] + */ +public class MergeIntervalIntersection { + + // inorder to find a overlapping part alone between two intervals + // we take + // start = max(a.start, b.start) + // end = min(a.end, b.end) + // That is, the highest start time and the lowest end time will be the overlapping interval. + public int[][] intervalIntersection(int[][] A, int[][] B) { + int i=0; + int j=0; + List result= new ArrayList<>(); + while(i=B[j][0] && A[i][0]<=B[j][1] || + B[j][0]>=A[i][0] && B[j][0]<=A[i][1]){ // this condition checks if there'a ovelapping + //A=>[0,2], B=> [1,5] + result.add(new int[]{Math.max(A[i][0],B[j][0]), Math.min(A[i][1],B[j][1])}); + } + // once added to result move the i or j based on lesser end time + if(A[i][1] result = new ArrayList<>(); - if (intervals.length == 0 || intervals == null) return result.toArray(new int[0][]); - - Arrays.sort(intervals, (a, b) -> a[0] - b[0]); + if (intervals.length <= 1) { + return intervals; + } - int start = intervals[0][0]; - int end = intervals[0][1]; + /* Arrays.sort(intervals, (a, b) -> a[0] - b[0]); + Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));*/ + Arrays.sort(intervals, Comparator.comparingInt(i -> i[0])); - for (int[] arr : intervals) { - System.out.println(arr[0] + "" + arr[1]); - if (arr[0] <= end) { - end = Math.max(end, arr[1]); - } else { - result.add(new int[]{start, end}); - start = arr[0]; - end = arr[1]; + List result = new ArrayList<>(); + int[] prevInterval = intervals[0]; + result.add(prevInterval); + for (int[] currInterval : intervals) { + if (currInterval[0] <= prevInterval[1]) // Overlapping intervals, move the end if needed + { + prevInterval[1] = Math.max(prevInterval[1], currInterval[1]); + } else { // Disjoint intervals, add the new interval to the list + prevInterval = currInterval; + result.add(prevInterval); } } - result.add(new int[]{start, end}); - return result.toArray(new int[0][]); - + return result.toArray(new int[result.size()][]); } public static void main(String[] args) { - int[][] arr = {{1, 3}, {2, 4}, {5, 7}, {6, 8}}; + // [[1,3],[2,6],[8,10],[15,18]] + int[][] arr = { { 1, 9 }, { 6, 8 }, { 2, 4 }, { 4, 7 } }; + //{ { 1, 3 }, { 2, 4 }, { 5, 7 }, { 6, 8 } }; //{{1, 9}, {2, 4}, {4, 7}, {6, 8}}; System.out.println(Arrays.deepToString(merge(arr))); } diff --git a/src/geeksforgeeks/MergeSortLinkedList.java b/src/geeksforgeeks/MergeSortLinkedList.java index 4e8fbb2..d9eaf1b 100644 --- a/src/geeksforgeeks/MergeSortLinkedList.java +++ b/src/geeksforgeeks/MergeSortLinkedList.java @@ -1,38 +1,35 @@ package geeksforgeeks; +/** + * https://www.geeksforgeeks.org/merge-sort-for-linked-list/ + */ public class MergeSortLinkedList { public static ListNode sortList(ListNode head) { - if (head == null || head.next == null) + if (head == null || head.next == null) { return head; - + } // step 1. cut the list to two halves ListNode prev = null; ListNode slow = head; ListNode fast = head; - // find the mid node while (fast != null && fast.next != null) { prev = slow; slow = slow.next; fast = fast.next.next; } - prev.next = null; - // step 2. sort each half ListNode l1 = sortList(head); ListNode l2 = sortList(slow); - // step 3. merge l1 and l2 return merge(l1, l2); } static ListNode merge(ListNode l1, ListNode l2) { - ListNode node = new ListNode(0); ListNode temp = node; - while (l1 != null && l2 != null) { if (l1.val < l2.val) { temp.next = l1; @@ -43,13 +40,12 @@ static ListNode merge(ListNode l1, ListNode l2) { } temp = temp.next; } - - if (l1 != null) + if (l1 != null) { temp.next = l1; - - if (l2 != null) + } + if (l2 != null) { temp.next = l2; - + } return node.next; } @@ -76,4 +72,9 @@ class ListNode { public ListNode(int val) { this.val = val; } + + @Override + public String toString() { + return "ListNode{val=" + val + '}'; + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MergeTwoLinkedList.java b/src/geeksforgeeks/MergeTwoLinkedList.java new file mode 100644 index 0000000..8e879ea --- /dev/null +++ b/src/geeksforgeeks/MergeTwoLinkedList.java @@ -0,0 +1,46 @@ +package geeksforgeeks; + +/** + * https://www.geeksforgeeks.org/merge-two-sorted-linked-lists/ + */ +public class MergeTwoLinkedList { + + public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { + if (l1 == null) { + return l2; + } else if (l2 == null) { + return l1; + } + ListNode dummy = new ListNode(0); + ListNode curr = dummy; + while (l1 != null && l2 != null) { + if (l1.val <= l2.val) { + curr.next = l1; + l1 = l1.next; + } else { + curr.next = l2; + l2 = l2.next; + } + curr = curr.next; + } + curr.next = l1 == null ? l2 : l1; + return dummy.next; + } + + public static void main(String[] args) { + ListNode l1 = new ListNode(1); + l1.next = new ListNode(2); + l1.next.next = new ListNode(3); + l1.next.next.next = new ListNode(4); + + ListNode l2 = new ListNode(1); + // l2.next = new ListNode(7); + + ListNode head = mergeTwoLists(l1, l2); + + while (head != null) { + System.out.println(head.val); + head = head.next; + } + } +} diff --git a/src/geeksforgeeks/MinCostRopeConnect.java b/src/geeksforgeeks/MinCostRopeConnect.java index 1297fff..cab85b9 100644 --- a/src/geeksforgeeks/MinCostRopeConnect.java +++ b/src/geeksforgeeks/MinCostRopeConnect.java @@ -2,26 +2,33 @@ import java.util.PriorityQueue; +/** + * https://www.geeksforgeeks.org/connect-n-ropes-minimum-cost/ + */ public class MinCostRopeConnect { - public static void main(String[] args) { - int arr[] = { 4, 3, 2, 6 }; + // 6 + 4 = 10 .. 10 + 3 = 13 .. 13 +2 = 15 - MinCostRopeConnect rope = new MinCostRopeConnect(); - rope.connectRopes(arr); - } + // 2+3 = 5 .. 5 + 4 = 9 .. 9 + 6 = 15 .. - private void connectRopes(int[] arr) { - PriorityQueue pq = new PriorityQueue<>(); - for (int i : arr) - pq.add(i); + public static void main(String[] args) { + int arr[] = { 4, 3, 2, 6 }; - while (pq.size() > 1) { - Integer remove = pq.remove(); - Integer remove2 = pq.remove(); + MinCostRopeConnect rope = new MinCostRopeConnect(); + rope.connectRopes(arr); + } - System.out.println("cost" + (remove + remove2)); - pq.add(remove + remove2); - } - } + private void connectRopes(int[] arr) { + PriorityQueue pq = new PriorityQueue<>(); + for (int i : arr) + pq.add(i); + + while (pq.size() > 1) { + Integer remove = pq.remove(); + Integer remove2 = pq.remove(); + + System.out.println("cost" + (remove + remove2)); + pq.add(remove + remove2); + } + } } diff --git a/src/geeksforgeeks/MinStepsToConvertXtoY.java b/src/geeksforgeeks/MinStepsToConvertXtoY.java new file mode 100644 index 0000000..44c0efa --- /dev/null +++ b/src/geeksforgeeks/MinStepsToConvertXtoY.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +class MinStepsToConvertXtoY { + private static int minOperations(int src, int target) { + + Set visited = new HashSet<>(1000); + LinkedList queue = new LinkedList(); + + GFG node = new GFG(src, 0); + + queue.offer(node); + visited.add(node); + + while (!queue.isEmpty()) { + GFG temp = queue.poll(); + visited.add(temp); + + if (temp.val == target) { + return temp.steps; + } + + int mul = temp.val * 2; + int sub = temp.val - 1; + + // given constraints + if (mul > 0 && mul < 1000) { + GFG nodeMul = new GFG(mul, temp.steps + 1); + queue.offer(nodeMul); + } + if (sub > 0 && sub < 1000) { + GFG nodeSub = new GFG(sub, temp.steps + 1); + queue.offer(nodeSub); + } + } + return -1; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MinTimeRotOranges.java b/src/geeksforgeeks/MinTimeRotOranges.java index a020b8a..5b1dfac 100644 --- a/src/geeksforgeeks/MinTimeRotOranges.java +++ b/src/geeksforgeeks/MinTimeRotOranges.java @@ -30,8 +30,9 @@ public String toString() { private boolean hasFreshOrange(int[][] grid) { for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 1) + if (grid[i][j] == 1) { return true; + } } } return false; @@ -48,8 +49,8 @@ private boolean isValidFresh(int row, int col, int[][] grid) { } private void rotOranges(Queue queue, Pair p, int[][] grid) { - int[] xMoves = {1, -1, 0, 0}; - int[] yMoves = {0, 0, 1, -1}; + int[] xMoves = { 1, -1, 0, 0 }; + int[] yMoves = { 0, 0, 1, -1 }; for (int k = 0; k < xMoves.length; k++) { int x = p.x + xMoves[k]; int y = p.y + yMoves[k]; @@ -65,33 +66,36 @@ public int findMinTime(int[][] grid) { Queue queue = new LinkedList<>(); for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 2) + if (grid[i][j] == 2) { queue.add(new Pair(i, j)); + } } } - if (queue.isEmpty()) + if (queue.isEmpty()) { return -1; + } queue.add(new Pair(-1, -1)); while (!queue.isEmpty()) { Pair p = queue.poll(); - if (!isDelimiter(p)) + if (!isDelimiter(p)) { rotOranges(queue, p, grid); - else if (!queue.isEmpty()) { + } else if (!queue.isEmpty()) { queue.add(p); // add back delimiter result += 1; } } - if (hasFreshOrange(grid)) + if (hasFreshOrange(grid)) { return -1; + } return result; } public static void main(String[] args) { - int grid[][] = {{2, 1, 0, 1, 1}, {1, 0, 2, 1, 1}, {1, 1, 1, 1, 1}}; + int grid[][] = { { 2, 1, 0, 1, 1 }, { 1, 0, 2, 1, 1 }, { 1, 1, 1, 1, 1 } }; System.out.println(new MinTimeRotOranges().findMinTime(grid)); } diff --git a/src/geeksforgeeks/MinimumBribes.java b/src/geeksforgeeks/MinimumBribes.java new file mode 100644 index 0000000..2107aa4 --- /dev/null +++ b/src/geeksforgeeks/MinimumBribes.java @@ -0,0 +1,50 @@ +package geeksforgeeks; +/** + * https://www.hackerrank.com/challenges/new-year-chaos/problem + * https://www.youtube.com/watch?v=UpmVTEvaXPE + * Any person in the queue can bribe the person directly in front of them to swap positions. + * If two people swap positions, they still wear the same sticker denoting their original place in line. + * One person can bribe at most two other persons. + * That is to say, if n = 8, and Person 5 bribes Person 4, the queue will look like this: 1,2,3,5,4,6,7,8. + * Fascinated by this chaotic queue, you decide you must know the minimum number of bribes that took place to get the queue into its current state! + * + * No person can bribe more than 2 persons if yes then print chaotic + * Input: 2 1 5 3 4 + * Output: 3 + * + * Input: 2 5 1 3 4 + * Output: Too chaotic + */ +public class MinimumBribes { + // input is 2 1 5 3 4, + // when index is at 2(val=>5) we see how many elements lesser than 5 is there + // if the value is greater that 2 we print too chaotic + // else we add it to result + void minimumBribes(int[] q) { + int bribes=0; + for(int i = q.length-1; i >= 0; i--) { + + if(i-1>=0 && q[i-1]==i+1){ + q[i-1]=q[i]; + q[i]=i+1; + bribes+=1; + } else if(i-2>=0 && q[i-2]==i+2){ + //2,1,5,3,4 we need to swap 2 elements to restore the array + q[i-2]=q[i-1]; + q[i-1]=q[i]; + q[i]=i+1; + bribes+=2; + }else{ + System.out.println("Too Chaotic"); + return; + } + } + System.out.println(bribes); + } + + public static void main(String[] args) { + // inputs 5,1,2,3,7,8,6,4 => too chaotic + // 1,2,5,3,7,8,6,4 => 7 + new MinimumBribes().minimumBribes(new int[]{2,1,5,3,4}); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java index 38b0d2d..c4c888a 100644 --- a/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java +++ b/src/geeksforgeeks/MinimumDistanceBetweenTwoNumbers.java @@ -1,26 +1,42 @@ package geeksforgeeks; -/*https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/*/ + + +/* +https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/ + +Given an unsorted array arr[] and two numbers x and y, find the minimum distance between x and y in arr[]. +The array might also contain duplicates. +You may assume that both x and y are different and present in arr[]. + +Input: arr[] = {2, 5, 3, 5, 4, 4, 2, 3}, +x = 3, y = 2 +Output: Minimum distance between 3 +and 2 is 1. +Explanation:3 is at index 7 and 2 is at +index 6, so the distance is 1 +*/ + class MinimumDistanceBetweenTwoNumbers { + int minDist(int arr[], int n, int x, int y) { int i = 0; int minDist = Integer.MAX_VALUE; int prev = 0; - // Find the first occurence of any of the two numbers (x or y) - // and store the index of this occurence in prev + // Find the first occurrence of any of the two numbers (x or y) + // and store the index of this occurrence in prev for (i = 0; i < n; i++) { if (arr[i] == x || arr[i] == y) { prev = i; break; } } - - // Traverse after the first occurrence + // sort of like sliding window tracks the first occurence + // of the element and check if both are not same and calculates the distance for (; i < n; i++) { if (arr[i] == x || arr[i] == y) { - // If the current element matches with any of the two then // check if current element and prev element are different // Also check if this value is smaller than minimum distance // so far @@ -30,18 +46,17 @@ int minDist(int arr[], int n, int x, int y) { prev = i; } } - return minDist; } public static void main(String[] args) { MinimumDistanceBetweenTwoNumbers min = new MinimumDistanceBetweenTwoNumbers(); - int arr[] = {2, 5, 3, 5, 4, 4, 2, 3}; + int arr[] = {3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3}; + int arr1[] = { 3, 5, 4, 3, 1, 2, 4, 6, 5, 6, 6, 5, 4, 8, 3 }; int n = arr.length; int x = 3; - int y = 2; + int y = 6; - System.out.println("Minimum distance between " + x + " and " + y - + " is " + min.minDist(arr, n, x, y)); + System.out.println("Minimum distance between " + x + " and " + y + " is " + min.minDist(arr, n, x, y)); } } diff --git a/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java b/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java index fd3ed21..f05449b 100644 --- a/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java +++ b/src/geeksforgeeks/MinimumIndexDistanceOfMaximumNumbers.java @@ -2,31 +2,30 @@ /** * https://www.geeksforgeeks.org/minimum-distance-between-two-occurrences-of-maximum/ - * */ class MinimumIndexDistanceOfMaximumNumbers { - static int minDistance(int arr[], int n) { - int maximumElement = arr[0]; - int minDist = n; - int index = 0; + static int minDistance(int arr[], int n) { + int maximumElement = arr[0]; + int minDist = n; + int index = 0; - for (int i = 1; i < n; i++) { - if (maximumElement == arr[i]) { - minDist = Math.min(minDist, (i - index)); - index = i; - } else if (maximumElement < arr[i]) { - maximumElement = arr[i]; - minDist = n; - index = i; - } - } - return minDist - 1; - } + for (int i = 1; i < n; i++) { + if (maximumElement == arr[i]) { + minDist = Math.min(minDist, (i - index)); + index = i; + } else if (maximumElement < arr[i]) { + maximumElement = arr[i]; + minDist = n; + index = i; + } + } + return minDist - 1; + } - public static void main(String[] args) { - int arr[] = { 6, 3, 1, 3, 6, 5, 4, 1 }; - int n = arr.length; - System.out.print("Minimum distance = " + minDistance(arr, n)); - } + public static void main(String[] args) { + int arr[] = { 6, 3, 1, 3, 6, 5, 4, 1 }; + int n = arr.length; + System.out.print("Minimum distance = " + minDistance(arr, n)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumPathSum.java b/src/geeksforgeeks/MinimumPathSum.java new file mode 100644 index 0000000..58b6da4 --- /dev/null +++ b/src/geeksforgeeks/MinimumPathSum.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +class MinPathSum { + public int minPathSum(int[][] grid) { + if (grid == null || grid.length == 0) + return 0; + int dp[][] = new int[grid.length][grid[0].length]; + return getMinPathSum(0, 0, grid, dp); + } + + public int getMinPathSum(int i, int j, int[][] grid, int[][] dp) { + if (i == grid.length - 1 && j == grid[0].length - 1) + return grid[i][j]; + else if (i > grid.length - 1 || j > grid[0].length - 1) + return Integer.MAX_VALUE; + else { + if (dp[i][j] != 0) + return dp[i][j]; + dp[i][j] = grid[i][j] + Math.min(getMinPathSum(i + 1, j, grid, dp), getMinPathSum(i, j + 1, grid, dp)); + } + return dp[i][j]; + } + + public int minPathSum1(int[][] grid) { + + for(int i=1;i s; + Stack stack; Integer minEle; MyStack() { - s = new Stack(); + stack = new Stack<>(); } void getMin() { - if (s.isEmpty()) + if (stack.isEmpty()) { System.out.println("Stack is empty"); - else + } else { System.out.println("Minimum Element in the " + " stack is: " + minEle); + } } void peek() { - if (s.isEmpty()) { + if (stack.isEmpty()) { System.out.println("Stack is empty "); return; } - Integer t = s.peek(); + Integer t = stack.peek(); System.out.print("Top Most Element is: "); - if (t < minEle) + if (t < minEle) { System.out.println(minEle); - else + } else { System.out.println(t); + } } void pop() { - if (s.isEmpty()) { + if (stack.isEmpty()) { System.out.println("Stack is empty"); return; } System.out.print("Top Most Element Removed: "); - Integer t = s.pop(); + Integer t = stack.pop(); if (t < minEle) { System.out.println(minEle); minEle = 2 * minEle - t; - } else + } else { System.out.println(t); + } } void push(Integer x) { - if (s.isEmpty()) { + if (stack.isEmpty()) { minEle = x; - s.push(x); + stack.push(x); System.out.println("Number Inserted: " + x); return; } @@ -61,10 +64,11 @@ void push(Integer x) { // x-minEle<0 // x-minEle+x<0+x // 2x-minEle + * https://www.techiedelight.com/chess-knight-problem-find-shortest-path-source-destination/ + */ class MinimumStepsKnight { - static class Cell { - int x; - int y; - int dis; - - public Cell(int x, int y, int dis) { - this.x = x; - this.y = y; - this.dis = dis; - } - - } - - // Utility method returns true if (x, y) lies - // inside Board - static boolean isInside(int x, int y, int N) { - if (x >= 1 && x <= N && y >= 1 && y <= N) - return true; - return false; - } - - // Method returns minimum step - // to reach target position - static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { - // x and y direction, where a knight can move - int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 }; - int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 }; - - // queue for storing states of knight in board - Queue q = new LinkedList<>(); - - // push starting position of knight with 0 distance - q.add(new Cell(knightPos[0], knightPos[1], 0)); - - Cell t; - int x, y; - boolean visit[][] = new boolean[N + 1][N + 1]; - - // make all cell unvisited - for (int i = 1; i <= N; i++) - for (int j = 1; j <= N; j++) - visit[i][j] = false; - - // visit starting state - visit[knightPos[0]][knightPos[1]] = true; - - // loop untill we have one element in queue - while (!q.isEmpty()) { - t = q.remove(); - - // if current cell is equal to target cell, - // return its distance - if (t.x == targetPos[0] && t.y == targetPos[1]) - return t.dis; - - // loop for all reachable states - for (int i = 0; i < 8; i++) { - x = t.x + dx[i]; - y = t.y + dy[i]; - - // If reachable state is not yet visited and - // inside board, push that state into queue - if (isInside(x, y, N) && !visit[x][y]) { - visit[x][y] = true; - q.add(new Cell(x, y, t.dis + 1)); - } - } - } - return Integer.MAX_VALUE; - } - - public static void main(String[] args) { - int N = 30; - int[] knightPos = { 1, 1 }; - int[] targetPos = { 30, 30 }; - System.out.println(minStepToReachTarget(knightPos, targetPos, N)); - } + static class Cell { + int x; + int y; + int steps; + + public Cell(int x, int y, int steps) { + this.x = x; + this.y = y; + this.steps = steps; + } + + } + + // Utility method returns true if (x, y) lies + // inside Board + static boolean isInside(int x, int y, int N) { + if (x >= 1 && x <= N && y >= 1 && y <= N) { + return true; + } + return false; + } + + // Method returns minimum step + // to reach target position + static int minStepToReachTarget(int knightPos[], int targetPos[], int N) { + // x and y direction, where a knight can move + int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 }; + int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 }; + + // queue for storing states of knight in board + Queue q = new LinkedList<>(); + + // push starting position of knight with 0 distance + q.add(new Cell(knightPos[0], knightPos[1], 0)); + + Cell cell; + int x, y; + boolean visit[][] = new boolean[N + 1][N + 1]; + + // make all cell unvisited + for (int i = 1; i <= N; i++) + for (int j = 1; j <= N; j++) + visit[i][j] = false; + + // visit starting state + visit[knightPos[0]][knightPos[1]] = true; + + // loop untill we have one element in queue + while (!q.isEmpty()) { + cell = q.remove(); + + // if current cell is equal to target cell, + // return its distance + if (cell.x == targetPos[0] && cell.y == targetPos[1]) { + return cell.steps; + } + + // loop for all reachable states + for (int i = 0; i < 8; i++) { + x = cell.x + dx[i]; + y = cell.y + dy[i]; + + // If reachable state is not yet visited and + // inside board, push that state into queue + if (isInside(x, y, N) && !visit[x][y]) { + visit[x][y] = true; + q.add(new Cell(x, y, cell.steps + 1)); + } + } + } + return Integer.MAX_VALUE; + } + + public static void main(String[] args) { + int N = 30; + int[] knightPos = { 1, 1 }; + int[] targetPos = { 30, 30 }; + System.out.println(minStepToReachTarget(knightPos, targetPos, N)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumSwapSortArray.java b/src/geeksforgeeks/MinimumSwapSortArray.java index ebea898..662e278 100644 --- a/src/geeksforgeeks/MinimumSwapSortArray.java +++ b/src/geeksforgeeks/MinimumSwapSortArray.java @@ -1,48 +1,124 @@ package geeksforgeeks; -import java.util.Map; -import java.util.TreeMap; +import java.util.Collections; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + /** * https://www.geeksforgeeks.org/minimum-number-swaps-required-sort-array/ - * */ class MinimumSwapSortArray { + private static class Pair { + T key; + I value; + + public T getKey() { + return key; + } + + public I getValue() { + return value; + } + + public void setKey(T key) { + this.key = key; + } + + public void setValue(I value) { + this.value = value; + } + public Pair(T key, I value){ + this.key=key; + this.value=value; + } + + @Override + public String toString() { + return "Pair{" + + "key=" + key + + ", value=" + value + + '}'; + } + } + + public static int minSwaps(int[] arr) { + int n = arr.length; + + // Create two arrays and use as pairs where first + // array is element and second array + // is position of first element + ArrayList> arrpos = + new ArrayList>(); + for (int i = 0; i < n; i++) + arrpos.add(new Pair(arr[i], i)); + + // Sort the array by array element values to + // get right position of every element as the + // elements of second array. + Collections.sort(arrpos, (a,b)-> { + if (a.getKey() == b.getKey()) { + return 0; + } + return Integer.compare(b.getKey(), a.getKey()); + }); + // arrpos.sort(new Comparator>() { + // @Override + // public int compare(Pair o1, + // Pair o2) { + // if (o1.getKey() > o2.getKey()) + // return -1; + + // // We can change this to make it then look at the + // // words alphabetical order + // else if (o1.getKey().equals(o2.getKey())) + // return 0; + + // else + // return 1; + // } + // }); + System.out.println(arrpos); + // To keep track of visited elements. Initialize + // all elements as not visited or false. + Boolean[] vis = new Boolean[n]; + Arrays.fill(vis, false); + + // Initialize result + int ans = 0; + + // Traverse array elements + for (int i = 0; i < n; i++) { + // already swapped and corrected or + // already present at correct pos + if (vis[i] || arrpos.get(i).getValue() == i) + continue; + + // find out the number of node in + // this cycle and add in ans + int cycle_size = 0; + int j = i; + while (!vis[j]) { + vis[j] = true; + + // move to next node + j = arrpos.get(j).getValue(); + cycle_size++; + } + + // Update answer by adding current cycle. + if (cycle_size > 0) { + ans += (cycle_size - 1); + } + } + + // Return result + return ans; + } - public int minSwaps(int[] A, int N) { - int i = 0; - // Tree map sorts the order - Map resMap = new TreeMap<>(); - for (; i < N; i++) { - System.out.print(A[i] + " --> " + i + " "); - resMap.put(A[i], i); - - } - System.out.println(); - i = 0; - for (Map.Entry entry : resMap.entrySet()) { - System.out.print(entry.getKey() + " --> " + i + " "); - entry.setValue(i++); - } - int swap = 0; - for (i = 0; i < N;) { - System.out.println(A[i] + "--" + resMap.get(A[i]) + "--" + i); - // check if array position is same as treeMap's index - if (resMap.get(A[i]) != i) { - int temp = A[i]; - A[i] = A[resMap.get(temp)]; - A[resMap.get(temp)] = temp; - swap++; - } else { - i++; - } - } - return swap; - } - - public static void main(String[] args) { - int[] a = { 1, 5, 4, 3, 2 }; - MinimumSwapSortArray g = new MinimumSwapSortArray(); - System.out.println(g.minSwaps(a, a.length)); - } + public static void main(String[] args) { + int[] a = {1, 5, 4, 3, 2}; + System.out.println(minSwaps(a)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/MinimumWindowSubsequence.java b/src/geeksforgeeks/MinimumWindowSubsequence.java index 2e4c2ca..4e67c90 100644 --- a/src/geeksforgeeks/MinimumWindowSubsequence.java +++ b/src/geeksforgeeks/MinimumWindowSubsequence.java @@ -1,45 +1,80 @@ package geeksforgeeks; -import java.util.Arrays; - -/*https://www.programcreek.com/2014/01/leetcode-minimum-window-subsequence-java/*/ +/** + * Input: + * S = "abcdebdde", T = "bde" + * Output: "bcde" + * Explanation: + * "bcde" is the answer because it occurs before "bdde" which has the same length. + * "deb" is not a smaller window because the elements of T in the window must occur in order. + */ // unresolved -public class MinimumWindowSubsequence { - - public static String minWindow(String S, String T) { - int m = T.length(), n = S.length(); - int[][] dp = new int[m + 1][n + 1]; - // fill first row with index values - for (int j = 0; j <= n; j++) { - dp[0][j] = j + 1; +public class MinimumWindowSubsequence { + public String minWindow(String S, String T) { + if (S.length() == 0 || T.length() == 0) { + return ""; } - // if any element is not present then it will set that row as zero so there wont - // be any valid values in last row - for (int i = 1; i <= m; i++) { - for (int j = 1; j <= n; j++) { - if (T.charAt(i - 1) == S.charAt(j - 1)) { - dp[i][j] = dp[i - 1][j - 1]; - } else { - dp[i][j] = dp[i][j - 1]; + + /** + * we can conduct two steps by using two pointers for this probelm: + * 1. check feasibility from left to right + * 2. check optimization from right to left + * we can traverse from left to right, find a possible candidate until reach the first ending character of T + * eg: for the string s = abcdebdde and t = bde, we should traverse s string until we find first e, + * i.e. abcde, then traverse back from current "e" to find if we have other combination of bde with smaller + * length. + * @param right: fast pointer that always points the last character of T in S + * @param left: slow pointer that used to traverse back when right pointer find the last character of T in S + * @param tIndex: third pointer used to scan string T + * @param minLen: current minimum length of subsequence + * */ + int right = 0; + int minLen = Integer.MAX_VALUE; + String result = ""; + + while (right < S.length()) { + int tIndex = 0; + // use fast pointer to find the last character of T in S + while (right < S.length()) { + if (S.charAt(right) == T.charAt(tIndex)) { + tIndex++; + } + if (tIndex == T.length()) { + break; } + right++; + } + + // if right pointer is over than boundary + if (right == S.length()) { + break; } - } - int start = 0; - int len = n + 1; - for (int j = 1; j <= n; j++) { - if (dp[m][j] != 0) { - if (j - dp[m][j] + 1 < len) { - start = dp[m][j] - 1; - len = j - dp[m][j] + 1; + // use another slow pointer to traverse from right to left until find first character of T in S + int left = right; + tIndex = T.length() - 1; + while (left >= 0) { + if (S.charAt(left) == T.charAt(tIndex)) { + tIndex--; } + if (tIndex < 0) { + break; + } + left--; + } + // if we found another subsequence with smaller length, update result + if (right - left + 1 < minLen) { + minLen = right - left + 1; + result = S.substring(left, right + 1); } + // WARNING: we have to move right pointer to the next position of left pointer, NOT the next position + // of right pointer + right = left + 1; } - System.out.println(Arrays.deepToString(dp)); - return len == n + 1 ? "" : S.substring(start, start + len); + return result; } - public static void main(String args[]) { - System.out.println(minWindow("abcdebdde", "bdd")); + public static void main(String[] args) { + System.out.printf(new MinimumWindowSubsequence().minWindow("abcdebdde","bcde")); } } diff --git a/src/geeksforgeeks/MinimumWindowSubstring.java b/src/geeksforgeeks/MinimumWindowSubstring.java index 64030c2..d36878a 100644 --- a/src/geeksforgeeks/MinimumWindowSubstring.java +++ b/src/geeksforgeeks/MinimumWindowSubstring.java @@ -3,53 +3,60 @@ import java.util.HashMap; import java.util.Map; +/** + * https://leetcode.com/problems/minimum-window-substring/ + */ class MinimumWindowSubstring { - public static String minWindow(String s, String t) { + public static void main(String[] args) { + System.out.println(minWindow("AADOBECODEBANC", "ABC")); + System.out.println(minWindow("abcdebdde", "bde")); + } - if (s.length() == 0 || t.length() == 0) { + public static String minWindow(String s, String t) { + if (t.length() > s.length()) { return ""; } + Map map = new HashMap<>(); + for (char c : t.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } - Map dictT = new HashMap<>(); - for (int i = 0; i < t.length(); i++) { - dictT.put(t.charAt(i), dictT.getOrDefault(t.charAt(i), 0) + 1); - } - - int required = dictT.size(); - int left = 0; - int right = 0; - int formed = 0; - Map windowCounts = new HashMap<>(); - int[] ans = {-1, 0, 0}; + int counter = map.size(); - while (right < s.length()) { - char c = s.charAt(right); - windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1); + int begin = 0, end = 0; + int head = 0; + int len = Integer.MAX_VALUE; - if (dictT.containsKey(c) && windowCounts.get(c).intValue() == dictT.get(c).intValue()) { - formed++; - } - while (left <= right && formed == required) { - c = s.charAt(left); - if (ans[0] == -1 || right - left + 1 < ans[0]) { - ans[0] = right - left + 1; - ans[1] = left; - ans[2] = right; + while (end < s.length()) { + char c = s.charAt(end); + if (map.containsKey(c)) { + map.put(c, map.get(c) - 1); + if (map.get(c) == 0) { + counter--; + } } - windowCounts.put(c, windowCounts.get(c) - 1); - if (dictT.containsKey(c) && windowCounts.get(c).intValue() < dictT.get(c).intValue()) { - formed--; + end++; + + while (counter == 0) { + char tempc = s.charAt(begin); + if (map.containsKey(tempc)) { + map.put(tempc, map.get(tempc) + 1); + if (map.get(tempc) > 0) { + counter++; + } + } + if (end - begin < len) { + len = end - begin; + head = begin; + } + begin++; } - left++; + } - right++; + if (len == Integer.MAX_VALUE) { + return ""; + } + return s.substring(head, head + len); } - return ans[0] == -1 ? "" : s.substring(ans[1], ans[2] + 1); - } - - public static void main(String[] args) { - System.out.println(minWindow("AADOBECODEBANC", "ABC")); - System.out.println(minWindow("abcdebdde", "bde")); } -} \ No newline at end of file diff --git a/src/geeksforgeeks/MirrorBinaryTree.java b/src/geeksforgeeks/MirrorBinaryTree.java index 4b166ed..8b1e8d2 100644 --- a/src/geeksforgeeks/MirrorBinaryTree.java +++ b/src/geeksforgeeks/MirrorBinaryTree.java @@ -1,8 +1,12 @@ -package geeksforgeeks;// Iterative Java program to convert a Binary -// Tree to its mirror +package geeksforgeeks; import java.util.*; +/** + * https://www.geeksforgeeks.org/write-an-efficient-c-function-to-convert-a-tree-into-its-mirror-tree/ + *

+ * Iterative Java program to convert a Binary Tree to its mirror + */ class MirrorBinaryTree { static class Node { @@ -11,7 +15,6 @@ static class Node { Node right; } - static Node newNode(int data) { Node node = new Node(); node.data = data; @@ -20,37 +23,37 @@ static Node newNode(int data) { } static void mirror(Node root) { - if (root == null) + if (root == null) { return; + } Queue q = new LinkedList<>(); q.add(root); while (q.size() > 0) { - Node curr = q.peek(); - q.remove(); - + Node curr = q.poll(); Node temp = curr.left; curr.left = curr.right; curr.right = temp; - if (curr.left != null) + if (curr.left != null) { q.add(curr.left); - if (curr.right != null) + } + if (curr.right != null) { q.add(curr.right); + } } } - static void inOrder(Node node) { - if (node == null) + if (node == null) { return; + } inOrder(node.left); System.out.print(node.data + " "); inOrder(node.right); } - public static void main(String args[]) { Node root = newNode(1); root.left = newNode(2); @@ -58,14 +61,12 @@ public static void main(String args[]) { root.left.left = newNode(4); root.left.right = newNode(5); - System.out.print("\n Inorder traversal of the" - + " coned tree is \n"); + System.out.print("\n Inorder traversal of the" + " coned tree is \n"); inOrder(root); mirror(root); - System.out.print("\n Inorder traversal of the " + - "mirror tree is \n"); + System.out.print("\n Inorder traversal of the " + "mirror tree is \n"); inOrder(root); } } diff --git a/src/geeksforgeeks/MobileKeyPadCombinations.java b/src/geeksforgeeks/MobileKeyPadCombinations.java new file mode 100644 index 0000000..a53ea51 --- /dev/null +++ b/src/geeksforgeeks/MobileKeyPadCombinations.java @@ -0,0 +1,59 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * https://www.geeksforgeeks.org/find-possible-words-phone-digits/ + */ +public class MobileKeyPadCombinations { + + public List letterCombinations(String digits) { + List result = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return result; + } + + String[] keypad = { "--", "00", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + + generateCombinations(digits, keypad, digits.length(), 0, new StringBuilder(), result); + return result; + } + + public void generateCombinations(String digits, String[] keypad, int len, int startIndex, StringBuilder sb, + List result) { + if (startIndex == len) { + result.add(sb.toString()); + return; + } + + for (char ch : keypad[digits.charAt(startIndex) - '0'].toCharArray()) { + sb.append(ch); + generateCombinations(digits, keypad, len, startIndex + 1, sb, result); + sb.deleteCharAt(sb.length() - 1); + } + } + + public static void main(String[] args) { + new MobileKeyPadCombinations().letterCombinations("23").stream().forEach(System.out::println); + } + + public List letterCombinationsIterative(String digits) { + LinkedList ans = new LinkedList<>(); + if (digits.isEmpty()) { + return ans; + } + String[] mapping = { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; + ans.add(""); + for (int i = 0; i < digits.length(); i++) { + int x = Character.getNumericValue(digits.charAt(i)); + while (ans.peek().length() == i) { + String t = ans.remove(); + for (char s : mapping[x].toCharArray()) + ans.add(t + s); + } + } + return ans; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/MoveZeroes.java b/src/geeksforgeeks/MoveZeroes.java new file mode 100644 index 0000000..2dcdd93 --- /dev/null +++ b/src/geeksforgeeks/MoveZeroes.java @@ -0,0 +1,33 @@ +package geeksforgeeks; + +import java.util.Arrays; + +/** + * https://leetcode.com/problems/move-zeroes/ + */ +class MoveZeroes { + + public static void main(String[] args) { + MoveZeroes mz = new MoveZeroes(); + int[] arr = { 0, 1, 0, 3, 12 }; + mz.moveZeroes(arr); + System.out.println(Arrays.toString(arr)); + } + + public void moveZeroes(int[] nums) { + if (nums == null || nums.length == 0) { + return; + } + + int insertPos = 0; + for (int num : nums) { + if (num != 0) { + nums[insertPos++] = num; + } + } + + while (insertPos < nums.length) { + nums[insertPos++] = 0; + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/NQueens.java b/src/geeksforgeeks/NQueens.java new file mode 100644 index 0000000..3a34980 --- /dev/null +++ b/src/geeksforgeeks/NQueens.java @@ -0,0 +1,90 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/n-queens/ + * + * Input: 4 + * Output: [ + * [".Q..", // Solution 1 + * "...Q", + * "Q...", + * "..Q."], + * + * ["..Q.", // Solution 2 + * "Q...", + * "...Q", + * ".Q.."] + * ] + * Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. + */ +public class NQueens { + + public List> solveNQueens(int n) { + if(n==0) return Collections.emptyList(); + + List> result= new ArrayList<>(); + char[][] board= new char[n][n]; + for(int i=0;i> result) { + + if(row==board.length){ + result.add(construct(board)); + return; + } + for(int i=0;i= 0 && j < chess.length; i--, j++) { + if (chess[i][j] == 'Q') { + return false; + } + } + //check 135 + for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { + if (chess[i][j] == 'Q') { + return false; + } + } + return true; + } + + private List construct(char[][] chess) { + List path = new ArrayList<>(); + for (int i = 0; i < chess.length; i++) { + path.add(new String(chess[i])); + } + return path; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/NewRoadsMST.java b/src/geeksforgeeks/NewRoadsMST.java index 2df9c93..507b751 100644 --- a/src/geeksforgeeks/NewRoadsMST.java +++ b/src/geeksforgeeks/NewRoadsMST.java @@ -1,113 +1,86 @@ package geeksforgeeks; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Queue; + +/** + * Given an undirected graph with n nodes labeled 1..n. Some of the nodes are already connected. + * The i-th edge connects nodes edges[i][0] and edges[i][1] together. Your task is to augment this set of edges with additional edges to connect all the nodes. + * Find the minimum cost to add new edges between the nodes such that all the nodes are accessible from each other. + * Input: n = 6, edges = [[1, 4], [4, 5], [2, 3]], newEdges = [[1, 2, 5], [1, 3, 10], [1, 6, 2], [5, 6, 5]] + * Output: 7 + * Explanation: + * There are 3 connected components [1, 4, 5], [2, 3] and [6]. + * We can connect these components into a single component by connecting node 1 to node 2 and node 1 to node 6 at a minimum cost of 5 + 2 = 7. + */ public class NewRoadsMST { - - public static void main(String[] args) { - Graph graph = new Graph(false); - graph.addEdge(1, 4, -1); - graph.addEdge(2, 3, -1); - graph.addEdge(4, 5, -1); - graph.addEdge(1, 2, 5); - graph.addEdge(1, 3, 10); - graph.addEdge(1, 6, 2); - graph.addEdge(5, 6, 5); - - NewRoadsMST newRoads = new NewRoadsMST(); - newRoads.mst(graph); - } - - private void mst(Graph graph) { - List edges = graph.allEdges; - EdgeComparator edgeComparator = new EdgeComparator(); - Collections.sort(edges, edgeComparator); - DisjointSet disjointSet = new DisjointSet(); - List resultEdges = new ArrayList<>(); - Collection allVertex = graph.getAllVertex(); - for (Object vertex : allVertex) { - disjointSet.makeNode((Vertex) vertex); - } - - for (Edge edge : edges) { - if (edge.weight < 0) { - if (disjointSet.unionSet(edge)) { - resultEdges.add(edge); - } - } - } - - for (Edge edge : edges) { - if (edge.weight > 0) { - if (disjointSet.unionSet(edge)) { - resultEdges.add(edge); - } - } - } - - for (Edge edge : resultEdges) { - System.out.println(edge.vertex1.data + "->" + edge.vertex2.data + "->" + edge.weight); - } - } - -} - -class EdgeComparator implements Comparator { - - @Override - public int compare(Edge e1, Edge e2) { - if (e1.weight < e2.weight) { - return -1; - } - return 1; - } -} - -class DisjointSet { - - Map allNodes = new HashMap<>(); - - protected void makeNode(Vertex vertex) { - Node node = new Node(vertex.id); - node.parent = node; - allNodes.put(vertex.id, node); - } - - public boolean unionSet(Edge edge) { - Node srcNode = allNodes.get(edge.vertex1.data); - Node destNode = allNodes.get(edge.vertex2.data); - - Node parentSrcNode = findParent(srcNode); - Node parentDestNode = findParent(destNode); - - if (parentSrcNode != parentDestNode) { - parentDestNode.parent = parentSrcNode; - return true; - } - return false; - } - - public Node findParent(Node node) { - Node parent = node.parent; - if (parent == node) { - return node; - } - return findParent(node.parent); - } + public static void main(String[] args) { + int n = 6; + int[][] edges = {{1, 4}, {4, 5}, {2, 3}}; + int[][] newEdges = {{1, 2, 5}, {1, 3, 10}, {1, 6, 2}, {5, 6, 5}}; + System.out.println(minCost(n, edges, newEdges)); + } + + public static int minCost(int n, int[][] edges, int[][] newEdges) { + UF uf = new UF(n + 1); // + 1 because nodes are 1-based + for (int[] edge : edges) { + uf.union(edge[0], edge[1]); + } + + Queue pq = new PriorityQueue<>(newEdges.length, (e1, e2) -> Integer.compare(e1[2], e2[2])); + pq.addAll(Arrays.asList(newEdges)); + + int totalCost = 0; + // 2 because nodes are 1-based and we have 1 unused component at index 0 + while (!pq.isEmpty() && uf.count != 2) { + int[] edge = pq.poll(); + if (!uf.connected(edge[0], edge[1])) { + uf.union(edge[0], edge[1]); + totalCost += edge[2]; + } + } + return totalCost; + } } -class Node { - long data; - Node parent; - Node child; - - public Node(long id) { - this.data = id; - } +class UF { + private int[] parent; // parent[i] = parent of i + private byte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) + public int count; // number of connected components + + public UF(int n) { + if (n < 0) throw new IllegalArgumentException(); + parent = new int[n]; + rank = new byte[n]; + for (int i = 0; i < n; i++) { + parent[i] = i; + } + count = n; + } + + public int find(int p) { + while (p != parent[p]) { + parent[p] = parent[parent[p]]; + p = parent[p]; + } + return p; + } + + public void union(int p, int q) { + int pr = find(p); + int qr = find(q); + if (pr == qr) return; + if (rank[pr] < rank[qr]) { + parent[pr] = qr; + } else { + parent[qr] = pr; + if (rank[pr] == rank[qr]) rank[pr]++; + } + count--; + } + + public boolean connected(int p, int q) { + return find(p) == find(q); + } } diff --git a/src/geeksforgeeks/NextGreaterElement.java b/src/geeksforgeeks/NextGreaterElement.java index 6128470..78d4a42 100644 --- a/src/geeksforgeeks/NextGreaterElement.java +++ b/src/geeksforgeeks/NextGreaterElement.java @@ -1,6 +1,6 @@ package geeksforgeeks; -import java.util.Stack; +import java.util.*; /** * https://www.geeksforgeeks.org/next-greater-element/ @@ -9,7 +9,7 @@ */ class NextGreaterElement { - static int arr[] = {4, 5, 2, 25}; + static int arr[] = { 1,3,4,2 }; // 9,1,2,3,4,5,6,7 public static void printNGE() { @@ -30,6 +30,60 @@ public static void printNGE() { } +// Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. +// Output: [-1,3,-1] +// Explanation: +// For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. +// For number 1 in the first array, the next greater number for it in the second array is 3. +// For number 2 in the first array, there is no next greater number for it in the second array, so output -1. + public int[] nextGreaterElement(int[] findNums, int[] nums) { + int[] ret = new int[findNums.length]; + ArrayDeque stack = new ArrayDeque<>(); + HashMap map = new HashMap<>(); + for(int i = nums.length - 1; i >= 0; i--) { + while(!stack.isEmpty() && stack.peek() <= nums[i]) { + stack.pop(); + } + if(stack.isEmpty()) map.put(nums[i], -1); + else map.put(nums[i], stack.peek()); + stack.push(nums[i]); + } + for(int i = 0; i < findNums.length; i++) { + ret[i] = map.get(findNums[i]); + } + return ret; + } + +// Input: [1,2,1] +// Output: [2,-1,2] +// Explanation: The first 1's next greater number is 2; +// The number 2 can't find next greater number; +// The second 1's next greater number needs to search circularly, which is also 2. + public static int[] nextGreaterElementCircular(int[] nums){ + if(nums==null || nums.length==0) return new int[0]; + int[] result= new int[nums.length]; + int n= nums.length; + Arrays.fill(result, -1); + Deque deque= new ArrayDeque<>(); + // to mimic the circular array we iterate for 2*n because input [1,2,1] will be like [1,2,1,1,2,1] + // and we take mod of 'n' to update the correct index + for (int i = 2 * nums.length - 1; i >= 0; --i) { + + while (!deque.isEmpty() && nums[deque.peek()] <= nums[i % nums.length]) { + deque.pop(); + } + // The stack is either empty, when no "greater element" is found to the right of nums[i], + // or contains the next greater element of nums[i] at the top. + result[i % nums.length] = deque.isEmpty() ? -1 : nums[deque.peek()]; + + // Push i into stack, so that nums[i-1] will compare with nums[i] first, before falling back to + // the next greater element of nums[i] + deque.push(i % nums.length); + } + + return result; + } + public static void main(String[] args) { printNGE(); } diff --git a/src/geeksforgeeks/NextGreaterNumber.java b/src/geeksforgeeks/NextGreaterNumber.java index 7278dd9..94d532d 100644 --- a/src/geeksforgeeks/NextGreaterNumber.java +++ b/src/geeksforgeeks/NextGreaterNumber.java @@ -8,65 +8,69 @@ * https://www.ideserve.co.in/learn/next-greater-number-using-same-digits */ public class NextGreaterNumber { + + // If all digits sorted in descending order, then output is always “Not Possible”. For example, 4321. + // If all digits are sorted in ascending order, then we need to swap last two digits. For example, 1234. + // For other cases, we need to process the number from rightmost side + //(why? because we need to find the smallest of all greater numbers) - private void swap(int[] number, int i, int j) { - int temp = number[i]; - number[i] = number[j]; - number[j] = temp; - } + // Traverse the given number from rightmost digit, + //keep traversing till you find a digit which is smaller than the previously traversed digit. + //For example, if the input number is “534976”, we stop at 4 because 4 is smaller than next digit 9. + // If we do not find such a digit, then output is “Not Possible”. + // II) Now search the right side of above found digit ‘d’ for the smallest digit greater than ‘d’. + // For “534976″, the right side of 4 contains “976”. The smallest digit greater than 4 is 6. + // III) Swap the above found two digits, we get 536974 in above example. + // IV) Now sort all digits from position next to ‘d’ to the end of number. + //The number that we get after sorting is the output. + //For above example, we sort digits in bold 536974. We get “536479” which is the next greater number for input 534976. + public int nextGreaterElement(int n) { - private void sortSubarray(int[] number, int i, int j) { - // for this sub-array, all the digits would be in there reverse sorted position - while (i < j) { - swap(number, i, j); - i += 1; - j -= 1; - } - } + char[] arr = String.valueOf(n).toCharArray(); + + int i = arr.length - 2; + // I) Start from the right most digit and + // find the first digit that is + // smaller than the digit next to it. + while (i >= 0 && arr[i] >= arr[i + 1]) + i--; - public void findNextGreaterNumber(int[] number) { - int lastDigitSeen = number[number.length - 1]; - int i; - int j; - for (i = number.length - 2; i >= 0; i--) { - // if this digit is where the sorted ordering breaks - if (lastDigitSeen > number[i]) { - break; - } - lastDigitSeen = number[i]; - } + // If no such digit is found, its the edge case 1. + if (i < 0) return -1; - if (i >= 0) // we found the digit breaking the sorted ordering - { - // find the next greater digit in the right sub-array from number[i+1 to end] - for (j = number.length - 1; j > i; j--) { - if (number[j] > number[i]) { - break; - } - } + // II) Find the smallest digit on right side of (i)'th + // digit that is greater than number[i] + int j = arr.length - 1; + while (arr[j] <= arr[i]) + j--; - // swap digits at indices 'i' and 'j' - swap(number, i, j); - System.out.println(Arrays.toString(number)); - // sort the sub-array - number[i+1 to end] - sortSubarray(number, i + 1, number.length - 1); - } + swap(arr, i, j); + reverse(arr, i + 1, arr.length - 1); + + try { + return Integer.valueOf(String.valueOf(arr)); + } catch (NumberFormatException e) { + return -1; } +} - public static void main(String[] args) { - NextGreaterNumber solution = new NextGreaterNumber(); +static void swap(char[] arr, int i, int j) { + arr[i] ^= arr[j]; + arr[j] ^= arr[i]; + arr[i] ^= arr[j]; +} - int[] number = {6, 9, 3, 8, 6, 5, 2}; - // 6938652 - // 6983652 - // 6982356 - // i =3 +static void reverse(char[] arr, int i, int j) { + int l = i, h = j; + while (l < h) + swap(arr, l++, h--); +} + - solution.findNextGreaterNumber(number); + public static void main(String[] args) { + NextGreaterNumber solution = new NextGreaterNumber(); - System.out.println("Next greater number is: "); - for (int i = 0; i < number.length; i++) { - System.out.print(number[i]); - } + System.out.println("Next greater number is: "+solution.nextGreaterElement(6938652)); + } } diff --git a/src/geeksforgeeks/NextLargestList.java b/src/geeksforgeeks/NextLargestList.java new file mode 100644 index 0000000..735e08c --- /dev/null +++ b/src/geeksforgeeks/NextLargestList.java @@ -0,0 +1,58 @@ +package geeksforgeeks; + +import java.util.Stack; + +/** + * https://leetcode.com/problems/next-greater-node-in-linked-list/ + */ +class NextLargestList { + + public int[] nextLargerNodes(ListNode head) { + + if (head == null) { + return new int[0]; + } + int size = getSize(head); + int[] result = new int[size]; + head = reverse(head); + Stack stack = new Stack<>(); + stack.push(head.val); + head = head.next; + int i = size - 2; + result[size - 1] = 0; + while (head != null) { + + while (!stack.isEmpty() && stack.peek() <= head.val) { + stack.pop(); + } + result[i] = stack.isEmpty() ? 0 : stack.peek(); + stack.push(head.val); + head = head.next; + i--; + } + + return result; + } + + public int getSize(ListNode head) { + int size = 0; + ListNode root = head; + while (root != null) { + root = root.next; + size++; + } + return size; + } + + public ListNode reverse(ListNode head) { + ListNode root = head; + ListNode prev = null; + while (root != null) { + ListNode next = root.next; + root.next = prev; + prev = root; + root = next; + } + return prev; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/Node.java b/src/geeksforgeeks/Node.java index 68985c0..04e0bb8 100644 --- a/src/geeksforgeeks/Node.java +++ b/src/geeksforgeeks/Node.java @@ -1,10 +1,11 @@ package geeksforgeeks; - +/** + * https://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/ + */ class RemoveBSTGivenOutsideRange { - private static BSTNode removeOutsideRange(BSTNode root, - int min, int max) { + private static BSTNode removeOutsideRange(BSTNode root, int min, int max) { if (root == null) { return null; } @@ -28,27 +29,20 @@ private static BSTNode removeOutsideRange(BSTNode root, public static BSTNode newNode(int num) { BSTNode temp = new BSTNode(); - temp.data - = num; + temp.data = num; temp.left = null; temp.right = null; return temp; } - public static BSTNode insert(BSTNode root, - int data) { + public static BSTNode insert(BSTNode root, int data) { if (root == null) { - return newNode(data - ); + return newNode(data); } - if (root.data - > data - ) { - root.left = insert(root.left, data - ); + if (root.data > data) { + root.left = insert(root.left, data); } else { - root.right = insert(root.right, data - ); + root.right = insert(root.right, data); } return root; } @@ -56,8 +50,7 @@ public static BSTNode insert(BSTNode root, private static void inorderTraversal(BSTNode root) { if (root != null) { inorderTraversal(root.left); - System.out.print(root.data - + " "); + System.out.print(root.data + " "); inorderTraversal(root.right); } } @@ -72,14 +65,12 @@ public static void main(String[] args) { root = insert(root, 13); root = insert(root, 7); - System.out.print("Inorder Traversal of " + - "the given tree is: "); + System.out.print("Inorder Traversal of " + "the given tree is: "); inorderTraversal(root); root = removeOutsideRange(root, -10, 13); - System.out.print("\nInorder traversal of " + - "the modified tree: "); + System.out.print("\nInorder traversal of " + "the modified tree: "); inorderTraversal(root); } } diff --git a/src/geeksforgeeks/NonDecreasingArray.java b/src/geeksforgeeks/NonDecreasingArray.java index b24d1f2..8c7bb2e 100644 --- a/src/geeksforgeeks/NonDecreasingArray.java +++ b/src/geeksforgeeks/NonDecreasingArray.java @@ -4,6 +4,7 @@ * https://leetcode.com/problems/non-decreasing-array/description/ */ class NonDecreasingArray { + public boolean checkPossibility(int[] nums) { int count = 0; @@ -22,8 +23,8 @@ public boolean checkPossibility(int[] nums) { public static void main(String[] args) { // 1,4,2,3 - //3,4,2,3 - int[] nums = {7, 8, 2, 3}; + // //3,4,2,3 + int[] nums = { 7, 8, 2, 3 }; NonDecreasingArray nda = new NonDecreasingArray(); System.out.println(nda.checkPossibility(nums)); } diff --git a/src/geeksforgeeks/NumberOfBallons.java b/src/geeksforgeeks/NumberOfBallons.java new file mode 100644 index 0000000..1923824 --- /dev/null +++ b/src/geeksforgeeks/NumberOfBallons.java @@ -0,0 +1,24 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/maximum-number-of-balloons/discuss/382401/WithComments-StraightForward-Java-Simple-count-of-chars + */ +public class NumberOfBallons { + + public static int maxNumberOfBalloons(String text) { + int[] chars = new int[26]; //count all letters + for (char c : text.toCharArray()) { + chars[c - 'a']++; + } + int min = chars[1];//for b + min = Math.min(min, chars[0]);//for a + min = Math.min(min, chars[11] / 2);// for l /2 + min = Math.min(min, chars[14] / 2);//similarly for o/2 + min = Math.min(min, chars[13]);//for n + return min; + } + + public static void main(String[] args) { + maxNumberOfBalloons("llonbioan"); + } +} diff --git a/src/geeksforgeeks/NutsAndBoltsMatch.java b/src/geeksforgeeks/NutsAndBoltsMatch.java index 95800bb..43f609b 100644 --- a/src/geeksforgeeks/NutsAndBoltsMatch.java +++ b/src/geeksforgeeks/NutsAndBoltsMatch.java @@ -1,18 +1,22 @@ package geeksforgeeks; -// Java program to solve nut and bolt problem using Quick Sort -// unresolved +/** + * https://www.geeksforgeeks.org/nuts-bolts-problem-lock-key-problem/ + * Java program to solve nut and bolt problem using Quick Sort + */ public class NutsAndBoltsMatch { + public static void main(String[] args) { // Nuts and bolts are represented as array of characters - char nuts[] = {'@', '#', '$', '%', '^', '&'}; - char bolts[] = {'$', '%', '&', '^', '@', '#'}; + char nuts[] = { '@', '#', '$', '%', '^', '&' }; + char bolts[] = { '$', '%', '&', '^', '@', '#' }; // Method based on quick sort which matches nuts and bolts matchPairs(nuts, bolts, 0, 5); System.out.println("Matched nuts and bolts are : "); printArray(nuts); + System.out.println(); printArray(bolts); } @@ -25,14 +29,13 @@ private static void printArray(char[] arr) { } // Method which works just like quick sort - private static void matchPairs(char[] nuts, char[] bolts, int low, - int high) { + private static void matchPairs(char[] nuts, char[] bolts, int low, int high) { if (low < high) { + // Choose last character of bolts array for nuts partition. int pivot = partition(nuts, low, high, bolts[high]); - // Now using the partition of nuts choose that for bolts - // partition. + // Now using the partition of nuts choose that for bolts partition. partition(bolts, low, high, nuts[pivot]); // Recur for [low...pivot-1] & [pivot+1...high] for nuts and diff --git a/src/geeksforgeeks/OverlappingIntervals.java b/src/geeksforgeeks/OverlappingIntervals.java new file mode 100644 index 0000000..775690d --- /dev/null +++ b/src/geeksforgeeks/OverlappingIntervals.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +/** + * Given a collection of intervals, find the minimum number of intervals + * you need to remove to make the rest of the intervals non-overlapping. + * Input: [[1,2],[2,3],[3,4],[1,3]] + Output: 1 + Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. + Input: [[1,2],[1,2],[1,2]] + Output: 2 + Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. + */ + +public class OverlappingIntervals{ + + public int eraseOverlapIntervals(int[][] intervals) { + if(intervals.length==0) return 0; + + PriorityQueue queue = new PriorityQueue((a, b) -> Integer.compare(a[0],b[0])); + + for(int[] interval: intervals){ + queue.offer(interval); + } + int result=0; + + int end= queue.poll()[1]; + + while(!queue.isEmpty()){ + if(end>queue.peek()[0]) { + result++; + end=Math.min(end, queue.poll()[1]); + }else{ + end=queue.poll()[1]; + } + } + + return result; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/OwnDataStructureUtil.java b/src/geeksforgeeks/OwnDataStructureUtil.java index 6ffe412..25693fb 100644 --- a/src/geeksforgeeks/OwnDataStructureUtil.java +++ b/src/geeksforgeeks/OwnDataStructureUtil.java @@ -2,50 +2,55 @@ import java.util.*; +/** + * https://leetcode.com/problems/insert-delete-getrandom-o1/ + */ class OwnDataStructureUtil { - ArrayList list; - HashMap map; - java.util.Random rand = new java.util.Random(); + ArrayList list; + HashMap map; + java.util.Random rand = new java.util.Random(); - public OwnDataStructureUtil() { - list = new ArrayList<>(); - map = new HashMap<>(); - } + public OwnDataStructureUtil() { + list = new ArrayList<>(); + map = new HashMap<>(); + } - public boolean insert(int val) { - if (map.containsKey(val)) - return false; - map.put(val, list.size()); - list.add(val); - return true; - } + public boolean insert(int val) { + if (map.containsKey(val)) { + return false; + } + map.put(val, list.size()); + list.add(val); + return true; + } - public boolean remove(int val) { - if (!map.containsKey(val)) - return false; - int loc = map.get(val); - if (loc < list.size() - 1) { // not the last one than swap the last one with this val - int lastOne = list.get(list.size() - 1); - list.set(loc, lastOne); - map.put(lastOne, loc); - } - map.remove(val); - list.remove(list.size() - 1); - return true; - } + public boolean remove(int val) { + if (!map.containsKey(val)) { + return false; + } + int loc = map.get(val); + if (loc < list.size() - 1) { // not the last one than swap the last one with this val + int lastOne = list.get(list.size() - 1); + list.set(loc, lastOne); + map.put(lastOne, loc); + } + map.remove(val); + list.remove(list.size() - 1); + return true; + } - public int getRandom() { - return list.get(rand.nextInt(list.size())); - } + public int getRandom() { + return list.get(rand.nextInt(list.size())); + } - public static void main(String[] args) { - OwnDataStructureUtil ds = new OwnDataStructureUtil(); - ds.insert(10); - ds.insert(20); - ds.insert(30); - ds.insert(40); - ds.remove(20); - ds.insert(50); - System.out.println(ds.getRandom()); - } + public static void main(String[] args) { + OwnDataStructureUtil ds = new OwnDataStructureUtil(); + ds.insert(10); + ds.insert(20); + ds.insert(30); + ds.insert(40); + ds.remove(20); + ds.insert(50); + System.out.println(ds.getRandom()); + } } diff --git a/src/geeksforgeeks/PalindromePartion.java b/src/geeksforgeeks/PalindromePartion.java new file mode 100644 index 0000000..58ed043 --- /dev/null +++ b/src/geeksforgeeks/PalindromePartion.java @@ -0,0 +1,52 @@ +package geeksforgeeks; + +import java.util.*; + +//https://leetcode.com/problems/palindrome-partitioning/ +/* +Given a string s, partition s such that every substring of the partition is a palindrome. + +Return all possible palindrome partitioning of s. + +Input: "aab" +Output: +[ + ["aa","b"], + ["a","a","b"] +] + */ +class PalindromePartion { + public List> partition(String s) { + List> res = new ArrayList>(); + List list = new ArrayList(); + dfs(s, 0, list, res); + return res; + } + + public void dfs(String s, int pos, List list, List> res) { + if (pos == s.length()) { + res.add(new ArrayList(list)); + return; + } + + for (int i = pos; i < s.length(); i++) { + if (isPal(s, pos, i)) { + list.add(s.substring(pos, i + 1)); + dfs(s, i + 1, list, res); + list.remove(list.size() - 1); + } + } + + } + + public boolean isPal(String s, int low, int high) { + while (low < high) if (s.charAt(low++) != s.charAt(high--)) return false; + return true; + } + + public static void main(String[] args) { + new PalindromePartion().partition("aab"); + } + + +} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromePartitioning.java b/src/geeksforgeeks/PalindromePartitioning.java new file mode 100644 index 0000000..bc76432 --- /dev/null +++ b/src/geeksforgeeks/PalindromePartitioning.java @@ -0,0 +1,57 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/palindrome-partitioning/ + */ +class PalindromePartitioning { + + public List> partition(String s) { + + if (s == null || s.length() == 0) { + return Collections.emptyList(); + } + + List> result = new ArrayList<>(); + backtrackingUtil(s, result, new ArrayList<>()); + + return result; + } + + public void backtrackingUtil(String s, List> result, List tempList) { + if (s == null || s.length() == 0) { + result.add(new ArrayList<>(tempList)); + return; + } + + for (int i = 1; i <= s.length(); i++) { + String temp = s.substring(0, i); + if (isPalindrome(temp)) { + tempList.add(temp); + backtrackingUtil(s.substring(i, s.length()), result, tempList); + tempList.remove(tempList.size() - 1); + } + } + } + + public boolean isPalindrome(String s) { + int start = 0; + int end = s.length() - 1; + while (start <= end) { + if (s.charAt(start) != s.charAt(end)) { + return false; + } + start++; + end--; + } + return true; + } + + public static void main(String[] args) { + PalindromePartitioning partitioning = new PalindromePartitioning(); + partitioning.partition("aab"); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PalindromeSinglyLinkedList.java b/src/geeksforgeeks/PalindromeSinglyLinkedList.java index 9c51c27..2bee7a4 100644 --- a/src/geeksforgeeks/PalindromeSinglyLinkedList.java +++ b/src/geeksforgeeks/PalindromeSinglyLinkedList.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://leetcode.com/problems/palindrome-linked-list/ + */ public class PalindromeSinglyLinkedList { class Node { @@ -47,13 +50,13 @@ public boolean isPalindrome(Node head) { return true; } - public Node reverse(Node head) { + public Node reverse(Node slow) { Node prev = null; - while (head != null) { - Node next = head.next; - head.next = prev; - prev = head; - head = next; + while (slow != null) { + Node next = slow.next; + slow.next = prev; + prev = slow; + slow = next; } return prev; } diff --git a/src/geeksforgeeks/PalindromicSubSequence.java b/src/geeksforgeeks/PalindromicSubSequence.java new file mode 100644 index 0000000..5a54ffc --- /dev/null +++ b/src/geeksforgeeks/PalindromicSubSequence.java @@ -0,0 +1,52 @@ +package geeksforgeeks; + +/** + * Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. + * Input: "cbbd" + * Output: 2 + * + * + */ +class PalindromicSubSequence { + // genral solution if s[l]==s[r] ? 2 + longestPalindromeSubseq(l+1,r-1, s) : + // max(longestPalindromeSubseq(l+1,r, s),longestPalindromeSubseq(l,r-1, s)); + public int longestPalindromeSubseq(String s) { + if(s==null || s.length()==0) return 0; + + int[][] dp= new int[s.length()][s.length()]; + + for(int i=s.length()-1;i>=0;i--){ + for(int j=i;j= 0; i--) { + dp[i] = 1; + int pre = 0; + for (int j = i + 1; j < s.length(); j++) { + int tmp = dp[j]; + if (s.charAt(i) == s.charAt(j)) { + dp[j] = pre + 2; + } else { + dp[j] = Math.max(dp[j], dp[j - 1]); + } + pre = tmp; + } + } + return dp[s.length() - 1]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PartitionLabel.java b/src/geeksforgeeks/PartitionLabel.java index c5f7d31..0be26c0 100644 --- a/src/geeksforgeeks/PartitionLabel.java +++ b/src/geeksforgeeks/PartitionLabel.java @@ -3,17 +3,34 @@ import java.util.ArrayList; import java.util.List; +/** + * https://leetcode.com/problems/partition-labels/ + * A string S of lowercase English letters is given. + * We want to partition this string into as many parts as possible + * so that each letter appears in at most one part, and return a list of integers representing the size of these parts. + * + * Input: S = "ababcbacadefegdehijhklij" + * Output: [9,7,8] + * Explanation: + * The partition is "ababcbaca", "defegde", "hijhklij". + * This is a partition so that each letter appears in at most one part. + * A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts. + */ class PartitionLabel { - public List partitionLabels(String S) { + + public List partitionLabels(String str) { + int[] last = new int[26]; - for (int i = 0; i < S.length(); ++i) - last[S.charAt(i) - 'a'] = i; + for (int i = 0; i < str.length(); ++i) + // find last appearance of the char + last[str.charAt(i) - 'a'] = i; int j = 0; int anchor = 0; List ans = new ArrayList<>(); - for (int i = 0; i < S.length(); ++i) { - j = Math.max(j, last[S.charAt(i) - 'a']); + for (int i = 0; i < str.length(); ++i) { + // find the max of j and last appearance of str[i] + j = Math.max(j, last[str.charAt(i) - 'a']); if (i == j) { // it is (1+i-anchor) int length = i - anchor + 1; diff --git a/src/geeksforgeeks/PascalsTriangle.java b/src/geeksforgeeks/PascalsTriangle.java new file mode 100644 index 0000000..5ec7791 --- /dev/null +++ b/src/geeksforgeeks/PascalsTriangle.java @@ -0,0 +1,70 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * https://leetcode.com/problems/pascals-triangle/ + *

+ * Input: 5 + * Output: + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] + */ +public class PascalsTriangle { + + public List> generate(int numRows) { + + if (numRows == 0) { + return Collections.emptyList(); + } + + List> result = new ArrayList<>(); + List first = Arrays.asList(1); + result.add(first); + if (numRows == 1) { + return result; + } + List second = Arrays.asList(1, 1); + result.add(second); + if (numRows == 2) { + return result; + } + + for (int i = 2; i < numRows; i++) { + List temp = new ArrayList<>(); + temp.add(1); + for (int k = 0; k < i - 1; k++) { + int j = k + 1; + temp.add(result.get(i - 1).get(k) + result.get(i - 1).get(j)); + } + temp.add(1); + result.add(temp); + } + return result; + } + + public List> generate1(int numRows) { + List> allrows = new ArrayList>(); + ArrayList row = new ArrayList(); + for (int i = 0; i < numRows; i++) { + // suppose if the row is [1,3,3,1] + // add 1 at start [1,1,3,3,1] + // then add together j and j+1 elements like below + // [1,4,3,3,1] => [1,4,6,3,1]=>[1,4,6,4,1] + row.add(0, 1); + for (int j = 1; j < row.size() - 1; j++) + row.set(j, row.get(j) + row.get(j + 1)); + allrows.add(new ArrayList(row));// every time the copy is only appended + } + return allrows; + + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PathSumIII.java b/src/geeksforgeeks/PathSumIII.java new file mode 100644 index 0000000..f189ad4 --- /dev/null +++ b/src/geeksforgeeks/PathSumIII.java @@ -0,0 +1,61 @@ +package geeksforgeeks; +public class PathSumIII { + List list= new ArrayList<>(); + int count=0; + public int pathSum(TreeNode root, int sum) { + if(root==null) return 0; + list.add(root.val); + pathSum(root.left,sum); + pathSum(root.right,sum); + + int k=0; + for(int i=list.size()-1;i>=0;i--){ // coming in reverse order, inorder to avoid considering + // head node + k+=list.get(i); + if(sum==k){ + count++; + } + } + + list.remove(list.size()-1); + return count; + } + + public void preorder(TreeNode node, int currSum) { + if (node == null) + return; + + // current prefix sum + currSum += node.val; + + // here is the sum we're looking for + if (currSum == k) + count++; + + // number of times the curr_sum − k has occured already, + // determines the number of times a path with sum k + // has occured upto the current node + count += h.getOrDefault(currSum - k, 0); + + // add the current sum into hashmap + // to use it during the child nodes processing + h.put(currSum, h.getOrDefault(currSum, 0) + 1); + + // process left subtree + preorder(node.left, currSum); + // process right subtree + preorder(node.right, currSum); + + // remove the current sum from the hashmap + // in order not to use it during + // the parallel subtree processing + h.put(currSum, h.get(currSum) - 1); + } + + public int pathSumAlter(TreeNode root, int sum) { + k = sum; + preorder(root, 0); + return count; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/Pattern132.java b/src/geeksforgeeks/Pattern132.java index e2815e5..26a95cf 100644 --- a/src/geeksforgeeks/Pattern132.java +++ b/src/geeksforgeeks/Pattern132.java @@ -1,31 +1,33 @@ package geeksforgeeks; import java.util.Arrays; + /*https://leetcode.com/problems/132-pattern/discuss/94089/Java-solutions-from-O(n3)-to-O(n)-for-%22132%22-pattern-(updated-with-one-pass-slution)*/ public class Pattern132 { - public static boolean find132pattern(int[] arr) { + int[] temp = Arrays.copyOf(arr, arr.length); for (int i = 1; i < arr.length; i++) { temp[i] = Math.min(arr[i - 1], temp[i - 1]); } - //{3, 3, 3, 1, 1, 1, 1, 1} + // {3, 3, 3, 1, 1, 1, 1, 1} for (int j = arr.length - 1, top = arr.length; j >= 0; j--) { - if (arr[j] <= temp[j]) continue; - while (top < arr.length && temp[top] <= temp[j]) top++; - if (top < arr.length && arr[j] > temp[top]) return true; + if (arr[j] <= temp[j]) + continue; + while (top < arr.length && temp[top] <= temp[j]) + top++; + if (top < arr.length && arr[j] > temp[top]) + return true; temp[--top] = arr[j]; } - return false; } public static void main(String[] args) { - int[] arr = {3, 4, 1, 2, 9, 6, 7, 8}; - + int[] arr = { 3, 4, 1, 2, 9, 6, 7, 8 }; find132pattern(arr); } } diff --git a/src/geeksforgeeks/PeakElement.java b/src/geeksforgeeks/PeakElement.java new file mode 100644 index 0000000..a1b35e3 --- /dev/null +++ b/src/geeksforgeeks/PeakElement.java @@ -0,0 +1,40 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/find-peak-element/ + * + * A peak element is an element that is greater than its neighbors. + * + * Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index. + * + * The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. + * + * You may imagine that nums[-1] = nums[n] = -∞. + */ +public class PeakElement { + + public int findPeakElement(int[] nums) { + if (nums == null || nums.length == 0) return -1; + int result = -1; + + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = start + (end - start) / 2; + + if ((mid == 0 || nums[mid] > nums[mid - 1]) && (mid == nums.length - 1 || nums[mid] > nums[mid + 1])) + return mid; + else if (mid > 0 && nums[mid - 1] > nums[mid]) end = mid - 1; + else if (nums[mid + 1] > nums[mid]) start = mid + 1; + + } + return result; + } + + public static void main(String[] args) { + PeakElement pe = new PeakElement(); + int[] arr = {1, 1, 1, 3, 2, 1, 2}; + System.out.println(arr[pe.findPeakElement(arr)]); + } + +} diff --git a/src/geeksforgeeks/PerfectSquare.java b/src/geeksforgeeks/PerfectSquare.java new file mode 100644 index 0000000..2f0e6f2 --- /dev/null +++ b/src/geeksforgeeks/PerfectSquare.java @@ -0,0 +1,71 @@ +package geeksforgeeks; + +import java.util.*; + +class PerfectSquare { + // let's solve by dynamic programming approach + // if we take value 13, the number of perfect squares less than + // the input at any point is Sqrt(input)=>(sqrt(13)=3, so max it can have answer below) + // 3,because 4*4 is 16, so perfect squares below 13 are (1*1, 2*2, 3*3) + // 13 can be broken down into + // 1/ 4| \ 9 deducting 1^2 leaves with val 12 + // / | \ deducting 2^2 leaves with val 9 + // 12 9 4 deducting 3^2 leaves with val 4 + // /|\ /|\ /| + // / | \ 8 5 0 3 0 + // 11 7 3 + + public int numSquaresDp(int n) { + int[] ns = new int[n+1]; + Arrays.fill(ns , -1); + ns[0] = 0; + for(int i=1;i0;j--){ + int result = i - j*j; + // the reason to take min is for i=5 j=sqrt(5)=2 + // when subract 1 we are left with 4 + // when subract 4 we are left with 1 so minimum is 1 and add 1 to it + min = Math.min(min, ns[result]+1); + } + ns[i] = min; + System.out.println(Arrays.toString(ns)); + } + return ns[n]; + } + + public int numSquares(int n){ + Queue q = new LinkedList<>(); + Set visited = new HashSet<>(); + q.offer(0); + visited.add(0); + int depth = 0; + while (!q.isEmpty()) { + int size = q.size(); + depth++; + while (size > 0) { + int removed = q.poll(); + for (int i = 1; i * i <= n; i++) { + int v = removed + i * i; + if (v == n) { + return depth; + } + if (v > n) { + break; + } + if (!visited.contains(v)) { + q.offer(v); + visited.add(v); + } + } + size--; + } + } + return depth; + } + + public static void main(String[] args) { + new PerfectSquare().numSquaresDp(13); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/PetrolGasStation.java b/src/geeksforgeeks/PetrolGasStation.java index fea857c..03a61f2 100644 --- a/src/geeksforgeeks/PetrolGasStation.java +++ b/src/geeksforgeeks/PetrolGasStation.java @@ -24,14 +24,13 @@ public static int canCompleteCircuit(int[] gas, int[] cost) { tank = 0; } } - return start; } public static void main(String[] args) { - int[] gas = {4, 6, 7, 4}; - int[] cost = {6, 5, 3, 5}; + int[] gas = { 4, 6, 7, 4 }; + int[] cost = { 6, 5, 3, 5 }; int start = canCompleteCircuit(gas, cost); System.out.println(start == -1 ? "No Solution" : "Start = " + start); } diff --git a/src/geeksforgeeks/PlusOne.java b/src/geeksforgeeks/PlusOne.java new file mode 100644 index 0000000..7c1f509 --- /dev/null +++ b/src/geeksforgeeks/PlusOne.java @@ -0,0 +1,26 @@ +package geeksforgeeks; + +class PlusOne { + public static int[] plusOne(int[] digits) { + if(digits==null || digits.length==0) return digits; + int temp=digits[digits.length-1]+1; + + digits[digits.length-1]= temp%10; + int rem=temp/10; + for(int i=digits.length-2;i>=0;i--){ + int sum=digits[i]+rem; + digits[i]=(sum)%10; + rem=(sum)/10; + } + + if(rem>0){ + int[] result= new int[digits.length+1]; + result[0]=1; + return result; + } + + + return digits; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/Pow.java b/src/geeksforgeeks/Pow.java new file mode 100644 index 0000000..4108096 --- /dev/null +++ b/src/geeksforgeeks/Pow.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + +// https://leetcode.com/problems/powx-n/ +public class Pow { + + public double myPow(double x, int n) { + + if (n < 0) { + n *= -1; + x = 1 / x; + } + double result = 1; + + result = powerCalcUtil(x, n); + return result; + } + + + public double powerCalcUtil(double x, int n) { + if (n == 0) + return 1; + + double half = powerCalcUtil(x, n / 2); + if (n % 2 == 0) { + return half * half; + } else { + return half * half * x; + } + } + + public double pow1(double x, int n) { + double result = 1.0; + for(int i = n; i != 0; i /= 2, x *= x) { + if( i % 2 != 0 ) { + result *= x; + } + } + return n < 0 ? 1.0 / result : result; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/PrisonAfterNDays.java b/src/geeksforgeeks/PrisonAfterNDays.java index db3c747..81327be 100644 --- a/src/geeksforgeeks/PrisonAfterNDays.java +++ b/src/geeksforgeeks/PrisonAfterNDays.java @@ -9,7 +9,9 @@ class PrisonAfterNDays { public static int[] prisonAfterNDays(int[] cells, int N) { - if (cells == null || cells.length == 0 || N <= 0) return cells; + if (cells == null || cells.length == 0 || N <= 0) { + return cells; + } boolean hasCycle = false; int cycle = 0; HashSet set = new HashSet<>(); @@ -43,7 +45,7 @@ private static int[] nextDay(int[] cells) { } public static void main(String[] args) { - int[] cells = {0, 1, 0, 1, 1, 0, 0, 1}; + int[] cells = { 0, 1, 0, 1, 1, 0, 0, 1 }; int N = 7; System.out.println(Arrays.toString(prisonAfterNDays(cells, N))); } diff --git a/src/geeksforgeeks/ProductExceptSelf.java b/src/geeksforgeeks/ProductExceptSelf.java index 6a0306e..d25d922 100644 --- a/src/geeksforgeeks/ProductExceptSelf.java +++ b/src/geeksforgeeks/ProductExceptSelf.java @@ -4,15 +4,40 @@ /** * https://leetcode.com/problems/product-of-array-except-self/ + *

+ * Given numbers [2, 3, 4, 5], regarding the third number 4, + * the product of array except 4 is 2*3*5 which consists of two parts: left 2*3 and right 5. + * The product is left*right. We can get lefts and rights + *

+ * Numbers: 2 3 4 5 + * Lefts: 2 2*3 2*3*4 + * Rights: 3*4*5 4*5 5 + *

+ * Let’s fill the empty with 1: + *

+ * Numbers: 2 3 4 5 + * Lefts: 1 2 2*3 2*3*4 + * Rights: 3*4*5 4*5 5 1 */ public class ProductExceptSelf { public static int[] productExceptSelf(int[] nums) { int n = nums.length; int[] res = new int[n]; res[0] = 1; + for (int i = 1; i < n; i++) { res[i] = res[i - 1] * nums[i - 1]; } + // once building the left product instead of having a new array to calculate rightsum + // we use a variable to store last seen value + // for number 2 3 4 5 + // the left product array is 1 2 2*3 2*3*4 + + // for rightProd during step1 2 3 4 5 right is 1 so last product value retained + // 2*3*4 + // during step 2 the right becomes 5(1*nums[i]=>5) + // so for value 4(length-2) the left product is 2*3 multiplying with 5 becomes 2*3*5 + // during step 3 the right is updated to (5*nums[i]=>4) 20 int right = 1; for (int i = n - 1; i >= 0; i--) { res[i] *= right; @@ -22,6 +47,6 @@ public static int[] productExceptSelf(int[] nums) { } public static void main(String[] args) { - System.out.println(Arrays.toString(productExceptSelf(new int[]{1, 2, 3, 4, 5}))); + System.out.println(Arrays.toString(productExceptSelf(new int[] { 1, 2, 3, 4, 5 }))); } } \ No newline at end of file diff --git a/src/geeksforgeeks/QueensAttackKing.java b/src/geeksforgeeks/QueensAttackKing.java new file mode 100644 index 0000000..4123789 --- /dev/null +++ b/src/geeksforgeeks/QueensAttackKing.java @@ -0,0 +1,54 @@ +package geeksforgeeks; + +import java.util.*; +//https://leetcode.com/problems/queens-that-can-attack-the-king/submissions/ + +/** + * On an 8x8 chessboard, there can be multiple Black Queens and one White King. + * + * Given an array of integer coordinates queens that represents the positions of the Black Queens, + * and a pair of coordinates king that represent the position of the White King, + * return the coordinates of all the queens (in any order) that can attack the King. + */ +class QueensAttackKing { + public List> queensAttacktheKing(int[][] queens, int[] king) { + List> result= new ArrayList<>(); + boolean[][] visited= new boolean[8][8]; + int[][]dirs= {{1,0},{-1,0},{0,1},{0,-1},{-1,-1},{1,1},{1,-1},{-1,1}}; + // first marking all queen positions + for(int[] qu:queens){ + visited[qu[0]][qu[1]]=true; + } + + for(int[] dir: dirs){ + List temp= findQueensPosistions(king,dir[0],dir[1],visited); + if(temp!=null) result.add(temp); + } + + return result; + + } + + public List findQueensPosistions(int[] king, int x, int y, boolean[][] visited){ + int newX= x+king[0]; + int newY= y+king[1]; + // going to walk along x,y only, not 8 directions at smae time; + while(newX<8 && newY<8 && newX>=0 && newY>=0){ + if(visited[newX][newY]){ + return Arrays.asList(newX,newY); // returns when first queen is met in row or column + } + + newX+=x; + newY+=y; + + } + + return null; + } + + public static void main(String[] args) { + int[][] queens= {{0,1},{1,0},{4,0},{0,4},{3,3},{2,4}}; + int[] king= {0,0}; + new QueensAttackKing().queensAttacktheKing(queens, king); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RaceCarMinSteps.java b/src/geeksforgeeks/RaceCarMinSteps.java new file mode 100644 index 0000000..0f26001 --- /dev/null +++ b/src/geeksforgeeks/RaceCarMinSteps.java @@ -0,0 +1,45 @@ +package geeksforgeeks; + +import java.util.*; +class RaceCarMinSteps { + public int racecar(int target) { + Set visited = new HashSet<>(); + Queue queue = new LinkedList<>(); + queue.add(new StateNode(1, 0)); + int distance = 0; + while (!queue.isEmpty()) { + int levelSize = queue.size(); + for (int i = 0; i < levelSize; i++) { + StateNode cur = queue.poll(); + if (cur.position == target) { + return distance; + } + // if A + int nextPosition = cur.position + cur.speed; + int nextSpeed = cur.speed * 2; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition)); + } + // if R + nextPosition = cur.position; + nextSpeed = cur.speed > 0 ? -1 : 1; + if (!visited.contains(nextSpeed + "," + nextPosition) && Math.abs(target - nextPosition) < target) { + visited.add(nextSpeed + "," + nextPosition); + queue.offer(new StateNode(nextSpeed, nextPosition)); + } + } + distance++; + } + return -1; + } +} + class StateNode { + int speed; + int position; + + public StateNode(int speed, int position) { + this.speed = speed; + this.position = position; + } + } \ No newline at end of file diff --git a/src/geeksforgeeks/RailwayPlatformProblem.java b/src/geeksforgeeks/RailwayPlatformProblem.java deleted file mode 100644 index 60fadd4..0000000 --- a/src/geeksforgeeks/RailwayPlatformProblem.java +++ /dev/null @@ -1,43 +0,0 @@ -package geeksforgeeks; - -import java.util.Arrays; - -/** - * https://www.geeksforgeeks.org/minimum-number-platforms-required-railwaybus-station/ - */ -public class RailwayPlatformProblem { - - static int findPlatform(int[] arrival, int[] departure, int n) { - Arrays.sort(arrival); - Arrays.sort(departure); - - int platNeeded = 1; - int result = 1; - int i = 1; - int j = 0; - - while (i < n && j < n) { - if (arrival[i] <= departure[j]) { - platNeeded++; - i++; - - if (platNeeded > result) - result = platNeeded; - } else { - platNeeded--; - j++; - } - } - return result; - } - - public static void main(String[] args) { - - int[] arr = {900, 940, 950, 1100, 1500, 1800}; - int[] dep = {910, 1200, 1120, 1130, 1900, 2000}; - - int n = arr.length; - System.out.println("Minimum Number of Platforms Required = " + findPlatform(arr, dep, n)); - } - -} diff --git a/src/geeksforgeeks/RandomLinkedList.java b/src/geeksforgeeks/RandomLinkedList.java index cd68a47..2e0070e 100644 --- a/src/geeksforgeeks/RandomLinkedList.java +++ b/src/geeksforgeeks/RandomLinkedList.java @@ -1,60 +1,62 @@ package geeksforgeeks; -class LLNode { - public int val; - public LLNode next; - public LLNode random; - - public LLNode() { - } +/** + * https://leetcode.com/problems/copy-list-with-random-pointer/ + */ +class RandomLinkedList { + + public LLNode copyRandomList(LLNode head) { + if (head == null) { + return null; + } + LLNode temp = head; + while (temp != null) { + LLNode LLNode = new LLNode(temp.val + 10, temp.next, null); + temp.next = LLNode; + temp = temp.next.next; + } + LLNode randomLLNode = head; + while (randomLLNode != null) { + randomLLNode.next.random = randomLLNode.random.next; + randomLLNode = randomLLNode.next.next; + } + LLNode copyHead = head.next; + LLNode tempHead = copyHead; + while (head != null && tempHead != null) { + head.next = head.next == null || head.next.next == null ? head.next : head.next.next; + tempHead.next = tempHead.next == null || tempHead.next.next == null ? tempHead.next : tempHead.next.next; + head = head.next; + tempHead = tempHead.next; + } + return copyHead; + } - public LLNode(int _val, LLNode _next, LLNode _random) { - val = _val; - next = _next; - random = _random; - } + public static void main(String[] args) { + LLNode head = new LLNode(1, null, null); + head.next = new LLNode(2, null, null); + head.next.next = new LLNode(3, null, null); + head.next.next.next = new LLNode(4, null, null); + head.random = head.next.next; + head.next.random = head.next.next.next; + head.next.next.random = head.next; + head.next.next.next.random = head; + RandomLinkedList solution = new RandomLinkedList(); + solution.copyRandomList(head); + } +} - public String toString() { - return "" + this.val; - } -}; +class LLNode { + public int val; + public LLNode next; + public LLNode random; -class RandomLinkedList { - public LLNode copyRandomList(LLNode head) { - if (head == null) - return null; - LLNode temp = head; - while (temp != null) { - LLNode LLNode = new LLNode(temp.val + 10, temp.next, null); - temp.next = LLNode; - temp = temp.next.next; - } - LLNode randomLLNode = head; - while (randomLLNode != null) { - randomLLNode.next.random = randomLLNode.random.next; - randomLLNode = randomLLNode.next.next; - } - LLNode copyHead = head.next; - LLNode tempHead = copyHead; - while (head != null && tempHead != null) { - head.next = head.next == null || head.next.next == null ? head.next : head.next.next; - tempHead.next = tempHead.next == null || tempHead.next.next == null ? tempHead.next : tempHead.next.next; - head = head.next; - tempHead = tempHead.next; - } - return copyHead; - } + public LLNode(int _val, LLNode _next, LLNode _random) { + val = _val; + next = _next; + random = _random; + } - public static void main(String[] args) { - LLNode head = new LLNode(1, null, null); - head.next = new LLNode(2, null, null); - head.next.next = new LLNode(3, null, null); - head.next.next.next = new LLNode(4, null, null); - head.random = head.next.next; - head.next.random = head.next.next.next; - head.next.next.random = head.next; - head.next.next.next.random = head; - RandomLinkedList solution = new RandomLinkedList(); - solution.copyRandomList(head); - } -} + public String toString() { + return "" + this.val; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RangeSum.java b/src/geeksforgeeks/RangeSum.java new file mode 100644 index 0000000..213f774 --- /dev/null +++ b/src/geeksforgeeks/RangeSum.java @@ -0,0 +1,18 @@ +package geeksforgeeks; + +public class RangeSum { + int[] dp; + public NumArray(int[] nums) { + if(nums.length==0) return ; + dp= new int[nums.length]; + dp[0]=nums[0]; + for(int i=1;i findItinerary(List> tickets) { + if(tickets==null || tickets.size()==0) return Collections.emptyList(); + + Map > map= new HashMap<>(); + + for(List ticket: tickets){ + map.putIfAbsent(ticket.get(0), new PriorityQueue<>()); + map.get(ticket.get(0)).offer(ticket.get(1)); + } + List res = new ArrayList(); + dfs(map, res, "JFK"); + return res; + } + + public void dfs( Map> map, List res, String s){ + + PriorityQueue queue= map.get(s); + + while(queue!=null && !queue.isEmpty()){ + String temp= queue.poll(); + dfs(map, res, temp); + } + + res.add(0,s); + } + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/RedundantConnection.java b/src/geeksforgeeks/RedundantConnection.java new file mode 100644 index 0000000..c122fed --- /dev/null +++ b/src/geeksforgeeks/RedundantConnection.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +public class RedundantConnection { + public int[] findRedundantConnection(int[][] edges) { + DisjointSet set= new DisjointSet(edges.length); + + for(int[]edge: edges){ + if(!set.union(edge[0]-1, edge[1]-1)) return edge; + } + return new int[]{-1,-1}; + } + + static class DisjointSet{ + int[] parent; + int[] rank; + + public DisjointSet(int n){ + this.parent= new int[n]; + this.rank= new int[n]; + } + + public int find(int x){ + if(parent[x]==0) return x; + return parent[x]=find(parent[x]); + } + + public boolean union(int x, int y){ + int rootX= find(x); + int rootY= find(y); + + if(rootX==rootY) return false; + + if(rank[rootX] stack = new Stack<>(); - int i = 0; - while (i < num.length()) { - while (k > 0 && !stack.isEmpty() && stack.peek() > num.charAt(i)) { - stack.pop(); + public static String removeKdigits(String num, int k) { + if(num==null || num.length()==0) return null; + + Deque queue= new ArrayDeque<>(); + for(char c: num.toCharArray()){ + + while(!queue.isEmpty() && queue.getLast()>c-'0' && k>0){ + queue.removeLast(); k--; } - stack.push(num.charAt(i)); - i++; + queue.addLast(c-'0'); } - - // corner case like "1111" - while (k > 0) { - stack.pop(); + + while(k>0){ + queue.removeLast(); k--; } - - StringBuilder sb = new StringBuilder(); - while (!stack.isEmpty()) - sb.append(stack.pop()); - sb.reverse(); - - while (sb.length() > 1 && sb.charAt(0) == '0') - sb.deleteCharAt(0); - return sb.toString(); + + StringBuilder result= new StringBuilder(); + while(!queue.isEmpty()){ + result.append(queue.removeFirst()); + } + + while(result.length()>0 && result.charAt(0)=='0'){ + result.deleteCharAt(0); + } + + return result.length()==0?"0":result.toString(); } public static void main(String[] args) { - System.out.println(removeKdigits("14232191", 3)); + System.out.println(removeKDigits("14232191", 3)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/RemoveParanthesisValid.java b/src/geeksforgeeks/RemoveParanthesisValid.java new file mode 100644 index 0000000..88982dc --- /dev/null +++ b/src/geeksforgeeks/RemoveParanthesisValid.java @@ -0,0 +1,58 @@ +package geeksforgeeks; +class RemoveParanthesisValid { + + public List removeInvalidParentheses(String s) { + if (isValid(s)) + return Collections.singletonList(s); + List ans = new ArrayList<>(); + //The queue only contains invalid middle steps + Queue queue = new LinkedList<>(); + //The 3-Tuple is (string, startIndex, lastRemovedChar) + queue.add(new Tuple(s, 0, ')')); + while (!queue.isEmpty()) { + Tuple x = queue.poll(); + //Observation 2, start from last removal position + for (int i = x.start; i < x.string.length(); ++i) { + char ch = x.string.charAt(i); + //Not parentheses + if (ch != '(' && ch != ')') continue; + //Observation 1, do not repeatedly remove from consecutive ones + if (i != x.start && x.string.charAt(i - 1) == ch) continue; + //Observation 3, do not remove a pair of valid parentheses + if (x.removed == '(' && ch == ')') continue; + String t = x.string.substring(0, i) + x.string.substring(i + 1); + //Check isValid before add + if (isValid(t)) + ans.add(t); + //Avoid adding leaf level strings + else if (ans.isEmpty()) + queue.add(new Tuple(t, i, ch)); + } + } + return ans; +} + +public static boolean isValid(String s) { + int count = 0; + for (int i = 0; i < s.length(); ++i) { + char c = s.charAt(i); + if (c == '(') ++count; + if (c == ')' && count-- == 0) return false; + } + return count == 0; +} + +} + + class Tuple { + public final String string; + public final int start; + public final char removed; + + public Tuple(String string, int start, char removed) { + this.string = string; + this.start = start; + this.removed = removed; + +} +} \ No newline at end of file diff --git a/src/geeksforgeeks/ReorderLogs.java b/src/geeksforgeeks/ReorderLogs.java index 2140cc1..ebda923 100644 --- a/src/geeksforgeeks/ReorderLogs.java +++ b/src/geeksforgeeks/ReorderLogs.java @@ -2,11 +2,28 @@ import java.util.Arrays; -/*https://leetcode.com/articles/reorder-log-files/*/ +/*https://leetcode.com/articles/reorder-log-files/ + +You have an array of logs. Each log is a space delimited string of words. + +For each log, the first word in each log is an alphanumeric identifier. Then, either: + +Each word after the identifier will consist only of lowercase letters, or; +Each word after the identifier will consist only of digits. +We will call these two varieties of logs letter-logs and digit-logs. It is guaranteed that each log has at least one word after its identifier. + +Reorder the logs so that all of the letter-logs come before any digit-log. +The letter-logs are ordered lexicographically ignoring identifier, with the identifier used in case of ties. +The digit-logs should be put in their original order. + +Input: logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"] +Output: ["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"] +*/ + class ReorderLogs { public static String[] reorderLogFiles(String[] logs) { Arrays.sort(logs, (s1, s2) -> { - String[] split1 = s1.split(" ", 2); + String[] split1 = s1.split(" ", 2); // splits arr in to 2 parts String[] split2 = s2.split(" ", 2); boolean isDigit1 = Character.isDigit(split1[1].charAt(0)); @@ -34,7 +51,7 @@ public static String[] reorderLogFiles(String[] logs) { } public static void main(String[] args) { - String[] string = {"dig1 8 1 5 1", "let1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero"}; + String[] string = {"dig1 8 1 5 1", "yet1 art can", "dig2 3 6", "let2 own kit dig", "let3 art zero"}; System.out.println(Arrays.toString(reorderLogFiles(string))); } } \ No newline at end of file diff --git a/src/geeksforgeeks/ReorganiseString.java b/src/geeksforgeeks/ReorganiseString.java new file mode 100644 index 0000000..c8288f9 --- /dev/null +++ b/src/geeksforgeeks/ReorganiseString.java @@ -0,0 +1,71 @@ +package geeksforgeeks; + +/** + * Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same. + * + * If possible, output any possible result. If not possible, return the empty string. + * + * Input: S = "aab" + * Output: "aba" + * + * Input: S = "aaab" + * Output: "" + */ +class ReorganiseString { + public String reorganizeString(String s) { + if (s == null || s.length() < 1) return ""; + + int[] hash = new int[26]; + for (char c : s.toCharArray()) { + hash[c - 'a']++; + } + + int max = 0; + int letter = 0; + + for (int i = 0; i < hash.length; i++) { + if (hash[i] > max) { + max = hash[i]; + letter = i; + } + } + + if (max > (s.length() + 1) / 2) return ""; + + char[] res = new char[s.length()]; + + int pos = 0; + while (hash[letter] > 0) { + res[pos] = (char) (letter + 'a'); + pos += 2; + hash[letter]--; + } + + // We construct the resulting string in sequence: at position 0, 2, 4, ... and then 1, 3, 5, ... + // In this way, we can make sure there is always a gap between the same characters + + // Consider this example: "aaabbbcdd", we will construct the string in this way: + + // a _ a _ a _ _ _ _ // fill in "a" at position 0, 2, 4 + // a b a _ a _ b _ b // fill in "b" at position 6, 8, 1 + // a b a c a _ b _ b // fill in "c" at position 3 + // a b a c a d b d b // fill in "d" at position 5, 7 + + for (int i = 0; i < hash.length; i++) { + while (hash[i] > 0) { + if (pos >= res.length) pos = 1; + + res[pos] = (char) (i + 'a'); + pos += 2; + hash[i]--; + } + } + + return new String(res); + } + + public static void main(String[] args) { + + new ReorganiseString().reorganizeString("aabccdeeee"); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RestoreIPAddress.java b/src/geeksforgeeks/RestoreIPAddress.java index 1ac6c71..452389c 100644 --- a/src/geeksforgeeks/RestoreIPAddress.java +++ b/src/geeksforgeeks/RestoreIPAddress.java @@ -1,32 +1,34 @@ package geeksforgeeks; import java.util.*; + //unresolved class RestoreIPAddress { - public List restoreIpAddresses(String s) { - List result = new ArrayList<>(); - doRestore(result, "", s, 0); - return result; - } + public List restoreIpAddresses(String s) { + List result = new ArrayList<>(); + doRestore(result, "", s, 0); + return result; + } - private void doRestore(List result, String path, String s, int k) { - if (s.isEmpty() || k == 4) { - if (s.isEmpty() && k == 4) - result.add(path.substring(1)); - return; - } - for (int i = 1; i <= (s.charAt(0) == '0' ? 1 : 3) && i <= s.length(); i++) { // Avoid leading 0 - String part = s.substring(0, i); - if (Integer.valueOf(part) <= 255) { - System.out.println(path); - doRestore(result, path + "." + part, s.substring(i), k + 1); - } - } - } + private void doRestore(List result, String path, String s, int k) { + if (s.isEmpty() || k == 4) { + if (s.isEmpty() && k == 4) { + result.add(path.substring(1)); + } + return; + } + for (int i = 1; i <= (s.charAt(0) == '0' ? 1 : 3) && i <= s.length(); i++) { // Avoid leading 0 + String part = s.substring(0, i); + if (Integer.valueOf(part) <= 255) { + System.out.println(path); + doRestore(result, path + "." + part, s.substring(i), k + 1); + } + } + } - public static void main(String[] args) { - RestoreIPAddress ip = new RestoreIPAddress(); - System.out.println(ip.restoreIpAddresses("25525511135").toString()); - } + public static void main(String[] args) { + RestoreIPAddress ip = new RestoreIPAddress(); + System.out.println(ip.restoreIpAddresses("25525511135").toString()); + } } diff --git a/src/geeksforgeeks/RestorepAddresses.java b/src/geeksforgeeks/RestorepAddresses.java new file mode 100644 index 0000000..e85178e --- /dev/null +++ b/src/geeksforgeeks/RestorepAddresses.java @@ -0,0 +1,42 @@ +package geeksforgeeks; + +import java.util.*; + +public class RestorepAddresses { + public List restoreIpAddresses(String s) { + if (s == null) + return Collections.emptyList(); + List result = new ArrayList<>(); + + for (int i = 1; i < 4 && i < s.length(); i++) { + String first = s.substring(0, i); + if (isValid(first)) { + for (int j = 1; j < 4 && j + i < s.length(); j++) { + String second = s.substring(i, i + j); + if (isValid(second)) { + for (int k = 1; i + j + k < s.length() && k < 4; k++) { + String third = s.substring(i + j, i + j + k); + String fourth = s.substring(i + j + k); + if (isValid(third) && isValid(fourth)) { + result.add(first + "." + second + "." + third + "." + fourth); + } + } + } + } + } + } + return result; + } + + public boolean isValid(String part) { + if (part == null || part.length() > 3) + return false; + + if (part.charAt(0) == '0' && part.length() > 1) + return false; + + int address = Integer.parseInt(part); + + return address >= 0 && address <= 255; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ReverseWordsInString.java b/src/geeksforgeeks/ReverseWordsInString.java new file mode 100644 index 0000000..0832f61 --- /dev/null +++ b/src/geeksforgeeks/ReverseWordsInString.java @@ -0,0 +1,38 @@ +package geeksforgeeks; + +public class ReverseWordsInString { + + public char[] reverse(char[] arr, int i, int j) { + while (i < j) { + char tmp = arr[i]; + arr[i++] = arr[j]; + arr[j--] = tmp; + } + return arr; + } + + public String reverseWords(String s) { + // reverse the whole string and convert to char array + char[] str = reverse(s.toCharArray(), 0, s.length()-1); + int start = 0, end = 0; // start and end positions of a current word + //for input "the sky is blue" + // the char arr contians + //[e u l b s i y k s e h t] + + System.out.println(Arrays.toString(str)); + for (int i = 0; i < str.length; i++) { + if (str[i] != ' ') { // if the current char is letter + str[end++] = str[i]; // just move this letter to the next free pos + } else if (i > 0 && str[i-1] != ' ') { // if the first space after word + reverse(str, start, end-1); // reverse the word + str[end++] = ' '; // and put the space after it + start = end; // move start position further for the next word + } + } + reverse(str, start, end-1); // reverse the tail word if it's there + // here's an ugly return just because we need to return Java's String + // also as there could be spaces at the end of original string + // we need to consider redundant space we have put there before + return new String(str, 0, end > 0 && str[end-1] == ' ' ? end-1 : end); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/RomanToInteger.java b/src/geeksforgeeks/RomanToInteger.java new file mode 100644 index 0000000..1469c62 --- /dev/null +++ b/src/geeksforgeeks/RomanToInteger.java @@ -0,0 +1,34 @@ +package geeksforgeeks; + +import java.util.*; + +public class RomanToInteger { + + public int romanToInteger(String s) { + Map map = new HashMap(); + + map.put('I', 1); + map.put('V', 5); + map.put('X', 10); + map.put('L', 50); + map.put('C', 100); + map.put('D', 500); + map.put('M', 1000); + + int sum = map.get(s.charAt(s.length() - 1)); + for (int i = s.length() - 2; i >= 0; --i) { + if (map.get(s.charAt(i)) < map.get(s.charAt(i + 1))) { + sum -= map.get(s.charAt(i)); + } else { + sum += map.get(s.charAt(i)); + } + } + return sum; + + } + + public static void main(String[] args) { + new RomanToInteger().romanToInteger("LIX"); + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/RotateMatrixInPlace.java b/src/geeksforgeeks/RotateMatrixInPlace.java index 950813b..88879d9 100644 --- a/src/geeksforgeeks/RotateMatrixInPlace.java +++ b/src/geeksforgeeks/RotateMatrixInPlace.java @@ -43,6 +43,36 @@ static void rotateMatrix(int N, int mat[][]) { } } + public void rotate(int[][] matrix) { + if(matrix == null || matrix.length == 0 || matrix[0].length == 0)return; + int n= matrix.length-1; + + for(int i=0; i + * https://leetcode.com/problems/rotate-image/discuss/298719/A-Java-one-pass-solution-with-detailed-explanation + *

+ * //x,y1=x2,y2 + * // x1=y2 + */ +class RotateMatrixInPlaceAntiClockwise { + + static void rotateMatrix(int N, int mat[][]) { + + for (int x = 0; x < N / 2; x++) { + + for (int y = x; y < N - x; y++) { + + // store current cell in temp variable + int temp = mat[x][y]; + + // move values from right to top + mat[x][y] = mat[y][N - x]; + + // move values from bottom to right + mat[y][N - x] = mat[N - x][N - y]; + + // move values from left to bottom + mat[N - x][N - y] = mat[N - y][x]; + + // assign temp to left + mat[N - y][x] = temp; + } + } + } + + static void displayMatrix(int N, int mat[][]) { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) + System.out.print(" " + mat[i][j]); + + System.out.print("\n"); + } + System.out.print("\n"); + } + + public static void main(String[] args) { + int N = 4; + + // Test Case 1 + int mat[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } }; + + // int mat[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; + // int mat[][] = { {1, 2}, {4, 5} }; + + // displayMatrix(mat); + + rotateMatrix(N - 1, mat); + + // Print rotated matrix + displayMatrix(N, mat); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SameTree.java b/src/geeksforgeeks/SameTree.java new file mode 100644 index 0000000..6db6fd9 --- /dev/null +++ b/src/geeksforgeeks/SameTree.java @@ -0,0 +1,60 @@ +package geeksforgeeks; + +/** + * Given two binary trees, write a function to check if they are the same or not. + * Two binary trees are considered the same if they are structurally identical and the nodes have the same value. +Input: 1 1 + / \ / \ + 2 1 1 2 + + [1,2,1], [1,1,2] + +Output: false + */ +public class SameTree { + public boolean check(TreeNode p, TreeNode q) { + // p and q are null + if (p == null || q == null) return p==q; + if (p.val != q.val) return false; + return true; + } + + public boolean isSameTree(TreeNode p, TreeNode q) { + if (p == null && q == null) return true; + if (!check(p, q)) return false; + + // init deques + ArrayDeque deqP = new ArrayDeque(); + ArrayDeque deqQ = new ArrayDeque(); + deqP.addLast(p); + deqQ.addLast(q); + + while (!deqP.isEmpty()) { + p = deqP.removeFirst(); + q = deqQ.removeFirst(); + + if (!check(p, q)) return false; + if (p != null) { + // in Java nulls are not allowed in Deque + if (!check(p.left, q.left)) return false; + if (p.left != null) { + deqP.addLast(p.left); + deqQ.addLast(q.left); + } + if (!check(p.right, q.right)) return false; + if (p.right != null) { + deqP.addLast(p.right); + deqQ.addLast(q.right); + } + } + } + return true; + } + + public boolean isSameTreeRecur(TreeNode p, TreeNode q){ + if(p==null || q==null) return p==q; + if(p.val==q.val) return true; + + return isSameTreeRecur(p.left, q.left) && isSameTreeRecur(p.right, q.right); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SearchAMaze.java b/src/geeksforgeeks/SearchAMaze.java index e810f2b..d7e19e1 100644 --- a/src/geeksforgeeks/SearchAMaze.java +++ b/src/geeksforgeeks/SearchAMaze.java @@ -1,6 +1,6 @@ package geeksforgeeks; -import java.util.ArrayDeque; +import java.util.LinkedList; import java.util.Queue; /** @@ -11,15 +11,16 @@ public class SearchAMaze { private static final int M = 10; private static final int N = 10; - private static final int row[] = {-1, 0, 0, 1}; - private static final int col[] = {0, -1, 1, 0}; + private static final int row[] = { -1, 0, 0, 1 }; + private static final int col[] = { 0, -1, 1, 0 }; private static boolean isValid(int mat[][], int row, int col) { return (row >= 0) && (row < M) && (col >= 0) && (col < N) && mat[row][col] == 1; } private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { - Queue q = new ArrayDeque<>(); + + Queue q = new LinkedList<>(); q.add(new MazeNode(srcX, srcY, 0)); @@ -55,10 +56,10 @@ private static void BFS(int mat[][], int srcX, int srcY, int destX, int destY) { } public static void main(String[] args) { - int[][] mat = {{1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 0, 1, 0, 1}, - {0, 0, 1, 0, 1, 1, 1, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 1, 1, 0, 1}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 1}, - {1, 0, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 0, 0, 0, 1, 0, 0, 1, 0, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 0, 0}, - {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, {0, 0, 1, 0, 0, 1, 1, 0, 0, 1}}; + int[][] mat = { { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 0, 1, 0, 1 }, + { 0, 0, 1, 0, 1, 1, 1, 0, 0, 1 }, { 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 }, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1 }, + { 1, 0, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 }, { 0, 0, 1, 0, 0, 1, 1, 0, 0, 1 } }; BFS(mat, 8, 0, 0, 9); } diff --git a/src/geeksforgeeks/SearchAnElementInMatrix.java b/src/geeksforgeeks/SearchAnElementInMatrix.java index 61bd8af..855a1b6 100644 --- a/src/geeksforgeeks/SearchAnElementInMatrix.java +++ b/src/geeksforgeeks/SearchAnElementInMatrix.java @@ -1,25 +1,28 @@ package geeksforgeeks; + /*https://www.youtube.com/watch?v=FOa55B9Ikfg * https://leetcode.com/problems/search-a-2d-matrix-ii/ https://leetcode.com/problems/search-a-2d-matrix/*/ - public class SearchAnElementInMatrix { private static boolean searchII(int[][] mat, int n, int x) { int i = 0; int j = n - 1; // set indexes for top right element - + // we can start from top right corner or bottom left corner, because from + // these points only we have 2 paths one increasing one decreasing while (i < n && j >= 0) { if (mat[i][j] == x) { System.out.print("n Found at " + i + " " + j); return true; } - if (mat[i][j] > x) + if (mat[i][j] > x) { j--; - else // if mat[i][j] < x + } else // if mat[i][j] < x + { i++; + } } System.out.print("n Element not found"); @@ -51,11 +54,9 @@ public static boolean searchI(int[][] matrix, int target) { } public static void main(String[] args) { - int[][] mat = {{10, 20, 30, 40}, {15, 25, 35, 45}, {27, 29, 37, 48}, {32, 33, 39, 50}}; + int[][] mat = { { 10, 20, 30, 40 }, { 15, 25, 35, 45 }, { 27, 29, 37, 48 }, { 32, 33, 39, 50 } }; - int[][] matI = {{1, 3, 5, 7}, - {10, 11, 16, 20}, - {23, 30, 34, 50}}; + int[][] matI = { { 1, 3, 5, 7 }, { 10, 11, 16, 20 }, { 23, 30, 34, 50 } }; System.out.println(searchI(matI, 11)); System.out.println(searchII(mat, 4, 33)); diff --git a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java index 64c5714..9ee10b5 100644 --- a/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java +++ b/src/geeksforgeeks/SearchElementInSortedAndRotatedArray.java @@ -1,41 +1,117 @@ package geeksforgeeks; -/*https://leetcode.com/problems/search-in-rotated-sorted-array/*/ +/*https://leetcode.com/problems/search-in-rotated-sorted-array/ +https://leetcode.com/problems/search-in-rotated-sorted-array-ii/ + */ public class SearchElementInSortedAndRotatedArray { public static void main(String[] args) { - int[] arr = {4, 5, 6, 7, 0, 1, 2}; + int[] arr = { 4, 5, 6, 7, 0, 1, 2 }; + SearchElementInSortedAndRotatedArray search = new SearchElementInSortedAndRotatedArray(); - System.out.println(search.searchInArray(arr, 1)); + System.out.println(search.searchI(arr, 0)); + + int[] nums = { 2, 5, 6, 0, 0, 1, 2 }; + System.out.println(search.searchII(nums, 2)); } - // 4, 5, 6, 7, 0, 1, 2 - int searchInArray(int arr[], int key) { + // 4, 5, 0, 1, 2, 3 + int searchI(int[] nums, int target) { - int left = 0; - int right = arr.length - 1; + // If arr[start] <= arr[middle], the numbers from start to middle are sorted in ascending order. + // Else, the numbers from middle+1 to end are sorted in ascending order. + int start = 0; + int end = nums.length - 1; + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] == target) { + return mid; + } + - while (left < right) { + if (nums[start] <= nums[mid]) { + if (target < nums[mid] && target >= nums[start]) { + end = mid - 1; + } else { + start = mid + 1; + } + } + - int mid = (left + right) / 2; - if (arr[mid] == key) - return mid; + if (nums[mid] <= nums[end]) { + if (target > nums[mid] && target <= nums[end]) { + start = mid + 1; + } else { + end = mid - 1; + } + } + } + return -1; + } + + // with duplicates + public boolean searchII(int[] nums, int target) { + int left = 0, right = nums.length-1, mid; + + while(left<=right) + { + mid = (left + right) >> 1; + if(nums[mid] == target) return true; + + // the only difference from the first one, trickly case, just updat left and right + if ((nums[left] == nums[mid]) && (nums[right] == nums[mid])) { + ++left; + --right; + } - if (arr[left] < arr[mid]) { - if (key > arr[left] && key < arr[mid]) { - right = mid - 1; + else if(nums[left] <= nums[mid]) + { + if( (nums[left]<=target) && (nums[mid] > target) ) right = mid-1; + else left = mid + 1; + } + else + { + if((nums[mid] < target) && (nums[right] >= target) ) left = mid+1; + else right = mid-1; + } + } + return false; + } + //[2,5,6,0,0,1,2] + // 0 + //duplicates, we know nums[mid] != target, so nums[start] != target //based on current information, + // we can only move left pointer to skip one cell //thus in the worst case, we would have target: 2, and array like 11111111, + // then //the running time would be O(n) + public boolean searchIIEff(int[] nums, int target) { + + int start = 0; + int end = nums.length - 1; + + while (start <= end) { + int mid = (start + end) / 2; + if (nums[mid] == target) { + return true; + } + + // the only difference from the first one, tricky case, just update start and end + if ((nums[start] == nums[mid]) && (nums[end] == nums[mid])) { + ++start; + --end; + } else if (nums[start] <= nums[mid]) { + if ((nums[start] <= target) && (nums[mid] > target)) { + end = mid - 1; } else { - left = mid + 1; + start = mid + 1; } } else { - if (key > arr[mid] && key < arr[right]) { - left = mid + 1; + if ((nums[mid] < target) && (nums[end] >= target)) { + start = mid + 1; } else { - right = mid - 1; + end = mid - 1; } } } - return -1; + return false; } } diff --git a/src/geeksforgeeks/SerializeAndDeserialize.java b/src/geeksforgeeks/SerializeAndDeserialize.java index 336a088..c982e89 100644 --- a/src/geeksforgeeks/SerializeAndDeserialize.java +++ b/src/geeksforgeeks/SerializeAndDeserialize.java @@ -17,67 +17,64 @@ public class SerializeAndDeserialize { - private static final String NULL_SYMBOL = "X"; - private static final String DELIMITER = ","; - - public String serialize(TreeNode root) { - - if (root == null) { - return NULL_SYMBOL + DELIMITER; - } - - String leftSerialized = serialize(root.left); - String rightSerialized = serialize(root.right); - - return root.val + DELIMITER + leftSerialized + rightSerialized; - } - - public TreeNode deserialize(String data) { - Queue nodesLeftToMaterialize = new LinkedList<>(); - nodesLeftToMaterialize.addAll(Arrays.asList(data.split(DELIMITER))); - return deserializeHelper(nodesLeftToMaterialize); - } - - public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { - - String valueForNode = nodesLeftToMaterialize.poll(); - - if (valueForNode.equals(NULL_SYMBOL)) { - return null; - } - - TreeNode newNode = new TreeNode(Integer.valueOf(valueForNode)); - newNode.left = deserializeHelper(nodesLeftToMaterialize); - newNode.right = deserializeHelper(nodesLeftToMaterialize); - - return newNode; - } - - public static void main(String[] args) { - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.right = new TreeNode(3); - root.left.right = new TreeNode(4); - root.right.left = new TreeNode(5); - root.right.right = new TreeNode(6); - root.right.left.left = new TreeNode(7); - root.right.left.right = new TreeNode(8); - SerializeAndDeserialize sede = new SerializeAndDeserialize(); - String serialize = sede.serialize(root); - System.out.println(serialize); - TreeNode deserialze = sede.deserialize(serialize); - sede.printTree(deserialze); - } - - public void printTree(TreeNode node) { - if (node == null) { - System.out.print("X,"); - return; - } - System.out.print(node.val + ","); - printTree(node.left); - printTree(node.right); - } + private static final String NULL_SYMBOL = "X"; + private static final String DELIMITER = ","; + + public String serialize(TreeNode root) { + + if (root == null) { + return NULL_SYMBOL + DELIMITER; + } + + String leftSerialized = serialize(root.left); + String rightSerialized = serialize(root.right); + + return root.val + DELIMITER + leftSerialized + rightSerialized; + } + + public TreeNode deserialize(String data) { + Queue nodesLeftToMaterialize = new LinkedList<>(); + nodesLeftToMaterialize.addAll(Arrays.asList(data.split(DELIMITER))); + return deserializeHelper(nodesLeftToMaterialize); + } + + public TreeNode deserializeHelper(Queue nodesLeftToMaterialize) { + + String valueForNode = nodesLeftToMaterialize.poll(); + + if (valueForNode.equals(NULL_SYMBOL)) { + return null; + } + + TreeNode newNode = new TreeNode(Integer.valueOf(valueForNode)); + newNode.left = deserializeHelper(nodesLeftToMaterialize); + newNode.right = deserializeHelper(nodesLeftToMaterialize); + + return newNode; + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.right.left = new TreeNode(4); + root.right.right = new TreeNode(5); + SerializeAndDeserialize sede = new SerializeAndDeserialize(); + String serialize = sede.serialize(root); + System.out.println(serialize); + TreeNode deserialze = sede.deserialize(serialize); + sede.printTree(deserialze); + } + + public void printTree(TreeNode node) { + if (node == null) { + System.out.print("X,"); + return; + } + System.out.print(node.val + ","); + printTree(node.left); + printTree(node.right); + } } diff --git a/src/geeksforgeeks/SerializeDeserializeBST.java b/src/geeksforgeeks/SerializeDeserializeBST.java new file mode 100644 index 0000000..6ca6222 --- /dev/null +++ b/src/geeksforgeeks/SerializeDeserializeBST.java @@ -0,0 +1,61 @@ +package geeksforgeeks; + +// Hi all, I think my solution is pretty straightforward and easy to understand, not that efficient though. And the serialized tree is compact. +// Pre order traversal of BST will output root node first, then left children, then right. + +// root left1 left2 leftX right1 rightX +// If we look at the value of the pre-order traversal we get this: + +// rootValue (rootValue) (>rootValue) +// Because of BST's property: before the |separate line| all the node values are less than root value, all the node values after |separate line| are greater than root value. We will utilize this to build left and right tree. + +class SerializeDeserializeBST{ + private static final String SEP = ","; + private static final String NULL = "null"; + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + StringBuilder sb = new StringBuilder(); + if (root == null) return NULL; + //traverse it recursively if you want to, I am doing it iteratively here + Stack st = new Stack<>(); + st.push(root); + while (!st.empty()) { + root = st.pop(); + sb.append(root.val).append(SEP); + if (root.right != null) st.push(root.right); + if (root.left != null) st.push(root.left); + } + return sb.toString(); + } + + // Decodes your encoded data to tree. + // pre-order traversal + public TreeNode deserialize(String data) { + if (data.equals(NULL)) return null; + String[] strs = data.split(SEP); + Queue q = new LinkedList<>(); + for (String e : strs) { + q.offer(Integer.parseInt(e)); + } + return getNode(q); + } + + // some notes: + // 5 + // 3 6 + // 2 7 + private TreeNode getNode(Queue q) { //q: 5,3,2,6,7 + if (q.isEmpty()) return null; + TreeNode root = new TreeNode(q.poll());//root (5) + Queue samllerQueue = new LinkedList<>(); + while (!q.isEmpty() && q.peek() < root.val) { + samllerQueue.offer(q.poll()); + } + //smallerQueue : 3,2 storing elements smaller than 5 (root) + root.left = getNode(samllerQueue); + //q: 6,7 storing elements bigger than 5 (root) + root.right = getNode(q); + return root; + } + +} \ No newline at end of file diff --git a/src/geeksforgeeks/SetBitCount.java b/src/geeksforgeeks/SetBitCount.java new file mode 100644 index 0000000..47777b4 --- /dev/null +++ b/src/geeksforgeeks/SetBitCount.java @@ -0,0 +1,21 @@ +package geeksforgeeks; + +/** + * https://leetcode.com/problems/number-of-1-bits/discuss/55099/Simple-Java-Solution-Bit-Shifting + */ +public class SetBitCount { + public int hammingWeight(int n) { + int count = 0; + + while (n != 0) { + n = n & (n - 1); + count++; + } + + return count; + } + + public static void main(String[] args) { + int input = 00000000000000000000000000001011; + } +} diff --git a/src/geeksforgeeks/ShipPackageWithNDays.java b/src/geeksforgeeks/ShipPackageWithNDays.java new file mode 100644 index 0000000..aabb35d --- /dev/null +++ b/src/geeksforgeeks/ShipPackageWithNDays.java @@ -0,0 +1,36 @@ +package geeksforgeeks; + +public class ShipPackageWithNDays{ + public int shipWithinDays(int[] weights, int D) { + if(weights.length==0 || D==0) return 0; + + int lowerBound= Arrays.stream(weights).max().orElse(0); + int upperBound= Arrays.stream(weights).sum(); + int mid=0; + while(lowerBoundmid){ + currentDay+=1; + sum=0; + + } + sum+=weight; + } + + return currentDay>D; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ShuffleArray.java b/src/geeksforgeeks/ShuffleArray.java new file mode 100644 index 0000000..def7ad7 --- /dev/null +++ b/src/geeksforgeeks/ShuffleArray.java @@ -0,0 +1,53 @@ +package geeksforgeeks; + +import java.util.Arrays; +import java.util.Random; + +/** + * https://leetcode.com/problems/shuffle-an-array/ + */ +public class ShuffleArray { + + private int[] nums; + private Random random; + + public ShuffleArray(int[] nums) { + this.nums = nums; + random = new Random(); + } + + /** + * Resets the array to its original configuration and return it. + */ + public int[] reset() { + return nums; + } + + /** + * Returns a random shuffling of the array. + */ + public int[] shuffle() { + if (nums == null) { + return null; + } + int[] a = nums.clone(); + for (int j = 1; j < a.length; j++) { + int i = random.nextInt(j + 1); + swap(a, i, j); + } + return a; + } + + private void swap(int[] a, int i, int j) { + int t = a[i]; + a[i] = a[j]; + a[j] = t; + } + + public static void main(String[] args) { + int[] arr = { 1, 2, 3 }; + ShuffleArray sa = new ShuffleArray(arr); + System.out.println("After shuffling :" + Arrays.toString(sa.shuffle())); + System.out.println("Reset : " + Arrays.toString(sa.reset())); + } +} diff --git a/src/geeksforgeeks/SimilarExperssions.java b/src/geeksforgeeks/SimilarExperssions.java deleted file mode 100644 index 37456b9..0000000 --- a/src/geeksforgeeks/SimilarExperssions.java +++ /dev/null @@ -1,56 +0,0 @@ -package geeksforgeeks; - -/** - * https://www.geeksforgeeks.org/check-two-expressions-brackets/ - * - */ -//unresolved -public class SimilarExperssions { - - public static void main(String[] args) { - - System.out.println('+' * '-'); - - String query = "-(a+b+c)"; - String response = "-a-b-c"; - - checkExpression(query.toCharArray(), response.toCharArray()); - } - - private static void checkExpression(char[] query, char[] response) { - - char symbol = 0; - int startIndex = 0; - int endIndex = 0; - for (int i = 0; i < query.length; i++) { - if (query[i] == '(') { - symbol = query[i - 1]; - startIndex = i + 1; - } else if (query[i] == ')') { - endIndex = i - 1; - solve(symbol, startIndex, endIndex, query); - - } - } - } - - private static void solve(char symbol, int startIndex, int endIndex, char[] query) { - - for (int i = startIndex; i <= endIndex; i++) { - char temp = 0; - if (query[startIndex] == '-') { - temp = '-' * '+'; - query[i] = temp; - } else if (symbol == '+') { - temp = '-'; - query[i] = temp; - } else if (Character.isLetter(query[startIndex])) { - if (startIndex == i) { - query[startIndex - 1] = temp; - } - System.out.print(query[startIndex]); - } - System.out.print(temp); - } - } -} \ No newline at end of file diff --git a/src/geeksforgeeks/SimilarExpressions.java b/src/geeksforgeeks/SimilarExpressions.java new file mode 100644 index 0000000..5adab24 --- /dev/null +++ b/src/geeksforgeeks/SimilarExpressions.java @@ -0,0 +1,55 @@ +package geeksforgeeks; + +/** + * https://www.geeksforgeeks.org/check-two-expressions-brackets/ + */ +//unresolved +public class SimilarExpressions { + + public static void main(String[] args) { + + System.out.println('+' * '-'); + + String query = "-(a+b+c)"; + String response = "-a-b-c"; + + checkExpression(query.toCharArray(), response.toCharArray()); + } + + private static void checkExpression(char[] query, char[] response) { + + char symbol = 0; + int startIndex = 0; + int endIndex = 0; + for (int i = 0; i < query.length; i++) { + if (query[i] == '(') { + symbol = query[i - 1]; + startIndex = i + 1; + } else if (query[i] == ')') { + endIndex = i - 1; + solve(symbol, startIndex, endIndex, query); + + } + } + } + + private static void solve(char symbol, int startIndex, int endIndex, char[] query) { + + for (int i = startIndex; i <= endIndex; i++) { + char temp = 0; + if (query[startIndex] == '-') { + temp = '-' * '+'; + query[i] = temp; + } else if (symbol == '+') { + temp = '-'; + query[i] = temp; + } else if (Character.isLetter(query[startIndex])) { + if (startIndex == i) { + query[startIndex - 1] = temp; + } + System.out.print(query[startIndex]); + } + System.out.print(temp); + } + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SingleElementInSortedArray.java b/src/geeksforgeeks/SingleElementInSortedArray.java new file mode 100644 index 0000000..0b2d43a --- /dev/null +++ b/src/geeksforgeeks/SingleElementInSortedArray.java @@ -0,0 +1,44 @@ +package geeksforgeeks; + +/** + * You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. + * Find this single element that appears only once. + */ +public class SingleElementInSortedArray { + public int singleNonDuplicate(int[] nums) { + if(nums==null || nums.length==0) return 0; + + int left=0; + int right= nums.length-1; + // for 1,1,2,3,3,4,4,8,8 + // when mid is at 4 and right-mid is even, means the rest elements are only pairs, so we check + // left side by right=mid-2 + // when mid is at 3 and right-mid is odd means the 3's duplicate is present in right and rest + //are all pairs only so we check left side by right=mid-1 + // when mid is 4 => nums[mid]==nums[mid-1] + // when mid is 3 => nums[mid]==nums[mid+1] + while(left deque = new LinkedList<>(); + public static int[] maxSlidingWindow(int[] nums, int k) { + if (nums.length == 0) { + return new int[0]; + } + if (nums.length == 1) { + return nums; + } + + List list = new ArrayList<>(); + Deque deque = new ArrayDeque<>(); int i = 0; - for (; i < k; i++) { - while (!deque.isEmpty() && arr[i] >= arr[deque.peekLast()]) + + while (i < k) { + + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { deque.removeLast(); + } deque.addLast(i); + i++; } - for (; i < length; i++) { - System.out.println(arr[deque.peekFirst()]); - while (!deque.isEmpty() && deque.peekFirst() <= i - k) + for (; i < nums.length; i++) { + + list.add(nums[deque.peekFirst()]); + + if (!deque.isEmpty() && deque.peekFirst() <= i - k) { deque.removeFirst(); + } - while (!deque.isEmpty() && arr[i] >= arr[deque.peekLast()]) + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) deque.removeLast(); deque.addLast(i); } - System.out.println(arr[deque.peekFirst()]); + list.add(nums[deque.peekFirst()]); + + return list.stream().mapToInt(Integer::new).toArray(); } + void maxSlidingVicky(int[] nums, int k) { + List result = new ArrayList<>(); + Deque queue = new ArrayDeque<>(); + for (int i = 0; i < nums.length; i++) { + while (!queue.isEmpty() && queue.peek() < i - k + 1) { + queue.poll(); + } + while (!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) { + queue.pollLast(); + } + + queue.offer(i); + + if (i >= k - 1) { + result.add(nums[queue.peekFirst()]); + } + } + } } \ No newline at end of file diff --git a/src/geeksforgeeks/SnakeAndLadder.java b/src/geeksforgeeks/SnakeAndLadder.java index cc10da3..f5777b5 100644 --- a/src/geeksforgeeks/SnakeAndLadder.java +++ b/src/geeksforgeeks/SnakeAndLadder.java @@ -1,72 +1,70 @@ package geeksforgeeks; import java.util.Queue; -import java.util.LinkedList; +import java.util.*; /** * https://leetcode.com/problems/snakes-and-ladders/ */ public class SnakeAndLadder { + class BoardCells { + int pos; + int steps; - static class QEntry { - int vertex; - int noOfMoves; + public BoardCells(int pos, int steps) { + this.pos = pos; + this.steps = steps; + } } - static int getMinDiceThrows(int board[], int n) { - Queue queue = new LinkedList<>(); - QEntry qEntry = new QEntry(); - qEntry.vertex = 0; - qEntry.noOfMoves = 0; - - board[0] = -21; - queue.add(qEntry); + private int n; + public int snakesAndLadders(int[][] board) { + n = board.length; + boolean[] visited = new boolean[n * n + 1]; + Queue queue = new LinkedList<>(); + queue.offer(new BoardCells(1, 1)); + visited[1] = true; + while (!queue.isEmpty()) { - qEntry = queue.remove(); - int v = qEntry.vertex; - - System.out.println(v); - - if (v == n - 1) - break; - - for (int j = v + 1; j <= (v + 6) && j < n; j++) { - if (board[j] != -21) { - QEntry entry = new QEntry(); - entry.noOfMoves = (qEntry.noOfMoves + 1); - - if (board[j] != -1) - entry.vertex = board[j]; - else - entry.vertex = j; - queue.add(entry); - board[j] = -21; + BoardCells cur = queue.poll(); + for (int i = 1; i <= 6; i++) { + int next = cur.pos + i; + int[] pos = numToPos(next); + if (board[pos[0]][pos[1]] > 0) { + next = board[pos[0]][pos[1]]; + } + if (next == n * n) { + return cur.steps; + } + if (!visited[next]) { + queue.offer(new BoardCells(next, cur.steps + 1)); + visited[next] = true; } } + } return qEntry.noOfMoves; } - public static void main(String[] args) { + private int[] numToPos(int target) { + int row = (target - 1) / n, col = (target - 1) % n; + int x = n - 1 - row, y = row % 2 == 0 ? col : n - 1 - col; + return new int[] { x, y }; + } - int N = 30; - int moves[] = new int[N]; - for (int i = 0; i < N; i++) - moves[i] = -1; + private int posToNum(int[] position) { + int row = (n - 1 - position[0]); + int y = row % 2 == 0 ? position[1] + 1 : n - position[1]; + return row * n + y; + } - // Ladders - moves[2] = 21; - moves[4] = 7; - moves[10] = 25; - moves[19] = 28; + public static void main(String[] args) { - // Snakes - moves[3] = 1; - moves[23] = 8; - moves[16] = 3; - moves[18] = 6; + int[][] board = { { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1, -1 }, + { -1, 35, -1, -1, 13, -1 }, { -1, -1, -1, -1, -1, -1 }, { -1, 15, -1, -1, -1, -1 } }; - System.out.println("Min Dice throws required is " + getMinDiceThrows(moves, N)); + System.out.println("Min Dice throws required is " + new SnakeAndLadder().snakesAndLadders(board)); + } } \ No newline at end of file diff --git a/src/geeksforgeeks/SortStack.java b/src/geeksforgeeks/SortStack.java new file mode 100644 index 0000000..2534453 --- /dev/null +++ b/src/geeksforgeeks/SortStack.java @@ -0,0 +1,29 @@ +package geeksforgeeks; + +class SortStack { + // Input : [34, 3, 31, 98, 92, 23] + // Output : [3, 23, 31, 34, 92, 98] + public static Stack sortStack(Stack input) { + /* If input is null, no processing needed */ + if (input == null) { + return null; + } + /* Create a temp stack */ + Stack tempStack = new Stack<>(); + /* Keep going until input is not empty */ + while (!input.isEmpty()) { + /* Pop value from input */ + int tempValue = input.pop(); + /* + * We want smallest one at the bottom. So keep comparing and if temp stack has + * bigger item, pop it and push it to input stack + */ + while (!tempStack.isEmpty() && tempStack.peek() > tempValue) { + input.push(tempStack.pop()); + } + /* Push temp value to the temp stack */ + tempStack.push(tempValue); + } + return tempStack; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SortedSquares.java b/src/geeksforgeeks/SortedSquares.java new file mode 100644 index 0000000..7af17cc --- /dev/null +++ b/src/geeksforgeeks/SortedSquares.java @@ -0,0 +1,28 @@ +package geeksforgeeks; + +public class SortedSquares { + // Input: [-7,-3,2,3,11] + // Output: [4,9,9,49,121] + public int[] sortedSquares(int[] A) { + if(A==null || A.length==0) return new int[0]; + + int[]result= new int[A.length]; + + int index= A.length-1; + int left=0; + int right=index; + + while(left<=right){ + if(Math.abs(A[left]) spiralOrder(int[][] matrix) { + + List res = new ArrayList(); + + if (matrix.length == 0) { + return res; + } + + int rowBegin = 0; + int rowEnd = matrix.length-1; + int colBegin = 0; + int colEnd = matrix[0].length - 1; + + while (rowBegin <= rowEnd && colBegin <= colEnd) { + // Traverse Right + for (int j = colBegin; j <= colEnd; j ++) { + res.add(matrix[rowBegin][j]); } - rowStart++; - - // Print the last column from the remaining colEnd - for (int i = rowStart; i < colEnd; ++i) { - System.out.print(a[i][rowEnd - 1] + " "); + rowBegin++; + + // Traverse Down + for (int j = rowBegin; j <= rowEnd; j ++) { + res.add(matrix[j][colEnd]); } - rowEnd--; - - // Print the last row from the remaining rowEnd */ - if (rowStart < colEnd) { - for (int i = rowEnd - 1; i >= colStart; --i) { - System.out.print(a[colEnd - 1][i] + " "); + colEnd--; + + if (rowBegin <= rowEnd) { + // Traverse Left + for (int j = colEnd; j >= colBegin; j --) { + res.add(matrix[rowEnd][j]); } - colEnd--; } - - // Print the first column from the remaining colEnd */ - if (colStart < rowEnd) { - for (int i = colEnd - 1; i >= rowStart; --i) { - System.out.print(a[i][colStart] + " "); + rowEnd--; + + if (colBegin <= colEnd) { + // Traver Up + for (int j = rowEnd; j >= rowBegin; j --) { + res.add(matrix[j][colBegin]); } - colStart++; } + colBegin ++; } + + return res; } public static void main(String[] args) { - int R = 4; - int C = 4; + int a[][] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; - spiralPrint(R, C, a); + spiralOrder(a); } } \ No newline at end of file diff --git a/src/geeksforgeeks/SplitLinkedList.java b/src/geeksforgeeks/SplitLinkedList.java index fb3e4d5..c09c0d4 100644 --- a/src/geeksforgeeks/SplitLinkedList.java +++ b/src/geeksforgeeks/SplitLinkedList.java @@ -2,67 +2,33 @@ //https://leetcode.com/problems/split-linked-list-in-parts/ class SplitLinkedList { - public ListNode[] splitListToParts(ListNode root, int k) { - if (root == null) return null; - if (k == 0) return null; - - if (k == 1) { - ListNode[] node = new ListNode[1]; - node[0] = root; - return node; - } - - ListNode[] node = new ListNode[k]; - int length = getRootLength(root); - - if (k > length) { - ListNode temp = root; - int index = 0; - - while (temp != null) { - ListNode result = temp; - temp = temp.next; - result.next = null; - node[index] = result; - index++; - } - - for (; index < k; index++) { - node[index] = null; - } - return node; - } - - int remainder = length % k; - int quo = length / k; - - for (int i = 0; i < k; i++) { - int value = remainder > 0 ? quo + 1 : quo; - remainder--; - ListNode head = root; - ListNode prev = null; - for (int j = 0; j < value && root != null; j++) { - if (j == value - 1) { - prev = root; - prev.next = null; - } - root = root.next; + public ListNode[] splitListToParts(ListNode root, int k) { + ListNode[] partsOfRoot = new ListNode[k]; + ListNode head = root; + int len = size(root); + int minNoOfElements = len / k; + int extraRoomForElement = len % k; + ListNode prev = null; + for (int i = 0; i < k && head != null; i++, extraRoomForElement--) { + partsOfRoot[i] = head; + for (int j = 0; j < minNoOfElements + (extraRoomForElement > 0 ? 1 : 0); j++) { + prev = head; + head = head.next; } - node[i] = head; + prev.next = null; } + return partsOfRoot; - return node; } - public int getRootLength(ListNode root) { - ListNode temp = root; - int count = 0; - while (temp != null) { - count++; - temp = temp.next; + public int size(ListNode root) { + int len = 0; + while (root != null) { + root = root.next; + len++; } - return count; + return len; } public static void main(String[] args) { diff --git a/src/geeksforgeeks/StockBuySellManyTimes.java b/src/geeksforgeeks/StockBuySellManyTimes.java index c4a4587..990a5ce 100644 --- a/src/geeksforgeeks/StockBuySellManyTimes.java +++ b/src/geeksforgeeks/StockBuySellManyTimes.java @@ -5,6 +5,8 @@ class Interval { int buy, sell; + int start; // for meeting problem + int end; } /** @@ -16,8 +18,9 @@ class StockBuySellManyTimes { //200, 180, 260, 310, 40, 535, 695 void stockBuySell(int price[], int n) { // Prices must be given for at least two days - if (n == 1) + if (n == 1) { return; + } int count = 0; @@ -31,8 +34,9 @@ void stockBuySell(int price[], int n) { i++; // If we reached the end, break as no further solution possible - if (i == n - 1) + if (i == n - 1) { break; + } Interval e = new Interval(); e.buy = i++; @@ -51,11 +55,13 @@ void stockBuySell(int price[], int n) { count++; } - if (count == 0) + if (count == 0) { System.out.println("There is no day when buying the stock " + "will make profit"); - else + } else { for (int j = 0; j < count; j++) - System.out.println("Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); + System.out.println( + "Buy on day: " + result.get(j).buy + " " + "Sell on day : " + result.get(j).sell); + } return; } @@ -63,7 +69,7 @@ void stockBuySell(int price[], int n) { public static void main(String args[]) { StockBuySellManyTimes stock = new StockBuySellManyTimes(); - int price[] = {200, 180, 260, 310, 40, 535, 695}; + int price[] = { 200, 180, 260, 310, 40, 535, 695 }; int n = price.length; stock.stockBuySell(price, n); diff --git a/src/geeksforgeeks/StockSpanner.java b/src/geeksforgeeks/StockSpanner.java new file mode 100644 index 0000000..fa9b77a --- /dev/null +++ b/src/geeksforgeeks/StockSpanner.java @@ -0,0 +1,20 @@ +package geeksforgeeks; + +class StockSpanner { + + Deque> stack; + public StockSpanner() { + this.stack= new ArrayDeque<>(); + } + + public int next(int price) { + int value=1; + while(!stack.isEmpty() && stack.peek().getKey()<=price){ + value+=stack.pop().getValue(); + } + + stack.push(new Pair(price,value)); + + return stack.peek().getValue(); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/StringIterator.java b/src/geeksforgeeks/StringIterator.java new file mode 100644 index 0000000..4afd362 --- /dev/null +++ b/src/geeksforgeeks/StringIterator.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +//StringIterator iterator = new StringIterator("L1e2t1C1o1d1e1"); +// iterator.next(); // return 'L' +// iterator.next(); // return 'e' +// iterator.next(); // return 'e' +// iterator.next(); // return 't' +// iterator.next(); // return 'C' +// iterator.next(); // return 'o' +// iterator.next(); // return 'd' +// iterator.hasNext(); // return true +// iterator.next(); // return 'e' +// iterator.hasNext(); // return false +// iterator.next(); // return ' ' +public class StringIterator { + String res; + int ptr = 0, num = 0; + char ch = ' '; + public StringIterator(String s) { + res = s; + } + public char next() { + if (!hasNext()) + return ' '; + if (num == 0) { + ch = res.charAt(ptr++); + while (ptr < res.length() && Character.isDigit(res.charAt(ptr))) { + num = num * 10 + res.charAt(ptr++) - '0'; + } + } + num--; + return ch; + } + public boolean hasNext() { + return ptr != res.length() || num != 0; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SubArraySumDivisibleByK.java b/src/geeksforgeeks/SubArraySumDivisibleByK.java new file mode 100644 index 0000000..dbd73b8 --- /dev/null +++ b/src/geeksforgeeks/SubArraySumDivisibleByK.java @@ -0,0 +1,42 @@ +package geeksforgeeks; + +/** + * Given an array A of integers, return the number of (contiguous, non-empty) subarrays that have a sum divisible by K. + * Input: A = [4,5,0,-2,-3,1], K = 5 + Output: 7 +Explanation: There are 7 subarrays with a sum divisible by K = 5: +[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3] + */ +public class SubArraySumDivisibleByK{ + + public int subarraysDivByK(int[] A, int K) { + Map count = new HashMap<>(); + count.put(0, 1); //if the first prefix sum is 0, it need to be counted as a mod of K, right? Rest of prefix sum from 1 to K-1 don't include the first prefix sum + int prefix = 0, res = 0; + for (int a : A) { + //(prefix+a%K+K)%K is just a trick to make the remainder positive. + prefix = (prefix + a % K + K) % K; + res += count.getOrDefault(prefix, 0); + count.put(prefix, count.getOrDefault(prefix, 0) + 1); + } + return res; + } + // A = [4,5,0,-2,-3,1], K = 5 + // step 1 : {0:1} a=4 sum=4 mod=4 count = 0+0 =0 + // step 2 : {0:1,4:1} a=5 sum=9 mod=4 count = 0+1 =1 + // step 3 : {0:1,4:2} a=0 sum=9 mod=4 count = 1+2 =3 + // step 4 : {0:1,4:3} a=-2 sum=7 mod=2 count = 3+0 =3 + // step 6 : {0:1,4:3,2:1} a=-3 sum=4 mod=4 count = 3+3 =6 + // step 7 : {0:1,4:4,2:1} a=1 sum=5 mod=0 count = 6+1 =7 + public int subarraysDivByKOptimised(int[] A, int K) { + int[] map = new int[K]; + map[0]=1; + int prefix = 0, res = 0; + for (int a : A) { + prefix = (prefix + a % K + K) % K; + res +=map[prefix]; + map[prefix]++; + } + return res; + } +} diff --git a/src/geeksforgeeks/SubArraySumEqualsK.java b/src/geeksforgeeks/SubArraySumEqualsK.java new file mode 100644 index 0000000..e8df984 --- /dev/null +++ b/src/geeksforgeeks/SubArraySumEqualsK.java @@ -0,0 +1,39 @@ +package geeksforgeeks; +public class SubArraySumEqualsK { + public int subarraySum(int[] nums, int k) { + int left=0; + int right=0; + int sum=0; + int result=0; + + Map map= new HashMap<>(); + map.put(0,1); + // Let’s assume (D+E+3=k) + // sum =A+B+C+D+E+3 + // preSum = A+B+C + // Thus, we can compose critical equation + // sum - preSum = k + // Since we’re looking for specific preSum to compose value k + // What specific preSum were looking? + // Some math operation results in + // sum - k = preSum + // For multiple matching counts + // Ex: + // input [0,-1,1,2,3] k=5 + // We notice that it’s necessary to record occurrence of specific preSum. + // In this case, we need to know preSum 2 occur three times. [0,-1,1,2], [-1,1,2], [2] + // This indicate that it's necessary to record preSum counts + + while(left queue = new ArrayDeque<>(); + int[][] dirs = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } }; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == 'O') { + if (i == board.length - 1 || j == board[0].length - 1 || i == 0 || j == 0) { + board[i][j] = '1'; + queue.offer(new Pair(i, j, 0)); + } + } + } + } + + while (!queue.isEmpty()) { + Pair temp = queue.poll(); + + for (int[] dir : dirs) { + int newx = temp.x + dir[0]; + int newy = temp.y + dir[1]; + + if (isValid(newx, newy, board) && board[newx][newy] == 'O') { + board[newx][newy] = '1'; + queue.offer(new Pair(newx, newy, 0)); + } + } + + } + + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == '1') { + board[i][j] = 'O'; + } else if (board[i][j] == 'O') { + board[i][j] = 'X'; + } + } + } + + } + + public boolean isValid(int x, int y, char[][] board) { + if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) + return false; + return true; + } + + public void solveDFS(char[][] board) { + if (board.length == 0 || board[0].length == 0) + return; + if (board.length < 2 || board[0].length < 2) + return; + int m = board.length, n = board[0].length; + // Any 'O' connected to a boundary can't be turned to 'X', so ... + // Start from first and last column, turn 'O' to '*'. + for (int i = 0; i < m; i++) { + if (board[i][0] == 'O') + boundaryDFS(board, i, 0); + if (board[i][n - 1] == 'O') + boundaryDFS(board, i, n - 1); + } + // Start from first and last row, turn '0' to '*' + for (int j = 0; j < n; j++) { + if (board[0][j] == 'O') + boundaryDFS(board, 0, j); + if (board[m - 1][j] == 'O') + boundaryDFS(board, m - 1, j); + } + // post-prcessing, turn 'O' to 'X', '*' back to 'O', keep 'X' intact. + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (board[i][j] == 'O') + board[i][j] = 'X'; + else if (board[i][j] == '*') + board[i][j] = 'O'; + } + } + } + + // Use DFS algo to turn internal however boundary-connected 'O' to '*'; + //Use DFS algo to turn internal however boundary-connected 'O' to '*'; +private void boundaryDFS(char[][] board, int i, int j) { + if (i < 0 || i > board.length - 1 || j <0 || j > board[0].length - 1 ) + return; + if (board[i][j] == 'O'){ + board[i][j] = '*'; + + boundaryDFS(board, i-1, j); + + boundaryDFS(board, i+1, j); + + boundaryDFS(board, i, j-1); + + boundaryDFS(board, i, j+1); + } +} +} + +class Pair { + int x; + int y; + int level; + + public Pair(int x, int y, int level) { + this.x = x; + this.y = y; + this.level = level; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/SwapRecoverBST.java b/src/geeksforgeeks/SwapRecoverBST.java index 4de4707..7a34899 100644 --- a/src/geeksforgeeks/SwapRecoverBST.java +++ b/src/geeksforgeeks/SwapRecoverBST.java @@ -24,7 +24,17 @@ private void traverse(TreeNode root) { return; traverse(root.left); - + // Let's assume this is the original in-order traversal sequence of BST: 1 2 3 4 5 + // If 2 and 3 get swapped, it becomes 1 3 2 4 5 and + //there is only one time that you will have prev.val >= root.val + // If 2 and 4 get swapped, it becomes 1 4 3 2 5 and + //there are two times that you will have prev.val >= root.val + + // If during the first time when you find prev.val >= root.val, + //the previous node "prev" MUST be one of two nodes that get swapped. + //However, the current node MAY OR MAY NOT be another node that gets swapped, + //which will depend on whether later during in-order traversal, there is another prev.val >= root.val or not. + // If there is, then the current node "root" during the 2nd time of prev.val >= root.val will be the other node that gets swapped // Start of "do some business", // If first element has not been found, assign it to prevElement (refer to 6 in the example above) if (firstElement == null && prevElement.val >= root.val) { diff --git a/src/geeksforgeeks/SymmetricTree.java b/src/geeksforgeeks/SymmetricTree.java new file mode 100644 index 0000000..8ef690c --- /dev/null +++ b/src/geeksforgeeks/SymmetricTree.java @@ -0,0 +1,21 @@ +package geeksforgeeks; + +class SymmetricTree { + public boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + + return isSymmetricHelp(root.left, root.right); + } + + private boolean isSymmetricHelp(TreeNode left, TreeNode right) { + if (left == null || right == null) { + return left == right; + } + if (left.val != right.val) { + return false; + } + return isSymmetricHelp(left.left, right.right) && isSymmetricHelp(left.right, right.left); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TaskLeastInterval.java b/src/geeksforgeeks/TaskLeastInterval.java index 107fbad..93f50ae 100644 --- a/src/geeksforgeeks/TaskLeastInterval.java +++ b/src/geeksforgeeks/TaskLeastInterval.java @@ -3,7 +3,7 @@ import java.util.*; /*https://leetcode.com/problems/task-scheduler/*/ -// unresolved + public class TaskLeastInterval { public static int leastInterval(char[] tasks, int n) { @@ -17,8 +17,15 @@ public static int leastInterval(char[] tasks, int n) { queue.addAll(map.entrySet()); int count = 0; + //At each iteration, we process at most 'n' elements, + //and move forwards exactly n+1 in time (regardless of how many elements we processed: + // Read the topmost from the queue and increment the time. Add it to a temp list to be added later. + // Add the element back to the queue from the temp list if count is > 0. + // if al elements are done, we're done too. + // Move time forward by n + 1 + // Return time in the end. while (!queue.isEmpty()) { - int k = n + 1; + int k = n + 1; //each time fill k elements, if k is not full, that's the idle List tempList = new ArrayList<>(); while (k > 0 && !queue.isEmpty()) { Map.Entry top = queue.poll(); @@ -40,6 +47,6 @@ public static int leastInterval(char[] tasks, int n) { public static void main(String[] args) { char[] arr = "AAAAAABCDEFG".toCharArray(); - leastInterval(arr, 2); + System.out.println(leastInterval(arr, 2)); } } diff --git a/src/geeksforgeeks/ThreeSum.java b/src/geeksforgeeks/ThreeSum.java new file mode 100644 index 0000000..7f7b26b --- /dev/null +++ b/src/geeksforgeeks/ThreeSum.java @@ -0,0 +1,35 @@ +package geeksforgeeks; + +public class ThreeSum { + public List> threeSum(int[] nums) { + if(nums==null || nums.length==0) return Collections.emptyList(); + + Arrays.sort(nums); + List> result= new ArrayList<>(); + for(int i=0;isum){ + right--; + } + } + } + } + + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TimeMap.java b/src/geeksforgeeks/TimeMap.java new file mode 100644 index 0000000..6a6d3ab --- /dev/null +++ b/src/geeksforgeeks/TimeMap.java @@ -0,0 +1,43 @@ +package geeksforgeeks; + +class TimeMap { + + class Node{ + String val; + int time; + Node next; + public Node(String value, int timestamp){ + val=value; + time=timestamp; + } + } + /** Initialize your data structure here. */ + HashMapmap; + + public TimeMap() { + map=new HashMap<>(); + } + + public void set(String key, String value, int timestamp) { + if(map.containsKey(key)){ + Node node=new Node(value,timestamp); + node.next=map.get(key); + map.put(key,node); + }else{ + Node temp=new Node(value,timestamp); + map.put(key,temp); + } + } + + public String get(String key, int timestamp) { + String vl=""; + if(map.containsKey(key)){ + Node y=map.get(key); + while(y.time>timestamp&&y.next!=null) + y=y.next; + if(y.time<=timestamp) + vl=y.val; + } + return vl; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TopKFrequentElement.java b/src/geeksforgeeks/TopKFrequentElement.java new file mode 100644 index 0000000..e8882c4 --- /dev/null +++ b/src/geeksforgeeks/TopKFrequentElement.java @@ -0,0 +1,33 @@ +package geeksforgeeks; + +class TopKFrequentElement{ + public List topKFrequent(int[] nums, int k) { + List result = new ArrayList<>(); + + HashMap map = new HashMap<>(); //Key: val, Val: #of freq + for (int num : nums) { + if (map.containsKey(num)) { + map.put(num, map.get(num)+1); + }else { + map.put(num, 1); + } + } + + List[] bucks = new List[nums.length+1]; // index : freq; val: set of key + for (int key : map.keySet()) { + int freq = map.get(key); + if (bucks[freq] == null) { + bucks[freq] = new ArrayList<>(); + } + bucks[freq].add(key); + } + + for (int freq = nums.length; freq >=0 && k > 0; freq--) { + if (bucks[freq] != null) { + k -=bucks[freq].size(); + result.addAll(bucks[freq]); + } + } + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/TopKFrequentElements.java b/src/geeksforgeeks/TopKFrequentElements.java new file mode 100644 index 0000000..9084b2d --- /dev/null +++ b/src/geeksforgeeks/TopKFrequentElements.java @@ -0,0 +1,38 @@ +package geeksforgeeks; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * https://leetcode.com/problems/top-k-frequent-elements/discuss/445815/Java8-Lambda-solution-3-lines-code + */ +public class TopKFrequentElements { + + public List topKFrequent(int[] nums, int k) { + if (nums.length == 0) { + return Collections.emptyList(); + } + + PriorityQueue> pq = new PriorityQueue<>( + (obj1, obj2) -> obj2.getValue() - obj1.getValue()); + Map map = new HashMap<>(); + + for (int i : nums) { + map.put(i, map.getOrDefault(i, 0) + 1); + } + + for (Map.Entry mapEntry : map.entrySet()) { + pq.add(mapEntry); + } + + List result = new ArrayList<>(); + for (int i = 0; i < k; i++) { + result.add(pq.remove().getKey()); + } + return result; + } +} diff --git a/src/geeksforgeeks/TrailingZeroes.java b/src/geeksforgeeks/TrailingZeroes.java index d77577e..87a2490 100644 --- a/src/geeksforgeeks/TrailingZeroes.java +++ b/src/geeksforgeeks/TrailingZeroes.java @@ -3,7 +3,6 @@ /*https://www.geeksforgeeks.org/count-trailing-zeroes-factorial-number/*/ class TrailingZeroes { public int trailingZeroes(int n) { - int count = 0; while (n != 0) { int tmp = n / 5; diff --git a/src/geeksforgeeks/TreasureIsland.java b/src/geeksforgeeks/TreasureIsland.java index 1230d8f..0f7c179 100644 --- a/src/geeksforgeeks/TreasureIsland.java +++ b/src/geeksforgeeks/TreasureIsland.java @@ -5,26 +5,25 @@ // https://leetcode.com/discuss/interview-question/347457/Amazon-or-OA-2019-or-Treasure-Island public class TreasureIsland { - private static final int[][] DIRS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + private static final int[][] DIRS = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; public static int minSteps(char[][] grid) { Queue q = new LinkedList<>(); - q.add(new Point(0, 0)); - grid[0][0] = 'D'; // mark as visited - for (int steps = 1; !q.isEmpty(); steps++) { - for (int sz = q.size(); sz > 0; sz--) { - Point p = q.poll(); - - for (int[] dir : DIRS) { - int r = p.r + dir[0]; - int c = p.c + dir[1]; - - if (isSafe(grid, r, c)) { - if (grid[r][c] == 'X') - return steps; - grid[r][c] = 'D'; - q.add(new Point(r, c)); + q.add(new Point(0, 0, 0)); + grid[0][0] = 'D'; + while (!q.isEmpty()) { + Point p = q.poll(); + + for (int[] dir : DIRS) { + int r = p.r + dir[0]; + int c = p.c + dir[1]; + + if (isSafe(grid, r, c)) { + if (grid[r][c] == 'X') { + return p.steps + 1; } + grid[r][c] = 'D'; + q.add(new Point(r, c, p.steps + 1)); } } } @@ -36,11 +35,14 @@ private static boolean isSafe(char[][] grid, int r, int c) { } private static class Point { - int r, c; + int r; + int c; + int steps; - Point(int r, int c) { + Point(int r, int c, int steps) { this.r = r; this.c = c; + this.steps = steps; } public String toString() { @@ -49,10 +51,14 @@ public String toString() { } public static void main(String[] args) { - char[][] grid = {{'O', 'O', 'O', 'O'}, + + char[][] grid = + {{'O', 'O', 'O', 'O'}, {'D', 'O', 'D', 'O'}, {'O', 'O', 'O', 'O'}, {'X', 'D', 'D', 'O'}}; + + System.out.println(minSteps(grid)); } } \ No newline at end of file diff --git a/src/geeksforgeeks/TreasureIslandII.java b/src/geeksforgeeks/TreasureIslandII.java index 3d4237f..0525e5a 100644 --- a/src/geeksforgeeks/TreasureIslandII.java +++ b/src/geeksforgeeks/TreasureIslandII.java @@ -4,7 +4,7 @@ import java.util.Queue; /*https://leetcode.com/discuss/interview-question/356150/amazon-oa-2019-shortest-path-from-multiple-sources*/ -// unresolved + public class TreasureIslandII { private static final int[][] DIRS = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; @@ -61,8 +61,12 @@ public String toString() { } public static void main(String[] args) { - char[][] grid = {{'S', 'O', 'O', 'S', 'S'}, {'D', 'O', 'D', 'O', 'D'}, {'O', 'O', 'O', 'O', 'X'}, - {'X', 'D', 'D', 'O', 'O'}, {'X', 'D', 'D', 'D', 'O'}}; + char[][] grid = { + {'S', 'O', 'O', 'S', 'S'}, + {'D', 'O', 'D', 'O', 'D'}, + {'O', 'O', 'O', 'O', 'X'}, + {'X', 'D', 'D', 'O', 'O'}, + {'X', 'D', 'D', 'D', 'O'}}; test(minDist(grid), 3); } diff --git a/src/geeksforgeeks/Trie.java b/src/geeksforgeeks/Trie.java new file mode 100644 index 0000000..3483d59 --- /dev/null +++ b/src/geeksforgeeks/Trie.java @@ -0,0 +1,65 @@ +package geeksforgeeks; + +class Trie { + + class TrieNode{ + char data; + TrieNode[] children; + boolean isWord; + TrieNode(char data){ + this.data=data; + this.children= new TrieNode[26]; + } + } + + + TrieNode root; + public Trie() { + this.root=new TrieNode(' '); + } + + + public void insert(String word) { + TrieNode head=root; + + for(int i=0;i userMap; + private Map userMap; // Tweet link to next Tweet so that we can save a lot of time // when we execute getNewsFeed(userId) @@ -30,7 +30,7 @@ public class User { public User(int id) { this.id = id; followed = new HashSet<>(); - follow(id); // first follow itself + follow(id); // first follow yourself tweet_head = null; } @@ -42,7 +42,6 @@ public void unfollow(int id) { followed.remove(id); } - // everytime user post a new tweet, add it to the head of tweet list. public void post(int id) { Tweet t = new Tweet(id); @@ -51,7 +50,6 @@ public void post(int id) { } } - /** * Initialize your data structure here. */ @@ -71,7 +69,6 @@ public void postTweet(int userId, int tweetId) { } - // Best part of this. // first get all tweets lists from one user including itself and all people it followed. // Second add all heads into a max heap. Every time we poll a tweet with @@ -79,15 +76,17 @@ public void postTweet(int userId, int tweetId) { // So after adding all heads we only need to add 9 tweets at most into this // heap before we get the 10 most recent tweet. public List getNewsFeed(int userId) { - List res = new LinkedList<>(); + List result = new LinkedList<>(); - if (!userMap.containsKey(userId)) return res; + if (!userMap.containsKey(userId)) { + return result; + } Set users = userMap.get(userId).followed; - PriorityQueue q = new PriorityQueue(users.size(), (a, b) -> (b.time - a.time)); + PriorityQueue q = new PriorityQueue<>(users.size(), (a, b) -> (b.time - a.time)); for (int user : users) { Tweet t = userMap.get(user).tweet_head; - // very imporant! If we add null to the head we are screwed. + // very important! If we add null to the head we are screwed. if (t != null) { q.add(t); } @@ -95,13 +94,14 @@ public List getNewsFeed(int userId) { int n = 0; while (!q.isEmpty() && n < 10) { Tweet t = q.poll(); - res.add(t.id); + result.add(t.id); n++; - if (t.next != null) + if (t.next != null) { q.add(t.next); + } } - return res; + return result; } @@ -124,8 +124,9 @@ public void follow(int followerId, int followeeId) { * Follower unfollows a followee. If the operation is invalid, it should be a no-op. */ public void unfollow(int followerId, int followeeId) { - if (!userMap.containsKey(followerId) || followerId == followeeId) + if (!userMap.containsKey(followerId) || followerId == followeeId) { return; + } userMap.get(followerId).unfollow(followeeId); } diff --git a/src/geeksforgeeks/TwoCityScheduling.java b/src/geeksforgeeks/TwoCityScheduling.java new file mode 100644 index 0000000..12a088a --- /dev/null +++ b/src/geeksforgeeks/TwoCityScheduling.java @@ -0,0 +1,47 @@ +package geeksforgeeks; + +/** + * There are 2N people a company is planning to interview. + * The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. + * Return the minimum cost to fly every person to a city such that exactly N people arrive in each city. + * Input: [[10,20],[30,200],[400,50],[30,20]] + * Output: 110 + * Explanation: + The first person goes to city A for a cost of 10. + The second person goes to city A for a cost of 30. + The third person goes to city B for a cost of 50. + The fourth person goes to city B for a cost of 20. + + * The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city + * + */ +public class TwoCityScheduling { + public int twoCitySchedCost(int[][] costs) { + // for input [[10,20],[30,200],[400,50],[30,20]] + // let's send all to A, the cost'd be => 10+30+400+30= 470 + // we need to remove one half to save some money + // what we can do is take the difference in each input + // (10-20) (30-200) (400-50) (30-20) + // [-10, -170, 350, 10] + // what the above array indicates is that for i'th candidate=>[10,20] we will save 10 in sending to A + // when i=2 we will have to spend 350 more to bring to A city so we sort by arr[0]-arr[1] + // greedily we take negative val candidates to A and rest to B for this input + PriorityQueue queue= new PriorityQueue<>((a,b)->(a[0] - a[1]) - (b[0] - b[1])); + + for(int[] cost: costs){ + queue.offer(cost); + } + int result=0; + int k=0; + while(k 0 ? result : -1); + } + + public static void main(String[] args) { + int[] nums = { 1, 2, 3, 2, 1, 4, 3 }; + xorApproach(nums); + } +} diff --git a/src/geeksforgeeks/UniquePath.java b/src/geeksforgeeks/UniquePath.java index c022223..88c2386 100644 --- a/src/geeksforgeeks/UniquePath.java +++ b/src/geeksforgeeks/UniquePath.java @@ -7,9 +7,7 @@ public class UniquePath { public static void main(String[] args) { System.out.println(uniquePathI(3, 2)); - int[][] matrix = {{0, 0, 0}, - {0, 1, 0}, - {0, 0, 0}}; + int[][] matrix = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; System.out.println(uniquePathII(matrix)); @@ -34,31 +32,58 @@ private static int uniquePathI(int row, int col) { return dp[row - 1][col - 1]; } - + /** + * Now consider if some obstacles are added to the grids. How many unique paths would there be? + * Input: + * [ + * [0,0,0], + * [0,1,0], + * [0,0,0] + * ] + * Output: 2 + * Explanation: + * There is one obstacle in the middle of the 3x3 grid above. + * There are two ways to reach the bottom-right corner: + * 1. Right -> Right -> Down -> Down + * 2. Down -> Down -> Right -> Right + */ private static int uniquePathII(int[][] mat) { - int[][] dp = new int[mat.length][mat[0].length]; - for (int i = 0; i < mat[0].length; i++) { - if (mat[0][i] != 1) { - dp[0][i] = 1; + + if (obstacleGrid[0][0] == 1) + return 0; + int m = obstacleGrid.length; + int n = obstacleGrid[0].length; + + int[][] dp = new int[obstacleGrid.length][obstacleGrid[0].length]; + + for (int i = 0; i < m; i++) { + if (obstacleGrid[i][0] == 1) { + dp[i][0] = 0; + break; + } else { + dp[i][0] = 1; } } - for (int i = 0; i < mat.length; i++) { - if (mat[i][0] != 1) { - dp[i][0] = 1; + for (int j = 0; j < n; j++) { + if (obstacleGrid[0][j] == 1) { + dp[0][j] = 0; + break; + } else { + dp[0][j] = 1; } } - for (int i = 1; i < mat.length; i++) { - for (int j = 1; j < mat[0].length; j++) { - if (mat[i][j] == 1) { + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if (obstacleGrid[i][j] == 1) { dp[i][j] = 0; } else { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } - } } - return dp[mat.length - 1][mat[0].length - 1]; + return dp[m - 1][n - 1]; + } } diff --git a/src/geeksforgeeks/UniquePathMaximum.java b/src/geeksforgeeks/UniquePathMaximum.java index ab7b7aa..ceef295 100644 --- a/src/geeksforgeeks/UniquePathMaximum.java +++ b/src/geeksforgeeks/UniquePathMaximum.java @@ -4,10 +4,25 @@ https://leetcode.com/discuss/interview-question/383669/ */ +/** + * find the maximum score of a path starting at [0, 0] and ending at [r-1, c-1]. The score of a path is the minimum value in that path. + *

+ * Input: + * [[1, 2, 3] + * [4, 5, 1]] + *

+ * Output: 4 + * Explanation: + * Possible paths: + * 1-> 2 -> 3 -> 1 + * 1-> 2 -> 5 -> 1 + * 1-> 4 -> 5 -> 1 + * So min of all the paths = [2, 2, 4]. Note that we don't include the first and final entry. + */ public class UniquePathMaximum { public static void main(String[] args) { - int[][] matrix = {{6, 7, 8}, {5, 4, 2}, {8, 7, 6}}; + int[][] matrix = { { 6, 7, 8 }, { 5, 4, 2 }, { 8, 7, 6 } }; System.out.println(findMaximumOfUniquePath(matrix)); } @@ -22,11 +37,10 @@ private static int findMaximumOfUniquePath(int[][] matrix) { for (int i = 1; i < matrix.length; i++) { for (int j = 1; j < matrix[i].length; j++) { - matrix[i][j] = Math.max(Math.min(matrix[i - 1][j], matrix[i][j]), Math.min(matrix[i][j - 1], matrix[i][j])); + matrix[i][j] = Math.max(Math.min(matrix[i - 1][j], matrix[i][j]), + Math.min(matrix[i][j - 1], matrix[i][j])); } } return matrix[matrix.length - 1][matrix[0].length - 1]; } - - } \ No newline at end of file diff --git a/src/geeksforgeeks/UrlEncode.java b/src/geeksforgeeks/UrlEncode.java new file mode 100644 index 0000000..1c54391 --- /dev/null +++ b/src/geeksforgeeks/UrlEncode.java @@ -0,0 +1,43 @@ +package geeksforgeeks; + +/** + * Write a method to replace all the spaces in a string with ‘%20’. + * You may assume that the string has sufficient space at the end to hold the additional characters, + * and that you are given the “true” length of the string. + */ +public class UrlEncode { + public void replaceSpaces(char[] str, int trueLength) { + int i = str.length - 1; + int extra = str.length - trueLength; + int j = i - extra; + while (i != j) { + if (!Character.isSpaceChar(str[j])) { + str[i--] = str[j--]; + } else { + str[i--] = '0'; + str[i--] = '2'; + str[i--] = '%'; + j--; + } + } + } + + public static void main(String[] args) { + test(new char[17], "Mr John Smith"); + test(new char[12], "Mr John "); + test(new char[5], "Mr "); + test(new char[5], " Mr"); + test(new char[8], " Mr "); + test(new char[3], " "); + test(new char[20], "Mr John Smith"); + test(new char[0], ""); + } + + private static void test(char[] str, String s) { + IntStream.range(0, s.length()).forEach(i -> str[i] = s.charAt(i)); + System.out.print(new String(str) +" - "); + UrlEncode ob = new UrlEncode(); + ob.replaceSpaces(str, s.length()); + System.out.println(new String(str)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidPalindromeII.java b/src/geeksforgeeks/ValidPalindromeII.java index 6036c1a..84768c8 100644 --- a/src/geeksforgeeks/ValidPalindromeII.java +++ b/src/geeksforgeeks/ValidPalindromeII.java @@ -1,5 +1,8 @@ package geeksforgeeks; +/** + * https://leetcode.com/problems/valid-palindrome-ii/ + */ class ValidPalindromeII { public static boolean validPalindrome(String s) { @@ -9,9 +12,13 @@ public static boolean validPalindrome(String s) { j--; } - if (i >= j) return true; + if (i >= j) { + return true; + } - if (isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1)) return true; + if (isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1)) { + return true; + } return false; } @@ -20,7 +27,9 @@ private static boolean isPalindrome(String s, int i, int j) { if (s.charAt(i) == s.charAt(j)) { i++; j--; - } else return false; + } else { + return false; + } } return true; } diff --git a/src/geeksforgeeks/ValidSudoku.java b/src/geeksforgeeks/ValidSudoku.java new file mode 100644 index 0000000..e67d31d --- /dev/null +++ b/src/geeksforgeeks/ValidSudoku.java @@ -0,0 +1,37 @@ +package geeksforgeeks; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author i312458 + */ +public class ValidSudoku { + + public boolean isValidSudoku(char[][] board) { + Set seen = new HashSet(); + for (int i = 0; i < 9; ++i) { + for (int j = 0; j < 9; ++j) { + char number = board[i][j]; + if (number != '.') { + if (!seen.add(number + " in row " + i) || !seen.add(number + " in column " + j) || !seen.add( + number + " in block " + i / 3 + '-' + j / 3)) { + return false; + } + } + } + } + return true; + } + + public static void main(String[] args) { + char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, + { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, + { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, { '4', '.', '.', '8', '.', '3', '.', '.', '1' }, + { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, + { '.', '.', '.', '4', '1', '9', '.', '.', '5' }, { '.', '.', '.', '.', '8', '.', '.', '7', '9' } }; + + ValidSudoku vs = new ValidSudoku(); + System.out.println(vs.isValidSudoku(board)); + } +} diff --git a/src/geeksforgeeks/ValidSuduko.java b/src/geeksforgeeks/ValidSuduko.java new file mode 100644 index 0000000..d287cc3 --- /dev/null +++ b/src/geeksforgeeks/ValidSuduko.java @@ -0,0 +1,31 @@ +package geeksforgeeks; + +class VulgarSuduko { + public boolean isValidSudoku(char[][] board) { + Set seen = new HashSet<>(); + + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + if (board[i][j] != '.') { + char number = board[i][j]; + if (!seen.add(number + "seen in row" + i) || !seen.add(number + "seen in col" + j) + || !seen.add(number + "seen in block" + i / 3 + "-" + j / 3)) { + return false; + } + } + } + } + + return true; + } + public static void main(String[] args) { + char[][] board = { { '5', '3', '.', '.', '7', '.', '.', '.', '.' }, + { '6', '.', '.', '1', '9', '5', '.', '.', '.' }, { '.', '9', '8', '.', '.', '.', '.', '6', '.' }, + { '8', '.', '.', '.', '6', '.', '.', '.', '3' }, { '4', '.', '.', '8', '.', '3', '.', '.', '1' }, + { '7', '.', '.', '.', '2', '.', '.', '.', '6' }, { '.', '6', '.', '.', '.', '.', '2', '8', '.' }, + { '.', '.', '.', '4', '1', '9', '.', '.', '5' }, { '.', '.', '.', '.', '8', '.', '.', '7', '9' } }; + + ValidSudoku vs = new ValidSudoku(); + System.out.println(vs.isValidSudoku(board)); + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/ValidateIpAddresses.java b/src/geeksforgeeks/ValidateIpAddresses.java new file mode 100644 index 0000000..4a17752 --- /dev/null +++ b/src/geeksforgeeks/ValidateIpAddresses.java @@ -0,0 +1,41 @@ +package geeksforgeeks; + +public class ValidateIpAddresses { + // the condition for IPv4 is + // there should be 4 components separated by 3 dots + // each component should have value between 0-9 (base 10) + // + public String validIPAddress(String IP) { + if(IP==null || IP.length()==0) return "Neither"; + + if(IP.chars().filter(e->e=='.').count()==3){ + + for(String s: IP.split("\\.",-1)){ + if(s.length()==0 || s.length()>4) return "Neither"; + if(s.charAt(0)=='0' && s.length()!=1) return "Neither"; + for(char c:s.toCharArray()) if(!Character.isDigit(c)) return "Neither"; + if(Integer.parseInt(s)>255) return "Neither"; + } + + return "IPv4"; + + } + // the condition for IPv6 is + // it should have 8 components, separated by 7 ':'s + // each component should have hex-value i.e 0-9, a-f or A-F + else if(IP.chars().filter(e->e==':').count()==7){ + for(String s: IP.split(":",-1)){ + if(s.length()==0 || s.length()>4) return "Neither"; + for(char c: s.toCharArray()){ + if(!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))){ + return "Neither"; + } + } + } + + return "IPv6"; + } + + return "Neither"; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/VulgarDecimal.java b/src/geeksforgeeks/VulgarDecimal.java index 973665e..9a76c62 100644 --- a/src/geeksforgeeks/VulgarDecimal.java +++ b/src/geeksforgeeks/VulgarDecimal.java @@ -6,64 +6,46 @@ public class VulgarDecimal { - public static String fractionToDecimal(long num, long den) { - if (num == 0) { - return "0"; + public static String fractionToDecimal(long numerator, long denominator) { + if(denominator==0) return null; + boolean isNegative= (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0) ? true : false; + + long denomiL= Math.abs((long)denominator); + long numerL= Math.abs((long)numerator); + + Map map= new HashMap<>(); + + StringBuilder sb= new StringBuilder(); + + sb.append((numerL/denomiL)); + + if(numerL%denomiL!=0){ + sb.append("."); } - StringBuilder result = new StringBuilder(); - - result.append(((num > 0) ^ (den > 0)) ? "-" : ""); - result.append(num / den); - num %= den; - if (num == 0) { - return result.toString(); - } - - result.append("."); - HashMap map = new HashMap<>(); - map.put(num, result.length()); - while (num != 0) { - num *= 10; - result.append(num / den); - num %= den; - if (map.containsKey(num)) { - int index = map.get(num); - result.insert(index, "("); - result.append(")"); + if(isNegative) sb.insert(0,"-"); + numerL%=denomiL; + if(numerL==0) return sb.toString(); + + map.put(numerL,sb.length()); + + while(numerL>0){ + + numerL*=10; + sb.append((numerL/denomiL)); + numerL= (numerL%denomiL); + + if(map.containsKey(numerL)){ + int index= map.get(numerL); + sb.insert(index,"("); + sb.append(")"); break; - } else { - map.put(num, result.length()); + }else{ + map.put(numerL,sb.length()); } } - return result.toString(); + + return sb.toString(); } - /** - * boolean doTestsPass() - * Returns true if all tests pass. Otherwise false - *

- * Consider adding more tests. - */ - public static boolean doTestsPass() { - boolean testsPassed = true; - - // testsPassed &= fractionToDecimal(1l, 2l).equals("0.5"); - //testsPassed &= fractionToDecimal(1l, 3l).equals("0.(3)"); - //testsPassed &= fractionToDecimal(1l, 30l).equals("0.0(3)"); - //testsPassed &= fractionToDecimal(1l, 75l).equals("0.01(3)"); - //testsPassed &= fractionToDecimal(4l, 7l).equals("0.(571428)"); - testsPassed &= fractionToDecimal(1l, 56l).equals("0.017(857142)"); - - if (testsPassed) { - System.out.println("Tests passes"); - } else { - System.out.println("Tests failed"); - } - return testsPassed; - } - - public static void main(String[] args) { - doTestsPass(); - } } diff --git a/src/geeksforgeeks/WordBreak.java b/src/geeksforgeeks/WordBreak.java new file mode 100644 index 0000000..87d0ecb --- /dev/null +++ b/src/geeksforgeeks/WordBreak.java @@ -0,0 +1,83 @@ +package geeksforgeeks; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class WordBreak { + + /* +|T| | | | | | | | | + 0 1 2 3 4 5 6 7 8 + +i = 1 +j = o sub = l + +i = 2 +j = 0 sub = le +j = 1 sub = e + +i = 3 +j = 0 sub = lee +j = 1 sub = ee +j = 2 sub = e + +i = 4 +j = 0 sub = leet && T[0] and then break, no need to check for rest +|T | | | |T| | | | | +0 1 2 3 4 5 6 7 8 + +i = 5 +j = 0 sub = leetc +j = 1 sub = eetc +j = 2 sub = etc +j = 3 sub = tc +j = 4 sub = c + +i = 6 +j = 0 sub = leetco +j = 1 sub = eetco +j = 2 sub = etco +j = 3 sub = tco +j = 4 sub = co +j = 5 sub = o + +i = 7 +j = 0 sub = leetcod +j = 1 sub = eetcod +j = 2 sub = etcod +j = 3 sub = tcod +j = 4 sub = cod +j = 5 sub = od +j = 6 sub = d + +i = 8 +j = 0 sub = leetcode +j = 1 sub = eetcode +j = 2 sub = etcode +j = 3 sub = tcode +j = 4 sub = code && T[4] and then break + +|T| | | |T| | | |T| + 0 1 2 3 4 5 6 7 8 +*/ + public boolean wordBreak(String s, List wordDict) { + if (s == null) { + return false; + } + boolean[] dp = new boolean[s.length() + 1]; + dp[0] = true; + Set set = new HashSet<>(wordDict); + + for (int i = 1; i <= s.length(); i++) { + for (int j = 0; j < i; j++) { + dp[i] = dp[j] && set.contains(s.substring(j, i)); + if (dp[i]) { + break; + } + } + } + + return dp[s.length()]; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/WordBreakII.java b/src/geeksforgeeks/WordBreakII.java new file mode 100644 index 0000000..1aa8a46 --- /dev/null +++ b/src/geeksforgeeks/WordBreakII.java @@ -0,0 +1,28 @@ +package geeksforgeeks; + +public class WordBreakII { + public List wordBreak(String s, List wordDict) { + Map> cache = new HashMap<>(); + backtrack(s,wordDict, cache); + return cache.get(s); + } + + public List backtrack(String s, List wordDict, Map> cache){ + + if(cache.containsKey(s)) return cache.get(s); + + List result = new ArrayList<>(); + for(String word: wordDict) { + if(!s.startsWith(word)) continue; // string does not start with this word? + String next = s.substring(word.length()); + if(next.isEmpty()) { // awesome! + result.add(word); + continue; + } + for(String sub: backtrack(next, wordDict, cache)) + result.add(word + " " + sub); + } + cache.put(s, result); + return result; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/WordDictionary.java b/src/geeksforgeeks/WordDictionary.java new file mode 100644 index 0000000..1571536 --- /dev/null +++ b/src/geeksforgeeks/WordDictionary.java @@ -0,0 +1,66 @@ +package geeksforgeeks; + +/** + * Design a data structure that supports the following two operations: + * void addWord(word) + * bool search(word) + * search(word) can search a literal word or + * a regular expression string containing only letters a-z or .. A . + * means it can represent any one letter. + * addWord("bad") + addWord("dad") + addWord("mad") + search("pad") -> false + search("bad") -> true + search(".ad") -> true + search("b..") -> true + */ +public class WordDictionary { + private TrieNode root; + + /** Initialize your data structure here. */ + private class TrieNode { + public Map children = new HashMap<>(); + public boolean isWord; + } + + public WordDictionary() { + root = new TrieNode(); + } + + /** Adds a word into the data structure. */ + public void addWord(String word) { + + TrieNode temp = root; + + for (char c : word.toCharArray()) { + if (temp.children.get(c) == null) + temp.children.put(c, new TrieNode()); + + temp = temp.children.get(c); + } + + temp.isWord = true; + } + + /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ + public boolean search(String word) { + return match(word.toCharArray(), 0, root); + } + + private boolean match(char[] chs, int k, TrieNode node) { + + if (k == chs.length) + return node.isWord; + + if (chs[k] == '.') { + for (Character curr: node.children.keySet()) { + if (node.children.get(curr) != null && match(chs, k+1, node.children.get(curr))) + return true; + } + } else + return node.children.get(chs[k]) != null && match(chs, k + 1, node.children.get(chs[k])); + + return false; + } +} \ No newline at end of file diff --git a/src/geeksforgeeks/WordLadder.java b/src/geeksforgeeks/WordLadder.java new file mode 100644 index 0000000..2a69ea3 --- /dev/null +++ b/src/geeksforgeeks/WordLadder.java @@ -0,0 +1,43 @@ +package geeksforgeeks; + +public class WordLadder { + public int ladderLength(String beginWord, String endWord, List wordList) { + Set set = new HashSet(wordList); + if(!set.contains(endWord)) return 0; // end word itself not in set + Queue queue = new LinkedList(); + queue.add(beginWord); + int count = 1; + + while(!queue.isEmpty()) { + + int size = queue.size(); + for (int i =0; i