├── .gitignore ├── README.md ├── java ├── ctci │ ├── .clang-format │ ├── .classpath │ ├── .project │ ├── .settings │ │ └── org.eclipse.jdt.core.prefs │ ├── bin │ │ ├── Library │ │ │ ├── Graph.class │ │ │ ├── GraphNode.class │ │ │ ├── TreeNode.class │ │ │ └── Util.class │ │ ├── graphs │ │ │ ├── BSTSequences.class │ │ │ ├── ListOfDepths.class │ │ │ ├── RouteBtwNodes$State.class │ │ │ ├── RouteBtwNodes.class │ │ │ ├── Successor.class │ │ │ ├── buildOrder.class │ │ │ ├── checkBalanced.class │ │ │ └── validateBST.class │ │ ├── recursion │ │ │ ├── factorial.class │ │ │ ├── permutation.class │ │ │ ├── rotation.class │ │ │ └── subsequence.class │ │ ├── sort │ │ │ ├── Merge.class │ │ │ ├── Quick.class │ │ │ ├── insertion.class │ │ │ ├── selection.class │ │ │ └── shell.class │ │ └── stacks │ │ │ └── FixedMultiStack.class │ └── src │ │ ├── Library │ │ ├── Graph.java │ │ ├── GraphNode.java │ │ ├── ListNode.java │ │ ├── TreeNode.java │ │ └── Util.java │ │ ├── String │ │ ├── IsPermuation.java │ │ └── isUnique.java │ │ ├── graphs │ │ ├── BSTSequences.java │ │ ├── ListOfDepths.java │ │ ├── RouteBtwNodes.java │ │ ├── Successor.java │ │ ├── buildOrder.java │ │ ├── checkBalanced.java │ │ └── validateBST.java │ │ ├── linkedlist │ │ ├── KthToLast.java │ │ ├── RemoveDuplicates.java │ │ └── findIntersection.java │ │ ├── recursion │ │ ├── factorial.java │ │ ├── permutation.java │ │ ├── rotation.java │ │ └── subsequence.java │ │ ├── sort │ │ ├── Merge.java │ │ ├── Quick.java │ │ ├── insertion.java │ │ ├── selection.java │ │ └── shell.java │ │ └── stacks │ │ ├── 3stacks.java │ │ └── MinStack.java ├── easy │ ├── DecodeRunLength.java │ ├── firstUnique.java │ └── flattenDictionary.java ├── google │ ├── CompareStrings.java │ ├── MaxLevelSum.java │ ├── MostBookedRoom.java │ ├── ServerLoads.java │ ├── StoresAndHouses.java │ ├── TimeToTypeString.java │ ├── allocation.java │ ├── countdown.java │ ├── largestSubArray.java │ ├── minAmplitude.java │ └── questions.md ├── hard │ ├── makePalindrome.java │ └── removePrisoner.java ├── medium │ ├── ArrayProducts.java │ ├── HuffmanDecoding.java │ ├── Itinerary.java │ ├── SentenceReverse.java │ ├── TreasureHunt.java │ ├── WordBreak.java │ ├── WordLadder.java │ ├── coursePrerequisites.java │ ├── decodeWays.java │ ├── findInRotatedArray.java │ ├── killProcess.java │ ├── knapSack.java │ ├── lowestCommonAncestor.java │ ├── matrixBlockSum.java │ ├── reverseLinkedList.java │ ├── swapNodes │ │ ├── SwapNodes.java │ │ ├── SwapNodes2.java │ │ ├── result.txt │ │ └── testFile.txt │ ├── topologicalSort.java │ └── txt.txt └── utils │ └── DiGraph.java ├── js ├── random │ └── study.js ├── stage_1 │ ├── addStrings.js │ ├── addTillSingleDigit.js │ ├── anagram.js │ ├── anglebetweenClockHands.js │ ├── birthdayBar.js │ ├── bitwiseAnd.js │ ├── bracketValidity.js │ ├── cavityMap.js │ ├── compareLetters.js │ ├── deepEqual.js │ ├── diagonalSums.js │ ├── fizzBuzz.js │ ├── halloweenParty.js │ ├── hammingDistance.js │ ├── hourGlassMax.js │ ├── indexSumToTarget.js │ ├── letterA.js │ ├── letterUsage.js │ ├── palindrome.js │ ├── primes.js │ ├── reverseInPlace.js │ ├── reverseInteger.js │ └── stripProperty.js ├── stage_2 │ ├── .vscode │ │ └── launch.json │ ├── alternatingSort.js │ ├── climbTheLeaderboard.js │ ├── countingSort.js │ ├── coursePrerequisites.js │ ├── cutTheTree1.js │ ├── encryption.js │ ├── fibonacci.js │ ├── fibonacciSum.js │ ├── findDigit.js │ ├── findMin.js │ ├── flattenLinkedList.js │ ├── h_index.js │ ├── isValidBST.js │ ├── kthNodeInBST.js │ ├── longestRepeatedSubstring.js │ ├── makeChange.js │ ├── mergeIntervals.js │ ├── migratoryBirds.js │ ├── minMoves.js │ ├── minStepToN.js │ ├── minimumBribes.js │ ├── minimumSwaps.js │ ├── rightSideView.js │ ├── savePrincess.js │ ├── shortestTransform.js │ ├── shuffleReset.js │ ├── specialMultiple.js │ ├── splitString.js │ ├── threeSumToTarget.js │ ├── viralAdvertising.js │ └── whatFlavor.js └── stage_3 │ ├── LFUCache.js │ ├── betweenTwoIntegers.js │ ├── concatSum.js │ ├── connectedGrid.js │ ├── connectedGrid2.js │ ├── customMerge.js │ ├── fourSumToTarget.js │ ├── gridClimbing.js │ ├── integersToEnglish.js │ ├── invalidParenthesis.js │ ├── islandCount.js │ ├── knapSack.js │ ├── largestSquareMatrix.js │ ├── leastSubse.js │ ├── lexicalMergeSort.js │ ├── programmerStrings.js │ ├── queensAttack.js │ ├── queensAttackII.js │ ├── randomCard.js │ ├── readInput.js │ ├── riverSizes.js │ ├── subseqInAB.js │ ├── subsequence.js │ ├── taxiCab.js │ ├── test.js │ ├── toys.js │ └── trapRain.js └── questions.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.class -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms and Data Structures 2 | 3 | This project contains a collection of algorithm and data structure questions I've been able to solve, in Java and JavaScript. 4 | 5 | I use it for learning purposes. 6 | 7 | Feel free to send a PR with modifications, corrections and ideas on how to improve on the time and space complexity. 8 | 9 | It would be nice if you could add some more questions you'd like me to try to solve into the 'questions folder'. 10 | 11 | Enjoy!!! :) 12 | 13 | -------------------------------------------------------------------------------- /java/ctci/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /java/ctci/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ctci 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | -------------------------------------------------------------------------------- /java/ctci/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.8 8 | -------------------------------------------------------------------------------- /java/ctci/bin/Library/Graph.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/Library/Graph.class -------------------------------------------------------------------------------- /java/ctci/bin/Library/GraphNode.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/Library/GraphNode.class -------------------------------------------------------------------------------- /java/ctci/bin/Library/TreeNode.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/Library/TreeNode.class -------------------------------------------------------------------------------- /java/ctci/bin/Library/Util.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/Library/Util.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/BSTSequences.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/BSTSequences.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/ListOfDepths.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/ListOfDepths.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/RouteBtwNodes$State.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/RouteBtwNodes$State.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/RouteBtwNodes.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/RouteBtwNodes.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/Successor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/Successor.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/buildOrder.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/buildOrder.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/checkBalanced.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/checkBalanced.class -------------------------------------------------------------------------------- /java/ctci/bin/graphs/validateBST.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/graphs/validateBST.class -------------------------------------------------------------------------------- /java/ctci/bin/recursion/factorial.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/recursion/factorial.class -------------------------------------------------------------------------------- /java/ctci/bin/recursion/permutation.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/recursion/permutation.class -------------------------------------------------------------------------------- /java/ctci/bin/recursion/rotation.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/recursion/rotation.class -------------------------------------------------------------------------------- /java/ctci/bin/recursion/subsequence.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/recursion/subsequence.class -------------------------------------------------------------------------------- /java/ctci/bin/sort/Merge.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/sort/Merge.class -------------------------------------------------------------------------------- /java/ctci/bin/sort/Quick.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/sort/Quick.class -------------------------------------------------------------------------------- /java/ctci/bin/sort/insertion.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/sort/insertion.class -------------------------------------------------------------------------------- /java/ctci/bin/sort/selection.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/sort/selection.class -------------------------------------------------------------------------------- /java/ctci/bin/sort/shell.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/sort/shell.class -------------------------------------------------------------------------------- /java/ctci/bin/stacks/FixedMultiStack.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/java/ctci/bin/stacks/FixedMultiStack.class -------------------------------------------------------------------------------- /java/ctci/src/Library/Graph.java: -------------------------------------------------------------------------------- 1 | package Library; 2 | 3 | public class Graph { 4 | public static int MAX_VERTICES = 6; 5 | private GraphNode vertices[]; 6 | public int count; 7 | 8 | public Graph() { 9 | vertices = new GraphNode[MAX_VERTICES]; 10 | count = 0; 11 | } 12 | 13 | public void addNodes(GraphNode[] x) { 14 | if (x.length > MAX_VERTICES) { 15 | System.out.printf("Only the first %s nodes will be added", MAX_VERTICES); 16 | } 17 | while (count < MAX_VERTICES) { 18 | vertices[count] = x[count++]; 19 | } 20 | } 21 | 22 | public void addNode(GraphNode x) { 23 | if (count < vertices.length) { 24 | vertices[count] = x; 25 | count++; 26 | } else { 27 | System.out.print("Graph full"); 28 | } 29 | } 30 | 31 | public GraphNode[] getNodes() { 32 | return vertices; 33 | } 34 | } -------------------------------------------------------------------------------- /java/ctci/src/Library/GraphNode.java: -------------------------------------------------------------------------------- 1 | package Library; 2 | 3 | import graphs.RouteBtwNodes; 4 | 5 | public class GraphNode { 6 | private final String vertex; 7 | public int adjacentCount; 8 | private final GraphNode adjacent[]; 9 | public RouteBtwNodes.State state; 10 | 11 | /** 12 | * Creates a graph node 13 | * @param vertex 14 | * @param adjacentLength 15 | */ 16 | public GraphNode(final String vertex, final int adjacentLength) { 17 | this.vertex = vertex; 18 | adjacentCount = 0; 19 | adjacent = new GraphNode[adjacentLength]; 20 | } 21 | 22 | public void addAdjacents(final GraphNode adjacents[]) { 23 | int n = adjacent.length; 24 | if (adjacents.length > n) { 25 | System.out.printf("Only the first %d adjacent nodes will be added", n); 26 | } 27 | while (--n >= 0) { 28 | adjacent[n] = adjacents[n]; 29 | } 30 | } 31 | 32 | public void addAdjacent(final GraphNode x) { 33 | if (adjacentCount < adjacent.length) { 34 | adjacent[adjacentCount++] = x; 35 | } 36 | } 37 | 38 | public GraphNode[] getAdjacent() { 39 | return adjacent; 40 | } 41 | 42 | public String getVertex() { 43 | return vertex; 44 | } 45 | } -------------------------------------------------------------------------------- /java/ctci/src/Library/ListNode.java: -------------------------------------------------------------------------------- 1 | package Library; 2 | 3 | public class ListNode { 4 | public char value; 5 | public ListNode next; 6 | } -------------------------------------------------------------------------------- /java/ctci/src/Library/Util.java: -------------------------------------------------------------------------------- 1 | package Library; 2 | 3 | import java.util.Random; 4 | 5 | public class Util { 6 | final static Random rand = new Random(); 7 | 8 | /** 9 | * Returns an array with random integers; 10 | */ 11 | public static int[] randomIntArray() { 12 | final int N = rand.nextInt(10); 13 | 14 | final int[] data = new int[N]; 15 | 16 | for (int i = 0; i < N; i++) { 17 | data[i] = rand.nextInt(1000); 18 | } 19 | return data; 20 | } 21 | 22 | /** 23 | * Returns an array with random doubles; 24 | * @param bound the length of the array, if omitted a random length is used 25 | */ 26 | 27 | public static double[] randomDoubleArray() { 28 | final int N = rand.nextInt(10); 29 | 30 | final double[] data = new double[N]; 31 | 32 | for (int i = 0; i < N; i++) { 33 | data[i] = Math.random() * rand.nextInt(1000); 34 | } 35 | return data; 36 | } 37 | 38 | /** 39 | * @param num1 40 | * @param num2 41 | * @return 1 if less, -1 if greater or 0 if equal 42 | * 43 | */ 44 | 45 | public static double less(double num1, double num2) { 46 | if (num1 > num2) return -1; 47 | if (num1 < num2) return 1; 48 | return 0; 49 | } 50 | 51 | /** 52 | * @param num1 53 | * @param num2 54 | * @return 1 if less, -1 if greater or 0 if equal 55 | */ 56 | 57 | public static int less(int num1, int num2) { 58 | if (num1 > num2) return -1; 59 | if (num1 < num2) return 1; 60 | return 0; 61 | } 62 | 63 | public static void exch(final double[] arr, final int i, final int j) { 64 | final double temp = arr[i]; 65 | arr[i] = arr[j]; 66 | arr[j] = temp; 67 | } 68 | 69 | public static void exch(final int[] arr, final int i, final int j) { 70 | final int temp = arr[i]; 71 | arr[i] = arr[j]; 72 | arr[j] = temp; 73 | } 74 | 75 | } -------------------------------------------------------------------------------- /java/ctci/src/String/IsPermuation.java: -------------------------------------------------------------------------------- 1 | package String; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Given two strings, write a method to see if one is a permutation of the other 7 | */ 8 | public class IsPermuation { 9 | public static Boolean solution(String s1, String s2) { 10 | if (s1.length() != s2.length()) return false; 11 | int N = s1.length(); 12 | if (N == 0) return false; 13 | 14 | Map freqCount = new HashMap<>(); 15 | for (int i = 0; i < N; i++) { 16 | char cur = s1.charAt(i); 17 | if (freqCount.get(cur) == null) { 18 | freqCount.put(cur, 1); 19 | } else { 20 | freqCount.put(cur, freqCount.get(cur) + 1); 21 | } 22 | } 23 | 24 | for (int i = 0; i < N; i++) { 25 | char cur = s2.charAt(i); 26 | if (freqCount.get(cur) == null || freqCount.get(cur) == 0) return false; 27 | freqCount.put(cur, freqCount.get(cur) - 1); 28 | } 29 | 30 | return true; 31 | } 32 | 33 | public static void main(String[] args) { 34 | String s1 = "leetcode"; 35 | String s2 = "lletcode"; 36 | 37 | System.out.println(IsPermuation.solution(s1, s2)); 38 | } 39 | } -------------------------------------------------------------------------------- /java/ctci/src/String/isUnique.java: -------------------------------------------------------------------------------- 1 | package String; 2 | /** 3 | * Write a function to determine if a s string haas all unique characters. 4 | * FOLLOW UP: What if you can't use additional DS? 5 | */ 6 | import java.util.*; 7 | 8 | public class isUnique { 9 | public static boolean solution(String s) { 10 | Set seen = new HashSet<>(); 11 | 12 | // O(N) 13 | for (int i = 0; i < s.length(); i++) { 14 | if (seen.contains(s.charAt(i))) return false; 15 | seen.add(s.charAt(i)); 16 | } 17 | 18 | return true; 19 | } 20 | /** 21 | * FOLLOW UP; if not allowed to use additional DS, we can check the rest of 22 | * the characters, with respect to a current character. This is O(N2). 23 | * OR we can sort the string 24 | */ 25 | } -------------------------------------------------------------------------------- /java/ctci/src/graphs/BSTSequences.java: -------------------------------------------------------------------------------- 1 | package graphs; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | 6 | import Library.TreeNode; 7 | 8 | /** 9 | * A binary search tree was created by traversing thorugh an array from left to right and inserting each element. Given a binary search tree with distinct elements, print all possible arrays that could have led to this tree. 10 | * Eg: Given 1 11 | * / \ 12 | * 2 3 13 | * Output: {2, 1, 3}, {2, 3, 1} 14 | */ 15 | public class BSTSequences { 16 | static public ArrayList> allSequences( 17 | final TreeNode head) { 18 | final ArrayList> result = new ArrayList<>(); 19 | if (head == null) { 20 | result.add(new LinkedList<>()); // this shouldnt be necessary 21 | return result; 22 | } 23 | 24 | // add head to prefix of children to be weaved 25 | final LinkedList prefix = new LinkedList<>(); 26 | prefix.add(head.data); 27 | 28 | final ArrayList> leftSeq = allSequences(head.left); 29 | final ArrayList> rightSeq = allSequences(head.right); 30 | 31 | // weave the two together 32 | for (final LinkedList left : leftSeq) { 33 | for (final LinkedList right : rightSeq) { 34 | final ArrayList> weaved = new ArrayList<>(); 35 | weaveList(left, right, prefix, weaved); 36 | result.addAll(weaved); 37 | } 38 | } 39 | return result; 40 | } 41 | 42 | static private void weaveList(LinkedList left, LinkedList right, LinkedList prefix ,ArrayList> res) { 43 | if (left.size() == 0 || right.size() == 0) { 44 | LinkedList prefixClone = (LinkedList) prefix.clone(); 45 | prefixClone.addAll(left); 46 | prefixClone.addAll(right); 47 | res.add(prefixClone); 48 | return; 49 | } 50 | 51 | // weave from head of left 52 | int headLeft = left.removeFirst(); 53 | prefix.addLast(headLeft); 54 | weaveList(left, right, prefix, res); 55 | // backtrack 56 | prefix.removeLast(); 57 | left.addFirst(headLeft); 58 | 59 | // weave from head of right 60 | int headRight = right.removeFirst(); 61 | prefix.addLast(headRight); 62 | weaveList(left, right, prefix, res); 63 | prefix.removeLast(); 64 | right.addFirst(headRight); 65 | } 66 | 67 | static public void main(String[] args) { 68 | int[] nodes_flattened = {2, 1, 5, 6, 7}; 69 | TreeNode root = TreeNode.createMinimalBST(nodes_flattened); 70 | ArrayList> res = BSTSequences.allSequences(root); 71 | System.out.print(res.toString()); 72 | } 73 | } -------------------------------------------------------------------------------- /java/ctci/src/graphs/ListOfDepths.java: -------------------------------------------------------------------------------- 1 | package graphs; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | 6 | import Library.TreeNode; 7 | 8 | public class ListOfDepths { 9 | /** 10 | * Add root to list as level 0, add roots direct children as level 1 and 11 | * children's children as next level 12 | * @param root 13 | * @return an arraylist with list of roots at each level 14 | */ 15 | public static ArrayList> levelListsBFS(TreeNode root) { 16 | ArrayList> result = new ArrayList<>(); 17 | 18 | LinkedList current = new LinkedList<>(); 19 | if (root != null) { 20 | current.add(root); 21 | } 22 | 23 | while (current.size() > 0) { 24 | // add current to array and iterate the children 25 | result.add(current); 26 | LinkedList parents = current; 27 | current = new LinkedList<>(); 28 | for (TreeNode parent : parents) { 29 | // visit the children 30 | if (parent.left != null) { 31 | current.add(parent.left); 32 | } 33 | if (parent.right != null) { 34 | current.add(parent.right); 35 | } 36 | } 37 | } 38 | return result; 39 | } 40 | 41 | /** 42 | * Recursively search through nodes, keeping track of levels and adding nodes 43 | * to list according to which level we are in 44 | * @param current 45 | * @param result 46 | * @param level 47 | */ 48 | 49 | private static void levelListsDFS(TreeNode current, 50 | ArrayList> result, 51 | int level) { 52 | if (current == null) return; 53 | // initialize a list 54 | LinkedList list = null; 55 | if (result.size() == 56 | level) { // if the level we are at hasn't been added to list 57 | list = new LinkedList<>(); 58 | result.add(list); 59 | } else { 60 | list = result.get(level); 61 | } 62 | list.add(current); // add the node to the list 63 | levelListsDFS(current.left, result, level + 1); 64 | levelListsDFS(current.right, result, level + 1); 65 | } 66 | 67 | public static ArrayList> levelListsDFS(TreeNode root) { 68 | ArrayList> result = new ArrayList<>(); 69 | levelListsDFS(root, result, 0); 70 | return result; 71 | } 72 | 73 | public static void printLevels(ArrayList> levels) { 74 | int depth = 0; 75 | for (LinkedList level : levels) { 76 | System.out.print("The nodes at depth " + depth + ":"); 77 | for (TreeNode node : level) { 78 | System.out.print(node.data + " "); 79 | } 80 | System.out.println(); 81 | depth++; 82 | } 83 | } 84 | 85 | public static void main(String[] args) { 86 | int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 87 | TreeNode root = TreeNode.createMinimalBST(nodes_flattened); 88 | TreeNode root2 = TreeNode.createTreeFromArray(nodes_flattened); 89 | ArrayList> list = levelListsBFS(root); 90 | ArrayList> list2 = levelListsDFS(root2); 91 | System.out.println("BFS Approach"); 92 | printLevels(list); 93 | System.out.println("------------"); 94 | System.out.println("DFS Approach"); 95 | printLevels(list2); 96 | } 97 | } -------------------------------------------------------------------------------- /java/ctci/src/graphs/RouteBtwNodes.java: -------------------------------------------------------------------------------- 1 | package graphs; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.util.LinkedList; 7 | 8 | import org.junit.Test; 9 | 10 | import Library.Graph; 11 | import Library.GraphNode; 12 | 13 | public class RouteBtwNodes { 14 | public enum State { Unvisited, Visiting, Visited } 15 | 16 | public static Graph createNewGraph() { 17 | final Graph g = new Graph(); 18 | final GraphNode[] temp = new GraphNode[6]; 19 | 20 | temp[0] = new GraphNode("a", 3); 21 | temp[1] = new GraphNode("b", 0); 22 | temp[2] = new GraphNode("c", 0); 23 | temp[3] = new GraphNode("d", 1); 24 | temp[4] = new GraphNode("e", 1); 25 | temp[5] = new GraphNode("f", 0); 26 | 27 | temp[0].addAdjacent(temp[1]); 28 | temp[0].addAdjacent(temp[2]); 29 | temp[0].addAdjacent(temp[3]); 30 | temp[3].addAdjacent(temp[4]); 31 | temp[4].addAdjacent(temp[5]); 32 | 33 | g.addNodes(temp); 34 | 35 | return g; 36 | } 37 | 38 | public static boolean search(Graph g, GraphNode start, GraphNode end) { 39 | if (start == null || end == null) { 40 | return false; 41 | } 42 | if (start == end) { 43 | return true; 44 | } 45 | 46 | // we will do BFS using Linked list 47 | // mark all nodes as unvisited 48 | for (GraphNode node : g.getNodes()) { 49 | node.state = State.Unvisited; 50 | } 51 | 52 | // visiting start 53 | start.state = State.Visiting; 54 | 55 | LinkedList n = new LinkedList<>(); 56 | n.add(start); 57 | 58 | GraphNode u; 59 | while (!n.isEmpty()) { 60 | // remove the first node 61 | u = n.removeFirst(); 62 | if (u != null) { 63 | for (GraphNode adj : u.getAdjacent()) { 64 | if (adj.state == State.Unvisited) { 65 | if (adj == end) { 66 | return true; 67 | } else { 68 | adj.state = State.Visiting; 69 | n.add(adj); 70 | } 71 | } 72 | } 73 | u.state = State.Visited; 74 | } 75 | } 76 | return false; 77 | } 78 | 79 | @Test 80 | public static void main(String[] args) { 81 | Graph g = RouteBtwNodes.createNewGraph(); 82 | GraphNode[] n = g.getNodes(); 83 | 84 | assertTrue("There's a path between d and f", search(g, n[3], n[5])); 85 | 86 | assertFalse("There's no path between a and e", search(g, n[1], n[4])); 87 | 88 | assertTrue("There's a path between same node", search(g, n[1], n[1])); 89 | 90 | assertFalse("There's no path when node is null", search(g, n[4], null)); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /java/ctci/src/graphs/Successor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Write an algorithm to find the "next" node (i.e., in-order successor) of a 3 | given node in a 4 | binary search tree. You may assume that each node has a link to its parent 5 | */ 6 | package graphs; 7 | 8 | import Library.TreeNode; 9 | 10 | public class Successor { 11 | public static TreeNode node(TreeNode n) { 12 | if (n == null) return null; 13 | // In inorder traversal, left >current->right 14 | // if n has right child, return leftmost node of right child 15 | if (n.right != null) { 16 | return leftMostNode(n.right); 17 | } 18 | // else, go up to the parent, if coming from the left, then the parent is to 19 | // be visited 20 | // if coming from the right, keep going up till you find, or return null; 21 | TreeNode current = n; 22 | TreeNode p = n.parent; 23 | while (p != null && p.left != current) { 24 | current = p; 25 | p = p.parent; 26 | } 27 | return current; 28 | } 29 | 30 | public static TreeNode leftMostNode(TreeNode right) { 31 | while (right.left != null) { 32 | right = right.left; 33 | } 34 | return right; 35 | } 36 | 37 | public static void main(String[] args) { 38 | int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 39 | TreeNode root = TreeNode.createMinimalBST(nodes_flattened); 40 | TreeNode next = Successor.node(root.left.right.left); 41 | System.out.println(next.data); 42 | } 43 | } -------------------------------------------------------------------------------- /java/ctci/src/graphs/buildOrder.java: -------------------------------------------------------------------------------- 1 | package graphs; 2 | 3 | public class buildOrder { 4 | 5 | } -------------------------------------------------------------------------------- /java/ctci/src/graphs/checkBalanced.java: -------------------------------------------------------------------------------- 1 | package graphs; 2 | 3 | import Library.TreeNode; 4 | 5 | // Implement a function to check if a binary tree is balanced. For the purposes 6 | // of 7 | // this question, a balanced tree is defined to be a tree such that the heights 8 | // of the two subtrees of any 9 | // node never differ by more than one. 10 | 11 | public class checkBalanced { 12 | /** 13 | * check if a tree is balance by checking the left and right trees recursively 14 | * and returning an error code(Integer.MIN_VALUE) if the tree isn't balanced 15 | * @param n 16 | * @return 17 | */ 18 | public static int checkHeight(TreeNode n) { 19 | if (n == null) return -1; 20 | 21 | int leftHeight = checkHeight(n.left); 22 | if (leftHeight == Integer.MIN_VALUE) return Integer.MIN_VALUE; 23 | 24 | int rightHeight = checkHeight(n.right); 25 | if (rightHeight == Integer.MIN_VALUE) return Integer.MIN_VALUE; 26 | 27 | int diff = Math.abs(leftHeight - rightHeight); 28 | if (diff > 0) return Integer.MIN_VALUE; 29 | return Math.max(leftHeight, rightHeight) + 1; 30 | } 31 | 32 | public static boolean isBalanced(TreeNode n) { 33 | return checkHeight(n) != Integer.MIN_VALUE; 34 | } 35 | 36 | public static void main(String[] args) { 37 | int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7}; 38 | TreeNode root = TreeNode.createMinimalBST(nodes_flattened); 39 | TreeNode root2 = TreeNode.createTreeFromArray(nodes_flattened); 40 | System.out.println("BST Tree"); 41 | System.out.println(checkBalanced.isBalanced(root)); 42 | System.out.println("------------"); 43 | System.out.println("Tree"); 44 | System.out.println(checkBalanced.isBalanced(root2)); 45 | } 46 | } -------------------------------------------------------------------------------- /java/ctci/src/graphs/validateBST.java: -------------------------------------------------------------------------------- 1 | package graphs; 2 | 3 | import Library.TreeNode; 4 | 5 | public class validateBST { 6 | /** 7 | * Using the in-order traversal to check that tree is in sorted order. Does 8 | * not account for duplicate values 9 | * @param n 10 | * @return 11 | */ 12 | static int lastValue = Integer.MIN_VALUE; 13 | public static boolean usingNorder(TreeNode n) { 14 | if (n == null) return true; 15 | // if left tree is not bst 16 | if (!usingNorder(n.left)) return false; 17 | 18 | // check current 19 | if (lastValue != Integer.MIN_VALUE && lastValue >= n.data) return false; 20 | lastValue = n.data; 21 | 22 | if (!usingNorder(n.right)) return false; 23 | return true; 24 | } 25 | 26 | public static boolean usingMinMax(TreeNode n) { 27 | return validateBST.checkBST(n, null, null); 28 | } 29 | 30 | /** 31 | * Recursively checks that the node on the right is not less than or equal to it's parent which 32 | * is the min value for that context and that the left node is not greater than it's parent 33 | * which is the max value for that context 34 | * @param n 35 | * @param min 36 | * @param max 37 | * @return 38 | */ 39 | public static boolean checkBST(TreeNode n, Integer min, Integer max) { 40 | if (n == null) return true; 41 | 42 | // check that either of the left node or right node is in check 43 | if ((max != null && n.data > max) || (min != null && n.data <= min)) return false; 44 | 45 | // recurse to the left and right 46 | if (!checkBST(n.left, min, n.data) || (!checkBST(n.right, n.data, max))) return false; 47 | 48 | return true; 49 | 50 | } 51 | public static void main(String[] args) { 52 | int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7}; 53 | TreeNode root = TreeNode.createMinimalBST(nodes_flattened); 54 | TreeNode root2 = TreeNode.createTreeFromArray(nodes_flattened); 55 | System.out.println("BST Tree"); 56 | System.out.println(validateBST.usingNorder(root)); 57 | System.out.println("------------"); 58 | System.out.println("Tree"); 59 | System.out.println(validateBST.usingMinMax(root2)); 60 | } 61 | } -------------------------------------------------------------------------------- /java/ctci/src/linkedlist/KthToLast.java: -------------------------------------------------------------------------------- 1 | package linkedlist; 2 | 3 | /** 4 | * Given a singly LinkedList, find the Kth to Last element; 5 | */ 6 | import Library.*; 7 | public class KthToLast { 8 | public static ListNode solution(ListNode head, int K) { 9 | if (K == 0) return null; 10 | if (head == null) return head; 11 | 12 | ListNode current = head; 13 | ListNode running = head; 14 | 15 | while(K > 0) { 16 | if (running == null) return null; 17 | running = running.next; 18 | K--; 19 | } 20 | 21 | while (running != null) { 22 | current = current.next; 23 | running = running.next; 24 | } 25 | 26 | return current; 27 | } 28 | 29 | public static void main(String[] args) { 30 | ListNode head = new ListNode(); 31 | head.value = '1'; 32 | ListNode cur = head; 33 | for (char i = '2'; i < '9'; i++) { 34 | ListNode next = new ListNode(); 35 | next.value = i; 36 | cur.next = next; 37 | cur = cur.next; 38 | } 39 | 40 | System.out.println(KthToLast.solution(head, 1)); 41 | System.out.println(KthToLast.solution(head, 2)); 42 | System.out.println(KthToLast.solution(head, 3)); 43 | // System.out.println(KthToLast.solution(head, 9)); 44 | System.out.println(KthToLast.solution(head, 8)); 45 | } 46 | } -------------------------------------------------------------------------------- /java/ctci/src/linkedlist/RemoveDuplicates.java: -------------------------------------------------------------------------------- 1 | package linkedlist; 2 | 3 | import java.util.HashSet; 4 | 5 | /** 6 | * Write code to remove duplicates from an unsorted linkedlist. 7 | * FOLLOW UP; How would you do it if a temporary buffer was not allowed? 8 | */ 9 | import java.util.*; 10 | import Library.*; 11 | public class RemoveDuplicates { 12 | 13 | private ListNode solve(ListNode head) { 14 | if (head == null) return head; 15 | // keep track of previous node 16 | // connect prevous to next of node if node is duplicate 17 | Set seen = new HashSet<>(); 18 | 19 | ListNode prev = null; 20 | ListNode cur = head; 21 | while (cur != null) { 22 | if (seen.contains(cur.value)) { 23 | prev.next = cur.next; 24 | } else { 25 | seen.add(cur.value); 26 | prev = cur; 27 | } 28 | cur = cur.next; 29 | } 30 | return head; 31 | } 32 | 33 | /** 34 | * Follow up: use an additional pointer to check the rest of the list while in cur node 35 | */ 36 | } -------------------------------------------------------------------------------- /java/ctci/src/linkedlist/findIntersection.java: -------------------------------------------------------------------------------- 1 | // LinkedListNode findIntersection(LinkedListNode l1, LinkedListNode l2) { 2 | // // find size and tail 3 | // // chop off difference in length on longer list 4 | // // find intersection by looping at same time 5 | 6 | // if (l1 == null || l2 == null) { 7 | // return null; 8 | // } 9 | 10 | // Result result1 = getTailAndSize(l1); 11 | // Result result2 = getTailAndSize(l2); 12 | 13 | // // if different tails return 14 | // if (result1.tail != result2.tail) { 15 | // return null; 16 | // } 17 | 18 | // LinkedListNode shorter = result1.size < result2.size ? l1 : l2; 19 | // LinkedListNode longer = result1.size < result2.size ? l2 : l1; 20 | 21 | // // cut off diffence ie advance pointer of longer 22 | // longer = getKthNode(longer, Math.abs(result1.size - result2.size)); 23 | 24 | // while (shorter != longer) { 25 | // shorter = shorter.next; 26 | // longer = longer.next; 27 | // } 28 | 29 | // return shorter; 30 | // } 31 | 32 | // Result getTailAndSize(LinkedListNode l) { 33 | // if (l == null) return null; 34 | 35 | // int size = 1; 36 | // LinkedListNode current = l; 37 | 38 | // while (current.next != null) { 39 | // size++; 40 | // current = current.next; 41 | // } 42 | // return new Result(tail, size); 43 | // } 44 | 45 | // class Result { 46 | // public LinkedListNode tail; 47 | // public int size; 48 | // public Result(LinkedListNode tail, int size) { 49 | // this.tail = tail; 50 | // this.size = size; 51 | // } 52 | // } -------------------------------------------------------------------------------- /java/ctci/src/recursion/factorial.java: -------------------------------------------------------------------------------- 1 | package recursion; 2 | 3 | public class factorial { 4 | 5 | // private int n; 6 | // public factorial(int n) { 7 | // this.n = n; 8 | // } 9 | 10 | public int result(final int n) { 11 | if (n == 0) return 1; 12 | return n * result(n - 1); 13 | } 14 | 15 | public static void main(final String[] args) { 16 | final factorial fact = new factorial(); 17 | 18 | System.out.println(fact.result(5)); 19 | } 20 | } -------------------------------------------------------------------------------- /java/ctci/src/recursion/permutation.java: -------------------------------------------------------------------------------- 1 | package recursion; 2 | 3 | public class permutation { 4 | public permutation (String data) { 5 | helper("", data); 6 | } 7 | 8 | public void helper(String perm, String data) { 9 | if (data.length() == 0) System.out.println(perm); 10 | else { 11 | for (int i = 0; i < data.length(); i++) { 12 | char at = data.charAt(i); 13 | String rem = data.substring(0, i) + data.substring(i+1); 14 | String sum = perm + at; 15 | helper(sum, rem); 16 | } 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | permutation test = new permutation("abc"); 22 | System.out.print(test); 23 | } 24 | } -------------------------------------------------------------------------------- /java/ctci/src/recursion/rotation.java: -------------------------------------------------------------------------------- 1 | package recursion; 2 | 3 | public class rotation { 4 | boolean isRotation(String s1, String s2) { 5 | int len = s1.length(); 6 | /* Check that s1 and s2 are equal length and not empty */ 7 | if (len == s2.length() && len> 8) { 8 | /* Concatenate 51 and sl within new buffer */ 9 | String s1s1 = s1 + s1; 10 | return isSubstring(s1s1, s2); 11 | } 12 | return false; 13 | } 14 | 15 | boolean isSubstring(String s1, String s2) { 16 | if (s1.length() < s2.length()) return false; 17 | // place s1 in hashtable with letter counts 18 | // loop through s2 and check if in s1 19 | return true; 20 | } 21 | } -------------------------------------------------------------------------------- /java/ctci/src/recursion/subsequence.java: -------------------------------------------------------------------------------- 1 | package recursion; 2 | 3 | public class subsequence { 4 | public subsequence (String data) { 5 | helper("", data); 6 | } 7 | 8 | public void helper(String perm, String data) { 9 | System.out.println(perm); 10 | if (data.length() == 0) return; 11 | else { 12 | for (int i = 0; i < data.length(); i++) { 13 | char at = data.charAt(i); 14 | String rem = data.substring(i+1); 15 | String sum = perm + at; 16 | helper(sum, rem); 17 | } 18 | } 19 | } 20 | 21 | public static void main(String[] args) { 22 | subsequence test = new subsequence("abcd"); 23 | System.out.print(test); 24 | } 25 | } -------------------------------------------------------------------------------- /java/ctci/src/sort/Merge.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import Library.Util; 4 | 5 | public class Merge { 6 | private static void merge(int[] a, int[] aux, int lo, int mid, int hi) { 7 | // copy a into aux 8 | for (int k = lo; k <= hi; k++) { 9 | aux[k] = a[k]; 10 | } 11 | 12 | int i = lo, j = mid + 1; 13 | 14 | for (int k = lo; k <= hi; k++) { 15 | if (i > mid) { 16 | a[k] = aux[j++]; 17 | } else if (j > hi) { 18 | a[k] = aux[i++]; 19 | } else if (Util.less(aux[i], aux[j]) > 0) { 20 | a[k] = aux[i++]; 21 | } else { 22 | a[k] = aux[j++]; 23 | } 24 | } 25 | } 26 | 27 | private static void sort(final int[] data, int[] aux, int lo, int hi) { 28 | // divide and conquer 29 | // divide in 2, sort left, sort right and merge 30 | if (hi <= lo) return; 31 | 32 | int mid = lo + (hi - lo) / 2; 33 | sort(data, aux, lo, mid); 34 | sort(data, aux, mid + 1, hi); 35 | merge(data, aux, lo, mid, hi); 36 | } 37 | 38 | private static void sort2(int[] data, int[] aux) { 39 | int N = data.length; 40 | for (int sz = 1; sz < N; sz += sz) { // O(log N) 41 | for (int lo = 0; lo <= N - sz; lo += sz + sz) { // O(log N/2) 42 | merge(data, aux, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N - 1)); 43 | } 44 | } 45 | } 46 | 47 | public static void main(String[] args) { 48 | int[] data = Util.randomIntArray(); 49 | int N = data.length; 50 | int[] aux = new int[N]; 51 | 52 | Merge.sort(data, aux, 0, N - 1); 53 | 54 | System.out.println("Recursive sort"); 55 | 56 | for (int i = 0; i < N; i++) { 57 | System.out.print(data[i] + " "); 58 | } 59 | System.out.println("----------------"); 60 | 61 | // bottom-up merge sort 62 | data = Util.randomIntArray(); 63 | N = data.length; 64 | aux = new int[N]; 65 | 66 | Merge.sort2(data, aux); 67 | 68 | System.out.println("Iterative sort"); 69 | 70 | for (int i = 0; i < N; i++) { 71 | System.out.print(data[i] + " "); 72 | } 73 | System.out.println("----------------"); 74 | } 75 | } -------------------------------------------------------------------------------- /java/ctci/src/sort/Quick.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import java.util.Random; 4 | import Library.Util; 5 | 6 | public class Quick { 7 | 8 | private static int[] shuffle(final int[] data) { 9 | final Random rand = new Random(); 10 | final int N = data.length; 11 | for (int i = 0; i < N; i++) { 12 | // obtain random num between i and N; rand.nextInt((max - min) + 1) + min 13 | final int ran = rand.nextInt(N - i) + i; 14 | final int temp = data[i]; 15 | data[i] = data[ran]; 16 | data[ran] = temp; 17 | } 18 | return data; 19 | } 20 | 21 | /** 22 | * @param data 23 | * @param lo 24 | * @param hi 25 | * @return the partition element correct position 26 | */ 27 | 28 | public int partition(final int[] data, final int lo, final int hi) { 29 | final int k = data[lo]; 30 | int i = lo, j = hi + 1; 31 | 32 | while (true) { 33 | // find item on left greater than k 34 | while (Util.less(data[++i], k) > 0) { 35 | if (i == hi) break; 36 | } 37 | // find item on right less than k 38 | while (Util.less(data[--j], k) <= 0) { 39 | if (j == lo) break; 40 | } 41 | 42 | if (i >= j) { 43 | break; 44 | } 45 | Util.exch(data, i, j); 46 | } 47 | 48 | // swap with partition item 49 | Util.exch(data, lo, j); 50 | 51 | return j; 52 | } 53 | 54 | /** 55 | * recursively partitions the data using divide and conquer 56 | * @param data 57 | * @param lo 58 | * @param hi 59 | */ 60 | private void sort(final int[] data, final int lo, final int hi) { 61 | if (lo >= hi) return; 62 | final int j = partition(data, lo, hi); 63 | sort(data, lo, j); 64 | sort(data, j + 1, hi); 65 | } 66 | 67 | public void sort(int[] data) { 68 | // shuffle data 69 | data = shuffle(data); 70 | sort(data, 0, data.length - 1); 71 | } 72 | 73 | public static void main(final String[] args) { 74 | final Random rand = new Random(); 75 | final int N = rand.nextInt(10); 76 | final int[] data = new int[N]; 77 | 78 | for (int i = 0; i < N; i++) { 79 | data[i] = rand.nextInt(1000); 80 | } 81 | 82 | final Quick quick = new Quick(); 83 | 84 | quick.sort(data); 85 | 86 | System.out.println("Recursive quick sort"); 87 | 88 | for (int i = 0; i < N; i++) { 89 | System.out.print(data[i] + " "); 90 | } 91 | System.out.println(); 92 | } 93 | } -------------------------------------------------------------------------------- /java/ctci/src/sort/insertion.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import Library.Util; 4 | // compares the current idx with the previous items and moves it till it gets to min o(N2) 5 | public class insertion { 6 | 7 | public insertion(final double[] data) { 8 | final double[] res = sort(data); 9 | for (final double i : res) { 10 | System.out.println(i + " "); 11 | } 12 | System.out.println(); 13 | } 14 | 15 | double[] sort(final double[] data) { 16 | for (int i = 1; i < data.length; i++) { 17 | for (int j = i; j > 0; j--) { 18 | if (Util.less(data[j], data[j - 1]) > 19 | 0) { // if data is less than or equal curData 20 | Util.exch(data, j, j - 1); 21 | } 22 | } 23 | } 24 | return data; 25 | } 26 | 27 | public static void main(final String[] args) { 28 | final double[] data = Util.randomDoubleArray(); 29 | new insertion(data); 30 | } 31 | } -------------------------------------------------------------------------------- /java/ctci/src/sort/selection.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import Library.Util; 4 | 5 | // compare the current idx with further items and select the minimum, and 6 | // exchange. ~ O(N2) 7 | public class selection { 8 | 9 | public selection(final double[] data) { 10 | final double[] res = sort(data); 11 | for (final double i : res) { 12 | System.out.println(i + " "); 13 | } 14 | System.out.println(); 15 | } 16 | 17 | double[] sort(final double[] data) { 18 | for (int i = 0; i < data.length; i++) { 19 | int min = i; 20 | for (int j = i + 1; j < data.length; j++) { 21 | if (Util.less(data[j], data[i]) > 22 | 0) { // if data is less than or equal curData 23 | min = j; 24 | } 25 | } 26 | Util.exch(data, i, min); 27 | } 28 | return data; 29 | } 30 | 31 | public static void main(final String[] args) { 32 | final double[] data = Util.randomDoubleArray(); 33 | new insertion(data); 34 | } 35 | } -------------------------------------------------------------------------------- /java/ctci/src/sort/shell.java: -------------------------------------------------------------------------------- 1 | package sort; 2 | 3 | import Library.Util; 4 | // selection sort going back h times at a time; O(N2) worst case 5 | public class shell { 6 | 7 | public shell(final double[] data) { 8 | final double[] res = sort(data); 9 | for (final double i : res) { 10 | System.out.println(i + " "); 11 | } 12 | System.out.println(); 13 | } 14 | 15 | double[] sort(final double[] data) { 16 | // obtain h sequence, starting from the largest within the file using 3h + 17 | // 1:Knuth formular 18 | int h = 1, N = data.length; 19 | while (h < N / 3) h = 3 * h + 1; 20 | 21 | while (h >= 1) { // while the sorting sequence still holds 22 | for (int i = h; i < N; i++) { 23 | for (int j = i; j >= h; j -= h) { // go back h spaces 24 | if (Util.less(data[j], data[j - h]) > 25 | 0) { // if data is less than or equal curData 26 | Util.exch(data, j, j - h); 27 | } 28 | } 29 | } 30 | h = h / 3; // reduce h 31 | } 32 | return data; 33 | } 34 | 35 | public static void main(final String[] args) { 36 | final double[] data = Util.randomDoubleArray(); 37 | new shell(data); 38 | } 39 | } -------------------------------------------------------------------------------- /java/ctci/src/stacks/MinStack.java: -------------------------------------------------------------------------------- 1 | package stacks; 2 | import static org.junit.Assert.assertEquals; 3 | 4 | /** 5 | * Design a stack, that in addition to push and pop has a function, Min, that 6 | * returns the min element in the stack. All operations should be O(1); 7 | */ 8 | import java.util.*; 9 | 10 | import org.junit.Test; 11 | public class MinStack { 12 | private int min; 13 | Stack stack; 14 | 15 | public MinStack() { 16 | stack = new Stack<>(); 17 | min = Integer.MAX_VALUE; 18 | } 19 | 20 | /** 21 | * SOLUTION: Each time we want to push a value that is less than min, we push 22 | * the previous min and then the value. 23 | * Such that, when we want to pop a min value, we pop twice. The first time to 24 | * get the actual value to be returned and the second, to get the old Min 25 | * value; 26 | */ 27 | 28 | public int pop() { 29 | if (stack.isEmpty()) throw new EmptyStackException(); 30 | int cur = stack.pop(); 31 | if (cur == min) { 32 | min = stack.pop(); 33 | } 34 | return cur; 35 | } 36 | 37 | public void push(int value) { 38 | if (value < min) { 39 | stack.push(min); 40 | min = value; 41 | } 42 | stack.push(value); 43 | } 44 | 45 | public int min() { 46 | if (stack.isEmpty()) return Integer.MAX_VALUE; 47 | return min; 48 | } 49 | 50 | @Test 51 | public static void main(String[] args) { 52 | MinStack stack = new MinStack(); 53 | stack.push(1); 54 | stack.push(2); 55 | assertEquals("min should be 1", 1, stack.min()); 56 | stack.push(-1); 57 | assertEquals("min should be -1", -1, stack.min()); 58 | assertEquals("pop should be -1", -1, stack.pop()); 59 | assertEquals("min should be 1", 1, stack.min()); 60 | stack.push(-2); 61 | assertEquals("min should be -2", -2, stack.min()); 62 | assertEquals("pop should be -2", -2, stack.pop()); 63 | assertEquals("min should be 1", 1, stack.min()); 64 | } 65 | } -------------------------------------------------------------------------------- /java/easy/DecodeRunLength.java: -------------------------------------------------------------------------------- 1 | package easy; 2 | 3 | import java.util.*; 4 | public class DecodeRunLength { 5 | public static int[] solve(int[] nums) { 6 | ArrayList res = new ArrayList<>(); 7 | 8 | for (int i = 2; i < nums.length; i += 2) { 9 | for (int count = 0; count < nums[i - 1]; count++) { 10 | res.add(nums[i]); 11 | } 12 | } 13 | int[] ret = new int[res.size()]; 14 | 15 | for (int i =0; i < res.size(); i++) { 16 | ret[i] = res.get(i); 17 | } 18 | 19 | return ret; 20 | } 21 | } -------------------------------------------------------------------------------- /java/easy/firstUnique.java: -------------------------------------------------------------------------------- 1 | package easy; 2 | 3 | import java.util.*; 4 | 5 | class firstUnique { 6 | // O(N) time and space 7 | static public int firstUniqueCharacter(String s) { 8 | HashMap freq = new HashMap<>(); 9 | 10 | // count freq 11 | for(int i = 0; i < s.length(); i++) { 12 | char val = s.charAt(i); 13 | Integer count = freq.get(val); 14 | if (count == null) { 15 | freq.put(val, 1); 16 | } else { 17 | freq.put(val, count + 1); 18 | } 19 | } 20 | 21 | // check string 22 | for (int i = 0; i < s.length(); i++) { 23 | if (freq.get(s.charAt(i)) == 1) return i; 24 | } 25 | return -1; 26 | } 27 | 28 | public static void main(String args[] ) { 29 | System.out.println(firstUnique.firstUniqueCharacter("loveleetcode")); 30 | } 31 | } 32 | 33 | 34 | 35 | /** 36 | #### First Unique Character in a String 37 | 38 | Given a string, find the first non-repeating character in it and return its index. 39 | If it doesn't exist, return -1. 40 | 41 | Examples: 42 | s = "leetcode" 43 | return 0. 44 | 45 | s = "loveleetcode" 46 | return 2. 47 | 48 | 49 | 50 | index = -1; 51 | count = 0; 52 | looping the string 53 | 54 | 55 | 56 | dict = { l: 1, e: 3, t: 1, c: 1, o: 1, d: 1} O(N) O(N) 57 | 58 | 59 | for(int i=0; i < s.length; i++) { O(N) time complexity 60 | if (dict.get(s[i]) == 1) return i; O(1) 61 | } 62 | return -1; 63 | 64 | O(N) time and O(N) 65 | 66 | 67 | { 68 | l: 1, e: 3, t: 1, c: 1, o: 1, d: 1 69 | } 70 | 71 | 72 | */ -------------------------------------------------------------------------------- /java/easy/flattenDictionary.java: -------------------------------------------------------------------------------- 1 | package easy; 2 | 3 | import java.util.*; 4 | 5 | class flattenDictionary { 6 | 7 | static HashMap solution(HashMap dict) { 8 | // your code goes here 9 | HashMap result = new HashMap<>(); 10 | flatten(dict, "", result); 11 | return result; 12 | } 13 | 14 | private static void flatten(HashMap subDict, String parentKey, HashMap result) { 15 | for (String el : subDict.keySet()) { 16 | String key = el; 17 | if (!parentKey.equals("") && parentKey != null) { 18 | if (el == "") { 19 | key = parentKey; 20 | } else { 21 | key = new StringBuilder(parentKey).append(".").append(el).toString(); 22 | } 23 | } 24 | 25 | if (subDict.get(el) instanceof String) { 26 | result.put(key, subDict.get(el).toString()); 27 | } else { 28 | flatten((HashMap) subDict.get(el), key, result); 29 | } 30 | } 31 | } 32 | 33 | public static void main(String[] args) { 34 | HashMap f = new HashMap<>(); 35 | f.put("", "awesome"); 36 | HashMap e = new HashMap<>(); 37 | e.put("f", f); 38 | HashMap d = new HashMap<>(); 39 | d.put("e", e); 40 | HashMap c = new HashMap<>(); 41 | c.put("d", d); 42 | HashMap b = new HashMap<>(); 43 | b.put("c", c); 44 | HashMap a = new HashMap<>(); 45 | a.put("b", b); 46 | HashMap dict = new HashMap<>(); 47 | dict.put("a", a); 48 | HashMap res = flattenDictionary.solution(dict); 49 | 50 | for (String string : res.keySet()) { 51 | System.out.println(string + " : " + res.get(string)); 52 | } 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /java/google/CompareStrings.java: -------------------------------------------------------------------------------- 1 | package google; 2 | 3 | /* 4 | https://leetcode.com/discuss/interview-question/352458/ 5 | SEE QUESTION ON LINE 71 6 | */ 7 | 8 | import java.util.*; 9 | 10 | public class CompareStrings { 11 | public static int[] compare(final String A, final String B) { 12 | if (A.length() < 1 || B.length() < 1) 13 | return new int[0]; 14 | 15 | final String[] A_arr = A.split(" "); 16 | final String[] B_arr = B.split(" "); 17 | final int[] C_arr = new int[B_arr.length]; 18 | 19 | final int[] A_help = new int[A_arr.length]; 20 | // O(M) 21 | for (int j = 0; j < A_arr.length; j++) { 22 | A_help[j] = getMin(A_arr[j]); 23 | } 24 | // O(NM) 25 | // A = "abcd aabc bd" 26 | // B = "aaa aa" 27 | 28 | for (int i = 0; i < B_arr.length; i++) { 29 | int count = 0; 30 | final int b_min = getMin(B_arr[i]); 31 | 32 | for (int j = 0; j < A_help.length; j++) { 33 | if (A_help[j] < b_min) { 34 | count += 1; 35 | } 36 | } 37 | 38 | C_arr[i] = count; 39 | } 40 | return C_arr; 41 | } 42 | 43 | private static int getMin(final String str) { 44 | // returns the freq of min element in a string 45 | final int[] freqArr = new int[26]; 46 | 47 | // create a char count for string 48 | for (int i = 0; i < str.length(); i++) { 49 | freqArr[str.charAt(i) - 'a'] += 1; 50 | } 51 | 52 | // get the first char that has a count greater than 0 ie the min count 53 | for (final int count : freqArr) { 54 | if (count > 0) { 55 | return count; 56 | } 57 | } 58 | 59 | return -1; 60 | } 61 | 62 | public static void main(final String[] args) { 63 | final String A = "abcd aabc bd"; 64 | final String B = "aaa"; 65 | 66 | System.out.println(Arrays.toString(CompareStrings.compare(A, B))); 67 | } 68 | } 69 | 70 | /* 71 | One string is strictly smaller than another when the frequency of 72 | occurrence of the smallest character in the string is less than the 73 | frequency of occurrence of the smallest character in the comparison string. 74 | 75 | For example, string "abcd" is smaller than string "aaa" because the 76 | smallest character in lexicographical order) in "abcd" is 'a', with a 77 | frequency of 1, and the smallest character in "aaa" is also 'a', 78 | but with a frequency of 3. 79 | 80 | In another example, string "a" is smaller than string "bb" because 81 | the smallest character in "a" is 'a' with a frequency of 1, and the 82 | smallest character in "bb" is 'b' with a frequency of 2. 83 | 84 | Write a function that, given string A (which contains M strings delimited by ',') 85 | and string B (which contains N strings delimited by','), 86 | returns an array C of N integers. For O<=J queue = new LinkedList<>(); 30 | queue.add(root); 31 | 32 | while (!queue.isEmpty()) { 33 | 34 | int sum = 0; 35 | level++; 36 | int size = queue.size(); 37 | for (int i = 0; i < size; i++) { 38 | // process the children of the queue 39 | TreeNode cur = queue.poll(); // 1 40 | 41 | if (cur.left != null) { 42 | queue.add(cur.left); 43 | sum += cur.left.val; 44 | } 45 | 46 | if (cur.right != null) { 47 | queue.add(cur.right); 48 | sum += cur.right.val; 49 | } 50 | } 51 | // increment the max if maxSum seen is greater than the current max sum; 52 | if (sum > maxSum) { 53 | maxSum = sum; 54 | res = level; 55 | } 56 | } 57 | return res; 58 | } 59 | } 60 | 61 | /* 62 | 63 | Given the root of a binary tree, the level of its root is 1, the level of its 64 | children is 2, and so on. 65 | 66 | Return the smallest level X such that the sum of all the values of nodes at 67 | level X is maximal. 68 | 69 | 1 70 | / \ 71 | 7 0 72 | / \ 73 | 7 -8 74 | 75 | Example 1: 76 | 77 | Input: [1,7,0,7,-8,null,null] 78 | Output: 2 79 | Explanation: 80 | Level 1 sum = 1. 81 | Level 2 sum = 7 + 0 = 7. 82 | Level 3 sum = 7 + -8 = -1. 83 | So we return the level with the maximum sum which is level 2. 84 | 85 | The number of nodes in the given tree is between 1 and 10^4. 86 | -10^5 <= node.val <= 10^5 87 | 88 | */ -------------------------------------------------------------------------------- /java/google/MostBookedRoom.java: -------------------------------------------------------------------------------- 1 | package google; 2 | 3 | /** 4 | Given a hotel which has 10 floors [0-9] and each floor has 26 rooms [A-Z]. 5 | You are given a sequence of rooms, where + suggests room is booked, - room is 6 | freed. 7 | You have to find which room is booked maximum number of times. 8 | You may assume that the list describe a correct sequence of bookings in 9 | chronological order; 10 | that is, only free rooms can be booked and only booked rooms can be freeed. All 11 | rooms are initially free. 12 | Note that this does not mean that all rooms have to be free at the end. 13 | In case, 2 rooms have been booked the same number of times, return the 14 | lexographically smaller room. 15 | 16 | You may assume: 17 | N (length of input) is an integer within the range [1, 600] 18 | each element of array A is a string consisting of three characters: "+" or "-"; 19 | a digit "0"-"9"; 20 | and uppercase English letter "A" - "Z", the sequence is correct. 21 | That is every booked room was previously free and every freed room was 22 | previously booked. 23 | Example: 24 | Input: ["+1A", "+3E", "-1A", "+4F", "+1A", "-3E"] 25 | Output: "1A" 26 | Explanation: 1A as it has been booked 2 times. 27 | */ 28 | import java.util.*; 29 | 30 | public class MostBookedRoom { 31 | public static String mostBookedHotelRoom(String[] roomActivity) { 32 | // this is constant space, it will never be greater than 260 33 | HashMap roomFreq = new HashMap<>(); 34 | 35 | int min = Integer.MAX_VALUE; 36 | String mostBookedRoom = ""; 37 | for (String el : roomActivity) { 38 | // we only keep track of booked times. 39 | // if a booking activity 40 | if (el.charAt(0) == '+') { 41 | String room = el.substring(1); 42 | int freq = roomFreq.getOrDefault(room, 0) + 1; 43 | roomFreq.put(room, freq); 44 | if (freq < min) { 45 | min = freq; 46 | mostBookedRoom = room; 47 | } else if (freq == min) { 48 | mostBookedRoom = compareRoom(mostBookedRoom, room); 49 | } 50 | } 51 | } 52 | return mostBookedRoom; 53 | } 54 | 55 | private static String compareRoom(String room1, String room2) { 56 | // when room 1 is smaller 57 | if (room1.compareTo(room2) <= 0) { 58 | return room1; 59 | } 60 | return room2; 61 | } 62 | 63 | public static void main(String[] args) { 64 | String[] books1 = { "+1A", "+3E", "-1A", "+4F", "+1A", "-3E", "+1A", "-1A", "+1A" }; 65 | String[] books2 = {"+1E", "-1E", "+1E", "-1E", "+1E", "-1E", "+1E", "-1E","+2A", "-2A", "+2A", "-2A", "+2A", "-2A", "+2A", 66 | "-2A","+2B", "-2B", "+2B", "-2B", "+2B", "-2B", "+2B", "-2B"}; 67 | System.out.println(MostBookedRoom.mostBookedHotelRoom(books1)); //1A 68 | System.out.println(MostBookedRoom.mostBookedHotelRoom(books2)); //1B 69 | } 70 | } 71 | /** 72 | 73 | { 1A : 2, 3E: 1, 4F: 1 } 74 | // go through the rooms and add the frequency of their of their bookings to a 75 | map 76 | // keep track of the smaller room 77 | */ -------------------------------------------------------------------------------- /java/google/TimeToTypeString.java: -------------------------------------------------------------------------------- 1 | package google; 2 | 3 | /** SEE QUESTION ON LINE 38 */ 4 | 5 | public class TimeToTypeString { 6 | public static int calculateTimeTaken(String kb, String text) { 7 | if (kb.length() == 0 || text.length() == 0) { 8 | return 0; 9 | } 10 | 11 | // store the index of the the keyboard characters 12 | int[] positions = buildPosition(kb); 13 | int totaltime = positions[text.charAt(0) - 'a']; 14 | 15 | for (int i = 0; i < text.length() - 1; i++) { 16 | // get diff between prev char position and next char position 17 | int index_i = positions[text.charAt(i) - 'a']; 18 | int index_j = positions[text.charAt(i + 1) - 'a']; 19 | totaltime += Math.abs(index_j - index_i); 20 | } 21 | 22 | return totaltime; 23 | } 24 | private static int[] buildPosition(String kb) { 25 | int[] positions = new int[26]; 26 | for (int i = 0; i < 26; i++) { 27 | positions[kb.charAt(i) - 'a'] = i; 28 | } 29 | return positions; 30 | } 31 | 32 | public static void name() { 33 | String kb = "abcdefghijklmnopqrstuvwxy"; 34 | String text = "yay"; 35 | int result = TimeToTypeString.calculateTimeTaken(kb,text); 36 | System.out.println("Print total time taken: " + result); 37 | } 38 | } 39 | /* 40 | Imagine you have a special keyboard with all keys in a single row. 41 | The layout of characters on a keyboard is denoted by a string keyboard of 42 | length 26. 43 | Initially your finger is at index 0. To type a character, you have to move 44 | your finger to the index of the desired character. 45 | The time taken to move your finger from index i to index j is abs(j - i). 46 | 47 | Given a string keyboard that describe the keyboard layout and a string text, 48 | return an integer denoting the time taken to type string text. 49 | 50 | Example 1: 51 | 52 | Input: keyboard = "abcdefghijklmnopqrstuvwxy", text = "yay" 53 | Output: 4 54 | Explanation: 55 | Initially your finger is at index 0. First you have to type 'c'. 56 | The time taken to type 'c' will be abs(2 - 0) = 2 because character 'c' is at 57 | index 2. 58 | The second character is 'b' and your finger is now at index 2. 59 | The time taken to type 'b' will be abs(1 - 2) = 1 because character 'b' is at 60 | index 1. 61 | The third character is 'a' and your finger is now at index 1. 62 | The time taken to type 'a' will be abs(0 - 1) = 1 because character 'a' is at 63 | index 0. 64 | The total time will therefore be 2 + 1 + 1 = 4. 65 | 66 | Constraints: 67 | 68 | length of keyboard will be equal to 26 and all the lowercase letters will 69 | occur exactly once; 70 | the length of text is within the range [1..100,000]; 71 | string text contains only lowercase letters [a-z]. 72 | 73 | string - 26 chars 74 | start = 0 75 | sum = 0 + 2 + 1 + 1 = 4 76 | 2 1 0 77 | c b a 78 | 79 | */ -------------------------------------------------------------------------------- /java/google/allocation.java: -------------------------------------------------------------------------------- 1 | package google; 2 | 3 | import java.util.Scanner; 4 | // new BufferedReader(new InputStreamReader(System.in) 5 | 6 | /** 7 | * allocation... this uses min heap principle 8 | */ 9 | public class allocation { 10 | private int[] data; 11 | private int N; 12 | 13 | public allocation(int cap) { data = new int[cap + 1]; } 14 | 15 | private void swim(int k) { 16 | while (k > 1 && greater(k / 2, k)) { 17 | exch(k, k / 2); 18 | k = k / 2; 19 | } 20 | } 21 | 22 | private void sink(int k) { 23 | while (2 * k <= N) { 24 | int j = 2 * k; 25 | if (j < N && greater(j, j + 1)) 26 | j++; 27 | if (!greater(k, j)) 28 | break; 29 | exch(k, j); 30 | k = j; 31 | } 32 | } 33 | 34 | private boolean greater(int i, int j) { return data[i] > data[j]; } 35 | 36 | private void exch(int i, int j) { 37 | int temp = data[i]; 38 | data[i] = data[j]; 39 | data[j] = temp; 40 | } 41 | 42 | public void insert(int el) { 43 | data[++N] = el; 44 | swim(N); 45 | } 46 | 47 | public int delMin() { 48 | int min = data[1]; 49 | exch(1, N--); 50 | sink(1); 51 | data[N + 1] = 0; 52 | return min; 53 | } 54 | 55 | public static void main(String[] args) { 56 | Scanner scan = new Scanner(System.in); 57 | int testsNo = Integer.parseInt(scan.nextLine()); 58 | for (int i = 0; i < testsNo; i++) { 59 | int arrLength = scan.nextInt(); 60 | int budget = scan.nextInt(); 61 | allocation test = new allocation(arrLength); 62 | for (int j = 0; j < arrLength; j++) { 63 | int next = scan.nextInt(); 64 | test.insert(next); 65 | } 66 | int total = 0, count = 0; 67 | while (total < budget && arrLength-- > 0) { 68 | int min = test.delMin(); 69 | total += min; 70 | if (total > budget) break; 71 | count++; 72 | } 73 | 74 | System.out.printf("Case #%s: %s %n", i+1, count); 75 | } 76 | scan.close(); 77 | } 78 | } -------------------------------------------------------------------------------- /java/google/countdown.java: -------------------------------------------------------------------------------- 1 | package google; 2 | 3 | import java.util.*; 4 | 5 | public class countdown { 6 | public int solve(int[] arr, int k) { 7 | int i = 0, count = 0; 8 | while (i <= arr.length - k) { 9 | if (arr[i] == k) { 10 | boolean valid = true; 11 | for (int j = 0; j < k - 1; j++) { 12 | if (arr[i + 1] != arr[i] - 1) { 13 | valid = false; 14 | break; 15 | } 16 | i++; 17 | } 18 | if (valid) { 19 | count++; 20 | } 21 | } 22 | i++; 23 | } 24 | return count; 25 | } 26 | 27 | // keep a decreasing counter and restart the counter each time the countdown 28 | // is incorrect 29 | public int solve2(int[] arr, int k) { 30 | int counter = 0, res = 0; 31 | for (int i = 1; i < arr.length; i++) { 32 | if (arr[i] == arr[i - 1] - 1) { 33 | counter++; 34 | } else { 35 | counter = 0; 36 | } 37 | if (arr[i] == 1 && counter >= k - 1) { 38 | res++; 39 | } 40 | } 41 | return res; 42 | } 43 | public static void main(String[] args) { 44 | 45 | Scanner scan = new Scanner(System.in); 46 | int testsNo = Integer.parseInt(scan.nextLine()); 47 | for (int i = 0; i < testsNo; i++) { 48 | int arrLength = scan.nextInt(); 49 | int K = scan.nextInt(); 50 | countdown test = new countdown(); 51 | int[] input = new int[arrLength]; 52 | for (int j = 0; j < arrLength; j++) { 53 | int next = scan.nextInt(); 54 | input[j] = next; 55 | } 56 | int count = test.solve(input, K); 57 | 58 | System.out.printf("Case #%s: %s %n", i + 1, count); 59 | } 60 | scan.close(); 61 | } 62 | } -------------------------------------------------------------------------------- /java/google/largestSubArray.java: -------------------------------------------------------------------------------- 1 | package google; 2 | /** 3 | Write a function that given a zero-indexed array of length N, 4 | returns the largest contiguous subarray of length K. 5 | Eg: 6 | Input: [1, 4, 3, 2, 5] k = 4 7 | Output; [4, 3, 2, 5], largest subarray of length 4 8 | 1 <= k <=N <= 100 9 | 1 <= a[j] <= 1000; 10 | assume the elements are all unique; 11 | 12 | FOLLOW-UP: What if the elements aren't unique? 13 | */ 14 | public class largestSubArray { 15 | /** 16 | * Here, we are told the elements are unique 17 | * @param arr 18 | * @return Integer[] 19 | */ 20 | public static int[] solve(int[] arr, int k) { 21 | // simply find the index of the largest element that allows for subarray of 22 | // K 23 | // there cant be a subarray of length k if the arr length is less than k 24 | int N = arr.length; 25 | if (arr == null || N < k) 26 | return null; 27 | 28 | if (N == k) 29 | return arr; 30 | 31 | int[] res = new int[k]; 32 | int minIndex = 0; 33 | 34 | for (int i = 1; i <= N - k; ++i) { 35 | if (arr[minIndex] < arr[i]) 36 | minIndex = i; 37 | } 38 | System.arraycopy(arr, minIndex, res, 0, k); 39 | 40 | return res; 41 | } 42 | 43 | /** 44 | * 45 | * @param arr 46 | * @param k 47 | * @return 48 | */ 49 | public static int[] solveNotUnique(int[] arr, int k) { 50 | // there cant be a subarray of length k if the arr length is less than k 51 | int N = arr.length; 52 | if (arr == null || N < k) 53 | return null; 54 | 55 | if (N == k) 56 | return arr; 57 | 58 | int[] res = new int[k]; 59 | int minIndex = 0; 60 | 61 | for (int i = 1; i <= N - k; ++i) { 62 | // compare the k elements 63 | for (int j = 0; j < k; ++j) { 64 | if (arr[minIndex + j] > arr[i + j]) 65 | break; 66 | if (arr[minIndex + j] < arr[i + j]) { 67 | minIndex = i; 68 | break; 69 | } 70 | // if equal continue comparing 71 | } 72 | } 73 | System.arraycopy(arr, minIndex, res, 0, k); 74 | 75 | return res; 76 | } 77 | } 78 | /** 79 | Write a function that given a zero-indexed array of length N, 80 | returns the largest contiguous subarray of length K. 81 | Eg: 82 | Input: [1, 4, 3, 2, 5] k = 4 83 | Output; [4, 3, 2, 5], largest subarray of length 4 84 | 1 <= k <=N <= 100 85 | 1 <= a[j] <= 1000; distinct 86 | 87 | Compare the first non-matching index values, the one with the greater value is 88 | the bigger array 89 | 90 | Input: [1, 4, 3, 2, 5] k = 4 91 | Output; [4, 3, 2, 5], largest subarray of length 4 92 | 1 <= k <=N <= 100 93 | 1 <= a[j] <= 1000; distinct 94 | 95 | => if len < k || arr == null return null; 96 | => if the arr.len = k, return System.copy(arr, 0, res, 0, 4) // copy the arry 97 | 0 1 2 3 4 5 98 | [1, 4, 3, 2, 5, 6] minIdx = 1 99 | ^ 100 | SOLUTION 101 | # find the max element in the array, from 0 to N - k 102 | # return the k elements starting from there 103 | 104 | Public int[] largestSubarray(int[] arr, int k) { 105 | // there cant be a subarray of length k if the arr length is less than k 106 | Int N = arr.length; 107 | If (arr == null || N < k) return null; 108 | 109 | If (N == k) { 110 | Return arr; 111 | } 112 | Int res = new int[k]; 113 | Int minIndex = 0; 114 | For (int i = 1; i <= N - k; ++i) { 115 | If (arr[minIndex] < arr[i]) minIndex = i; 116 | } 117 | System.arraycopy(arr, minIndex, res, 0, k); 118 | Return res; 119 | } 120 | 121 | FOLLOW-UP: What if the elements were not unique? 122 | Int[] idxs=[0, 2] 123 | x=2 i=1 124 | [4, 2, 4, 1, 5, 6] 125 | ^ 126 | // loop through k times, 127 | // compare the indexes and keep track of the array idx with max value 128 | i=1 129 | [4, 2, 4, 1] 130 | [4, 1, 5, 6] 131 | 132 | */ -------------------------------------------------------------------------------- /java/google/questions.md: -------------------------------------------------------------------------------- 1 | Stores and Houses (solved) 2 | Min Amplitude [New Grad] 🆕(solved) 3 | Compare Strings [Intern] (solved) 4 | Largest Subarray Length K ⭐⭐⭐[Intern] (solved) 5 | Maximum Time ⭐⭐⭐ [Intern] (Solved) 6 | Min Abs Difference of Server Loads ⭐ [Intern] (Solved) 7 | Most Booked Hotel Room ⭐⭐⭐ [Intern] (Solved) 8 | Watering Flowers [New Grad] (Solved) 9 | Minimum Domino Rotations For Equal Row [New Grad] 10 | Time to Type a String 11 | Maximum Level Sum of a Binary Tree 12 | Min Number of Chairs 13 | Hash(Set|Map) Implementation 14 | K Closest Points to Origin 15 | Odd Even Jump 16 | License Key Formatting 17 | Unique Email Addresses 18 | Fruit Into Baskets 19 | Min Days to Bloom 20 | Fill Matrix 21 | Decreasing Subsequences 22 | Max Distance 23 | Greatest Common Divisor 24 | Relative Sort 25 | Maximum Number of Strawberries 26 | Delayed Projects 27 | Min Cost to Keep Employees 28 | Statistics 29 | Pizza Shop 30 | Min Distance To The Farthest Node 31 | Cut The Cake 🆕 32 | Best Fruit 🆕 33 | Count pair of leaf nodes with specific distance 🆕 34 | Treasure Hunt 🆕 35 | Count Univalue Subtrees 🆕 -------------------------------------------------------------------------------- /java/hard/makePalindrome.java: -------------------------------------------------------------------------------- 1 | package hard; 2 | 3 | public class makePalindrome { 4 | public static int inMinWays(String s) { 5 | int N = s.length(); 6 | int[][] memo = new int[N][N]; 7 | for (int i = 0; i < N; i++) { 8 | for (int j = 0; j < N; j++) { 9 | memo[i][j] = -1; 10 | } 11 | } 12 | return inMinWaysHelper(s, 0, N - 1, memo); 13 | } 14 | 15 | private static int inMinWaysHelper(String s, int start, int end, int[][] memo) { 16 | if (start >= end) return 0; 17 | 18 | if (memo[start][end] > -1) { return memo[start][end]; } 19 | 20 | if (s.charAt(start) == s.charAt(end)) { 21 | memo[start][end] = inMinWaysHelper(s, start + 1, end - 1, memo); 22 | return memo[start][end]; 23 | } 24 | 25 | memo[start][end] = Math.min(inMinWaysHelper(s, start + 1, end, memo), inMinWaysHelper(s, start, end - 1, memo)) + 1; 26 | return memo[start][end]; 27 | } 28 | } -------------------------------------------------------------------------------- /java/medium/ArrayProducts.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | /** 3 | * Array of Array Products 4 | 5 | * Given an array of integers arr, you’re asked to calculate for each index i the product of all integers except the integer at that index (i.e. except arr[i]). Implement a function arrayOfArrayProducts that takes an array of integers and returns an array of the products. 6 | 7 | * Solve without using division and analyze your solution’s time and space complexities. 8 | 9 | * Examples: 10 | 11 | * input: arr = [8, 10, 2] 12 | * output: [20, 16, 80] # by calculating: [10*2, 8*2, 8*10] 13 | 14 | * input: arr = [2, 7, 3, 4] 15 | * output: [84, 24, 56, 42] # by calculating: [7*3*4, 2*3*4, 2*7*4, 2*7*3] 16 | 17 | */ 18 | 19 | public class ArrayProduct { 20 | public static int[] arrayProduct(int[] arr) { 21 | int N = arr.length; 22 | int[] leftThenRight = new int[N]; 23 | 24 | // find all left product 25 | int runningProduct = 1; 26 | for (int i = 0; i < N; i++) { 27 | leftThenRight[i] = runningProduct; 28 | runningProduct = runningProduct * arr[i]; 29 | } 30 | 31 | // multiply with right product 32 | runningProduct = 1; 33 | for (int i = N - 1; i >= 0; i++) { 34 | leftThenRight[i] = leftThenRight[i] * runningProduct; 35 | runningProduct = runningProduct * arr[i]; 36 | } 37 | } 38 | 39 | return leftThenRight; 40 | } -------------------------------------------------------------------------------- /java/medium/HuffmanDecoding.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | public class HuffmanDecoding { 4 | // private class Node { 5 | // int data; 6 | // Node left; 7 | // Node right; 8 | // int depth; 9 | 10 | // Node(final int data, final int depth) { 11 | // this.data = data; 12 | // this.depth = depth; 13 | // } 14 | // } 15 | public HuffmanDecoding(final String s, final Node root) { 16 | if (root == null) { 17 | System.out.print(""); 18 | return; 19 | } 20 | for (int i = 0; i < s.length();) { 21 | Node current = root; 22 | while (current.left != null || current.right != null) { 23 | final char bit = s.charAt(i++); 24 | if (bit == '1') 25 | current = current.right; 26 | else 27 | current = current.left; 28 | } 29 | System.out.print(current.data); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /java/medium/Itinerary.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | import java.util.HashMap; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.PriorityQueue; 8 | 9 | public class Itinerary { 10 | // priority queue takes care of the ordering 11 | Map> airports = new HashMap<>(); 12 | List route = new LinkedList<>(); 13 | 14 | public List itinerary(String[][] tickets) { 15 | // compute the airports and their destination 16 | for (String[] ticket : tickets) { 17 | // this basically says, if ticket[0] doesn't exist, create it and map to a 18 | // priority queue, add ticket[1] 19 | airports.computeIfAbsent(ticket[0], k -> new PriorityQueue<>()) 20 | .add(ticket[1]); 21 | } 22 | visit("JFK"); 23 | return route; 24 | } 25 | 26 | private void visit(String airport) { 27 | while (airports.containsKey(airport) && !airports.get(airport).isEmpty()) { 28 | // poll means the first element, in sorted order. 29 | visit(airports.get(airport).poll()); 30 | } 31 | // once we reach the end of a route, add it to list, and add the routes as 32 | // we retreat in reverse order, till we find other routes we haven't visited 33 | route.add(0, airport); 34 | } 35 | 36 | public static void main(String[] args) { 37 | String[][] input = {{"MUC", "LHR"}, {"JFK", "MUC"}, {"SFO", "SJC"}, {"LHR", "SFO"}}; 38 | 39 | List res = new Itinerary().itinerary(input); 40 | System.out.println(res.toString()); 41 | } 42 | } 43 | 44 | /* 45 | 46 | Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK. 47 | 48 | Note: 49 | 50 | If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"]. 51 | All airports are represented by three capital letters (IATA code). 52 | You may assume all tickets form at least one valid itinerary. 53 | One must use all the tickets once and only once. 54 | 55 | Example 1: 56 | Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] 57 | Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] 58 | 59 | Example 2: 60 | Input: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] 61 | Output: ["JFK","ATL","JFK","SFO","ATL","SFO"] 62 | Explanation: Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]. 63 | But it is larger in lexical order. 64 | */ -------------------------------------------------------------------------------- /java/medium/SentenceReverse.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | /** 4 | * Given an array of char, where an empty char indicates a sentence space, reverse the sentence; 5 | * Eg: 6 | * input: [p, r, a, c, t, i, c, e, , m, a, k, e, s, , p, e, r, f, e, c, t] 7 | * output: [p, e, r, f, e, c, t, ,m, a, k, e, s, ,p, r, a, c, t, i, c, e] 8 | */ 9 | 10 | import java.util.*; 11 | 12 | class SentenceReverse { 13 | public static char[] sentenceReverse(char[] arr) { 14 | // start from the back and copy to front; keeping track of where we are on both sides 15 | 16 | int len = arr.length - 1; 17 | int start = len; 18 | int cur = 0; 19 | char[] res = new char[len + 1]; 20 | 21 | while (start >= 0) { 22 | if (arr[start] == ' ') { 23 | res[cur] = arr[start]; 24 | start--; cur++; 25 | } 26 | 27 | while(start >= 0 && arr[start] != ' ') { 28 | start--; 29 | } 30 | 31 | int reverseFrom = start + 1; 32 | 33 | while (cur < len - start) { 34 | res[cur] = arr[reverseFrom]; 35 | cur++; reverseFrom++; 36 | } 37 | } 38 | 39 | return res; 40 | } 41 | 42 | public static void main(String[] args) { 43 | char[] input = {'p', 'r', 'a', 'c', 't', 'i', 'c', 'e',' ', 'm', 'a', 'k', 'e', 's', ' ', 'p', 'e', 'r', 'f', 'e', 'c', 't'}; 44 | char[] res = SentenceReverse.sentenceReverse(input); 45 | System.out.println(res.toString()); 46 | } 47 | } -------------------------------------------------------------------------------- /java/medium/TreasureHunt.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | import java.util.*; 4 | 5 | public class TreasureHunt { 6 | 7 | // String API = "https://findtreasure.app/api/v1/contestants/register"; 8 | Scanner input = new Scanner(System.in); 9 | 10 | public TreasureHunt() { 11 | int res = BFS(); 12 | System.out.print("You found "); 13 | System.out.print(res); 14 | System.out.print(" treasures"); 15 | System.out.println(); 16 | } 17 | 18 | int BFS() { 19 | int treasureFound = 0; 20 | Queue queue = new LinkedList<>(); 21 | Set visited = new HashSet<>(); 22 | System.out.println("Enter input url"); 23 | String startUrl = input.nextLine(); 24 | queue.add(startUrl); 25 | 26 | while (!queue.isEmpty()) { 27 | String cur = queue.poll(); 28 | System.out.println("Visit " + cur); 29 | String[] curArr = cur.split("/"); 30 | String curEnd = curArr[curArr.length - 1]; 31 | visited.add(curEnd); 32 | 33 | System.out.println("is treasureFound? (y/n)"); 34 | String treasure = input.nextLine(); 35 | if (treasure.equals("y")) treasureFound++; 36 | 37 | System.out.println("Enter paths array"); 38 | String[] paths = input.nextLine().split(","); 39 | 40 | for (int i = 0; i < paths.length; i++) { 41 | String[] path = paths[i].split("/"); 42 | String end = path[path.length - 1]; 43 | if (!visited.contains(end) && !paths[i].equals((""))) { 44 | queue.add(paths[i]); 45 | } 46 | } 47 | } 48 | return treasureFound; 49 | } 50 | public static void main(String[] args) { 51 | TreasureHunt hunt = new TreasureHunt(); 52 | } 53 | } 54 | /** 55 | "https://findtreasure.app/api/v1/games/test/8316a24e-d716-4cc5-8c28-7353e4a62079","https://findtreasure.app/api/v1/games/test/10bd1864-3657-4a85-8c92-7d46e0985115","https://findtreasure.app/api/v1/games/test/ddd3abbe-495c-484a-bc9f-fe94c1988afa","https://findtreasure.app/api/v1/games/test/3abec613-a2fe-41e9-83d2-8a62e0681e10","https://findtreasure.app/api/v1/games/test/start" */ -------------------------------------------------------------------------------- /java/medium/WordBreak.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | import java.util.*; 4 | 5 | public class WordBreak { 6 | public static boolean solve(List wordDict, String s) { 7 | Set dict = new HashSet<>(wordDict); 8 | Set visited = new HashSet<>(); 9 | Queue queue = new LinkedList<>(); 10 | 11 | queue.add(0); 12 | visited.add(0); 13 | 14 | while (!queue.isEmpty()) { 15 | StringBuilder cur = new StringBuilder(); 16 | // keep the index of valid words in the queue for further processing 17 | int curIdx = queue.poll(); 18 | 19 | for (int i = curIdx + 1; i <= s.length(); i++) { 20 | cur.append(s.charAt(i-1)); 21 | if (visited.contains(i)) continue; 22 | 23 | if (dict.contains(cur.toString())) { 24 | // if the reached the end and we have valid words, then voila! 25 | if (i == s.length()) return true; 26 | 27 | // if not, add to queue and mark as visited so as not to process again 28 | queue.add(i); 29 | visited.add(i); 30 | } 31 | } 32 | } 33 | return false; 34 | } 35 | 36 | public static void main(String[] args) { 37 | List wordDict = new LinkedList<>(); 38 | wordDict.add("apple"); 39 | wordDict.add("pen"); 40 | // wordDict.add("cat"); 41 | // wordDict.add("cats"); 42 | // wordDict.add("sand"); 43 | // wordDict.add("and"); 44 | // wordDict.add("dog"); 45 | // String s = "catsandog"; 46 | String s = "applepenapple"; 47 | System.out.println(WordBreak.solve(wordDict, s)); 48 | } 49 | } -------------------------------------------------------------------------------- /java/medium/WordLadder.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * Given a start word, an end word and a dictionary of words 8 | * find the length of the shortest transformation from the start word to end word 9 | * such that 10 | * 1. Each word is transformed to the next word by a change in just one letter 11 | * 2. Each word transformed to, must be in the dictionary 12 | * eg, the sample given below maybe transformed as follows: 13 | * hit -> hot -> lot -> log -> cog 14 | * giving transformation length as 5. 15 | */ 16 | 17 | public class WordLadder { 18 | // approach is to do a bidrectional search and return the length the two searches meet. 19 | // to ensure the two searches meet, we first check that the endWord exists in list 20 | public static int search(String startWord, String endWord, Set wordList) { 21 | if (!wordList.contains(endWord)) return 0; 22 | 23 | Set beginSet = new HashSet<>(); 24 | Set endSet = new HashSet<>(); 25 | // add both words to begin and end sets respectively 26 | beginSet.add(startWord); endSet.add(endWord); 27 | // remove from wordList to avoid duplicated search 28 | wordList.remove(endWord); 29 | 30 | int count = 1; 31 | 32 | while(!beginSet.isEmpty()) { 33 | // choose the lesser of the two trees 34 | if (beginSet.size() > endSet.size()) { 35 | Set temp = beginSet; 36 | beginSet = endSet; 37 | endSet = temp; 38 | } 39 | 40 | // store children in arbitrary set 41 | Set next = new HashSet<>(); 42 | for (String el : beginSet) { 43 | // generate all one char variation of word and see if it exists in wordList 44 | // or has been seen in endSet 45 | char[] word = el.toCharArray(); 46 | for (int i = 0; i < word.length; i++) { 47 | char original = word[i]; 48 | for (char letter = 'a'; letter <= 'z'; letter++) { 49 | word[i] = letter; 50 | 51 | String newWord = String.valueOf(word); 52 | 53 | if (endSet.contains(newWord)) { 54 | return count + 1; 55 | } 56 | 57 | if (wordList.contains(newWord)) { 58 | next.add(newWord); 59 | wordList.remove(newWord); 60 | } 61 | } 62 | word[i] = original; 63 | } 64 | } 65 | beginSet = next; 66 | count++; 67 | } 68 | return 0; 69 | } 70 | 71 | public static void main(String[] args) { 72 | String[] dict = {"hot","dot","dog","lot","log", "cog"}; 73 | String start = "hit", end = "cog"; 74 | Set wordList = new HashSet<>(); 75 | 76 | for (String el : dict) { 77 | wordList.add(el); 78 | } 79 | 80 | System.out.println(WordLadder.search(start, end, wordList)); 81 | } 82 | 83 | } -------------------------------------------------------------------------------- /java/medium/decodeWays.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | // Given a string of integers encoded using the numbers of the letters of the 4 | // alphabet, 5 | // return how many ways the string can be decoded 6 | // Eg, Given 1236 can be decoded as 7 | // 1, 2, 3, 6 8 | // 12, 3, 6 9 | // 1, 23, 6 10 | public class decodeWays { 11 | static int decodeVariation(String s) { return decodeVariationHelper(0, s); } 12 | 13 | private static int decodeVariationHelper(int start, String s) { 14 | if (start == s.length()) 15 | return 1; // passes 16 | 17 | int left = 0, right = 0; // initialize to fail 18 | int leftNumber = Integer.parseInt(s.substring(start, start + 1)); 19 | if (leftNumber > 0 && leftNumber < 10) { 20 | left = decodeVariationHelper(start + 1, s); 21 | } 22 | if (start + 2 <= s.length()) { 23 | int rightNumber = Integer.parseInt(s.substring(start, start + 2)); 24 | if (rightNumber >= 10 && rightNumber <= 26) { 25 | right = decodeVariationHelper(start + 2, s); 26 | } 27 | } 28 | 29 | return left + right; 30 | } 31 | 32 | private static int decodeVariationIterative(String s) { 33 | // at i, the number of ways to decode it is, the number of ways to decode 34 | // i+1 and the number of ways to decode i+2 if valid 35 | int N = s.length(); 36 | int[] decode = new int[N + 1]; 37 | decode[N] = 1; 38 | decode[N - 1] = 1; 39 | // 1 2 0 6 40 | //[1 ,1, 0 ,1] 41 | for (int i = N - 2; i >= 0; i--) { 42 | if (s.charAt(i) == '0') { 43 | decode[i] = 0; 44 | } else if (s.charAt(i) == '1') { 45 | decode[i] = decode[i + 1] + decode[i + 2]; 46 | } else if (s.charAt(i) == '2') { 47 | decode[i] = decode[i + 1]; 48 | if (i + 1 < s.length() && s.charAt(i + 1) < '7') { 49 | decode[i] += decode[i + 2]; 50 | } else { 51 | decode[i] = decode[i + 1]; 52 | } 53 | } 54 | } 55 | 56 | return decode[0]; 57 | } 58 | 59 | public static void main(String[] args) { 60 | String s = "1216"; 61 | System.out.println(decodeWays.decodeVariation(s)); 62 | System.out.println(decodeWays.decodeVariationIterative(s)); 63 | } 64 | } 65 | 66 | /** 67 | * . 68 | * 1226 69 | * / \ 70 | * . . 71 | * 1226 1226 72 | * / \ / \ 73 | * . . . . 74 | * 1226 1226 (P) 1226 1226(P) 75 | * / \ / \ 76 | * . . . F 77 | * 1226 1226 (P) 1226(P) 78 | * / \ 79 | * . F 80 | * 1226(P) 81 | * 82 | * 83 | * 1222 84 | * 1, 222 85 | * 1, 2, 22 86 | * 1, 22, 2 87 | * 1, 2, 2, 2 88 | * 12, 22 89 | * 12, 2, 2 90 | * i = 0 91 | * 1222 92 | * if (i == s.length) return 0; 93 | * if (i == s.length - 1) return 1; 94 | * if (s.charAt(i) == 0) return 0; 95 | * if [memo[i] > -1] return memo[i] 96 | * let count = decode(s, i+1); 97 | * 98 | * if (s.charAt(i) == 1) { 99 | * count += decode(s, i+2) 100 | * } 101 | * if (s.charAt(i) == 2 && (i+1 < s.length && s.charAt(i+1) < 7)) { 102 | * count += decode(s, i+2) 103 | * } 104 | * memo[i] = count; 105 | * return memo[i]; 106 | * 0123 107 | * 1222 * count = 1 count = 3 108 | * 109 | * 110 | * i = 2 111 | * i = 0 112 | */ -------------------------------------------------------------------------------- /java/medium/findInRotatedArray.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | public class findInRotatedArray { 4 | public static int solution1(int[] arr, int target) { 5 | int start = 0; 6 | int end = arr.length - 1; 7 | 8 | while (start <= end) { 9 | int mid = start + (end - start) / 2; 10 | if (arr[mid] == target) return mid; 11 | 12 | if (arr[mid] < arr[end]) { 13 | // all element to the right are greater than mid 14 | if (target > arr[mid]) { 15 | if (target > arr[end]) { 16 | end = mid - 1; 17 | } else { 18 | start = mid + 1; 19 | } 20 | } else { 21 | // go left since we know all elements to the right are greater 22 | end = mid - 1; 23 | } 24 | } else { 25 | // all elements to the left are less than mid 26 | if (target < arr[mid]) { 27 | if (target <= arr[end]) { 28 | start = mid + 1; 29 | } else { 30 | end = mid - 1; 31 | } 32 | } else { 33 | // go right, since we know all elements to the left are less 34 | start = mid + 1; 35 | } 36 | } 37 | } 38 | return -1; 39 | } 40 | 41 | public static int solution2(int[] arr, int target) { 42 | // find offset index ie by how much was the input shifted? 43 | // we find this by getting the index of min element 44 | int start = 0; 45 | int end = arr.length - 1; 46 | 47 | while (start < end) { 48 | int mid = start + (end - start)/2; 49 | 50 | if (arr[mid] > arr[end]) { 51 | start = mid + 1; 52 | } else { 53 | end = mid; 54 | } 55 | } 56 | 57 | int offset = start; 58 | 59 | start = 0; 60 | end = arr.length - 1; 61 | 62 | // do normal binary search, taking into consideration, the offset 63 | 64 | while (start <= end) { 65 | int mid = start + (end - start)/2; 66 | 67 | int actualMid = (mid + offset) % arr.length; 68 | 69 | // use offset to compare values 70 | if (arr[actualMid] == target) { 71 | return actualMid; 72 | } 73 | 74 | if (arr[actualMid] > target) { 75 | end = mid - 1; 76 | } else { 77 | start = mid + 1; 78 | } 79 | } 80 | 81 | return -1; 82 | } 83 | 84 | public static void main(String[] args) { 85 | int[] input = {0, 1, 2, 3, 4, 5, 6, 7}; 86 | int[] input1 = {2, 3, 4, 5, 6, 7, 0, 1}; 87 | int[] input2 = {4, 5, 6, 7, 0, 1, 2, 3}; 88 | 89 | System.out.println("*******SOLUTION 1*********"); 90 | System.out.println(findInRotatedArray.solution1(input, 3)); 91 | System.out.println(findInRotatedArray.solution1(input1, 0)); 92 | System.out.println(findInRotatedArray.solution1(input2, 5)); 93 | 94 | System.out.println("*******SOLUTION 2*********"); 95 | System.out.println(findInRotatedArray.solution2(input, 3)); 96 | System.out.println(findInRotatedArray.solution2(input1, 0)); 97 | System.out.println(findInRotatedArray.solution2(input2, 5)); 98 | } 99 | } -------------------------------------------------------------------------------- /java/medium/killProcess.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | import java.util.*; 4 | 5 | class KillProcess { 6 | static public LinkedList killProcess(int[] pid, int[] ppid, int kill) { 7 | // PID = [1, 3, 10, 5], PPID = [3, 0, 5, 3], killID = 5 8 | HashMap> tree = new HashMap<>(); 9 | 10 | for (int i = 0; i < ppid.length; i++) { 11 | if (ppid[i] == 0) continue; 12 | LinkedList children = tree.get(ppid[i]); 13 | if (children == null) { 14 | children = new LinkedList<>(); 15 | children.add(pid[i]); 16 | tree.put(ppid[i], children); 17 | } else { 18 | children.add(pid[i]); 19 | } 20 | } 21 | 22 | // do the kill process 23 | LinkedList killed = new LinkedList<>(); 24 | proceedToKill(tree, kill, killed); 25 | return killed; 26 | } 27 | 28 | static private void proceedToKill(HashMap> tree, int kill, LinkedList killed) { 29 | 30 | Queue queue = new LinkedList<>(); 31 | queue.add(kill); 32 | 33 | int current; 34 | // remove from queue 35 | // add to killed 36 | // add the children to queue 37 | while (queue.size() != 0) { 38 | current = queue.remove(); // queue = []; c = 10 39 | killed.add(current); // killed = [5, 10] 40 | LinkedList children = tree.get(current); 41 | if (children != null) { 42 | for (Integer child : tree.get(current)) { // tree = { 3:[1, 5], 5:[10]}; 43 | queue.add(child); 44 | } 45 | } 46 | } 47 | } 48 | 49 | static public void main( String args[] ) { 50 | int[] pid = {10, 8, 3, 7, 6, 1, 5, 2, 4, 9}; 51 | int[] ppid = {5, 10, 0, 2, 1, 3, 3, 1, 5, 10}; 52 | int kill = 2; 53 | LinkedList killed = KillProcess.killProcess(pid, ppid, kill); 54 | System.out.println(killed.toString()); 55 | } 56 | } 57 | 58 | /** 59 | * """ 60 | Problem: Kill Process 61 | 62 | In this problem, each process has a unique PID (process id) and 63 | PPID (parent process id). 64 | 65 | p -> parent 66 | 67 | Each process only has one parent process, but may have one or more 68 | children processes. 69 | This is just like a tree structure. Only one process has PPID that is 0, 70 | which means this process has no parent process. All the PIDs will be 71 | distinct positive integers. 72 | 73 | We use two list of integers to represent a list of processes, where the 74 | first list contains PID for each process and the second list contains the 75 | corresponding PPID. 76 | 77 | Now given the two lists, and a PID representing a process you want to kill, 78 | return a list of PIDs of processes that will be killed in the end. 79 | You should assume that when a process is killed, all its children processes 80 | will be killed. No order is required for the final answer. 81 | 82 | 83 | Example 1: 84 | Input: PID = [1, 3, 10, 5], PPID = [3, 0, 5, 3], killID = 5 85 | Output: [5, 10] 86 | Explanation: Kill 5 will also kill 10. 87 | 3 88 | / \ 89 | 1 5 90 | / 91 | 10 92 | 93 | Example 2: 94 | Input: PID = [1, 2, 3], PPID = [0, 1, 1], killID = 2 95 | Output: [2] 96 | Notice: 97 | The given kill id is guaranteed to be one of the given PIDs. 98 | There is at least one PID in the list. 99 | """ 100 | 101 | """ 102 | 3 103 | / \ 104 | 1 5 105 | / \ / \ 106 | 2 6 10 4 107 | / / \ 108 | 7 8 9 109 | 110 | PID = [10, 8, 3, 7, 6, 1, 5, 2, 4, 9], 111 | PPID = [5, 10, 0, 2, 1, 3, 3, 1, 5, 10] 112 | kill = 10 113 | 114 | 3 115 | / \ 116 | 1 5 117 | / \ / \ 118 | 2 6 10 4 119 | / / \ 120 | 7 8 9 121 | */ -------------------------------------------------------------------------------- /java/medium/knapSack.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | /** 4 | * Given a list of items with values and weights, as well as a max weight, find 5 | * the maximum value you can generate from items, where the sum of the weights 6 | * is less than or equal to the max 7 | * 8 | * Eg 9 | * items = {(w: 1, v: 6), (w:2, v, 10), (w: 3, v: 12)} 10 | * max_weight = 5 11 | * knapsack(items, max_weight) = 22 12 | */ 13 | 14 | public class knapSack { 15 | private class Item { 16 | int weight; 17 | int value; 18 | } 19 | private static int getMax(Item[] items, int maxWeight) { 20 | // get max value, starting from 0 21 | return getMax(items, maxWeight, 0); 22 | } 23 | private static int getMax(Item[] items, int maxWeight, int idx) { 24 | if (idx > items.length) return 0; 25 | 26 | // if the current item's weight, greater than maxWeight, check the next item 27 | if (items[idx].weight > maxWeight) { 28 | return getMax(items, maxWeight, idx + 1); 29 | } 30 | 31 | return Math.max(getMax(items, maxWeight - items[idx].weight + items[idx].value, idx + 1) /*include cur */, 32 | getMax(items, maxWeight, idx+1) /*exclude cur*/); 33 | } 34 | } 35 | /** for each weight, you either add or not add it with the remaining items 36 | take the maximum weight you'll get between the two above 37 | i = 0: adding 1 -> 18, not adding 1 -> i(2) 38 | i = 1: adding 2 -> 10 + i(3), not adding 2 -> i(3) 39 | i = 2: adding 3 -> 12, not adding 3 -> 0 40 | it's a bit more complicated, take into considering that the weight must not exceed 5 41 | thus, my result is 22 42 | 43 | 5,i=0 44 | /include 1 \exclude 1 45 | 4,i=1,w=6 5,i=1,w=0 46 | /inc 2 \exc 2 /inc 2 \exc 2 47 | 2,i=2,w=16 4,i=2,w=6 3,i=2,w=10 5,i=2,w=0 48 | /inc 3 \exc 3 /inc3 \exc3 /inc 3 \exc 3 /inc 3 \exc 49 | F 2,i=3,w=16 1,i=3,w=18 4,i=3,w=6 0,i=3,w=22 3,i=3,w=10 2,i=3,w=12 5,i=3,w=0 50 | end end(Max here) end end(Maxhere) end end end 51 | 52 | */ -------------------------------------------------------------------------------- /java/medium/lowestCommonAncestor.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * You are given pointer to the root of the binary search tree and two values 7 | * and . You need to return the lowest common ancestor (LCA) of and in the 8 | * binary search tree. 9 | */ 10 | 11 | class Node { 12 | Node left; 13 | Node right; 14 | int data; 15 | 16 | Node(int data) { 17 | this.data = data; 18 | left = null; 19 | right = null; 20 | } 21 | } 22 | 23 | class lowestCommonAncestor { 24 | 25 | public static Node lca(Node root, int v1, int v2) { 26 | // Write your code here. 27 | if (root == null) 28 | return null; 29 | 30 | int less = Math.min(v1, v2); 31 | int greater = Math.max(v1, v2); 32 | if (less <= root.data && greater >= root.data) 33 | return root; 34 | if (less <= root.data && greater <= root.data) 35 | return lca(root.left, less, greater); 36 | if (less > root.data && greater > root.data) 37 | return lca(root.right, less, greater); 38 | return null; 39 | } 40 | 41 | /** 42 | * 43 | * @param root 44 | * @param data 45 | * @return 46 | */ 47 | 48 | public static Node insert(Node root, int data) { 49 | if (root == null) { 50 | return new Node(data); 51 | } else { 52 | if (data <= root.data) { 53 | root.left = insert(root.left, data); 54 | } else { 55 | root.right = insert(root.right, data); 56 | } 57 | return root; 58 | } 59 | } 60 | 61 | public static void main(String[] args) { 62 | Scanner scan = new Scanner(System.in); 63 | int t = scan.nextInt(); 64 | Node root = null; 65 | while (t-- > 0) { 66 | int data = scan.nextInt(); 67 | root = insert(root, data); 68 | } 69 | int v1 = scan.nextInt(); 70 | int v2 = scan.nextInt(); 71 | scan.close(); 72 | Node ans = lca(root, v1, v2); 73 | System.out.println(ans.data); 74 | } 75 | } 76 | 77 | /**given 1 2 78 | * 4 79 | * / 80 | * 2 81 | * 82 | */ -------------------------------------------------------------------------------- /java/medium/matrixBlockSum.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | /** 4 | Given a m * n matrix mat and an integer K, return a matrix answer where each answer[i][j] is the sum of all 5 | elements mat[r][c] for i - K <= r <= i + K, j - K <= c <= j + K, and (r, c) is a valid position in the matrix. 6 | 7 | Example 1: 8 | Input: mat = [[1,2,3],[4,5,6],[7,8,9]], K = 1 9 | Output: [[12,21,16],[27,45,33],[24,39,28]] 10 | 11 | Example 2: 12 | Input: mat = [[1,2,3],[4,5,6],[7,8,9]], K = 2 13 | Output: [[45,45,45],[45,45,45],[45,45,45]] 14 | 15 | */ 16 | 17 | public class matrixBlockSum { 18 | private int rows; 19 | private int cols; 20 | public int[][] brute(int[][] mat, int K) { 21 | rows = mat.length; 22 | cols = mat[0].length; 23 | int[][] answer = new int[rows][cols]; 24 | // O(r * c * (2k + 1)) 25 | for (int row = 0; row < rows; row++) { 26 | for (int col = 0; col < cols; col++) { 27 | int sum = 0; 28 | for (int i = row - K; i <= row + K; i++) { 29 | for (int j = col - K; j <= col + K; j++) { 30 | if (isValid(i, j)) { 31 | sum += mat[i][j]; 32 | } 33 | } 34 | } 35 | answer[row][col] = sum; 36 | } 37 | } 38 | 39 | return answer; 40 | } 41 | 42 | private boolean isValid(int row, int col) { 43 | if (row >= 0 && row < rows && col >= 0 && col < cols) 44 | return true; 45 | return false; 46 | } 47 | 48 | // see solution explanation here: https://computersciencesource.wordpress.com/2010/09/03/computer-vision-the-integral-image/ 49 | 50 | public int[][] rangeSum(int[][] matrix, int K) { 51 | int rows = matrix.length; 52 | int cols = matrix[0].length; 53 | int[][] sumTable = new int[rows + 1][cols + 1]; 54 | generateSumsTable(matrix, sumTable); 55 | 56 | return getBlockSums(sumTable, K); 57 | } 58 | 59 | private void generateSumsTable(int[][] matrix, int[][] sumTable) { 60 | int rows = matrix.length; 61 | int cols = matrix[0].length; 62 | 63 | for (int i = 1; i <= rows; i++) { 64 | for (int j = 1; j <= cols; j++) { // top 65 | sumTable[i][j] = matrix[i - 1][j - 1] + sumTable[i - 1][j] + 66 | // left // top-left dia 67 | sumTable[i][j - 1] - sumTable[i - 1][j - 1]; 68 | } 69 | } 70 | } 71 | 72 | private int[][] getBlockSums(int[][] sumTable, int K) { 73 | int rows = sumTable.length - 1; 74 | int cols = sumTable[0].length - 1; 75 | int[][] ans = new int[rows][cols]; 76 | for (int r = 0; r < rows; r++) { 77 | for (int c = 0; c < cols; c++) { 78 | int r1 = Math.max(0, r - K), c1 = Math.max(0, c - K); 79 | int r2 = Math.min(rows, r + K + 1), c2 = Math.min(cols, c + K + 1); 80 | ans[r][c] = sumTable[r1][c1] + sumTable[r2][c2] - 81 | sumTable[r1][c2] - sumTable[r2][c1]; 82 | } 83 | } 84 | return ans; 85 | } 86 | } -------------------------------------------------------------------------------- /java/medium/reverseLinkedList.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | /** 4 | * Reverse a linked list from position m to n. Do it in one-pass. 5 | * Note: 1 ≤ m ≤ n ≤ length of list. 6 | * 7 | * Example: 8 | * 9 | * Input: 1->2->3->4->5->NULL, m = 2, n = 4 10 | * Output: 1->4->3->2->5->NULL 11 | * 12 | */ 13 | import java.io.BufferedReader; 14 | import java.io.IOException; 15 | import java.io.InputStreamReader; 16 | 17 | // Definition for singly-linked list. 18 | class ListNode { 19 | int val; 20 | ListNode next; 21 | ListNode() {} 22 | ListNode(int val) { this.val = val; } 23 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 24 | } 25 | 26 | class Solution { 27 | public ListNode reverseBetween(ListNode head, int m, int n) { 28 | if (head == null) return head; 29 | ListNode start = null, first = head; 30 | 31 | // initialize start position 32 | if (m-1 > 0) { 33 | start = advancePointer(m-1, head); 34 | first = start.next; 35 | } 36 | 37 | if (first == null) return head; 38 | 39 | ListNode prev = first, current = first.next; 40 | 41 | int i = m; 42 | while (i < n && current != null) { 43 | ListNode temp = current.next; 44 | current.next = prev; 45 | prev = current; 46 | current = temp; 47 | i++; 48 | } 49 | first.next = current; 50 | if (start == null) { 51 | head = prev; 52 | } else { 53 | start.next = prev; 54 | } 55 | 56 | return head; 57 | } 58 | private ListNode advancePointer(int offset, ListNode head) { 59 | ListNode current = head; 60 | for (int i = 1; i < offset; i++) { 61 | current = current.next; 62 | } 63 | return current; 64 | } 65 | } 66 | 67 | class MainClass { 68 | public static int[] stringToIntegerArray(String input) { 69 | input = input.trim(); 70 | input = input.substring(1, input.length() - 1); 71 | if (input.length() == 0) { 72 | return new int[0]; 73 | } 74 | 75 | String[] parts = input.split(","); 76 | int[] output = new int[parts.length]; 77 | for(int index = 0; index < parts.length; index++) { 78 | String part = parts[index].trim(); 79 | output[index] = Integer.parseInt(part); 80 | } 81 | return output; 82 | } 83 | 84 | public static ListNode stringToListNode(String input) { 85 | // Generate array from the input 86 | int[] nodeValues = stringToIntegerArray(input); 87 | 88 | // Now convert that list into linked list 89 | ListNode dummyRoot = new ListNode(0); 90 | ListNode ptr = dummyRoot; 91 | for(int item : nodeValues) { 92 | ptr.next = new ListNode(item); 93 | ptr = ptr.next; 94 | } 95 | return dummyRoot.next; 96 | } 97 | 98 | public static String listNodeToString(ListNode node) { 99 | if (node == null) { 100 | return "[]"; 101 | } 102 | 103 | String result = ""; 104 | while (node != null) { 105 | result += Integer.toString(node.val) + ", "; 106 | node = node.next; 107 | } 108 | return "[" + result.substring(0, result.length() - 2) + "]"; 109 | } 110 | 111 | public static void main(String[] args) throws IOException { 112 | BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 113 | String line; 114 | while ((line = in.readLine()) != null) { 115 | ListNode head = stringToListNode(line); 116 | line = in.readLine(); 117 | int m = Integer.parseInt(line); 118 | line = in.readLine(); 119 | int n = Integer.parseInt(line); 120 | 121 | ListNode ret = new Solution().reverseBetween(head, m, n); 122 | 123 | String out = listNodeToString(ret); 124 | 125 | System.out.print(out); 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /java/medium/swapNodes/SwapNodes.java: -------------------------------------------------------------------------------- 1 | package medium.swapNodes; 2 | 3 | // My local solution 4 | 5 | import java.util.LinkedList; 6 | import java.util.Scanner; 7 | 8 | public class SwapNodes { 9 | private Node root; 10 | private class Node { 11 | int data; 12 | Node left; 13 | Node right; 14 | int depth; 15 | 16 | Node(int data, int depth) { 17 | this.data = data; 18 | this.depth = depth; 19 | } 20 | } 21 | 22 | public SwapNodes() { root = new Node(1, 1); } 23 | 24 | public Node getRoot() { return root; } 25 | 26 | public Node addNode(int data, int depth) { return new Node(data, depth); } 27 | 28 | public void solve(int k) { 29 | LinkedList current = new LinkedList<>(); 30 | current.add(root); 31 | while (current.size() > 0) { 32 | LinkedList parents = current; 33 | current = new LinkedList<>(); 34 | for (Node parent : parents) { 35 | if (parent.depth % k == 0) { 36 | Node temp = parent.left; 37 | parent.left = parent.right; 38 | parent.right = temp; 39 | } 40 | 41 | if (parent.left != null && parent.left.data != -1) { 42 | current.add(parent.left); 43 | } 44 | 45 | if (parent.right != null && parent.right.data != -1) { 46 | current.add(parent.right); 47 | } 48 | } 49 | } 50 | } 51 | 52 | public LinkedList inOrder(Node x, LinkedList res, int i) { 53 | if (x == null || x.data == -1) 54 | return res; 55 | inOrder(x.left, res, i-1); 56 | res.add(x.data); 57 | inOrder(x.right, res, i-1); 58 | return res; 59 | } 60 | 61 | public static void main(String[] args) { 62 | Scanner input = new Scanner(System.in); 63 | SwapNodes test = new SwapNodes(); 64 | LinkedList current = new LinkedList<>(); 65 | current.add(test.getRoot()); 66 | int i = 1; 67 | int noOfNodes = Integer.parseInt(input.nextLine()); 68 | while (i < noOfNodes) { 69 | LinkedList parents = current; 70 | current = new LinkedList<>(); 71 | for (Node parent : parents) { 72 | parent.left = test.addNode(input.nextInt(), parent.depth + 1); 73 | parent.right = test.addNode(input.nextInt(), parent.depth + 1); 74 | if (parent.left.data != -1) { 75 | current.add(parent.left); 76 | } 77 | if (parent.right.data != -1) { 78 | current.add(parent.right); 79 | } 80 | i++; 81 | } 82 | } 83 | int k = input.nextInt(); 84 | for (int j = 0; j < k; j++) { 85 | test.solve(input.nextInt()); 86 | LinkedList res = new LinkedList<>(); 87 | res = test.inOrder(test.getRoot(), res, noOfNodes); 88 | for (int l : res) { 89 | System.out.print(l + " "); 90 | } 91 | System.out.print("\n"); 92 | } 93 | 94 | input.close(); 95 | } 96 | } -------------------------------------------------------------------------------- /java/medium/swapNodes/result.txt: -------------------------------------------------------------------------------- 1 | 2 9 6 4 1 3 7 5 11 8 10 2 | 2 6 9 4 1 3 7 5 10 8 11 3 | -------------------------------------------------------------------------------- /java/medium/swapNodes/testFile.txt: -------------------------------------------------------------------------------- 1 | 11 2 | 2 3 3 | 4 -1 4 | 5 -1 5 | 6 -1 6 | 7 8 7 | -1 9 8 | -1 -1 9 | 10 11 10 | -1 -1 11 | -1 -1 12 | -1 -1 13 | 2 14 | 2 15 | 4 -------------------------------------------------------------------------------- /java/medium/topologicalSort.java: -------------------------------------------------------------------------------- 1 | package medium; 2 | 3 | import java.util.Stack; 4 | 5 | import utils.DiGraph; 6 | 7 | public class topologicalSort { 8 | private DiGraph g; 9 | private int vertices; 10 | private boolean marked[]; 11 | private Stack postOrder = new Stack<>(); 12 | 13 | public topologicalSort(DiGraph g) { 14 | this.g = g; 15 | vertices = g.V(); 16 | } 17 | 18 | // do a depth first search, and then add any vertex returned from, to a stack. 19 | // meaning, the last vertex must be returned, b4 the one following it, b4 the 20 | // next... 21 | private void DFS(int v) { 22 | if (marked[v]) 23 | return; 24 | marked[v] = true; 25 | for (Integer edge : g.adj(v)) { 26 | DFS(edge); 27 | } 28 | postOrder.push(v); 29 | } 30 | 31 | public Iterable sort() { 32 | marked = new boolean[vertices]; 33 | for (int i = 0; i < vertices; i++) { 34 | DFS(i); 35 | } 36 | return postOrder; 37 | } 38 | 39 | public boolean hasCycle() { 40 | boolean[] recStack = new boolean[vertices]; 41 | marked = new boolean[vertices]; 42 | for (int i = 0; i < vertices; i++) { 43 | if (cycleDFS(i, recStack)) 44 | return true; 45 | } 46 | return false; 47 | } 48 | // keep track of items in the recursive tree, if any is found, return true; 49 | private boolean cycleDFS(int v, boolean[] recStack) { 50 | if (marked[v]) 51 | return false; 52 | 53 | recStack[v] = true; 54 | marked[v] = true; 55 | for (Integer edge : g.adj(v)) { 56 | if (recStack[edge]) 57 | return true; 58 | cycleDFS(edge, recStack); 59 | } 60 | recStack[v] = false; 61 | return false; 62 | } 63 | 64 | public static void main(String[] args) { 65 | DiGraph input = new DiGraph(5); 66 | input.addEdge(0, 1); 67 | input.addEdge(0, 2); 68 | input.addEdge(1, 3); 69 | input.addEdge(1, 4); 70 | input.addEdge(3, 4); 71 | input.addEdge(3, 2); 72 | // input.addEdge(3, 5); 73 | // input.addEdge(3, 4); 74 | // input.addEdge(3, 6); 75 | // input.addEdge(3, 2); 76 | // input.addEdge(5, 2); 77 | // input.addEdge(4, 0); 78 | 79 | topologicalSort test = new topologicalSort(input); 80 | System.out.println(test.hasCycle()); 81 | 82 | // note that this only returns correct ordering because Iterable iterates in 83 | // the order the elements are stored inside the stack. For direct 84 | // implementation, use Deque 85 | for (Integer value : test.sort()) { 86 | System.out.println(value); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /java/medium/txt.txt: -------------------------------------------------------------------------------- 1 | "https://findtreasure.app/api/v1/games/test/65cee928-9578-44ec-9ebc-1b1b2942dfc7","https://findtreasure.app/api/v1/games/test/95f6dcf6-6820-4e86-9c9f-72c6ea6858a5","https://findtreasure.app/api/v1/games/test/start","https://findtreasure.app/api/v1/games/test/ef2e7852-f98b-4bc1-a901-919bd98d4f6b","https://findtreasure.app/api/v1/games/test/ae824669-6ebe-4352-a482-057faf46a443" 2 | 3 | https://findtreasure.app/api/v1/games/ileya/bd0582e4-9a13-494f-a6f6-0850bc776a96 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | curl --location --request GET 'https://findtreasure.app/api/v1/games/ileya/d1b98318-4c7b-4da9-bef6-13e20509122f' --header 'gomoney: 07069037532' --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiIzYWJmYjQxMC1kMjdmLTQxZWEtYjAyNC0xMmRlMDU5NzZlZWMiLCJlbWFpbCI6Implbm5pZmVyb2xpYmllQGdtYWlsLmNvbSIsIm5hbWUiOiJDaGlkZXJhIE9saWJpZSIsImlhdCI6MTU5NjE1NDAxMSwibmJmIjoxNTk2MTU0MDExLCJleHAiOjE1OTg4MzI0MTF9.P7r-8Ci75_czKWBTaYNYJPtBkje6POq6QuJxUS_TGt8' -------------------------------------------------------------------------------- /java/utils/DiGraph.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class DiGraph { 6 | private int v; 7 | private int e; 8 | private LinkedList[] adj; 9 | 10 | public DiGraph(int n) { 11 | v = n; 12 | adj = (LinkedList[]) new LinkedList[v]; 13 | for (int i = 0; i < v; i++) { 14 | adj[i] = new LinkedList<>(); 15 | } 16 | } 17 | public void addEdge(int v, int w) { 18 | adj[v].add(w); 19 | e++; 20 | } 21 | 22 | public Iterable adj(int v) { return adj[v]; } 23 | 24 | /** 25 | * Number of vertices 26 | * @return int 27 | */ 28 | public int V() { return v; } 29 | 30 | /** 31 | *Number of edges 32 | *@return int 33 | */ 34 | public int E() { return e; } 35 | /** 36 | * Reverses the graph direction 37 | * For directed graphs only 38 | * @param g 39 | * @return reversed graph 40 | */ 41 | public DiGraph reverse() { 42 | DiGraph rev = new DiGraph(v); 43 | 44 | for (int i = 0; i < v; i++) { 45 | for (Integer v : adj(i)) { 46 | rev.addEdge(v, i); 47 | } 48 | } 49 | return rev; 50 | } 51 | public static void main(String[] args) { 52 | DiGraph test = new DiGraph(4); 53 | test.addEdge(0, 1); 54 | test.addEdge(1, 2); 55 | test.addEdge(1, 3); 56 | test.addEdge(3, 0); 57 | 58 | System.out.println(test.E() + " edges"); 59 | System.out.println(test.V() + " vertices"); 60 | 61 | for (Integer v : test.adj(2)) { 62 | System.out.println("2->" + v); 63 | } 64 | 65 | DiGraph revTest = test.reverse(); 66 | for (Integer v : revTest.adj(2)) { 67 | System.out.println("2->" + v); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /js/random/study.js: -------------------------------------------------------------------------------- 1 | function sum(...numbers){ 2 | return numbers.reduce(function(a,b){ return a+b}); 3 | } 4 | const arr = [6,5,4]; -------------------------------------------------------------------------------- /js/stage_1/addStrings.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} num1 3 | * @param {string} num2 4 | * @return {string} 5 | */ 6 | var addStrings = function (num1, num2) { 7 | let nums = {} 8 | for (let i = 0; i < 10; i++) { 9 | nums[i] = i; 10 | } 11 | let sum = 0; 12 | let i = num1.length - 1; 13 | let j = num2.length - 1; 14 | while (i >= 0 || j >= 0) { 15 | if (i >= 0) { sum += nums[num1[i]]; } 16 | if (j >= 0) { sum += nums[num2[j]]; } 17 | res.push(sum % 10); 18 | sum = Math.floor(sum / 10); 19 | i--; j--; 20 | } 21 | if (sum > 0) res.push(sum); 22 | 23 | return res.reverse().join(""); 24 | }; 25 | 26 | 27 | 28 | /* 29 | Given two non-negative integers num1 and num2 represented as string, 30 | return the sum of num1 and num2. 31 | 32 | Note: 33 | The length of both num1 and num2 is < 5100. 34 | Both num1 and num2 contains only digits 0-9. 35 | Both num1 and num2 does not contain any leading zero. 36 | 37 | You must not use any built-in BigInteger library or convert the inputs to integer directly. 38 | 39 | */ 40 | 41 | -------------------------------------------------------------------------------- /js/stage_1/addTillSingleDigit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an integer, add it's digits till it results to a single digit 3 | */ 4 | 5 | function addRepeatedly(num){ 6 | let val = num.toString(); 7 | if (val.length == 1) return parseInt(val); 8 | val = val.split(''); 9 | let result = val.reduce((prev, next) => { 10 | return parseInt(prev) + parseInt(next); 11 | }, 0); 12 | return addRepeatedly(result); 13 | } 14 | 15 | // console.log(addRepeatedly(119)); -------------------------------------------------------------------------------- /js/stage_1/anagram.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns an array of anagrams contained in a given array, of a query word 3 | * @param {String} word a query word 4 | * @param {Array} arr an array of strings to check for anagrams 5 | */ 6 | function anagram(word, arr) { 7 | let res = []; 8 | word = word.split("").sort(); 9 | 10 | arr.forEach(el => { 11 | if (word.length != el.length) { return; } 12 | if (word.join("") === (el.split("").sort().join(""))) res.push(el); 13 | }) 14 | return res; 15 | } 16 | 17 | console.log(anagram('abba', ['bbaa', 'abab', 'abcd', 'aaaa'])); -------------------------------------------------------------------------------- /js/stage_1/anglebetweenClockHands.js: -------------------------------------------------------------------------------- 1 | /**Question: 2 | * Find the angle between the hour and minutes hands 3 | * of a clock, given the time 4 | */ 5 | 6 | function angleBetween(time){ 7 | let times = time.split(':'); 8 | let hour = times[0]; 9 | let min = times[1]; 10 | hour = hour > 12 ? hour - 12: hour; 11 | let minAngle = min * 6; 12 | let hourAngle = (hour * 30) + (min/2); 13 | let degreesBetween = Math.abs(hourDegree - minDegree); 14 | return degreesBetween; 15 | } 16 | 17 | // console.log(degreesBetween('2:30')); 18 | // console.log(degreesBetween('24:00')); -------------------------------------------------------------------------------- /js/stage_1/birthdayBar.js: -------------------------------------------------------------------------------- 1 | function birthday(s, d, m) { 2 | let counter=0, sum=0; 3 | for(let i=0; i<=s.length-m;i++){ 4 | for(let j=i,x=1;x<=m;x++,j++){ 5 | sum+=s[j]; 6 | } 7 | if(sum==d){ 8 | counter++; 9 | } 10 | sum=0; 11 | } 12 | 13 | return counter; 14 | 15 | } -------------------------------------------------------------------------------- /js/stage_1/bitwiseAnd.js: -------------------------------------------------------------------------------- 1 | //Given a range of values inclusive, 2 | //find the reuslt of their bitwise And 3 | 4 | function bitwiseAnd(arr){ 5 | let and = arr[0], i = and++; 6 | while( i <= arr[arr.length-1]){ 7 | and &= i; 8 | i++ 9 | } 10 | return and; 11 | } 12 | // console.log(bitwiseAnd([5,7])); 13 | // console.log(bitwiseAnd([0,1])); -------------------------------------------------------------------------------- /js/stage_1/bracketValidity.js: -------------------------------------------------------------------------------- 1 | /** given a string containing only the characters, 2 | * (, ), {, }, [, ]. Check if the string is valid ie 3 | * that each closing bracket has a corresponding closing bracket 4 | * in the right order 5 | * eg [(((]))) is invalid 6 | * while {()[{}()]} is valid 7 | */ 8 | 9 | function isValid(brackets) { 10 | let stack = [], popped; 11 | let open = ['(', '{', '[']; 12 | for (let i = 0; i < brackets.length; i++) { 13 | 14 | //check if the bracket is open and not at the end 15 | if (open.includes(brackets[i])) { 16 | if (i === brackets.length - 1) return false; 17 | stack.push(brackets[i]); 18 | continue; 19 | } 20 | 21 | // checks that stack is not empty since there's no open bracket 22 | if (stack.length === 0) return false; 23 | 24 | // checks that closing bracket corresponds with that of open 25 | switch (brackets[i]){ 26 | case ')': 27 | popped = stack.pop(); 28 | if ( popped !== '(') return false; 29 | break; 30 | 31 | case '}': 32 | popped = stack.pop(); 33 | if ( popped !== '{') return false; 34 | break; 35 | 36 | case ']': 37 | popped = stack.pop(); 38 | if ( popped !== '[') return false; 39 | break; 40 | } 41 | } 42 | return true; 43 | } 44 | 45 | // You can also solve for validity of brackets 46 | //even with extra characters. eg [(a+b){a-b}] 47 | -------------------------------------------------------------------------------- /js/stage_1/cavityMap.js: -------------------------------------------------------------------------------- 1 | function cavityMap(grid) { 2 | let len = grid.length 3 | for (let i = 1; i <= len-2; i++){ 4 | for (let j = 1; j<=len-2; j++){ 5 | if ((grid[i][j] > grid[i+1][j]) && 6 | (grid[i][j] > grid[i-1][j]) && 7 | (grid[i][j] > grid[i][j+1]) && 8 | (grid[i][j] > grid[i][j-1])) { 9 | let str = grid[i].split(''); 10 | str.splice(j, 1, 'X'); 11 | grid[i] = str.join('') 12 | } 13 | } 14 | } 15 | return grid; 16 | 17 | } 18 | 19 | console.log(cavityMap(['1112', '1912','1892','1234'])); -------------------------------------------------------------------------------- /js/stage_1/compareLetters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Compares two strings and count how many letters in the first string 3 | * are in the second string 4 | * 5 | * @param {*} stringA The string to compare 6 | * @param {*} stringB The string to be compared with 7 | */ 8 | 9 | const J = "aA"; 10 | const S = "aAAbbbb"; 11 | 12 | function mine(stringA, stringB){ 13 | stringA = stringA.toString(); 14 | stringB = stringB.toString(); 15 | let count = 0; 16 | for (let letter of stringA){ 17 | for (let char of stringB){ 18 | if (letter == char){ 19 | count++; 20 | } 21 | } 22 | } 23 | return count; 24 | } 25 | 26 | console.log(mine(J, S)); -------------------------------------------------------------------------------- /js/stage_1/deepEqual.js: -------------------------------------------------------------------------------- 1 | /**Given two values, check if they are equal 2 | * ie have the same values 3 | */ 4 | 5 | function deepEqual(obj1, obj2) { 6 | if (obj1 === obj2) return true; 7 | else if ((typeof(obj1) === 'object' && obj1 !== null) 8 | && (typeof(obj2) === 'object' && obj2 !== null)) { 9 | //first check to see that they have same number of keys 10 | if (Object.keys(obj1).length !== Object.keys(obj2).length) return false; 11 | //check each property 12 | for (let prop in obj1){ 13 | if (obj2.hasOwnProperty(prop)){ 14 | if (!deepEqual(obj1[prop], obj2[prop])) return false; 15 | } else return false 16 | } 17 | return true; 18 | } 19 | else return false 20 | } 21 | 22 | let obj1 = {data: 1, left: {right: 1}}; 23 | let obj2 = {data: 1, left: {right: {right: 3}}}; 24 | console.log(deepEqual(obj1, obj2)); -------------------------------------------------------------------------------- /js/stage_1/diagonalSums.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the absolute difference of the left and right diagonal sum of a 2D array 3 | * @param {Array} param 4 | */ 5 | function diagonalSums(param) { 6 | const n = param.length; 7 | // to help immutability, copy arr out 8 | const arr = [...param]; 9 | // right diagonal 10 | let i = 0, ltrSum = 0; 11 | while (i < arr.length) { 12 | ltrSum += arr[i][i] 13 | i++; 14 | } 15 | 16 | // left diagonal 17 | let j = 0, k = n - 1, rtlSum = 0; 18 | while (j < n && k >= 0) { 19 | rtlSum += arr[j][k]; 20 | j++; k--; 21 | } 22 | 23 | return Math.abs(ltrSum - rtlSum); 24 | 25 | } 26 | 27 | console.log(diagonalSums([[-10, 3, 0, 5, 4], 28 | [2, -1, 0, 2, -8], 29 | [9, -2, -5, 6, 0], 30 | [9, -7, 4, 8, -2], 31 | [3, 7, 8, -5, 0]])); -------------------------------------------------------------------------------- /js/stage_1/fizzBuzz.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Complete the 'fizzBuzz' function below. 3 | * 4 | * The function accepts INTEGER n as parameter. 5 | */ 6 | 7 | function fizzBuzz(n) { 8 | // Write your code here 9 | if (n % 3 == 0 && n%5 == 0) {console.log("FizzBuzz");} 10 | else if (n % 3 == 0 && n % 5 != 0) {console.log("Fizz");} 11 | else if (n % 5 == 0 && n % 3 != 0) {console.log("Buzz");} 12 | else { console.log(n) } 13 | 14 | } 15 | 16 | fizzBuzz(15); 17 | fizzBuzz(5); 18 | fizzBuzz(3); 19 | -------------------------------------------------------------------------------- /js/stage_1/halloweenParty.js: -------------------------------------------------------------------------------- 1 | function halloweenParty(k) { 2 | /* 3 | * Write your code here. 4 | */ 5 | let horizontal = Math.floor(k/2); 6 | let vertical = Math.ceil(k/2) 7 | return horizontal*vertical 8 | 9 | } 10 | 11 | console.log(halloweenParty(8)) -------------------------------------------------------------------------------- /js/stage_1/hammingDistance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The Hamming distance between two integers is the number of positions at which the corresponding bits are different. 3 | Given two integers x and y, calculate the Hamming distance. 4 | 5 | Note: 6 | 0 ≤ x, y < 231. 7 | 8 | Example: 9 | 10 | Input: x = 1, y = 4 11 | 12 | Output: 2 13 | 14 | Explanation: 15 | 1 (0 0 0 1) 16 | 4 (0 1 0 0) 17 | ↑ ↑ 18 | 19 | The above arrows point to positions where the corresponding bits are different. 20 | */ 21 | /** 22 | * Returns the hammingDistance 23 | * @param {Number} i 24 | * @param {Number} j 25 | */ 26 | function hammingDistance(i, j) { 27 | let n = i ^ j; 28 | let count = 0; 29 | while (n > 0) { 30 | n = n & (n - 1); 31 | count++; 32 | } 33 | return count; 34 | } 35 | 36 | console.log(hammingDistance(1, 5)); 37 | 38 | /* 39 | Subtracting 1 from a decimal number flips all the bits after the rightmost set bit(which is 1) including the rightmost set bit. 40 | for example : 41 | 10 in binary is 00001010 42 | 9 in binary is 00001001 43 | 8 in binary is 00001000 44 | 7 in binary is 00000111 45 | So if we subtract a number by 1 and do bitwise & with itself (n & (n-1)), we unset the rightmost set bit. If we do n & (n-1) in a loop and count the no of times loop executes we get the set bit count. 46 | The beauty of this solution is the number of times it loops is equal to the number of set bits in a given integer. 47 | */ -------------------------------------------------------------------------------- /js/stage_1/hourGlassMax.js: -------------------------------------------------------------------------------- 1 | /* Question: 2 | Given an nxn matrix, compute the hourglass sum and return the max. 3 | for example, given the matrix 4 | [a1, a2, a3, a4 5 | b1, b2, b3, b4 6 | c1, c2, c3, c4 7 | d1, d2, d3, d4] 8 | It's possible hourglass would be 9 | 1. a1, a2, a3 10 | b2 ;sum = a1+a2+a3+b2+c1+c2+c3 11 | c1, c2, c3 12 | 13 | 2. a2, a3, a4 14 | b3 ;sum = sum them all; 15 | c2, c3, c4 16 | 17 | 3. b1, b2, b3 18 | c2 19 | d1, d2, d3 20 | 21 | 3. b2, b3, b4 22 | c3 23 | d2, d3, d4 24 | */ 25 | 26 | const DATA = [[-1, -1, 0, -9, -2, -2], [-2, -1, -6, -8, -2, -5], [-1, -1, -1, -2, -3, -4], 27 | [-1, -9, -2, -4, -4, -5], [-7, -3, -3, -2, -9, -9], [-1, -3, -1, -2, -4, -5]]; 28 | 29 | const hourGlassMax = (ar) => { 30 | let max = -Infinity; 31 | for(let i = 0; i < ar.length - 2; i++) { 32 | for(let j = 0; j < 4; j++) { 33 | //computing the sum of each hourglass figure 34 | const sum = ar[i][j] + ar[i][j+1] + ar[i][j+2] + ar[i+1][j+1] 35 | + ar[i+2][j] + ar[i+2][j+1] + ar[i+2][j+2]; 36 | 37 | //computing the max 38 | max = sum > max ? sum : max; 39 | } 40 | } 41 | return max; 42 | } -------------------------------------------------------------------------------- /js/stage_1/indexSumToTarget.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an array, find the index of two digits that sum 3 | * up to a given target. Provided that 4 | * 1. the numbers are not repeated 5 | * 2. you cant sum same number twice 6 | * For eg 7 | */ 8 | 9 | const nums = [2, 7, 11, 15]; 10 | const target = 22; 11 | 12 | const targetFunction = (nums, target) => { 13 | for (let i = 0; i < nums.length - 1; i++){ 14 | for (let j = 1; j < nums.length; j++){ 15 | let sum = nums[i] + nums[j]; 16 | if (sum === target) return [i, j]; 17 | } 18 | } 19 | } 20 | // console.log(targetFunction(nums, target)); 21 | //output = [1, 3] 22 | 23 | //OR 24 | //I think this is less space complex 25 | 26 | // Lol, It's not babe 27 | function getTarget(nums, target){ 28 | for (let i = 0; ii; j--){ 30 | if((nums[i]+nums[j] === target)) return [i, j]; 31 | } 32 | } 33 | return 'none' 34 | } 35 | // console.log(getTarget(nums, target)); 36 | 37 | // See this. Using Hash Tables 38 | 39 | function getTarget2(array, target){ 40 | let nums = {}; 41 | for(let num in array){ 42 | let secondNum = target - array[num]; 43 | if ( nums[secondNum] ) return [num, nums[secondNum]] 44 | nums[array[num]] = num; 45 | } 46 | return 'none' 47 | } 48 | 49 | // console.log(getTarget2(nums, target)); 50 | 51 | // Or using pointers 52 | // sort in ascending order 53 | // start sum from the utmost left and utmost right, if sum < target, move the left forward 54 | // else move the right backward 55 | 56 | function getTarget3(array, target){ 57 | const sortedArray = array.sort((a, b) => a - b) 58 | let left = 0; 59 | let right = array.length - 1; 60 | while (left < right){ 61 | let cS = sortedArray[left] + sortedArray[right]; 62 | if ( cS === target ) return [left, right] 63 | else if (cS < target) left++; 64 | else if (cS > target) right--; 65 | } 66 | return 'none' 67 | } 68 | 69 | console.log(getTarget3(nums, target)); 70 | 71 | 72 | -------------------------------------------------------------------------------- /js/stage_1/letterA.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Prints the capital letter A in asterisks 3 | * @param {*} n , the height of the letter 4 | */ 5 | function letterA(n) { 6 | let space = n; 7 | let string = ""; 8 | for (let i = 1; i <= n; i++) { 9 | for (let k = 1; k <= space; k++) { 10 | string +=" "; 11 | } 12 | string += "*" ; 13 | for (let m = 1; m < 2 * i - 1; m++) { 14 | if (i == Math.ceil(n / 2)) { string += "*"; } 15 | else { string += " "; } 16 | } 17 | if (i != 1) string += "*"; 18 | string += "\n"; 19 | space--; 20 | } 21 | console.log(string); 22 | } 23 | 24 | letterA(7); -------------------------------------------------------------------------------- /js/stage_1/letterUsage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given a word, you need to judge whether the usage of capitals in it is right or not. 3 | We define the usage of capitals in a word to be right when one of the following cases holds: 4 | 1. All letters in this word are capitals, like "USA". 5 | 2. All letters in this word are not capitals, like "leetcode". 6 | 3. Only the first letter in this word is capital, like "Google". 7 | Otherwise, we define that this word doesn't use capitals in a right way. 8 | * @param {*} str 9 | * 10 | */ 11 | function letterUsage(str){ 12 | let sentenceCase = str[0].toUpperCase() + str.slice(1, str.length).toLowerCase(); 13 | if ((str.toUpperCase() === str) || 14 | (str.toLowerCase() === str) || 15 | (sentenceCase === str)){ 16 | return true; 17 | } 18 | return false; 19 | } 20 | 21 | console.log(letterUsage('GoaH')); -------------------------------------------------------------------------------- /js/stage_1/palindrome.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given a string, check how many palindromes it has. 3 | * A palindrome is a value which is same when reversed, eg mum, 1001 4 | * The substrings with different start indexes or end indexes are 5 | * counted as different substrings even they consist of same characters. 6 | * 7 | * Eg: Given: 8 | * Input: 'aaa'; 9 | * Output: 6 ie 'a', 'a', 'a', 'aa', 'aa', 'aaa' ; 10 | */ 11 | 12 | function palindrome(str){ 13 | let count = 0 14 | for(let i = 0; i 0) { 51 | let rem = x % 10; 52 | x = Math.floor(x / 10); 53 | new_x = new_x * 10 + rem 54 | i++; 55 | } 56 | return new_x === old_x; 57 | }; 58 | 59 | 60 | /* 61 | Determine whether an integer is a palindrome. 62 | An integer is a palindrome when it reads the same backward as forward. 63 | 64 | Example 1: 65 | Input: 121 66 | Output: true 67 | 68 | Example 2: 69 | Input: -121 70 | Output: false 71 | Explanation: From left to right, it reads -121. From right to left, it becomes 121-. 72 | Therefore it is not a palindrome. 73 | 74 | Example 3: 75 | Input: 10 76 | Output: false 77 | Explanation: Reads 01 from right to left. Therefore it is not a palindrome. 78 | 79 | Follow up: 80 | Coud you solve it without converting the integer to a string? 81 | 82 | 83 | if -ve return false 84 | if less than 10 return true 85 | 86 | 87 | 6 88 | 696 % 10 = 6 nums = [6, 9, 6] res = 6 + 90 + 600 = 696 89 | 696 / 10 = 69 90 | 6 * 10 ^ 0 = 6 91 | 92 | 69 % 10 = 9 93 | 69 / 10 = 6 94 | 9 * 10 ^ 2 = 90 95 | 96 | 6 % 10 = 6 97 | 6 * 10 ^ 3 = 600 98 | 6 / 10 = 0 STOP 99 | 100 | end = nums.length - 1 101 | for i to nums.length: 102 | if nums[i] != nums[end] 103 | return False 104 | end--; 105 | return True 106 | 107 | 108 | 109 | 121 --> 110 | 111 | 121 % 10 = 1 112 | 121 / 10 = 12 113 | 114 | 12 % 10 = 2 115 | 12 / 10 = 1 116 | 117 | 1 % 10 = 1 118 | 1 / 10 = 0 STOP 119 | 120 | 121 | 756 --> 122 | 123 | 756 % 10 = 6 124 | 756 / 10 = 75 125 | 126 | 75 % 10 = 5 127 | 75 / 10 = 7 128 | 129 | 7 % 10 = 7 130 | 7 / 10 = 0 STOP 131 | 132 | 133 | */ 134 | -------------------------------------------------------------------------------- /js/stage_1/primes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Count the number of prime numbers less than a non-negative number, num. 3 | * @param {*} num any num 4 | */ 5 | 6 | function isPrime(num){ 7 | for (let i = 2; i< 10; i++){ 8 | if ((num % i) == 0 && (num != i)) return false; 9 | } 10 | return true; 11 | } 12 | 13 | function primes(num){ 14 | let count = 0; 15 | if (num == 1 || num < 1) return 0; 16 | for (let i = 2; i < num; i++){ 17 | if (isPrime(i)) { 18 | console.log(i) 19 | count++; 20 | } 21 | } 22 | return count; 23 | } 24 | 25 | console.log(primes(25)); -------------------------------------------------------------------------------- /js/stage_1/reverseInPlace.js: -------------------------------------------------------------------------------- 1 | // Given an array, reverse it's content 2 | // without creating another array 3 | 4 | function reverseInPlace(arr){ 5 | for(let i = arr.length - 1; i>0; i--){ 6 | let el = arr.shift(); 7 | arr.splice(i, 0, el); 8 | } 9 | return arr; 10 | } 11 | console.log(reverseInPlace([1,2,3,4,5])); -------------------------------------------------------------------------------- /js/stage_1/reverseInteger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given a signed integer, find it's reverse, 3 | * while maintaining the sign 4 | */ 5 | 6 | const int = -2345; //output = -5432 7 | 8 | function reverseInteger(value) { 9 | // const val = int.toString().split('').reverse().join(''); 10 | // or 11 | const val = int.toString(); 12 | let rev = ''; 13 | for( let char of val) rev = char + rev; 14 | const result = Math.sign(value) * parseInt(rev); 15 | return result; 16 | } 17 | console.log(reverseInteger(int)); 18 | -------------------------------------------------------------------------------- /js/stage_1/stripProperty.js: -------------------------------------------------------------------------------- 1 | function getFixedCounter(k) { 2 | // write your code here 3 | const counter = (function counter() { 4 | let value = 0; 5 | return { 6 | getValue: function() { 7 | return value; 8 | }, 9 | changeBy: function(k) { 10 | value += k; 11 | }, 12 | } 13 | })(); 14 | const res = {} 15 | res.increment = function() { 16 | return counter.changeBy(k); 17 | } 18 | res.decrement = function() { 19 | return counter.changeBy(-k); 20 | } 21 | res.getValue = function() { 22 | return counter.getValue(); 23 | } 24 | return res; 25 | } 26 | 27 | const data = getFixedCounter(5); 28 | data.increment(); 29 | console.log(data.getValue()); -------------------------------------------------------------------------------- /js/stage_2/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}/minimumBribes.js" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /js/stage_2/alternatingSort.js: -------------------------------------------------------------------------------- 1 | function alternatingSort(a) { 2 | let left = 0; 3 | let right = a.length - 1; 4 | while (left <= right){ 5 | console.log(a[left], a[right]) 6 | if (a[left] > a[right]) return false; 7 | else if (left === right && a[left] < a[right + 1]) return false 8 | left++; 9 | right--; 10 | } 11 | return true 12 | } 13 | 14 | console.log(alternatingSort([-92, -23, 0, 45, 89, 96, 99, 95, 89, 41, -17, -48])) -------------------------------------------------------------------------------- /js/stage_2/climbTheLeaderboard.js: -------------------------------------------------------------------------------- 1 | function climbTheLeaderboard(scores,alice){ 2 | //create a hashtable of scores 3 | let hashScores = {} 4 | hashScores[scores[0]] = 1; 5 | for(let i = 1; i < scores.length; i++){ 6 | let score = scores[i]; 7 | let prevScore = scores[i-1] 8 | if(!hashScores[score]) hashScores[score] = hashScores[prevScore] + 1; 9 | } 10 | 11 | 12 | let alicePointer = 0; 13 | let scoresPointer = scores.length - 1; 14 | let result = [] 15 | 16 | // since scores are arranged in descending order and alice in ascending order, we move the pointers respectivelu 17 | while (alicePointer < alice.length){ 18 | if (alice[alicePointer] < scores[scoresPointer]){ 19 | // the position becomes the next position 20 | let res = hashScores[scores[scoresPointer]] + 1; 21 | result.push(res) 22 | alicePointer++; 23 | } else if (alice[alicePointer] === scores[scoresPointer]){ 24 | // the position remains the same 25 | let res = hashScores[scores[scoresPointer]]; 26 | result.push(res); 27 | alicePointer++; 28 | } else if (alice[alicePointer] > scores[0]) { 29 | result.push(1); 30 | alicePointer++ 31 | }else { 32 | scoresPointer--; 33 | } 34 | } 35 | return result 36 | } 37 | 38 | climbTheLeaderboard(scores,alice); 39 | 40 | //TEST CASES 41 | 42 | // const scores = [100, 90, 90, 80, 75, 60]; 43 | // const alice = [50, 65, 77, 90, 102]; // output [6, 5, 4, 2, 1] 44 | 45 | // const scores = [100, 100, 50, 40, 40, 20, 10]; 46 | // const alice = [5, 25, 50, 120]; // output [6, 4, 2, 1] 47 | 48 | const scores = [295, 294, 291, 287, 287 ,285, 285, 284 ,283, 279 ,277 ,274 ,274, 271, 270, 268, 268, 49 | 268, 264, 260, 259, 258, 257, 255, 252, 250, 244, 241, 240 ,237 ,236, 236 ,231, 227, 227 ,227, 226, 50 | 225, 224, 223, 216, 212, 200, 197, 196, 194, 193, 189, 188, 187, 183, 182, 178, 177, 173, 171, 169, 51 | 165, 143, 140 ,137, 135, 133, 130, 130, 130, 128, 127, 122, 120, 116, 114, 113, 109, 106 ,103 ,99 ,92, 85, 81, 69, 68, 52 | 63, 63, 63 ,61 ,57 ,51 ,47, 46 ,38, 30 ,28, 25, 22 ,15 ,14, 12, 6 ,4] 53 | 54 | const alice = [5,5,6,14,19,20,23,25,29,29,30,30,32,37,38,38,38,41,41,44,45,45,47,59,59,62,63,65,67,69,70,72,72,76,79,82,83,90,91,92,93,98,98,100,100,102,103,105,106,107,109,112,115,118,118,121,122,122, 55 | 123,125,125,125,127,128,131,131,133,134,139,140,141,143,144,144,144,144,147,150,152,155,156,160, 56 | 164,164,165,165,166,168,169,170,171,172,173,174,174,180,184,187,187,188,194,197,197,197,198,201, 57 | 202,202,207,208,211,212,212,214,217,219,219,220,220,223,225,227,228,229,229,233,235,235,236,242, 58 | 242,245,246,252,253,253,257,257,260,261,266,266,268,269,271,271,275,276,281,282,283,284,285,287, 59 | 289,289,295,296,298,300,300,301,304,306,308,309,310,316,318,318,324,326,329,329,329,330, 60 | 330,332,337,337,341,341,349,351,351,354,356,357,366,369,377,379,380,382,391,391,394,396,396,400] 61 | 62 | // output = [ 88 88 87 85 84 84 83 82 81 81 80 80 80 80 79 79 79 79 79 79 79 79 77 75 75 74 73 73 73 71 63 | // 71 71 71 71 71 70 70 69 69 68 68 68 68 67 67 67 66 66 65 65 64 64 62 61 61 60 59 59 59 59 64 | // 59 59 58 57 56 56 55 55 53 52 52 51 51 51 51 51 51 51 51 51 51 51 51 51 50 50 50 50 49 49 48 48 65 | // 47 47 47 45 43 42 42 41 38 36 36 36 36 35 35 35 35 35 35 34 34 34 33 33 33 33 33 32 30 28 28 28 28 66 | // 27 27 27 26 23 23 22 22 20 20 20 18 18 15 15 14 14 13 13 11 11 10 10 8 8 7 6 5 4 4 4 1 1 1 1 1 1 1 67 | // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] -------------------------------------------------------------------------------- /js/stage_2/countingSort.js: -------------------------------------------------------------------------------- 1 | function countingSort(arr){ 2 | let countArray = []; 3 | let res = []; 4 | // count frequency of occurence of each digit and store in countArray with +1 offset 5 | for (let i = 0; i < arr.length; i++) { 6 | if (countArray[arr[i] + 1] > 0) { 7 | countArray[arr[i] + 1] += 1; 8 | } else { 9 | countArray[arr[i] + 1] = 1; 10 | } 11 | } 12 | 13 | // sum the countArray 14 | for (let i = 0; i < countArray.length - 1; i++) { 15 | if (countArray[i] == undefined) countArray[i] = 0 16 | if (countArray[i+1] == undefined) countArray[i+1] = 0 17 | countArray[i+1] += countArray[i]; 18 | } 19 | 20 | // assign the elements to the position specified by the count array 21 | for (let i = 0; i < arr.length; i++) { 22 | res[countArray[arr[i]]++] = arr[i]; 23 | } 24 | console.log(res) 25 | } 26 | 27 | countingSort([1, 2, 3,4,5,4,3,1]) -------------------------------------------------------------------------------- /js/stage_2/coursePrerequisites.js: -------------------------------------------------------------------------------- 1 | //I'M NOT SURE IF THIS SOLUTION IS CORRECT-- 2 | 3 | // There are a total of n courses you have to take, labeled from 0 to n-1. 4 | // Some courses may have prerequisites, 5 | // For example to take course 0 you have to first take 6 | // course 1, which is expressed as a pair: [0,1] 7 | // Given the total number of courses and a list of prerequisite pairs, is it possible for you to 8 | // finish all courses? 9 | // For the course given below, it is not possible because 10 | // for the first pair: 11 | // to take course 0, you have to take course 1 12 | // and for the second pair: 13 | // to take course 1, you have to take course 0, 14 | // which is impossible. 15 | 16 | let totalCourses = 2; 17 | let courses = [[1, 0], [1, 0]]; 18 | 19 | function search(arr){ 20 | let obj = {}; 21 | for( let elm of arr){ 22 | if (Object.keys(obj).includes(elm[0].toString()) 23 | && obj[elm[0]] == elm[1]) return false; 24 | obj[elm[1]] = elm[0]; 25 | } 26 | return true; 27 | } 28 | // console.log(search(courses)); -------------------------------------------------------------------------------- /js/stage_2/cutTheTree1.js: -------------------------------------------------------------------------------- 1 | // incorrect 2 | function cutTheTree(data, edges) { 3 | let minDiff = Infinity; 4 | edges.forEach(edge => { 5 | // take each edge 6 | let tempEdges = [...edges]; 7 | let index = tempEdges.indexOf(edge); 8 | tempEdges.splice(index, 1); // remove it from search 9 | let leftSum = data[edge[0] - 1]; 10 | let rightSum = data[edge[1] - 1]; 11 | let leftArray = [], rightArray = []; //an array to store the child nodes 12 | for (let i = 0; i 4000000) return sum; 6 | return fibonacci(next, term, sum); 7 | } 8 | 9 | console.log(fibonacci(1, 2)); -------------------------------------------------------------------------------- /js/stage_2/findDigit.js: -------------------------------------------------------------------------------- 1 | function findDigits(n) { 2 | n = ''+n+''; 3 | let count = 0; 4 | let split = n.split(''); 5 | for (let i of split){ 6 | if(n % Number(i) === 0) count++; 7 | } 8 | return count 9 | 10 | } 11 | 12 | console.log(findDigits(55)) -------------------------------------------------------------------------------- /js/stage_2/findMin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var findMin = function(nums) { 6 | let lo = 0; 7 | let hi = nums.length - 1; 8 | while (lo < hi) { 9 | let mid = lo + (hi-lo)/2; 10 | if (nums[mid] < nums[hi]) { 11 | hi = mid; 12 | } else { 13 | lo = mid+1; 14 | } 15 | } 16 | return nums[lo]; 17 | }; 18 | 19 | 20 | /* 21 | Find Minimum in Rotated Sorted Array 22 | 23 | 24 | Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. 25 | 26 | (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). 27 | 28 | Find the minimum element. 29 | 30 | You may assume no duplicate exists in the array. 31 | 32 | Example 1: 33 | 34 | Input: [3,4,5,1,2] 35 | Output: 1 36 | Example 2: 37 | 38 | Input: [4,5,6,7,0,1,2] 39 | Output: 0 40 | 41 | s m e 42 | [4, 15, 20, -5, -3, 0, 3] {s:0, m:3 e: 6} 43 | 0 1 2 3 4 5 6 min = -5 44 | 45 | 46 | s m e 47 | [-3, 0, 3, 4, 15, 20, -5] {s:0, m:3 e: 6} 48 | [ 15, 20, -5] {s:4, m:5 e: 6} 49 | [ -5] {s:6, m:6 e: 6} 50 | 51 | s m e 52 | [3, 4, 5, 1, 2] {s:0, m:2 e: 4} 53 | [ 1, 2] {s:3, m:3 e: 4} 54 | 55 | 56 | s m e 57 | [7,0,1,2,4,5,6] 58 | 59 | 60 | while (start < end) 61 | right must greater 62 | left must less 63 | 64 | if the left and right is greater == min 65 | 66 | 67 | s m e 68 | [4, 15, 20, -5, -3, 0, 3] {s:0, m:3 e: 6} 69 | 0 1 2 3 4 5 6 70 | 71 | m 72 | s e 73 | [-3, 0, 3, 4, 15, 20, -5] {s:0, m:3 e: 6} 74 | 75 | 76 | if mid greater than start and less than end // go left 77 | if mid is less than start // go left 78 | else (=> mid greater than or equal to start) // go right 79 | 80 | 81 | m 82 | s 83 | e 84 | [3, 4, 5, 1, 2] {s:0, m:2 e: 4} 85 | 86 | 87 | [1, 2, 3, 4, 5, 6] 88 | 89 | 90 | m 91 | s 92 | e 93 | [7, 0, 1, 2, 4, 5, 6] {s:0, m:0 e: 1} 94 | 95 | [7, 0, 1, 2] 96 | 97 | [7, 0] 98 | [0] 99 | 100 | 101 | 102 | 103 | */ 104 | -------------------------------------------------------------------------------- /js/stage_2/flattenLinkedList.js: -------------------------------------------------------------------------------- 1 | /** 2 | * // Definition for a Node. 3 | * function Node(val,prev,next,child) { 4 | * this.val = val; 5 | * this.prev = prev; 6 | * this.next = next; 7 | * this.child = child; 8 | * }; 9 | */ 10 | 11 | /** 12 | * @param {Node} head 13 | * @return {Node} 14 | */ 15 | var flatten = function(head) { 16 | if(head === null) return head; 17 | /* 18 | 1---2---3---4---5---6--NULL 19 | | 20 | 7---8---9---10--NULL 21 | | 22 | 11--12--NULL 23 | */ 24 | // initialize the stack with your head node 25 | const stack = [head]; 26 | 27 | let curr = head; 28 | 29 | // 1 <-> 2 <-> 3 30 | 31 | // while stack is not empty 32 | while (stack.length > 0) { // s = [3] 33 | // pop node from stack 34 | let node = stack.pop(); // s = [], n = 3, cur = 2 35 | if (node !== head) { 36 | // add to doubly linkedlist 37 | curr.next = node; 38 | node.prev = curr; 39 | curr = node; 40 | } 41 | 42 | // if node has next 43 | // add next to start 44 | if(node.next !== null){ // s = [7, 4], n = 3, cur = 3 45 | stack.push(node.next); 46 | node.next = null; 47 | } 48 | 49 | // if node has child 50 | // add child to stack 51 | if (node.child !== null){ 52 | stack.push(node.child); 53 | node.child = null; 54 | } 55 | 56 | } 57 | return head 58 | } 59 | /* 60 | 61 | https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/ 62 | 63 | You are given a doubly linked list which in addition to the next and previous pointers, 64 | it could have a child pointer, which may or may not point to a separate doubly linked list. 65 | These child lists may have one or more children of their own, and so on, 66 | to produce a multilevel data structure, as shown in the example below. 67 | 68 | Flatten the list so that all the nodes appear in a single-level, doubly linked list. 69 | You are given the head of the first level of the list. 70 | 71 | 72 | Example 1: 73 | 74 | Input: head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12] 75 | Output: [1,2,3,7,8,11,12,9,10,4,5,6] 76 | Explanation: 77 | 78 | The multilevel linked list in the input is as follows: 79 | 80 | After flattening the multilevel linked list it becomes: 81 | 82 | Example 2: 83 | 84 | Input: head = [1,2,null,3] 85 | Output: [1,3,2] 86 | Explanation: 87 | 88 | The input multilevel linked list is as follows: 89 | 90 | 1---2---NULL 91 | | 92 | 3---NULL 93 | Example 3: 94 | 95 | Input: head = [] 96 | Output: [] 97 | 98 | 99 | How multilevel linked list is represented in test case: 100 | 101 | We use the multilevel linked list from Example 1 above: 102 | 103 | 1---2---3---4---5---6--NULL 104 | | 105 | 7---8---9---10--NULL 106 | | 107 | 11--12--NULL 108 | 109 | 1 -> 2 -> 3 -> 7 -> 8 -> 11 -> 12 -> 9 -> 10 -> 4 -> 5 -> 6 -> null 110 | 111 | stack = [1] 112 | res = <-- Head --> 1 <-- Tail ---> 113 | 114 | 115 | while stack is not empty: s = [3] 116 | 117 | remove from stack s = [] 118 | add to linkedList res = 1 <-> 2 <-> 3 119 | 120 | if node has child 121 | add child to stack s = [7] 122 | if node has next 123 | add next to stack s = [7, 4] 124 | 125 | s = [1 4] 126 | 127 | 128 | The serialization of each level is as follows: 129 | 130 | [1,2,3,4,5,6,null] 131 | [7,8,9,10,null] 132 | [11,12,null] 133 | To serialize all levels together we will add nulls in each level to signify no node 134 | connects to the upper node of the previous level. The serialization becomes: 135 | 136 | [1,2,3,4,5,6,null] 137 | [null,null,7,8,9,10,null] 138 | [null,11,12,null] 139 | Merging the serialization of each level and removing trailing nulls we obtain: 140 | 141 | [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12] 142 | 143 | Constraints: 144 | 145 | Number of Nodes will not exceed 1000. 146 | 1 <= Node.val <= 10^5 147 | 148 | */ 149 | -------------------------------------------------------------------------------- /js/stage_2/h_index.js: -------------------------------------------------------------------------------- 1 | /**Given a list of publications, find the publishers h-index 2 | * Please google what h-index means if you're confused 3 | */ 4 | 5 | function hIndex(arr){ 6 | arr = arr.sort((a, b) => b-a); 7 | console.log(arr) 8 | for (let i = 0; i= maximum.val){ 42 | return false 43 | } 44 | 45 | return isValidBST(root.left, minimum, root) && isValidBST(root.right, root, maximum) 46 | 47 | } -------------------------------------------------------------------------------- /js/stage_2/kthNodeInBST.js: -------------------------------------------------------------------------------- 1 | 2 | function TreeNode(val, left, right) { 3 | this.val = (val===undefined ? 0 : val) 4 | this.left = (left===undefined ? null : left) 5 | this.right = (right===undefined ? null : right) 6 | } 7 | 8 | /** 9 | * @param {TreeNode} root 10 | * @param {number} k 11 | * @return {number} 12 | */ 13 | function kthLargest(root, k) { 14 | this.res = root.val; 15 | this.count = 0; 16 | this.root = root; 17 | }; 18 | 19 | kthLargest.prototype.modifyKthLargest = function (root) { 20 | if (root == null) return; 21 | 22 | // go to the right 23 | this.modifyKthLargest(root.right); 24 | 25 | // count node as seen 26 | this.count++; 27 | 28 | // return if node is greater than k 29 | if (this.count >= k) { 30 | if (this.count == k) this.res = root.val; 31 | return; 32 | } 33 | 34 | // go to the left 35 | this.modifyKthLargest(root.left); 36 | } 37 | 38 | kthLargest.prototype.getKth = function() { 39 | this.modifyKthLargest(this.root); 40 | return this.res; 41 | } 42 | 43 | 44 | const getTree = () => { 45 | /* 46 | 7 47 | / \ 48 | 3 15 49 | / \ / \ 50 | 2 5 10 20 51 | / / / \ / \ 52 | 1 4 8 12 18 22 53 | */ 54 | const nodeVals = [8, 12, 18, 22, 10, 20, 1, 4, 2, 5, 3, 7, 15] 55 | const root = new TreeNode(nodeVals[0]) 56 | for(let i=1; i < nodeVals.length; i++){ 57 | let currNode = new TreeNode(nodeVals[i]); 58 | insertToTree(root, currNode); 59 | } 60 | return root; 61 | } 62 | 63 | const insertToTree = (root, node) => { 64 | if (node.val <= root.val) { 65 | if (root.left === null) { 66 | root.left = node; 67 | return 68 | } 69 | insertToTree(root.left, node); 70 | } 71 | else { 72 | if (root.right === null){ 73 | root.right = node; 74 | return 75 | } 76 | insertToTree(root.right, node); 77 | } 78 | } 79 | 80 | const root = getTree(); 81 | const k = 10; 82 | const kth = new kthLargest(root, k); 83 | console.log(kth.getKth()); 84 | 85 | 86 | 87 | /* 88 | 89 | Given a binary search tree, write a function to find the kth largest element in it. 90 | 91 | Example 1: 92 | Input: root = [3,1,4,null,2], k = 1 93 | 3 94 | / \ 95 | 1 4 96 | \ 97 | 2 98 | Output: 4 99 | 100 | 101 | Example 2: 102 | Input: root = [5,3,6,2,4,null,null,1], k = 3 103 | 5 104 | / \ 105 | 3 6 106 | / \ 107 | 2 4 108 | / 109 | 1 110 | Output: 4 111 | 112 | 113 | Follow up: 114 | 115 | What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? 116 | How would you optimize the kthSmallest routine? 117 | 118 | 119 | Constraints: 120 | 121 | The number of elements of the BST is between 1 to 10^4. 122 | You may assume k is always valid, 1 ≤ k ≤ BST's total elements. 123 | 124 | #### SOLUTION: 125 | 126 | METHOD 1: 127 | Traverse the tree, inorder, then print the n - kth element 128 | 129 | Inorder - left ROOT right 130 | Preorder - ROOT left right 131 | Postorder- left right ROOT 132 | 133 | METHOD 2: 134 | O() 135 | 136 | res; 137 | count; 138 | 7 139 | / \ 140 | 3 15 141 | / \ / \ 142 | 2 5 10 20 143 | / / / \ / \ 144 | 1 4 8 12 18 22 145 | null 146 | 147 | If node == null return; 148 | check(node.right) 149 | count +=1 count=6 150 | if count >= k { 151 | if count == k res = node; 152 | return 153 | } 154 | check(node.left) 155 | return 156 | 157 | 3 158 | / \ 159 | 1 4 count = 1 if count = k, res = 4, return 160 | \ 161 | 2 162 | 163 | k = 6, value=10 164 | */ -------------------------------------------------------------------------------- /js/stage_2/longestRepeatedSubstring.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | var lengthOfLongestSubstring = function(s) { 6 | let max = 0; 7 | let start = 0 8 | let already_visited = {} 9 | for (let e = 0; e < s.length; e++) { 10 | if (s[e] in already_visited && start <= already_visited[s[e]]) { 11 | start = already_visited[s[e]] + 1; 12 | } 13 | already_visited[s[e]] = e; 14 | max = Math.max(max, e - start + 1); 15 | } 16 | 17 | return max; 18 | }; 19 | 20 | 21 | 22 | /* 23 | Longest Substring Without Repeating Characters 24 | 25 | Given a string, find the length of the longest substring without repeating characters. 26 | 27 | Example 1: 28 | 01234567 29 | Input: "abcabcbb" 30 | Output: 3 31 | Explanation: The answer is "abc", with the length of 3. 32 | 33 | Example 2: 34 | Input: "bbbbb" 35 | Output: 1 36 | Explanation: The answer is "b", with the length of 1. 37 | 38 | Example 3: 39 | Input: "pwwkew" 40 | Output: 3 41 | Explanation: The answer is "wke", with the length of 3. 42 | Note that the answer must be a substring, "pwke" is a subsequence and not a substring. 43 | 44 | 45 | let max = 0; 46 | start = 0 47 | let already_visited = {} 48 | for (let e = 0; e < s.length; e++) { 49 | if (already_visited[s[e]] && start <= already_visited[e]) { 50 | start = already_visted[s[e]] + 1; 51 | } 52 | already_visited[s[e]] = e; 53 | max = Math.max(max, start - end + 1); 54 | } 55 | 56 | return max; 57 | 58 | 59 | {a:4, b:1, c:5} 60 | s=4 61 | 62 | a b c a a c b d 63 | e=6 64 | 65 | 66 | max = e - s + 1 = 3 67 | 68 | 69 | */ -------------------------------------------------------------------------------- /js/stage_2/makeChange.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given an integer representing a given amount of change, 3 | * write a function to compute the min total amount of coins required to make that amount of change. 4 | * You can assume that there's always a N1 coin 5 | * Eg given coins = {1, 5, 10, 25} 6 | * makeChange(1) = 1 (1) 7 | * makeChange(6) = 2 (5 + 1) 8 | * makeChange(49) = 7 (25 + 10 + 10 + 1 + 1 + 1 + 1); 9 | */ 10 | 11 | /** 12 | * Brute force checks all possible combinations of change and returns the min 13 | * @param {Number[]} coins 14 | * @param {Number} target 15 | */ 16 | // 25 [10, 6, 1] 17 | /** 18 | 19 | */ 20 | function bruteForce(target, coins) { 21 | if (target === 0) return 0; 22 | 23 | let minCoins = Infinity; 24 | // check all combinations by removing each coin 25 | for (const coin of coins) { 26 | if (target - coin < 0) continue; // we can't make change with this current coin, so next one 27 | let curMinCoins = 1 + bruteForce(target - coin, coins); 28 | if (curMinCoins < minCoins) { 29 | minCoins = curMinCoins; 30 | } 31 | } 32 | return minCoins; 33 | } 34 | 35 | // Since each make coin calls a subproblem, we will see from the graph that we can optimize it 36 | /** [10, 6, 1] a = -10, b = -6, c = -1 37 | * 25 38 | * /a \ 39 | * 15 40 | * /a |b \c 41 | * 5 9 14 42 | * /a |b \c /a |b \c ... 43 | * F F 4 F 3 8 44 | * ... ... ... 45 | * 46 | * 47 | */ 48 | function DPTopDown(target, coins) { 49 | // initialize cache 50 | return DPTopDownHelper(target, coins, [0]); 51 | } 52 | 53 | function DPTopDownHelper(target, coins, cache) { 54 | if (cache[target] !== undefined) return cache[target]; 55 | 56 | let minCoins = Infinity; 57 | // check all combinations by removing each coin 58 | for (const coin of coins) { 59 | if (target - coin < 0) continue; // we can't make change with this current coin, so next one 60 | let curMinCoins = 1 + DPTopDownHelper(target - coin, coins, cache); 61 | if (curMinCoins < minCoins) { 62 | minCoins = curMinCoins; 63 | } 64 | } 65 | cache[target] = minCoins; 66 | return cache[target]; 67 | 68 | } 69 | 70 | // calculate the amount of coins needed to make change from 1 up till target - 1, then get for target 71 | // this works because there is always a one dollar coin or maybe not. What do you think? 72 | 73 | function DPBottomUp(target, coins) { 74 | const cache = [0]; 75 | for(let i = 1; i <= target; i++) { 76 | let minCoins = Infinity; 77 | 78 | for (const coin of coins) { 79 | if (i - coin < 0) continue; 80 | let curMinCoins = 1 + cache[i-coin]; 81 | if (curMinCoins < minCoins) { 82 | minCoins = curMinCoins; 83 | } 84 | } 85 | cache[i] = minCoins; 86 | } 87 | return cache[target]; 88 | } 89 | console.time("bruteForce"); 90 | console.log(bruteForce(49, [1, 5, 10, 25])); 91 | console.timeEnd("bruteForce"); 92 | 93 | console.time("DPTopDown"); 94 | console.log(DPTopDown(49, [1, 5, 10, 25])); 95 | console.timeEnd("DPTopDown"); 96 | 97 | console.time("DPBottomUp"); 98 | console.log(DPBottomUp(49, [1, 5, 10, 25])); 99 | console.timeEnd("DPBottomUp"); 100 | -------------------------------------------------------------------------------- /js/stage_2/mergeIntervals.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} intervals 3 | * @return {number[][]} 4 | */ 5 | var merge = function(intervals) { 6 | if (intervals.length <= 0) return []; 7 | 8 | // sort the intervals according to index 0; 9 | intervals.sort((a, b) => a[0]-b[0]); 10 | 11 | const merged = [intervals[0]]; 12 | // keep track of current and next 13 | // loop through 14 | let end = merged.length - 1; 15 | for(let i = 0; i < intervals.length; i++) { 16 | if (merged[end][1] >= intervals[i][0]) { 17 | merged[end][1] = Math.max(intervals[i][1], merged[end][1]); 18 | } else { 19 | merged.push(intervals[i]); 20 | } 21 | end = merged.length - 1; 22 | } 23 | 24 | return merged; 25 | } 26 | 27 | 28 | 29 | 30 | /* 31 | Merge Interval: Medium 32 | 33 | Given a collection of intervals, merge all overlapping intervals. 34 | 35 | Example 1: 36 | 37 | Input: [ [1, 3], [2, 6], [8, 10], [15, 18] ] 38 | Output: [ [1, 6], [8, 10], [15, 18]] 39 | Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. 40 | Example 2: 41 | 42 | Input: [[1,4],[4,5]] 43 | Output: [[1,5]] 44 | Explanation: Intervals [1,4] and [4,5] are considered overlapping. 45 | 46 | 47 | result = [[1, 6], [8, 10], [15, 18]] 48 | current = [15, 18] 49 | [ [1, 3], [8, 10], [15, 18], [2, 6]] 50 | n=3 51 | 52 | intervals = [ [1, 9], [2, 5], [19, 20], [10, 11], [12, 20], [0, 1], [0, 3], [0, 2] ] 53 | n = 3 54 | 55 | [[0, 1], [0, 3], [0, 2], [1, 9], [2, 5], [10, 11], [12, 20], [19, 20]] 56 | i=0 57 | 58 | merged = [[0, 9], [10, 11]] 59 | 60 | merged = [[0, 9], [10, 11], [12, 20]] 61 | Array.sort((a, b) => { 62 | return a[0]-b[0]; 63 | }) 64 | */ -------------------------------------------------------------------------------- /js/stage_2/migratoryBirds.js: -------------------------------------------------------------------------------- 1 | 2 | /**You have been asked to help study the population of birds migrating across the continent. 3 | * Each type of bird you are interested in will be identified by an integer value. Each time a 4 | * particular kind of bird is spotted, its id number will be added to your array of sightings. 5 | * You would like to be able to find out which type of bird is most common given a list of sightings. Your task is to print the type number of that bird and if 6 | * two or more types of birds are equally common, choose the type with the smallest ID number.*/ 7 | 8 | function migratoryBirds(arr) { 9 | let count = {}, compare = 0, mostFrequent = 0; 10 | for (let i = 0; i < arr.length; i++){ 11 | if (count[arr[i]]) { 12 | count[arr[i]] = count[arr[i]] + 1; 13 | if (compare < count[arr[i]]){ 14 | compare = count[arr[i]]; 15 | mostFrequent = arr[i]; 16 | } 17 | } 18 | else { 19 | count[arr[i]] = 1; 20 | if (compare < count[arr[i]]){ 21 | compare = count[arr[i]]; 22 | mostFrequent = arr[i]; 23 | } 24 | } 25 | } 26 | return mostFrequent; 27 | } 28 | 29 | console.log(migratoryBirds([1,1,2,2,3,3])) -------------------------------------------------------------------------------- /js/stage_2/minMoves.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, where a move is incrementing a selected element by 1 or decrementing a selected element by 1. 3 | 4 | You may assume the array's length is at most 10,000. 5 | 6 | Example: 7 | 8 | Input: 9 | [1,2,3] 10 | 11 | Output: 12 | 2 13 | 14 | Explanation: 15 | Only two moves are needed (remember each move increments or decrements one element): 16 | 17 | [1,2,3] => [2,2,3] => [2,2,2] 18 | 19 | */ 20 | 21 | /** 22 | * @param {number[]} nums 23 | * @return {number} 24 | */ 25 | var minMoves2 = function (nums) { 26 | if (nums.length <= 1) return 0; 27 | // get the median element and calculate the sum of distances of each element from the median 28 | // we will be using quick select, for get median in average O(N) time 29 | 30 | // find median, which is the kth smallest element in nums ie 31 | // if nums in sorted order: nums[floor(l/2)] for odd numbers or (nums[l/2] + nums[l/2 - 1])/2 element 32 | let median = Math.floor(nums.length / 2); 33 | if (nums.length % 2 == 1) { 34 | median = getMedian(nums, median); 35 | } else { 36 | median = Math.floor((getMedian(nums, median) + getMedian(nums, median - 1)) / 2) 37 | } 38 | 39 | // get sum 40 | let min = 0; 41 | for (let i = 0; i < nums.length; i++) { 42 | min += Math.abs(nums[i] - median) 43 | } 44 | return min; 45 | }; 46 | 47 | var getMedian = function (nums, k) { 48 | // O(N) average case 49 | let pivot = getPivot(nums); 50 | let arr = [...nums]; 51 | while (arr.length > 1) { 52 | // get all numbers greater than pivot 53 | // get all numbers less than pivot 54 | // get all numbers equal to pivot 55 | let less = [], greater = [], pivots = []; 56 | for (let i = 0; i < arr.length; i++) { 57 | let cur = arr[i]; 58 | if (cur < pivot) { less.push(cur); } 59 | else if (cur > pivot) { greater.push(cur); } 60 | else { pivots.push(cur); } 61 | } 62 | 63 | if (k < less.length) { // ie our median is somewhere in the less array 64 | pivot = getPivot(less); 65 | arr = less; 66 | } else if (k < less.length + pivots.length) { // ie our element is in the pivots arr, the value is pivot 67 | arr = [pivot]; 68 | break; 69 | } else { // median is in the greater array 70 | pivot = getPivot(greater); 71 | arr = greater; 72 | k = k - less.length - pivots.length; // the kth element into the greater array, counting from the less array 73 | } 74 | } 75 | return arr[0]; 76 | } 77 | 78 | var getPivot = function (arr) { 79 | return arr[Math.floor(Math.random() * arr.length)]; 80 | } 81 | 82 | console.log(minMoves2([1, 0, 0, 8, 6])); -------------------------------------------------------------------------------- /js/stage_2/minStepToN.js: -------------------------------------------------------------------------------- 1 | /** 2 | Initial 15 minutes resume and experience. Then, one technical question on coderpad: 3 | 4 | Given an int n. You can use only 2 operations: 5 | 6 | multiply by 2 7 | integer division by 3 (e.g. 10 / 3 = 3) 8 | Find the minimum number of steps required to generate n from 1. 9 | 10 | Example 1: 11 | Input: 10 12 | Output: 6 13 | Explanation: 1 * 2 * 2 * 2 * 2 / 3 * 2 14 | 6 steps required, as we have used 5 multiplications by 2, and one division by 3. 15 | 16 | 17 | Example 2: 18 | 19 | Input: 3 20 | Output: 7 21 | Explanation: 1 * 2 * 2 * 2 * 2 * 2 / 3 / 3 22 | 7 steps required, as we have used 5 multiplications by 2 and 2 divisions by 3 23 | 24 | 1 val(10) 25 | *2 / \ \3 26 | 2 0 (F) 27 | *2 / \ \3 28 | 4 0 (F) 29 | *2 / \ \3 30 | 8 1 seen 31 | *2 / \ \3 32 | 16 2 (seen) 33 | *2 / \ \3 34 | 32 5 35 | *2 / 36 | 10 (P) 37 | 38 | 39 | oldLevel = [1] 40 | seen = {} // hash set 41 | step = 0 42 | 43 | while oldLevel not empty { 44 | newLevel = [] 45 | // get the children 46 | for (child in oldLevel) { 47 | seen.put(child) 48 | if (child == target) { 49 | return step; 50 | } 51 | // append children if greater than zero and we have not seen it before 52 | // multiply 2 53 | 54 | let left = child * 2; 55 | if (left != seen and left is not zero) { 56 | left.push(newLevel) 57 | } 58 | let right = child \3; 59 | // divide by 3 60 | if (right is not seen and left is not zero) 61 | } 62 | step += 1 63 | oldLevel = newLevel 64 | } 65 | 66 | */ 67 | 68 | const minStepToN = function(target) { 69 | let oldLevel = [1]; 70 | let seen = {}; 71 | let step = 0; 72 | 73 | while (oldLevel.length > 0) { 74 | let newLevel = []; 75 | 76 | // get the children 77 | for(let parent of oldLevel) { 78 | seen[parent] = true; 79 | 80 | if (parent === target) { 81 | return step; 82 | } 83 | 84 | // left child 85 | let left = parent * 2; 86 | if (!(left in seen) && left > 0) { 87 | newLevel.push(left); 88 | } 89 | 90 | // right child 91 | let right = Math.floor(parent / 3); 92 | if(!(right in seen) && right > 0){ 93 | newLevel.push(right); 94 | } 95 | } 96 | step += 1; 97 | oldLevel = newLevel; 98 | } 99 | return step; 100 | } 101 | 102 | 103 | const n = 3; 104 | console.log(minStepToN(n)); 105 | -------------------------------------------------------------------------------- /js/stage_2/minimumSwaps.js: -------------------------------------------------------------------------------- 1 | /**You are given an unordered array consisting of consecutive integers [1, 2, 3, ..., n] 2 | * without any duplicates. You are allowed to swap any two elements. 3 | * You need to find the minimum number of swaps required to sort the array in ascending order. */ 4 | 5 | function minimumSwaps(arr) { 6 | let temp, pos = {}, count = 0; 7 | 8 | // create hash to store initial conditions // o(n) 9 | for (let i = 0; i < arr.length; i++) { 10 | pos[arr[i]] = i; 11 | } 12 | 13 | for (let i = 0; i < arr.length - 1; i++) { 14 | if (arr[i] === i+1) continue; 15 | // swap 16 | temp = arr[i]; 17 | arr[i] = i + 1; 18 | arr[pos[i+1]] = temp; 19 | 20 | // update position 21 | pos[temp] = pos[i+1] 22 | ++count; 23 | } 24 | return count; 25 | } 26 | 27 | console.log(minimumSwaps([7, 1, 3, 2, 4, 5 ,6])); 28 | console.log(minimumSwaps([4, 3, 1, 2])); 29 | console.log(minimumSwaps([1, 3, 5, 2, 4, 6, 7])); 30 | -------------------------------------------------------------------------------- /js/stage_2/rightSideView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * function TreeNode(val, left, right) { 4 | * this.val = (val===undefined ? 0 : val) 5 | * this.left = (left===undefined ? null : left) 6 | * this.right = (right===undefined ? null : right) 7 | * } 8 | */ 9 | /** 10 | * @param {TreeNode} root 11 | * @return {number[]} 12 | 13 | levelNodes = [1] 14 | level = 1 15 | sideView = [] 16 | 17 | 18 | while levelNodes is not empty: 19 | // for every child in level nodes, append to new level 20 | sideView.append(levelNodes[-1]) 21 | new_level_nodes = [] 22 | for parent in levelNodes { 23 | if (parent.left != null) { 24 | new_level_nodes.append(child) 25 | } 26 | if (parent.right != null) { 27 | new_level_nodes.append(child) 28 | } 29 | } 30 | 31 | levelNodes = new_level_nodes 32 | level += 1 33 | 34 | */ 35 | 36 | var rightSideView = function(root) { 37 | if(root === null) return []; 38 | let levelNodes = [root]; 39 | const sideView = []; 40 | while (levelNodes.length > 0) { 41 | sideView.push(levelNodes[levelNodes.length-1].val); 42 | let newLevelNodes = []; 43 | for (let parent of levelNodes) { 44 | if (parent.left !== null) { 45 | newLevelNodes.push(parent.left); 46 | } 47 | if (parent.right !== null) { 48 | newLevelNodes.push(parent.right) 49 | } 50 | } 51 | levelNodes = newLevelNodes; 52 | } 53 | return sideView; 54 | }; 55 | 56 | 57 | /* 58 | 1 59 | / 60 | 2 61 | 62 | https://leetcode.com/problems/binary-tree-right-side-view/ 63 | 64 | Given a binary tree, imagine yourself standing on the right side of it, 65 | return the values of the nodes you can see ordered from top to bottom. 66 | 67 | Example: 68 | 69 | Input: [1,2,3,null,5,null,4] 70 | Output: [1, 3, 4] 71 | Explanation: 72 | 73 | 1 <--- (-) 74 | / \ | 75 | 2 3 <--- | 76 | \ / \ 77 | 5 <--- 78 | 79 | 80 | 1 81 | / \ 82 | 2 3 83 | \ / \ 84 | 5 6 7 85 | / \ / 86 | 4 8 12 87 | / \ 88 | 9 10 89 | 90 | levelNodes = [1] 91 | level = 1 92 | sideView = [] 93 | 94 | 95 | while levelNodes is not empty: 96 | // for every child in level nodes, append to new level 97 | sideView.append(levelNodes[-1]) 98 | new_level_nodes = [] 99 | for parent in levelNodes { 100 | if (parent.left != null) { 101 | new_level_nodes.append(child) 102 | } 103 | if (parent.right != null) { 104 | new_level_nodes.append(child) 105 | } 106 | } 107 | 108 | levelNodes = new_level_nodes 109 | level += 1 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | */ 119 | -------------------------------------------------------------------------------- /js/stage_2/savePrincess.js: -------------------------------------------------------------------------------- 1 | function displayPathtoPrincess(dimension, grid) 2 | { 3 | // Your Code here 4 | //get bot position 5 | var bot, princess, move = ''; 6 | for(let r = 0; r < dimension; r++){ 7 | for(let c = 0; c < dimension; c++){ 8 | if (grid[r][c] === 'm') { 9 | bot = [r, c]; 10 | if (princess) break; 11 | } 12 | //get princess position 13 | if (grid[r][c] === 'p') { 14 | princess = [r, c]; 15 | if (bot) break; 16 | } 17 | } 18 | } 19 | function moveDown(){ 20 | bot[0] += 1; 21 | move += 'DOWN \n'; 22 | } 23 | function moveUp(){ 24 | bot[0] -= 1; 25 | move += 'UP \n'; 26 | } 27 | function moveRight(){ 28 | bot[1] += 1; 29 | move += 'RIGHT \n'; 30 | } 31 | function moveLeft(){ 32 | bot[1] -=1; 33 | move += 'LEFT \n'; 34 | } 35 | // move up, down, right till bot position = princess 36 | while(bot[0] !== princess[0]|| bot[1] !== princess[1]){ 37 | if (bot[0] > princess[0]) moveUp(); 38 | else if (bot[0] < princess[0]) moveDown(); 39 | if (bot[1] > princess[1]) moveLeft(); 40 | else if (bot[1] < princess[1]) moveRight(); 41 | } 42 | return move; 43 | } 44 | 45 | console.log(displayPathtoPrincess(3, [['-','-','-'], ['-','m','-'], ['p','-','-']])) -------------------------------------------------------------------------------- /js/stage_2/shortestTransform.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given a start word, an end word and a dictionary of words 3 | * find the length of the shortest transformation from the start word to end word 4 | * such that 5 | * 1. Each word is transformed to the next word by a change in just one letter 6 | * 2. Each word transformed to, must be in the dictionary 7 | * eg, the sample given below maybe transformed as follows: 8 | * hit -> hot -> lot -> log -> cog 9 | * giving transformation length as 5. 10 | */ 11 | 12 | //function to check if two words are adjacent 13 | function isAdjacent(word1, word2){ 14 | let count = 0; 15 | for (let i = 0; i 1) return false; 18 | } 19 | return (count == 1) ? true: false; 20 | } 21 | 22 | //bfs 23 | function shortestTransform (begin, end, dict){ 24 | let count = 1; 25 | let queue = [begin]; 26 | 27 | let seen = {}; 28 | 29 | while(queue.length > 0){ 30 | let level = []; 31 | 32 | // for each word in the queue 33 | for (let i = 0; i < queue.length; i++) { 34 | let curItem = queue[i]; 35 | 36 | if (queue[i] == end){ 37 | return count; 38 | } 39 | 40 | // add their children only if we've not seen that word before 41 | // this is inefficient because you are checking each word in dict 42 | // check variations of the current word and see if it exists in dict(convert dict to obj for o(1) search) 43 | // SEE WORD LADDER JAVA IMPLEMENTATION 44 | for(let j = 0; j < dict.length; j++){ 45 | if (isAdjacent(curItem, dict[j]) && !seen[dict[j]]){ 46 | seen[dict[j]] = true; 47 | level.push(dict[j]); 48 | } 49 | } 50 | } 51 | queue = level; 52 | count++; 53 | } 54 | return 0; 55 | } 56 | 57 | let start = 'hit', end = 'cog', dict = ['hot','dot','dog','lot','log', 'cog']; 58 | // let start = 'a', end = 'c', dict = ['a','b','c']; 59 | 60 | console.log(shortestTransform(start,end, dict)) -------------------------------------------------------------------------------- /js/stage_2/shuffleReset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | */ 4 | var Solution = function(nums) { 5 | this.orig = [...nums]; 6 | this.nums = nums; 7 | this.randAll = []; 8 | }; 9 | 10 | /** 11 | * Resets the array to its original configuration and return it. 12 | * @return {number[]} 13 | */ 14 | Solution.prototype.reset = function() { 15 | // console.log("// Calling Reset..."); 16 | // console.log("Shuffled: " + this.nums); 17 | // console.log("Original: " + this.orig); 18 | return this.orig; 19 | }; 20 | 21 | /** 22 | * Returns a random shuffling of the array. 23 | * @return {number[]} 24 | */ 25 | Solution.prototype.shuffle = function() { 26 | for(let i=0; i < this.nums.length; i++){ 27 | let randIdx = Math.floor(Math.random() * this.nums.length); 28 | this.randAll.push(randIdx); 29 | let randNum = this.nums[randIdx]; 30 | let currNum = this.nums[i]; 31 | this.nums[i] = randNum; 32 | this.nums[randIdx] = currNum; 33 | } 34 | // console.log("// Calling Shuffle...") 35 | // console.log("Original: " + this.orig); 36 | // console.log("Shuffled: " + this.nums); 37 | // console.log("\n"); 38 | return this.nums 39 | }; 40 | 41 | const nums = [1, 2, 3] 42 | var obj = new Solution(nums) 43 | var param_2 = obj.shuffle() 44 | var param_1 = obj.reset() 45 | 46 | 47 | /** 48 | * Your Solution object will be instantiated and called as such: 49 | * var obj = new Solution(nums) 50 | * var param_1 = obj.reset() 51 | * var param_2 = obj.shuffle() 52 | */ 53 | 54 | 55 | 56 | 57 | /* 58 | 59 | Shuffle a set of numbers without duplicates. 60 | 61 | Example: 62 | 63 | // Init an array with set 1, 2, and 3. 64 | int[] nums = {1,2,3}; 65 | Solution solution = new Solution(nums); 66 | 67 | // Shuffle the array [1,2,3] and return its result. 68 | Any permutation of [1,2,3] must equally likely to be returned. 69 | solution.shuffle(); 70 | 71 | // Resets the array back to its original configuration [1,2,3]. 72 | solution.reset(); 73 | 74 | // Returns the random shuffling of array [1,2,3]. 75 | solution.shuffle(); 76 | 77 | 78 | 79 | // shuffle 80 | r = [0, 3] 81 | random_values = [3, 3, 2, 0]; 82 | 83 | [1, 5, 9, 4] 84 | i=0 85 | [4, 5, 9, 1] r = 3 86 | i=1 87 | [4, 1, 9, 5] r = 3 88 | i=2 89 | [4, 1, 9, 5] r = 2 90 | i=3 91 | [5, 1, 9, 4] r = 0 92 | 93 | // reset 94 | [5, 1, 9, 4] 95 | 0 1 2 3 96 | random_values = [3, 3, 2, 0]; 97 | 98 | [4, 1, 9, 5] 99 | 100 | [4, 5, 9, 1] 101 | 102 | [1, 5, 9, 4] 103 | 104 | (4/2)(4+1) 10 105 | 106 | [1, 2, 3, 4] 107 | 108 | [1, 3, 2, 4] 109 | [1, 3, 4, 2] 110 | [1, 4, 3, 2] 111 | [1, 4, 2, 3] 112 | [1, 2, 4, 3] 113 | ... 114 | [] 115 | [] 116 | [] 117 | 118 | 119 | 4! 120 | 121 | */ -------------------------------------------------------------------------------- /js/stage_2/specialMultiple.js: -------------------------------------------------------------------------------- 1 | function solve(x, value = '4') { 2 | let a = value.lastIndexOf('4'); 3 | let b = value.length - a - 1; 4 | if (x <= Number(value)){ 5 | 6 | if ((Number(value) % x) === 0) { 7 | return (2*(a+1))+b; 8 | } 9 | } 10 | if (value[a+1] == 0) { 11 | value = '4'.repeat(a+2) + '0'.repeat(b-1) 12 | return solve(x, value); 13 | } 14 | if(value[a+1] === undefined){ 15 | value = '4' + '0'.repeat(a+1); 16 | return solve(x, value); 17 | } 18 | } 19 | 20 | console.log(solve(81)); -------------------------------------------------------------------------------- /js/stage_2/splitString.js: -------------------------------------------------------------------------------- 1 | // split number into k, ignore leading zeros 2 | function splitNum(number, k){ 3 | let i = 0, rsl = []; 4 | while(i < number.length){ 5 | let n = k, el = ''; 6 | while(n > 0 && i < number.length){ 7 | if (number[i] === "0" && el === '') i++; 8 | else if (number[i] === "0" && number[i+1] === undefined){ 9 | el += number[i]; 10 | i++; 11 | n--; 12 | }else { 13 | el += number[i]; 14 | i++; 15 | n--; 16 | } 17 | } 18 | rsl.push(el) 19 | } 20 | return rsl; 21 | } 22 | 23 | console.log(splitNum('0050010020', 4)) -------------------------------------------------------------------------------- /js/stage_2/threeSumToTarget.js: -------------------------------------------------------------------------------- 1 | const array = [1, 2, 3, 4, -1, -3] 2 | const target = 0 3 | 4 | //using pointers: for each element, add from left and extreme right. If sum > target, reduce the right, 5 | // else if less increase the left, 6 | // else push to array and alter both left and right 7 | 8 | function threeSumToTarget(array, target){ 9 | let sums = [] 10 | array = array.sort((a, b) => a - b) 11 | for (let i = 0; i < array.length - 2; i++){ 12 | let left = i+1; 13 | let right = array.length - 1 14 | while (left < right){ 15 | let cS = array[i] + array[left] + array[right]; 16 | if (cS === target ) { 17 | sums.push([array[i], array[left], array[right]]); 18 | left++; 19 | right--; 20 | } 21 | else if (cS > target) right--; 22 | else if (cS < target) left++; 23 | } 24 | } 25 | return sums 26 | } 27 | 28 | console.log(threeSumToTarget(array, target)) -------------------------------------------------------------------------------- /js/stage_2/viralAdvertising.js: -------------------------------------------------------------------------------- 1 | // Complete the viralAdvertising function below. 2 | function viralAdvertising(n, sum = 0, shared = 5) { 3 | if (n == 0) return sum; 4 | let likedBy = Math.floor(shared/2); 5 | sum += likedBy; 6 | shared = likedBy * 3 7 | return viralAdvertising(n-1, sum, shared); 8 | } 9 | 10 | console.log(viralAdvertising(5)) -------------------------------------------------------------------------------- /js/stage_2/whatFlavor.js: -------------------------------------------------------------------------------- 1 | // calculate number of flavors you can buy with the money 2 | 3 | function whatFlavors(cost, money) { 4 | const costHash = {}; 5 | for(let i = 0; i < cost.length; i++) { 6 | costHash[cost[i]] = i+1; 7 | } 8 | 9 | for(let i = 0; i < cost.length; i++) { 10 | let diff = money - cost[i]; 11 | if (i+1 == costHash[diff]) continue; 12 | if (costHash[diff]) { 13 | const res = costHash[diff] > i+1 ? `${i+1} ${costHash[diff]}` : `${costHash[diff]} ${i+1}`; 14 | console.log(res); 15 | return res; 16 | } 17 | } 18 | 19 | } 20 | 21 | whatFlavors([7,2,5,4,11], 12); 22 | whatFlavors([4,3,2,5,7], 8); -------------------------------------------------------------------------------- /js/stage_3/betweenTwoIntegers.js: -------------------------------------------------------------------------------- 1 | // Incorrect??? 2 | 3 | function betweenTwoIntegers(a, b){ 4 | const maxA = Math.max(...a) 5 | const maxB = Math.max(...b) 6 | let factorA = [] 7 | let factorB = [] 8 | for (let i = maxA, j = 1; i <= maxB; i = maxA*++j ){ 9 | let factor = true; 10 | for(let el of a){ 11 | if (i%el != 0) { 12 | factor = false; 13 | break; 14 | } 15 | } 16 | factor ? factorA.push(i) : '' 17 | } 18 | 19 | for (let i = 0; i < factorA.length; i++ ){ 20 | let factor = true; 21 | for(let el of b){ 22 | if (el%factorA[i] != 0) { 23 | factor = false; 24 | break; 25 | } 26 | } 27 | factor ? factorB.push(factorA[i]) : '' 28 | } 29 | return factorB.length 30 | } 31 | 32 | console.log(betweenTwoIntegers([2,4], [16 ,32 ,96])) -------------------------------------------------------------------------------- /js/stage_3/concatSum.js: -------------------------------------------------------------------------------- 1 | function concatenationsSum(a) { 2 | let sum = 0; 3 | for (let i = 0; i < a.length; i++){ 4 | //go forward 5 | for (let j = i; j < a.length; j++){ 6 | let concat = a[i] + `${a[j]}` 7 | console.log(concat) 8 | sum += parseInt(concat) 9 | } 10 | 11 | // go backward 12 | for (let k = i - 1; k >= 0; k--){ 13 | let concat = a[i] + `${a[k]}` 14 | console.log(concat) 15 | sum += parseInt(concat) 16 | } 17 | } 18 | return sum; 19 | } 20 | 21 | console.log(concatenationsSum([10, 2])) -------------------------------------------------------------------------------- /js/stage_3/connectedGrid.js: -------------------------------------------------------------------------------- 1 | function connectedGrid(rows, cols, grid){ 2 | function isValid(row, col){ 3 | if ( row < 0 4 | || col < 0 5 | || row >= rows 6 | || col >= cols 7 | || grid[row][col] < 1 8 | ) { 9 | return false; 10 | } 11 | else { 12 | return true; 13 | } 14 | } 15 | 16 | // Stores size of current largest region 17 | let maxVal = 0, count=0; 18 | function dfs(row, col){ 19 | // cordinates for up, down, right and left 20 | let rowNum = [-1, 1, 0, 0] 21 | let colNum = [0, 0, 1, -1] 22 | 23 | //mark grid as visited 24 | grid[row][col] = -1; 25 | 26 | for(let i = 0; i < 4; i++){ 27 | if (isValid(row + rowNum[i], col + colNum[i])){ 28 | count +=1 29 | dfs(row + rowNum[i], col + colNum[i]) 30 | } 31 | } 32 | } 33 | 34 | for (let i = 0; i < rows; i++) { 35 | for (let j = 0; j < cols; j++) { 36 | if (isValid(i, j)){ 37 | count = 1; 38 | dfs(i, j); 39 | if(count > maxVal) { 40 | maxVal = count; 41 | } 42 | } 43 | } 44 | } 45 | return maxVal; 46 | } 47 | 48 | console.log(connectedGrid(4,5, [[1, 0, 1, 1, 1], 49 | [1, 0, 1, 1, 1], 50 | [1, 0, 1, 1, 1], 51 | [0, 1, 0, 0, 0]])) -------------------------------------------------------------------------------- /js/stage_3/connectedGrid2.js: -------------------------------------------------------------------------------- 1 | //number of connected grids 2 | function noOfOffices(rows, cols, grid){ 3 | function isValid(x, y){ 4 | if ( x < 0 || y < 0 || x >= rows || y >= cols || grid[x][y] < 1 ) return false; 5 | return true 6 | } 7 | 8 | function dfs(x, y){ 9 | if (!isValid(x, y)) return; 10 | 11 | const row_dir = [-1, 1, 0, 0] 12 | const col_dir = [0, 0, -1, 1] 13 | 14 | grid[x][y] = -1; 15 | 16 | for (let i = 0; i<4; i++){ 17 | if (isValid(x+row_dir[i],y+col_dir[i])){ 18 | dfs(x+row_dir[i],y+col_dir[i]); 19 | } 20 | } 21 | return 1; 22 | } 23 | 24 | let count = 0; 25 | for(let i = 0; i 0; k--){ 18 | let sum = array[i] + array[k]; 19 | if (allPairSums[sum]){ 20 | allPairSums[sum].push([array[i], array[k]]) 21 | }else { 22 | allPairSums[sum] = [[array[i], array[k]]] 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /js/stage_3/gridClimbing.js: -------------------------------------------------------------------------------- 1 | 2 | function numberOfConnections(gridOfNodes) { 3 | // Write your code here 4 | const rows = gridOfNodes.length; 5 | const cols = gridOfNodes[0].length; 6 | let sum = 0; 7 | const noOfOnes = {} 8 | for (let row = 0; row < rows; row++) { 9 | let count = 0; 10 | for(let col = 0; col < cols; col++) { 11 | const el = gridOfNodes[row][col]; 12 | if (el == 1) count++; 13 | } 14 | noOfOnes[row] = count; 15 | } 16 | 17 | for (let row = 0; row < rows - 1; row++) { 18 | if (noOfOnes[row] == 0) continue; 19 | for (let child = row+1; child < rows; child++) { 20 | if (noOfOnes[child] != 0) { 21 | sum = sum + (noOfOnes[child] * noOfOnes[row]); 22 | break; 23 | } 24 | } 25 | } 26 | return console.log(sum); 27 | } 28 | 29 | numberOfConnections([[1,0,1,1], [0,1,1,0], [0,0,0,0], [1,0,0,0]]); -------------------------------------------------------------------------------- /js/stage_3/integersToEnglish.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1. 3 | * Example 1: 4 | * Input: 123 5 | * Output: "One Hundred Twenty Three" 6 | */ 7 | 8 | 9 | const unit = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']; 10 | const tens = ['', 'ten', 'twenty', 'thirty', 'fourty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']; 11 | const above10 = ['', 'eleven', 'twelve', 'thirteen', 'fouteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']; 12 | 13 | function english(num){ 14 | let str = ''; 15 | let arr = [] 16 | num = num.toString().split(''); 17 | while(num.length != 0){ 18 | len = num.length - 1; 19 | arr.push(num[num.length-1]); 20 | switch(arr.length){ 21 | case 1: { 22 | str = unit[num[len]]+ str; 23 | num.pop(); 24 | break; 25 | } 26 | case 2: { 27 | str = tens[num[len]] + ' ' + str; 28 | num.pop(); 29 | break; 30 | } 31 | case 3: { 32 | str = unit[num[len]] + ' Hundred' + ' ' + str; 33 | num.pop(); 34 | break; 35 | } 36 | case 4: { 37 | if (`${num[len-1]}` + num[len].toString() < 20){ 38 | str = above10[num[len]] + ' thousand' + ' ' + str; 39 | num.pop(); 40 | num.pop(); 41 | break; 42 | } 43 | else{ 44 | str = unit[num[len]] + ' Thousand' + ' ' + str; 45 | num.pop(); 46 | break; 47 | } 48 | } 49 | case 5: { 50 | str = tens[num[len]] + ' ' + str; 51 | num.pop(); 52 | break; 53 | } 54 | case 6: { 55 | str = unit[num[len]] + ' Hundred' + ' ' + str; 56 | num.pop(); 57 | break; 58 | } 59 | case 7: { 60 | str = unit[num[len]] + ' Million' + ' ' + str; 61 | num.pop(); 62 | break; 63 | } 64 | case 8: { 65 | if (`${num[len-1]}` + num[len].toString() < 20){ 66 | str = above10[num[len]] + ' thousand' + ' ' + str; 67 | num.pop(); 68 | num.pop(); 69 | break; 70 | } 71 | else{ 72 | str = tens[num[len]] + ' ' + str; 73 | num.pop(); 74 | break; 75 | } 76 | } 77 | case 9: { 78 | str = unit[num[len]] + ' Hundred' + str; 79 | num.pop(); 80 | break; 81 | } 82 | case 10: { 83 | str = unit[num[len]] + ' Billion' + str; 84 | num.pop(); 85 | break; 86 | } 87 | } 88 | } 89 | return str; 90 | } 91 | 92 | console.log(english(123476)); -------------------------------------------------------------------------------- /js/stage_3/islandCount.js: -------------------------------------------------------------------------------- 1 | function islandCount(binaryMatrix) { 2 | // your code goes here 3 | let currentIsland = 1; 4 | let sub = 0; 5 | for(let i = 0; i < binaryMatrix.length; i++){ 6 | for(let j = 0; j < binaryMatrix[i].length; j++){ 7 | if(binaryMatrix[i][j] === 1){ 8 | // keep count of islands as you go and merge islands 9 | 10 | let above = binaryMatrix[i-1] ? binaryMatrix[i-1][j] : 0 11 | let left = binaryMatrix[i][j-1] ? binaryMatrix[i][j-1] : 0 12 | if(above >= 1 && left >= 1 && left !== above){ 13 | binaryMatrix[i][j] = binaryMatrix[i-1][j]; 14 | binaryMatrix[i][j-1] = binaryMatrix[i-1][j]; 15 | sub--; // merge island cause you must've seen either left or above before. 16 | } else if(left >= 1){ 17 | binaryMatrix[i][j] = binaryMatrix[i][j-1]; 18 | } else if(above >= 1){ 19 | binaryMatrix[i][j] = binaryMatrix[i-1][j]; 20 | } else { 21 | binaryMatrix[i][j] = currentIsland + 1; // new island 22 | currentIsland++; 23 | console.log(currentIsland) 24 | } 25 | } 26 | } 27 | } 28 | return currentIsland - 1 + sub; 29 | } 30 | /** 31 | [1, 0, 2, 0] 32 | [0, 2, 2, 2] 33 | [0, 0, 2, 0] 34 | [3, 0, 0, 0] 35 | */ 36 | -------------------------------------------------------------------------------- /js/stage_3/knapSack.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colibie/solved_algorithms/abfb9e358784e6a8a750a5877d92a6740254f18c/js/stage_3/knapSack.js -------------------------------------------------------------------------------- /js/stage_3/largestSquareMatrix.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given a 2D boolean array, find thr largest square subarray of true values. 3 | * The return value should be the side length of the largest square subarray. 4 | * 5 | * Eg 6 | * arr = 7 | * ________________________________ 8 | * | False | True | False | False | 9 | * --------________________--------- 10 | * | True ||True | True || True | 11 | * -------------------------------- 12 | * | False ||True | True || False | 13 | * --------________________-------- 14 | * squareSubmatrix(arr) = 2, ie cells (1, 1) to (1, 2), (2, 1), (2, 2) 15 | */ 16 | 17 | function squareSubmatrix(arr) { 18 | // Brute force would be doing a DFS, while keeping count of max seen so far 19 | // Using DP, what are the subproblems 20 | // for each cell, we check if it's left, bottom and bottom-right is the start of a truthy square matrix, ie at the top left 21 | // if it is, we return the min of the square matrix(all edges must be valid) + the current cell(1) 22 | 23 | let max = 0, cache = []; 24 | for (let i = 0; i < arr.length; i++) { 25 | for (let j = 0; j < arr.length; j++) { 26 | // if valid 27 | if (!arr[i][j]) continue; 28 | max = Math.max(max, squareSubmatrixHelper(arr, i, j)); 29 | // max = Math.max(max, squareSubmatrixHelper(arr, i, j, cache)); //dp top down 30 | } 31 | } 32 | return max; 33 | } 34 | 35 | function squareSubmatrixHelper(arr, i, j) { 36 | // if it's the end 37 | if (i >= arr.length || j >= arr[0].length) return 0; 38 | 39 | // return 0 if cell is false; 40 | if (!arr[i][j]) return 0; 41 | 42 | // Why min? If any of the adjacent cells are false, 43 | // then the current cell is not the start of a larger squareMatrix 44 | // and thus the size is 1; 45 | return 1 + Math.min(/*Left*/ squareSubmatrixHelper(arr, i, j + 1), 46 | /*Bottom*/ squareSubmatrixHelper(arr, i + 1, j), 47 | /*Bottom-Right*/ squareSubmatrixHelper(arr, i + 1, j + 1)); 48 | } 49 | 50 | function squareSubmatrixHelperTopDown(arr, i, j, cache) { 51 | // if it's the end 52 | if (i >= arr.length || j >= arr[0].length) return 0; 53 | 54 | // return 0 if cell is false; 55 | if (!arr[i][j]) return 0; 56 | 57 | if (cache[i][j]) return cache[i][j]; 58 | // Why min? If any of the adjacent cells are false, 59 | // then the current cell is not the start of a larger squareMatrix 60 | // and thus the size is 1; 61 | cache[i][j] = 1 + Math.min(/*Left*/ squareSubmatrixHelperTopDown(arr, i, j + 1), 62 | /*Bottom*/ squareSubmatrixHelperTopDown(arr, i + 1, j), 63 | /*Bottom-Right*/ squareSubmatrixHelperTopDown(arr, i + 1, j + 1)); 64 | return cache[i][j]; 65 | } 66 | 67 | function squareSubMatrixBottomUp(arr) { 68 | // we check if a cell if the bottom right corner of a bigger left-ward square submatrix 69 | let cache = [], max = 0; 70 | for (let i = 0; i < arr.length; i++) { 71 | for (let j = 0; j < arr.length; j++) { 72 | // if we are the first row or col, the value is just 1 if the cell is truth 73 | if (i == 0 || j == 0) { 74 | cache[i][j] = arr[i][j] ? 1 : 0; 75 | } else if (arr[i][j]) { 76 | cache[i][j] = 1 + Math.min(cache[i - 1][j], cache[i][j - 1], cache[i - 1][j - 1]); 77 | } else { 78 | cache[i][j] = 0; 79 | } 80 | } 81 | max = Math.max(max, cache[i][j]); 82 | } 83 | return max; 84 | 85 | } -------------------------------------------------------------------------------- /js/stage_3/leastSubse.js: -------------------------------------------------------------------------------- 1 | // subsequence = arrangement of substrings in concurrent order ( adjacent?? I think) 2 | function subsequence(word){ 3 | let node = ""; 4 | let subseq = [], fringe = [] 5 | word = word.split(''); 6 | for(let i = 0; i xx; k--) { 30 | let testStr = str.substring(k, strLen) 31 | // if( i <= FWi ) return 0 32 | // var patt = new RegExp("^[progra(m){2}era-z]{10,}$"); 33 | var patt = new RegExp("(([programer]([a-z]){0,}){1}|(m[a-z]{0,}){1}){10}$"); 34 | let match = patt.test(testStr); 35 | 36 | if (match) { 37 | SWi = k 38 | break 39 | } 40 | } 41 | 42 | return SWi - FWi - 1 43 | } 44 | 45 | console.log(programmerStrings("xppbroraxmmverxxxxprproxgracmmer")) -------------------------------------------------------------------------------- /js/stage_3/randomCard.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* 4 | 5 | A linked list of cards are given. Write a code, to Shuffle the cards, 6 | without using inbuilt shuffle / random functions. 7 | 8 | Functionalities : 9 | Create a deck of card through linked list 10 | Split the deck of cards randomly into 2 subsets 11 | Merge the subsets randomly, so that previous order is not maintained 12 | Display the deck of cards . 13 | 14 | 15 | Eg: 16 | I/p Cards: [A,4,6,7,9,Q,J,2] 17 | Expected Output: 18 | 19 | Create Linked List : [A->4->6->7->9->Q->J->2] 20 | 21 | Split List into 3 decks : A->4->6->7 9->Q J->2 22 | 23 | Merge the decks randomly : 9->6->7 ->Q ->J->2->4->A 24 | 25 | 26 | 27 | */ -------------------------------------------------------------------------------- /js/stage_3/readInput.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | process.stdin.resume(); 6 | process.stdin.setEncoding('utf-8'); 7 | 8 | let inputString = ''; 9 | let currentLine = 0; 10 | 11 | process.stdin.on('data', inputStdin => { 12 | inputString += inputStdin; 13 | }); 14 | 15 | process.stdin.on('end', _ => { 16 | inputString = inputString.replace(/\s*$/, '') 17 | .split('\n') 18 | .map(str => str.replace(/\s*$/, '')); 19 | 20 | main(); 21 | }); 22 | 23 | function readLine() { 24 | return inputString[currentLine++]; 25 | } 26 | 27 | function main() { 28 | const ws = fs.createWriteStream(process.env.OUTPUT_PATH); 29 | 30 | const nk = readLine().split(' '); 31 | 32 | const n = parseInt(nk[0], 10); 33 | 34 | const k = parseInt(nk[1], 10); 35 | 36 | const r_qC_q = readLine().split(' '); 37 | 38 | const r_q = parseInt(r_qC_q[0], 10); 39 | 40 | const c_q = parseInt(r_qC_q[1], 10); 41 | 42 | let obstacles = Array(k); 43 | 44 | for (let i = 0; i < k; i++) { 45 | obstacles[i] = readLine().split(' ').map(obstaclesTemp => parseInt(obstaclesTemp, 10)); 46 | } 47 | 48 | let result = queensAttack(n, k, r_q, c_q, obstacles); 49 | 50 | ws.write(result + "\n"); 51 | 52 | ws.end(); 53 | } 54 | -------------------------------------------------------------------------------- /js/stage_3/riverSizes.js: -------------------------------------------------------------------------------- 1 | // print the number of each group of connected cells in a grid 2 | 3 | function riverSizes(matrix) { 4 | // Write your code here. 5 | const rows = matrix.length; 6 | const columns = matrix[0].length; 7 | 8 | function isValid(x, y){ 9 | if (x < 0 || y < 0 || x >= rows || y >= columns || matrix[x][y] < 1) return false; 10 | return true; 11 | } 12 | 13 | let count = 0; 14 | 15 | function dfs(x, y){ 16 | if (!isValid(x, y)) return; 17 | const x_dir = [-1, 1, 0, 0] 18 | const y_dir = [0, 0, 1, -1] 19 | matrix[x][y] = -1; 20 | 21 | for(let i = 0; i < 4; i++){ 22 | if (isValid(x + x_dir[i], y + y_dir[i])){ 23 | count += 1; 24 | dfs(x+x_dir[i], y+y_dir[i]) 25 | } 26 | } 27 | } 28 | //start 29 | let result = [] 30 | for (let i = 0; i < rows; i++){ 31 | for (let j = 0; j < columns; j++){ 32 | if (isValid(i, j)){ 33 | count = 1; 34 | dfs(i, j); 35 | result.push(count); 36 | } 37 | 38 | } 39 | } 40 | console.log(result) 41 | } 42 | 43 | let matrix = [ 44 | [1, 0, 0, 1, 0], 45 | [1, 0, 1, 0, 0], 46 | [0, 0, 1, 0, 1], 47 | [1, 0, 1, 0, 1], 48 | [1, 0, 1, 1, 0] 49 | ] 50 | 51 | riverSizes(matrix) -------------------------------------------------------------------------------- /js/stage_3/subseqInAB.js: -------------------------------------------------------------------------------- 1 | // number of subsequences of string A that form string B 2 | function subseqInAB(A, B){ 3 | let sub = []; 4 | for (let i = 0; i < A.length; i++) { 5 | for (let j = i+1; j <= A.length; j++) { 6 | sub.push(A.substring(i,j)); 7 | } 8 | } 9 | sub = sub.sort(function(a, b) { 10 | return b.length - a.length || // sort by length, if equal then 11 | a.localeCompare(b); // sort by dictionary order 12 | }); 13 | console.log(sub) 14 | let count = 0; 15 | sub.forEach(el => { 16 | 17 | let mat = new RegExp(el,"g"); 18 | let sum = B.match(mat) 19 | if (sum) { 20 | count += sum.length; 21 | B=B.replace(mat, "*"); 22 | } 23 | }) 24 | if (B != Array(B.length).fill('*').join("")) return -1; 25 | return count; 26 | 27 | } 28 | console.log(subseqInAB('abcd', 'acbcd')) // a + c + bcd = 3 29 | console.log(subseqInAB('abcd', 'acbcgd')) // -1, no arrangement -------------------------------------------------------------------------------- /js/stage_3/subsequence.js: -------------------------------------------------------------------------------- 1 | // subsequence = arrangement of substrings in concurrent order ( adjacent?? I think) 2 | function subsequence(word){ 3 | // ive no idea what's going on here. I think this is brute force. Checked all letters 4 | // check below 5 | let node = ""; 6 | let subseq = [], fringe = [] 7 | word = word.split(''); 8 | for(let i = 0; i { 100 | 101 | let mat = new RegExp(el,"g"); 102 | let sum = B.match(mat) 103 | if (sum) { 104 | count += sum.length; 105 | B=B.replace(mat, "*"); 106 | } 107 | }) 108 | if (B != Array(B.length).fill('*').join("")) return -1; 109 | return count; 110 | 111 | } 112 | console.log(subseq('abcd', 'acbcd')) // a + c + bcd = 3 113 | console.log(subseq('abcd', 'acbcgd')) // -1, no arrangement 114 | -------------------------------------------------------------------------------- /js/stage_3/taxiCab.js: -------------------------------------------------------------------------------- 1 | /** 2 | * returns the taxicab value of a given number. 3 | * A taxicab number is a number that is a sum of the cube of two different numbers in n ways. 4 | * Eg the taxicab value of 5 would have 5 instances a sum of cube of two numbers. 5 | * There are two versions of taxicab numbers 6 | * The running time of the algorithm below is too expensive. 7 | */ 8 | 9 | class TaxiCab { 10 | constructor(k) { 11 | this.k = k; 12 | this.hash = {}; 13 | } 14 | 15 | solve() { 16 | 17 | let value, stop = false; 18 | let n; 19 | if (this.k < 6) n = Math.pow(10, this.k + 1) - 1; 20 | else if (this.k > 6 && this.k < 9) n = Math.pow(10, this.k + Math.ceil(this.k/2)) - 1; 21 | else n = Math.pow(10, this.k*2) - 1; 22 | for (let i = 1; i < n; i++) { 23 | for (let j = 1; j < n; j++) { 24 | if (j < i) continue; 25 | value = Math.pow(i, 3) + Math.pow(j, 3); 26 | this.hash[value] = this.hash[value] == null ? 1 : this.hash[value] + 1; 27 | if (this.hash[value] == this.k) { 28 | stop = true; 29 | break; 30 | } 31 | } 32 | if (stop) break; 33 | } 34 | return value; 35 | } 36 | } 37 | 38 | let sample = new TaxiCab(5); 39 | console.log(sample.solve()); 40 | 41 | function taxiCab(k) { 42 | let num = 2, hash = {}, stop = false, res; // base num 43 | while (!stop) { 44 | for (let i = 1; i < Math.cbrt(num); i++) { 45 | // check if taxicab ie a3 + b3 = num 46 | let value = Math.cbrt(num - Math.pow(i, 3)); 47 | if (value < i) continue; 48 | if (Number.isInteger(value)) { 49 | hash[num] = hash[num] == null ? 1 : hash[num] + 1; 50 | if (hash[num] == k) { 51 | stop = true; 52 | res = num; 53 | break; 54 | } 55 | } 56 | } 57 | num++; 58 | } 59 | return res; 60 | } 61 | 62 | // console.log(taxiCab(3)); -------------------------------------------------------------------------------- /js/stage_3/toys.js: -------------------------------------------------------------------------------- 1 | function toys(w){ 2 | w = w.sort((a, b) => a-b) 3 | let count = 1; 4 | let i = 0 5 | while (i < w.length){ 6 | console.log(count) 7 | let currentNum = w[i]; 8 | let next = currentNum + 4 9 | for (let j = i; j < w.length;){ 10 | if (w[j] < next) { 11 | j++; 12 | i++ 13 | } 14 | else{ 15 | count++ 16 | i = j 17 | break; 18 | } 19 | 20 | } 21 | 22 | } 23 | return count 24 | 25 | } 26 | 27 | console.log(toys([1, 2, 3, 21, 7, 12, 14, 21])) -------------------------------------------------------------------------------- /js/stage_3/trapRain.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} height 3 | * @return {number} 4 | */ 5 | var trap = function(height) { 6 | 7 | } 8 | 9 | /* 10 | 11 | Given n non-negative integers representing an elevation map where the width of each bar is 1, 12 | compute how much water it is able to trap after raining. 13 | 14 | 15 | The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. 16 | In this case, 6 units of rain water (blue section) are being trapped. 17 | Thanks Marcos for contributing this image! 18 | 19 | Example: 20 | Input: [0,1,0,2,1,0,1,3,2,1,2,1] 21 | Output: 6 22 | 23 | 24 | minimum of maximum height of bars on both the sides minus its own height. 25 | 26 | 4| 27 | 3| ___ 28 | 2| ___ | |__ ___ 29 | 1| ___ | |__ __| | |_| |__ 30 | |__|_|__|_|_|_|_|_|_|_|_|_| 31 | 0 1 2 3 4 5 6 7 8 9 10 11 12 32 | 33 | 34 | [ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1] 35 | 36 | [ 0, ] 37 | 38 | 39 | 40 | 41 | 42 | */ -------------------------------------------------------------------------------- /questions.md: -------------------------------------------------------------------------------- 1 | ## Algorithms to solve for Google Interview 2 | 3 | ### Cracking the code Interview 4 | 2 from here 5 | Solve questions from the book, alternating between the various topics. 6 | 7 | ### Leetcode 8 | 1. --------------------------------------------------------------------------------