├── .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.
--------------------------------------------------------------------------------