From cd71920b73020987d8eec9605facb6c6c3cef56d Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 30 Aug 2020 22:56:00 -0400 Subject: [PATCH 01/11] Generate tests classes --- LeetcodeProblemsTests/3Sum_Test.js | 22 +++ LeetcodeProblemsTests/Add_Two_Numbers_Test.js | 29 ++++ .../Award_Budget_Cuts_Test.js | 15 ++ .../Backspace_String_Compare_Test.js | 18 +++ ...Best_Time_To_Buy_And_Sell_Stock_II_Test.js | 68 ++++++++ LeetcodeProblemsTests/Binary_Gap_Test.js | 73 +++++++++ LeetcodeProblemsTests/Clone_Graph_Test.js | 99 ++++++++++++ LeetcodeProblemsTests/Coin_Change_Test.js | 117 ++++++++++++++ ...rom_Preorder_and_Inorder_Traversal_Test.js | 70 ++++++++ .../Deletion_Distance_Test.js | 131 +++++++++++++++ .../Design_Circular_Deque_Test.js | 152 ++++++++++++++++++ LeetcodeProblemsTests/Edit_Distance_Test.js | 113 +++++++++++++ .../Escape_The_Ghosts_Test.js | 73 +++++++++ LeetcodeProblemsTests/Flood_Fill_Test.js | 67 ++++++++ .../Generate_Parenthesis_Test.js | 94 +++++++++++ LeetcodeProblemsTests/Group_Anagrams_Test.js | 62 +++++++ .../Implement_stack_using_queues_Test.js | 99 ++++++++++++ .../Kth_Largest_Element_in_an_Array_Test.js | 71 ++++++++ .../Linked_List_Cycle_II_Test.js | 90 +++++++++++ .../Longest_Consecutive_Sequence_Test.js | 69 ++++++++ .../Longest_Palindromic_Substring_Test.js | 80 +++++++++ ...t_Common_Ancestor_of_a_Binary_Tree_Test.js | 129 +++++++++++++++ .../Majority_Element_Test.js | 58 +++++++ LeetcodeProblemsTests/Maximal_Square_Test.js | 82 ++++++++++ .../Maximun_Subarray_Test.js | 48 ++++++ LeetcodeProblemsTests/Min_Stack_Test.js | 92 +++++++++++ .../Minimum_Window_Substring_Test.js | 80 +++++++++ LeetcodeProblemsTests/NQueens_Test.js | 98 +++++++++++ .../Number_of_Islands_Test.js | 83 ++++++++++ .../Number_of_Segments_in_a_String_Test.js | 49 ++++++ LeetcodeProblemsTests/Permutations_II_Test.js | 80 +++++++++ LeetcodeProblemsTests/Permutations_Test.js | 62 +++++++ .../Permutations_With_Duplicates_Test.js | 56 +++++++ .../Permutations_Without_Duplicates_Test.js | 62 +++++++ .../Regular_Expression_Matching_Test.js | 106 ++++++++++++ .../Remove_Invalid_Parentheses_Test.js | 84 ++++++++++ .../Restore_IP_Addresses_Test.js | 53 ++++++ .../Reverse_String_II_Test.js | 53 ++++++ LeetcodeProblemsTests/Same_Tree_Test.js | 57 +++++++ .../SearchIng_Rotated_Sorted_Array_Test.js | 65 ++++++++ .../Search_a_2D_Matrix_II_Test.js | 64 ++++++++ .../Search_a_2D_Matrix_Test.js | 74 +++++++++ .../Set_Matrix_Zeroes_Test.js | 124 ++++++++++++++ LeetcodeProblemsTests/Simplify_Path_Test.js | 76 +++++++++ LeetcodeProblemsTests/Spiral_Matrix_Test.js | 83 ++++++++++ .../Subarray_Sum_Equals_K_Test.js | 74 +++++++++ LeetcodeProblemsTests/Subsets_Test.js | 58 +++++++ .../Sum_Of_Square_Numbers_Test.js | 52 ++++++ .../Swap_Nodes_In_Pairs_Test.js | 63 ++++++++ LeetcodeProblemsTests/Symmetric_Tree_Test.js | 51 ++++++ LeetcodeProblemsTests/Tic_Tac_Toe_Test.js | 86 ++++++++++ .../Unique_Binary_Search_Trees_Test.js | 133 +++++++++++++++ LeetcodeProblemsTests/Unique_Paths_Test.js | 108 +++++++++++++ .../Valid_Parentheses_Test.js | 73 +++++++++ ...der_Serialization_of_a_Binary_Tree_Test.js | 80 +++++++++ .../merge_k_sorted_lists_Test.js | 104 ++++++++++++ 56 files changed, 4312 insertions(+) create mode 100644 LeetcodeProblemsTests/3Sum_Test.js create mode 100644 LeetcodeProblemsTests/Add_Two_Numbers_Test.js create mode 100644 LeetcodeProblemsTests/Award_Budget_Cuts_Test.js create mode 100644 LeetcodeProblemsTests/Backspace_String_Compare_Test.js create mode 100644 LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js create mode 100644 LeetcodeProblemsTests/Binary_Gap_Test.js create mode 100644 LeetcodeProblemsTests/Clone_Graph_Test.js create mode 100644 LeetcodeProblemsTests/Coin_Change_Test.js create mode 100644 LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js create mode 100644 LeetcodeProblemsTests/Deletion_Distance_Test.js create mode 100644 LeetcodeProblemsTests/Design_Circular_Deque_Test.js create mode 100644 LeetcodeProblemsTests/Edit_Distance_Test.js create mode 100644 LeetcodeProblemsTests/Escape_The_Ghosts_Test.js create mode 100644 LeetcodeProblemsTests/Flood_Fill_Test.js create mode 100644 LeetcodeProblemsTests/Generate_Parenthesis_Test.js create mode 100644 LeetcodeProblemsTests/Group_Anagrams_Test.js create mode 100644 LeetcodeProblemsTests/Implement_stack_using_queues_Test.js create mode 100644 LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js create mode 100644 LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js create mode 100644 LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js create mode 100644 LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js create mode 100644 LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js create mode 100644 LeetcodeProblemsTests/Majority_Element_Test.js create mode 100644 LeetcodeProblemsTests/Maximal_Square_Test.js create mode 100644 LeetcodeProblemsTests/Maximun_Subarray_Test.js create mode 100644 LeetcodeProblemsTests/Min_Stack_Test.js create mode 100644 LeetcodeProblemsTests/Minimum_Window_Substring_Test.js create mode 100644 LeetcodeProblemsTests/NQueens_Test.js create mode 100644 LeetcodeProblemsTests/Number_of_Islands_Test.js create mode 100644 LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js create mode 100644 LeetcodeProblemsTests/Permutations_II_Test.js create mode 100644 LeetcodeProblemsTests/Permutations_Test.js create mode 100644 LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js create mode 100644 LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js create mode 100644 LeetcodeProblemsTests/Regular_Expression_Matching_Test.js create mode 100644 LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js create mode 100644 LeetcodeProblemsTests/Restore_IP_Addresses_Test.js create mode 100644 LeetcodeProblemsTests/Reverse_String_II_Test.js create mode 100644 LeetcodeProblemsTests/Same_Tree_Test.js create mode 100644 LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js create mode 100644 LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js create mode 100644 LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js create mode 100644 LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js create mode 100644 LeetcodeProblemsTests/Simplify_Path_Test.js create mode 100644 LeetcodeProblemsTests/Spiral_Matrix_Test.js create mode 100644 LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js create mode 100644 LeetcodeProblemsTests/Subsets_Test.js create mode 100644 LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js create mode 100644 LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js create mode 100644 LeetcodeProblemsTests/Symmetric_Tree_Test.js create mode 100644 LeetcodeProblemsTests/Tic_Tac_Toe_Test.js create mode 100644 LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js create mode 100644 LeetcodeProblemsTests/Unique_Paths_Test.js create mode 100644 LeetcodeProblemsTests/Valid_Parentheses_Test.js create mode 100644 LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js create mode 100644 LeetcodeProblemsTests/merge_k_sorted_lists_Test.js diff --git a/LeetcodeProblemsTests/3Sum_Test.js b/LeetcodeProblemsTests/3Sum_Test.js new file mode 100644 index 0000000..84f4b44 --- /dev/null +++ b/LeetcodeProblemsTests/3Sum_Test.js @@ -0,0 +1,22 @@ +const assert = require('assert'); +const threeSum = require('../LeetcodeProblems/3Sum').threeSum; + +var test = function () { + assert.deepEqual(threeSum([]), []); + assert.deepEqual(threeSum([0]), []); + assert.deepEqual(threeSum([0, 0]), []); + assert.deepEqual( + threeSum([0, 0, 0]), + [[0, 0, 0]] + ); + assert.deepEqual( + threeSum([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]), + [[0, 0, 0]] + ); + assert.deepEqual( + threeSum([-1, 0, 1, 2, -1, -4]), + [ [ -1, 2, -1 ], [ 0, 1, -1 ] ] + ); +} + +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Add_Two_Numbers_Test.js b/LeetcodeProblemsTests/Add_Two_Numbers_Test.js new file mode 100644 index 0000000..4c16541 --- /dev/null +++ b/LeetcodeProblemsTests/Add_Two_Numbers_Test.js @@ -0,0 +1,29 @@ +const assert = require('assert'); +const addTwoNumbers = require('../LeetcodeProblems/Add_Two_Numbers').addTwoNumbers; +const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); +var ListNode = require('../UtilsClasses/ListNode').ListNode; + +function test() { + const list1 = ListNode.linkenList([1,2,3,4]); + const list2 = ListNode.linkenList([1,2,3,4]); + ListNodeTestHelper.assertList( + addTwoNumbers(list1, list2), + [2, 4, 6, 8] + ); + + const list3 = ListNode.linkenList([1]); + const list4 = ListNode.linkenList([1,2]); + ListNodeTestHelper.assertList( + addTwoNumbers(list3, list4), + [2, 2] + ); + + const list5 = ListNode.linkenList([]); + const list6 = ListNode.linkenList([1,2]); + ListNodeTestHelper.assertList( + addTwoNumbers(list5, list6), + [1, 2] + ); +} + +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Award_Budget_Cuts_Test.js b/LeetcodeProblemsTests/Award_Budget_Cuts_Test.js new file mode 100644 index 0000000..9950f95 --- /dev/null +++ b/LeetcodeProblemsTests/Award_Budget_Cuts_Test.js @@ -0,0 +1,15 @@ +const assert = require('assert'); +const cutAwardBadges = require('../LeetcodeProblems/Award_Budget_Cuts').cutAwardBadges; + +function test() { + assert.deepEqual( + cutAwardBadges([2, 100, 50, 120, 1000], 190), + [ 47, 47, 47, 47, 2 ] + ); + assert.deepEqual( + cutAwardBadges([2, 100, 50, 120, 1000], 5), + [ 1, 1, 1, 1, 1 ] + ); +} + +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Backspace_String_Compare_Test.js b/LeetcodeProblemsTests/Backspace_String_Compare_Test.js new file mode 100644 index 0000000..5cef889 --- /dev/null +++ b/LeetcodeProblemsTests/Backspace_String_Compare_Test.js @@ -0,0 +1,18 @@ +const assert = require('assert'); +const backspaceCompare = require('../LeetcodeProblems/Backspace_String_Compare').backspaceCompare; +const backspaceCompare2 = require('../LeetcodeProblems/Backspace_String_Compare').backspaceCompare2; + +function test() { + assert.equal(backspaceCompare("ab#c", "ad#c"), true); // true + assert.equal(backspaceCompare("ab##", "c#d#"), true); // true + assert.equal(backspaceCompare("a##c", "#a#c"), true); // true + assert.equal(backspaceCompare("a#c", "b"), false); // false + + assert.equal(backspaceCompare2("ab#c", "ad#c"), true); // true + assert.equal(backspaceCompare2("ab##", "c#d#"), true); // true + assert.equal(backspaceCompare2("a##c", "#a#c"), true); // true + assert.equal(backspaceCompare2("a#c", "b"), false); // false +} +test(); + +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js b/LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js new file mode 100644 index 0000000..1179880 --- /dev/null +++ b/LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js @@ -0,0 +1,68 @@ +/* +https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ +Best Time to Buy and Sell Stock II + +Say you have an array for which the ith element is the price of a given stock on day i. + +Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). + +Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). + +Example 1: + +Input: [7,1,5,3,6,4] +Output: 7 +Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. + Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. +Example 2: + +Input: [1,2,3,4,5] +Output: 4 +Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. + Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are + engaging multiple transactions at the same time. You must sell before buying again. +Example 3: + +Input: [7,6,4,3,1] +Output: 0 +Explanation: In this case, no transaction is done, i.e. max profit = 0. +*/ +const assert = require('assert'); + +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function(prices) { + var profit = 0; + var iter = 0; + + while(iter < prices.length) { + while(iter < prices.length - 1 && prices[iter] > prices[iter + 1]) { + iter++; + } + const buy = prices[iter]; + iter++; + while(iter < prices.length - 1 && prices[iter] < prices[iter + 1]) { + iter++; + } + + if(iter < prices.length) { + const sell = prices[iter]; + profit = profit + sell - buy; + } + } + + return profit; +}; + +var main = function() { + test(); +} + +function test() { + assert.equal(maxProfit([7,1,5,3,6,4]), 7); + assert.equal(maxProfit([7,1,5,3320,6,4]), 3319); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Binary_Gap_Test.js b/LeetcodeProblemsTests/Binary_Gap_Test.js new file mode 100644 index 0000000..0385125 --- /dev/null +++ b/LeetcodeProblemsTests/Binary_Gap_Test.js @@ -0,0 +1,73 @@ +/* +Binary Gap +https://leetcode.com/problems/binary-gap/description/ + +Given a positive integer N, find and return the longest distance between two consecutive 1's in the binary representation of N. + +If there aren't two consecutive 1's, return 0. + +Example 1: + +Input: 22 +Output: 2 +Explanation: +22 in binary is 0b10110. +In the binary representation of 22, there are three ones, and two consecutive pairs of 1's. +The first consecutive pair of 1's have distance 2. +The second consecutive pair of 1's have distance 1. +The answer is the largest of these two distances, which is 2. +Example 2: + +Input: 5 +Output: 2 +Explanation: +5 in binary is 0b101. +Example 3: + +Input: 6 +Output: 1 +Explanation: +6 in binary is 0b110. +Example 4: + +Input: 8 +Output: 0 +Explanation: +8 in binary is 0b1000. +There aren't any consecutive pairs of 1's in the binary representation of 8, so we return 0. +*/ +const assert = require('assert'); + +/** + * @param {number} N + * @return {number} + */ +var binaryGap = function(N) { + var maxDist = 0; + var currentDist = 0; + while(N > 0) { + const bit = N % 2; + N >>= 1; + if(bit === 1) { + currentDist = 1; + while(N > 0 && N % 2 === 0 ) { + currentDist++; + N >>= 1; + } + if(N !== 0 && currentDist > maxDist) + maxDist = currentDist; + } + } + return maxDist; +}; + +var main = function() { + test(); +} + +function test() { + assert.equal(binaryGap(22), 2); // 10110 + assert.equal(binaryGap(8), 0); // 1000 +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Clone_Graph_Test.js b/LeetcodeProblemsTests/Clone_Graph_Test.js new file mode 100644 index 0000000..ee74cdd --- /dev/null +++ b/LeetcodeProblemsTests/Clone_Graph_Test.js @@ -0,0 +1,99 @@ +/* +Clone Graph +https://leetcode.com/problems/clone-graph/description/ + +Given the head of a graph, return a deep copy (clone) of the graph. Each node in the graph contains a label (int) and a list (List[UndirectedGraphNode]) of its neighbors. There is an edge between the given node and each of the nodes in its neighbors. + + +OJ's undirected graph serialization (so you can understand error output): +Nodes are labeled uniquely. + +We use # as a separator for each node, and , as a separator for node label and each neighbor of the node. + + +As an example, consider the serialized graph {0,1,2#1,2#2,2}. + +The graph has a total of three nodes, and therefore contains three parts as separated by #. + +First node is labeled as 0. Connect node 0 to both nodes 1 and 2. +Second node is labeled as 1. Connect node 1 to node 2. +Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. + + +Visually, the graph looks like the following: + + 1 + / \ + / \ + 0 --- 2 + / \ + \_/ +Note: The information about the tree serialization is only meant so that you can understand error output if you get a wrong answer. +You don't need to understand the serialization to solve the problem. +*/ + +/** + * Definition for undirected graph. + * function UndirectedGraphNode(label) { + * this.label = label; + * this.neighbors = []; // Array of UndirectedGraphNode + * } + */ + + +// SOLUTION 1 Using DFS +/** + * @param {UndirectedGraphNode} graph + * @return {UndirectedGraphNode} + */ +var cloneGraph = function(graph) { + if(!graph) + return graph; + + return dfs(graph, {}); +}; + +var dfs = function(graph, visited) { + if(visited[graph.label]) + return visited[graph.label]; + + var newNode = new UndirectedGraphNode(graph.label); + visited[newNode.label] = newNode; + + for(var i = 0; i < graph.neighbors.length; i++) { + const neighbor = dfs(graph.neighbors[i], visited); + newNode.neighbors.push(neighbor); + } + + return newNode; +} + +// SOLUTION 2 Using DFS +var cloneGraphBFS = function(graph) { + if(graph === null) + return graph; + + var visitedMap = {}; + var queue = [graph]; + var copyReturn = new UndirectedGraphNode(graph.label); + visitedMap[graph.label] = copyReturn; + + while(queue.length > 0) { + var node = queue.shift(); + var nodeCopied = visitedMap[node.label]; + + for(var i = 0; i < node.neighbors.length; i++) { + var neighbor = node.neighbors[i]; + + if(!visitedMap[neighbor.label]) { + var copyNeighbor = new UndirectedGraphNode(neighbor.label); + visitedMap[neighbor.label] = copyNeighbor; + queue.push(neighbor); + } + + nodeCopied.neighbors.push(visitedMap[neighbor.label]); + } + } + + return copyReturn; +} diff --git a/LeetcodeProblemsTests/Coin_Change_Test.js b/LeetcodeProblemsTests/Coin_Change_Test.js new file mode 100644 index 0000000..716465c --- /dev/null +++ b/LeetcodeProblemsTests/Coin_Change_Test.js @@ -0,0 +1,117 @@ +/* +Coin Change +https://leetcode.com/problems/coin-change/ + +You are given coins of different denominations and a total amount of money amount. +Write a function to compute the fewest number of coins that you need to make up that amount. +If that amount of money cannot be made up by any combination of the coins, return -1. + +Example 1: + +Input: coins = [1, 2, 5], amount = 11 +Output: 3 +Explanation: 11 = 5 + 5 + 1 +Example 2: + +Input: coins = [2], amount = 3 +Output: -1 +Note: +You may assume that you have an infinite number of each kind of coin. +*/ +const assert = require('assert'); + +// Solution 3 +var coinChange = function(coins, amount) { + var memo = []; + for(var i = 0; i <= amount; i++) + memo[i] = Number.POSITIVE_INFINITY; + + memo[0] = 0; + for(var i = 0; i < coins.length; i++) { + const coin = coins[i]; + for(var j = coin; j < memo.length; j++) + memo[j] = min2(memo[j], memo[j - coin] + 1); + } + + return (memo[amount] == Number.POSITIVE_INFINITY) ? -1 : memo[amount]; +}; + +var min2 = function(a, b) { + return (a < b) ? a : b; +} + +// Solution 2 +var buildMemoKey = function(position, amount) { + return position + "-" + amount; +} + +var coinChange2 = function(coins, amount) { + var memo = {}; + var solution = coinChangeAux2(coins, amount, 0, memo, Number.POSITIVE_INFINITY); + return solution == Number.POSITIVE_INFINITY ? -1 : solution; +}; + +var coinChangeAux2 = function(coins, amount, pos, memo) { + var key = buildMemoKey(pos, amount); + if(memo[key]) + return memo[key]; + + if(amount < 0) { + return Number.POSITIVE_INFINITY; + } else if(amount == 0) { + return 0; + } else if(pos >= coins.length) { + return Number.POSITIVE_INFINITY; + } + + var left = coinChangeAux2(coins, amount, pos + 1, memo); + var middle = 1 + coinChangeAux2(coins, amount - coins[pos], pos + 1, memo); + var right = 1 + coinChangeAux2(coins, amount - coins[pos], pos, memo); + + var solution = min(left, middle, right); + memo[key] = solution; + return solution; +} + +// Solution 1 naive +var coinChange1 = function(coins, amount) { + var solution = coinChangeAux1(coins, amount, 0); + return solution == Number.POSITIVE_INFINITY ? -1 : solution; +}; + +var coinChangeAux1 = function(coins, amount, pos) { + if(amount < 0) { + return Number.POSITIVE_INFINITY; + } else if(amount == 0) { + return 0; + } else if(pos >= coins.length) { + return Number.POSITIVE_INFINITY; + } + + var left = coinChangeAux1(coins, amount, pos + 1); + var middle = 1 + coinChangeAux1(coins, amount - coins[pos], pos + 1); + var right = 1 + coinChangeAux1(coins, amount - coins[pos], pos); + + var partialSol = min(left, middle, right); + return partialSol; +} + +var min = function(a, b, c) { + if(a < b) + return (a < c) ? a : c; + return (b < c) ? b : c; +} + +function main() { + test(); +} + +function test() { + assert.equal(coinChange([], 3), -1); + assert.equal(coinChange([2], 3), -1); + assert.equal(coinChange([1, 2, 5], 11), 3); + assert.equal(coinChange([3, 7, 405, 436], 8839), 25); + assert.equal(coinChange([370, 417, 408, 156, 143, 434, 168, 83, 177, 280, 117], 9953), 24); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js b/LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js new file mode 100644 index 0000000..da702cc --- /dev/null +++ b/LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js @@ -0,0 +1,70 @@ +/* +Construct Binary Tree from Preorder and Inorder Traversal +https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + +Given preorder and inorder traversal of a tree, construct the binary tree. + +Note: +You may assume that duplicates do not exist in the tree. + +For example, given + +preorder = [3,9,20,15,7] +inorder = [9,3,15,20,7] +Return the following binary tree: + + 3 + / \ + 9 20 + / \ + 15 7 +*/ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +const assert = require('assert'); + +var TreeNode = require('../UtilsClasses/TreeNode').TreeNode; + +/** + * @param {number[]} preorder + * @param {number[]} inorder + * @return {TreeNode} + */ +var buildTree = function(preorder, inorder) { + if(preorder === null || inorder === null || preorder.length !== inorder.length) + return nil; + + return buildTreeAux(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); +}; + +var buildTreeAux = function(preorder, pl, ph, inorder, il, ih) { + if(pl > ph || il > ih) + return null; + + const rootValue = preorder[pl]; + var countElementsLeft = 0; + while(inorder[il + countElementsLeft] !== rootValue) + countElementsLeft++; + + var ret = new TreeNode(rootValue); + ret.left = buildTreeAux(preorder, pl + 1, pl + countElementsLeft, inorder, il, il + countElementsLeft - 1); + ret.right = buildTreeAux(preorder, pl + countElementsLeft + 1, ph, inorder, il + countElementsLeft + 1, ih); + + return ret; +} + +var main = function() { + test(); +} + +function test() { + console.log(buildTree([3,9,20,15,7], [9,3,15,20,7])); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Deletion_Distance_Test.js b/LeetcodeProblemsTests/Deletion_Distance_Test.js new file mode 100644 index 0000000..2714fb3 --- /dev/null +++ b/LeetcodeProblemsTests/Deletion_Distance_Test.js @@ -0,0 +1,131 @@ +/* +Deletion Distance +The deletion distance of two strings is the minimum number of characters you need to delete in the two strings in order to get the same string. For instance, the deletion distance between "heat" and "hit" is 3: + +By deleting 'e' and 'a' in "heat", and 'i' in "hit", we get the string "ht" in both cases. +We cannot get the same string from both strings by deleting 2 letters or fewer. +Given the strings str1 and str2, write an efficient function deletionDistance that returns the deletion distance between them. Explain how your function works, and analyze its time and space complexities. + +input: str1 = "dog", str2 = "frog" +output: 3 + +input: str1 = "some", str2 = "some" +output: 0 + +input: str1 = "some", str2 = "thing" +output: 9 + +input: str1 = "", str2 = "" +output: 0 +*/ +const assert = require('assert'); + +// Solution 3 Using DP +var deletionDistanceDP = function(str1, str2) { + if(str1.length === 0) + return str2.length; + if(str2.length === 0) + return str1.length; + + var matrix = []; + for(var i = 0; i <= str1.length; i++) { + matrix[i] = []; + for(var j = 0; j <= str2.length; j++) { + if(i === 0) { + matrix[i][j] = j; + } else if(j == 0) { + matrix[i][j] = i; + } else if(str1[i - 1] === str2[j - 1]) { + matrix[i][j] = matrix[i - 1][j - 1]; + } else { + matrix[i][j] = 1 + min(matrix[i - 1][j], matrix[i][j - 1]); + } + } + } + + return matrix[str1.length][str2.length]; +} + +// Solution 2 Using memoization +var deletionDistance2 = function(str1, str2) { + var memo = {}; + return deletionDistanceAux2(str1, str2, 0, 0, memo); +} + +var deletionDistanceAux2 = function(str1, str2, pos1, pos2, memo) { + const valueCashed = getValue(pos1, pos2, memo); + if(valueCashed !== undefined) + return valueCashed; + var result; + + if(str1.length === pos1) + result = str2.length - pos2; + else if(str2.length === pos2) + result = str1.length - pos1; + else if(str1[pos1] === str2[pos2]) + result = deletionDistanceAux2(str1, str2, pos1 + 1, pos2 + 1, memo); + else + result = 1 + min(deletionDistanceAux2(str1, str2, pos1, pos2 + 1, memo), deletionDistanceAux2(str1, str2, pos1 + 1, pos2, memo)) + + return setValue(pos1, pos2, result, memo); +} + +var getMemoKey = function(pos1, pos2) { + return pos1 + "-" + pos2; +} + +var getValue = function(pos1, pos2, memo) { + const memoKey = getMemoKey(pos1, pos2); + return memo[memoKey]; +} + +var setValue = function(pos1, pos2, value, memo) { + const memoKey = getMemoKey(pos1, pos2); + memo[memoKey] = value; + return value; +} + +// Solution 1 naive +var deletionDistance = function(str1, str2) { + return deletionDistanceAux(str1, str2, 0, 0); +} + +var deletionDistanceAux = function(str1, str2, pos1, pos2) { + if(str1.length === pos1) + return str2.length - pos2; + + if(str2.length === pos2) + return str1.length - pos1; + + if(str1[pos1] === str2[pos2]) + return deletionDistanceAux(str1, str2, pos1 + 1, pos2 + 1); + + return 1 + min(deletionDistanceAux(str1, str2, pos1, pos2 + 1), deletionDistanceAux(str1, str2, pos1 + 1, pos2)); +} + +var min = function(a, b) { + return (a < b) ? a : b; +} + +function main() { + test(); +} + +function test() { + assert.equal(deletionDistance("dog", "frog"), 3); + assert.equal(deletionDistance("some", "some"), 0); + assert.equal(deletionDistance("some", "thing"), 9); + assert.equal(deletionDistance("", ""), 0); + + assert.equal(deletionDistance2("dog", "frog"), 3); + assert.equal(deletionDistance2("some", "some"), 0); + assert.equal(deletionDistance2("some", "thing"), 9); + assert.equal(deletionDistance2("", ""), 0); + + assert.equal(deletionDistanceDP("dog", "frog"), 3); + assert.equal(deletionDistanceDP("some", "some"), 0); + assert.equal(deletionDistanceDP("some", "thing"), 9); + assert.equal(deletionDistanceDP("", ""), 0); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Design_Circular_Deque_Test.js b/LeetcodeProblemsTests/Design_Circular_Deque_Test.js new file mode 100644 index 0000000..60dace9 --- /dev/null +++ b/LeetcodeProblemsTests/Design_Circular_Deque_Test.js @@ -0,0 +1,152 @@ +/* +Design Circular Deque +https://leetcode.com/problems/design-circular-deque/description/ + +Design your implementation of the circular double-ended queue (deque). + +Your implementation should support following operations: + +MyCircularDeque(k): Constructor, set the size of the deque to be k. +insertFront(): Adds an item at the front of Deque. Return true if the operation is successful. +insertLast(): Adds an item at the rear of Deque. Return true if the operation is successful. +deleteFront(): Deletes an item from the front of Deque. Return true if the operation is successful. +deleteLast(): Deletes an item from the rear of Deque. Return true if the operation is successful. +getFront(): Gets the front item from the Deque. If the deque is empty, return -1. +getRear(): Gets the last item from Deque. If the deque is empty, return -1. +isEmpty(): Checks whether Deque is empty or not. +isFull(): Checks whether Deque is full or not. + +Example: + +MyCircularDeque circularDeque = new MycircularDeque(3); // set the size to be 3 +circularDeque.insertLast(1); // return true +circularDeque.insertLast(2); // return true +circularDeque.insertFront(3); // return true +circularDeque.insertFront(4); // return false, the queue is full +circularDeque.getRear(); // return 2 +circularDeque.isFull(); // return true +circularDeque.deleteLast(); // return true +circularDeque.insertFront(4); // return true +circularDeque.getFront(); // return 4 + +Note: + +All values will be in the range of [0, 1000]. +The number of operations will be in the range of [1, 1000]. +Please do not use the built-in Deque library. +*/ +const assert = require('assert'); + +/** + * Initialize your data structure here. Set the size of the deque to be k. + * @param {number} k + */ +var MyCircularDeque = function(k) { + this.queue = []; + this.maxSize = k; +}; + +/** +* Adds an item at the front of Deque. Return true if the operation is successful. +* @param {number} value +* @return {boolean} +*/ +MyCircularDeque.prototype.insertFront = function(value) { + if(this.isFull()) + return false; + + this.queue.unshift(value); + return true; +}; + +/** +* Adds an item at the rear of Deque. Return true if the operation is successful. +* @param {number} value +* @return {boolean} +*/ +MyCircularDeque.prototype.insertLast = function(value) { + if(this.isFull()) + return false; + + this.queue[this.queue.length] = value; + return true; +}; + +/** +* Deletes an item from the front of Deque. Return true if the operation is successful. +* @return {boolean} +*/ +MyCircularDeque.prototype.deleteFront = function() { + if(this.isEmpty()) + return false; + + this.queue.shift(1); + return true; +}; + +/** +* Deletes an item from the rear of Deque. Return true if the operation is successful. +* @return {boolean} +*/ +MyCircularDeque.prototype.deleteLast = function() { + if(this.isEmpty()) + return false; + + this.queue.splice(this.queue.length - 1, 1); + return true; +}; + +/** +* Get the front item from the deque. +* @return {number} +*/ +MyCircularDeque.prototype.getFront = function() { + if(this.isEmpty()) + return -1; + return this.queue[0]; +}; + +/** +* Get the last item from the deque. +* @return {number} +*/ +MyCircularDeque.prototype.getRear = function() { + if(this.isEmpty()) + return -1; + return this.queue[this.queue.length - 1]; +}; + +/** +* Checks whether the circular deque is empty or not. +* @return {boolean} +*/ +MyCircularDeque.prototype.isEmpty = function() { + return this.queue.length === 0; +}; + +/** +* Checks whether the circular deque is full or not. +* @return {boolean} +*/ +MyCircularDeque.prototype.isFull = function() { + return this.queue.length === this.maxSize; +}; + +var main = function(){ + test(); +}; + +var test = function() { + const obj = new MyCircularDeque(3); + assert.equal(obj.insertLast(1), true); + assert.equal(obj.insertLast(2), true); + assert.equal(obj.insertFront(3), true); + assert.equal(obj.insertFront(4), false); + assert.equal(obj.getRear(), 2); + assert.equal(obj.isFull(), true); + assert.equal(obj.deleteLast(), true); + assert.equal(obj.insertFront(4), true); + assert.equal(obj.getFront(), 4); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Edit_Distance_Test.js b/LeetcodeProblemsTests/Edit_Distance_Test.js new file mode 100644 index 0000000..c337677 --- /dev/null +++ b/LeetcodeProblemsTests/Edit_Distance_Test.js @@ -0,0 +1,113 @@ +/* +Edit Distance +https://leetcode.com/problems/edit-distance/ + +Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2. + +You have the following 3 operations permitted on a word: + +Insert a character +Delete a character +Replace a character +Example 1: + +Input: word1 = "horse", word2 = "ros" +Output: 3 +Explanation: +horse -> rorse (replace 'h' with 'r') +rorse -> rose (remove 'r') +rose -> ros (remove 'e') +Example 2: + +Input: word1 = "intention", word2 = "execution" +Output: 5 +Explanation: +intention -> inention (remove 't') +inention -> enention (replace 'i' with 'e') +enention -> exention (replace 'n' with 'x') +exention -> exection (replace 'n' with 'c') +exection -> execution (insert 'u') +*/ +const assert = require('assert'); + +// Optimal solution +var minDistance = function(word1, word2) { + var matrix = []; + for(var i = 0; i <= word1.length; i++) { + matrix[i] = []; + for(var j = 0; j <= word2.length; j++) { + if(i === 0) + matrix[i][j] = j; + else if(j === 0) + matrix[i][j] = i; + else + matrix[i][j] = 0; + } + }; + + for(var i = 1; i <= word1.length; i++) { + for(var j = 1; j <= word2.length; j++) { + if(word1.charAt(i - 1) === word2.charAt(j - 1)) { + matrix[i][j] = matrix[i - 1][j - 1]; + } else { + matrix[i][j] = 1 + min( + matrix[i - 1][j - 1], + matrix[i - 1][j], // add + matrix[i][j - 1] // remove + ); + } + } + } + + return matrix[word1.length][word2.length]; +}; + +var min = function(a, b, c) { + if(a < b) { + return (a < c) ? a : c; + } + return (b < c) ? b : c; +} + +//Solution 2 +var minDistance2 = function(word1, word2) { + return minDistanceAux(word1, word2, 0, 0); +} + +var minDistanceAux = function(word1, word2, iter1, iter2) { + if(word1.length === iter1) + return word2.length - iter2; + + if(word2.length === iter2) + return word1.length - iter1; + + if(word1.charAt(iter1) === word2.charAt(iter2)) + return minDistanceAux(word1, word2, iter1 + 1, iter2 + 1); + + return 1 + min( + minDistanceAux(word1, word2, iter1 + 1, iter2 + 1), + minDistanceAux(word1, word2, iter1, iter2 + 1), // add + minDistanceAux(word1, word2, iter1 + 1, iter2 ) // delete + ) +}; + +var min = function(a, b, c) { + if(a < b) + return (a < c) ? a : c; + + return (b < c) ? b : c; +} + +var main = function() { + test(); +} + +function test() { + assert.equal(minDistance("ros", "horse"), 3); + assert.equal(minDistance("intention", "execution"), 5); + + assert.equal(minDistance2("ros", "horse"), 3); + assert.equal(minDistance2("intention", "execution"), 5); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Escape_The_Ghosts_Test.js b/LeetcodeProblemsTests/Escape_The_Ghosts_Test.js new file mode 100644 index 0000000..3e8ee10 --- /dev/null +++ b/LeetcodeProblemsTests/Escape_The_Ghosts_Test.js @@ -0,0 +1,73 @@ +/* +Escape The Ghosts +https://leetcode.com/problems/escape-the-ghosts/description/ + +You are playing a simplified Pacman game. You start at the point (0, 0), and your destination is (target[0], target[1]). There are several ghosts on the map, the i-th ghost starts at (ghosts[i][0], ghosts[i][1]). + +Each turn, you and all ghosts simultaneously *may* move in one of 4 cardinal directions: north, east, west, or south, going from the previous point to a new point 1 unit of distance away. + +You escape if and only if you can reach the target before any ghost reaches you (for any given moves the ghosts may take.) If you reach any square (including the target) at the same time as a ghost, it doesn't count as an escape. + +Return True if and only if it is possible to escape. + +Example 1: +Input: +ghosts = [[1, 0], [0, 3]] +target = [0, 1] +Output: true +Explanation: +You can directly reach the destination (0, 1) at time 1, while the ghosts located at (1, 0) or (0, 3) have no way to catch up with you. +Example 2: +Input: +ghosts = [[1, 0]] +target = [2, 0] +Output: false +Explanation: +You need to reach the destination (2, 0), but the ghost at (1, 0) lies between you and the destination. +Example 3: +Input: +ghosts = [[2, 0]] +target = [1, 0] +Output: false +Explanation: +The ghost can reach the target at the same time as you. +Note: + +All points have coordinates with absolute value <= 10000. +The number of ghosts will not exceed 100. +*/ +const assert = require('assert'); + +/** + * @param {number[][]} ghosts + * @param {number[]} target + * @return {boolean} + */ +var escapeGhosts = function(ghosts, target) { + var distancePacman = getDistance([0,0], target); + for(ghost in ghosts) { + const distanceGhost = getDistance(ghosts[ghost], target); + if(distancePacman > distanceGhost) + return false + } + + return true; +}; + +var getDistance = function(a, b) { + const horizontalMoves = Math.abs(a[0] - b[0]); + const verticalMoves = Math.abs(a[1] - b[1]); + return horizontalMoves + verticalMoves; +} + +var main = function() { + test(); +} + +function test() { + assert.equal(escapeGhosts([[1, 0], [0, 3]], [0, 1]), true); + assert.equal(escapeGhosts([[1, 0]], [2, 0]), false); + assert.equal(escapeGhosts([[2, 0]], [1, 0]), true); +} + +module.exports.main = main \ No newline at end of file diff --git a/LeetcodeProblemsTests/Flood_Fill_Test.js b/LeetcodeProblemsTests/Flood_Fill_Test.js new file mode 100644 index 0000000..14ed4e3 --- /dev/null +++ b/LeetcodeProblemsTests/Flood_Fill_Test.js @@ -0,0 +1,67 @@ +/* +Flood Fill +https://leetcode.com/problems/flood-fill/description/ + +An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535). + +Given a coordinate (sr, sc) representing the starting pixel (row and column) of the flood fill, and a pixel value newColor, "flood fill" the image. + +To perform a "flood fill", consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, +plus any pixels connected 4-directionally to those pixels (also with the same color as the starting pixel), and so on. +Replace the color of all of the aforementioned pixels with the newColor. + +At the end, return the modified image. + +Example 1: +Input: +image = [[1,1,1],[1,1,0],[1,0,1]] +sr = 1, sc = 1, newColor = 2 +Output: [[2,2,2],[2,2,0],[2,0,1]] +Explanation: +From the center of the image (with position (sr, sc) = (1, 1)), all pixels connected +by a path of the same color as the starting pixel are colored with the new color. +Note the bottom corner is not colored 2, because it is not 4-directionally connected +to the starting pixel. +Note: + +The length of image and image[0] will be in the range [1, 50]. +The given starting pixel will satisfy 0 <= sr < image.length and 0 <= sc < image[0].length. +The value of each color in image[i][j] and newColor will be an integer in [0, 65535]. +*/ +const assert = require('assert'); + +var floodFill = function(image, sr, sc, newColor) { + var oldColor = image[sr][sc]; + + if(newColor == oldColor) + return image; + + image[sr][sc] = newColor; + + if(sr > 0 && image[sr - 1][sc] == oldColor) + floodFill(image, sr - 1, sc, newColor); //Left + + if(sc > 0 && image[sr][sc - 1] == oldColor) + floodFill(image, sr, sc - 1, newColor); //Up + + if(sr < image.length - 1 && image[sr + 1][sc] == oldColor) + floodFill(image, sr + 1, sc, newColor); //Down + + if(sc < image[0].length - 1 && image[sr][sc + 1] == oldColor) + floodFill(image, sr, sc + 1, newColor); // Right + + return image; +}; + +function main() { + test(); +} + +function test() { + assert.deepEqual( + [ [ 2, 2, 2 ], [ 2, 2, 0 ], [ 2, 0, 1 ] ], + floodFill([[1,1,1],[1,1,0],[1,0,1]], 1, 1, 2) + ); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Generate_Parenthesis_Test.js b/LeetcodeProblemsTests/Generate_Parenthesis_Test.js new file mode 100644 index 0000000..323b6ef --- /dev/null +++ b/LeetcodeProblemsTests/Generate_Parenthesis_Test.js @@ -0,0 +1,94 @@ +/* +Generate Parentheses +https://leetcode.com/problems/generate-parentheses + +Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + +For example, given n = 3, a solution set is: + +[ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" +] +*/ + +// ************************************************ Approach1 ************************************************ +var generateParenthesisApproach1 = function(n) { + if(n === 0) + return []; + + var str = "(".repeat(n); + sol = []; + + genParAux(str, 0, 0, sol) + return sol; +}; + +var genParAux = function(str, position, leftParentheses, sol) { + if(position === str.length) { + var ret = str + ")".repeat(leftParentheses); + sol.push(ret); + return; + } + + genParAux(str, position + 1, leftParentheses + 1, sol); // Don't insert anything + if(leftParentheses === 0) + return; + + for(var i = 1; i <= leftParentheses; i++) { + var parString = ")".repeat(i); + var partSol = str.slice(0, position) + parString + str.slice(position); // Insert i parentheses in the position + genParAux(partSol, position + i + 1, leftParentheses - i + 1, sol); + } +} + +// ************************************************ Approach2 ************************************************ +var generateParenthesisApproach2 = function(n) { + if(n === 0) + return []; + + var sol = []; + genParAuxApproach2("", 0, 0, 0, n * 2, sol) + return sol; +} + +var genParAuxApproach2 = function(str, leftPar, rightPar, index, totalCharCount, sol) { + if(index === totalCharCount) { + if(rightPar === leftPar) + sol.push(str); + + return; + } + + var strLeft = insertAt(str, index, "("); + genParAuxApproach2(strLeft, leftPar + 1, rightPar, index + 1, totalCharCount, sol); + + if(rightPar === leftPar) + return; + + var strRight = insertAt(str, index, ")"); + genParAuxApproach2(strRight, leftPar, rightPar + 1, index + 1, totalCharCount, sol); +} + +var insertAt = function(str, position, value) { + return str.slice(0, position) + value + str.slice(position); +} + +function main() { + console.log("Approach 1"); + [0, 1, 2, 3].forEach(function(elem) { + console.log(`${elem}: ${generateParenthesisApproach2(elem)}`); + }) + + console.log("-------------"); + + console.log("Approach 2"); + [0, 1, 2, 3].forEach(function(elem) { + console.log(`${elem}: ${generateParenthesisApproach2(elem)}`); + }) +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Group_Anagrams_Test.js b/LeetcodeProblemsTests/Group_Anagrams_Test.js new file mode 100644 index 0000000..230af77 --- /dev/null +++ b/LeetcodeProblemsTests/Group_Anagrams_Test.js @@ -0,0 +1,62 @@ +/* +Group Anagrams +https://leetcode.com/problems/group-anagrams/description/ + +Given an array of strings, group anagrams together. + +Example: + +Input: ["eat", "tea", "tan", "ate", "nat", "bat"], +Output: +[ + ["ate","eat","tea"], + ["nat","tan"], + ["bat"] +] +Note: + +All inputs will be in lowercase. +The order of your output does not matter. +*/ +const assert = require('assert'); + +var groupAnagrams = function(strs) { + var ret = []; + var hashMap = {}; + for(var i = 0; i < strs.length; i++) { + const elem = strs[i]; + const elemSorted = sortString(strs[i]); + + if(hashMap[elemSorted]) { + hashMap[elemSorted].push(elem); + } else { + hashMap[elemSorted] = [elem]; + } + } + + for(key in hashMap) + ret.push(hashMap[key]); + + + return ret; +}; + +var sortString = function(str) { + if(str.length === 0) + return str; + + return str.split("").sort().join(""); +} + +var main = function() { + test(); +} + +function test() { + assert.deepEqual( + groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]), + [ [ 'eat', 'tea', 'ate' ], [ 'tan', 'nat' ], [ 'bat' ] ] + ) +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js b/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js new file mode 100644 index 0000000..9f33c41 --- /dev/null +++ b/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js @@ -0,0 +1,99 @@ +/* +Implement Stack using Queues +URL: https://leetcode.com/problems/implement-stack-using-queues/description/ + +Implement the following operations of a stack using queues. + +push(x) -- Push element x onto stack. +pop() -- Removes the element on top of the stack. +top() -- Get the top element. +empty() -- Return whether the stack is empty. +Example: + +MyStack stack = new MyStack(); + +stack.push(1); +stack.push(2); +stack.top(); // returns 2 +stack.pop(); // returns 2 +stack.empty(); // returns false +Notes: + +You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid. +Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. +You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). +*/ +const assert = require('assert'); +class MyStack { + constructor() { + this.q1 = []; + this.q2 = []; + }; + + push(elem) { + if(this.q1.length > 0) { + this.q1.push(elem); + } else { + this.q2.push(elem); + } + }; + + pop() { + if(this.q1.length === 0 && this.q2.length === 0) + return null; + + if(this.q1.length > 0) { + while(this.q1.length > 1) { + var elem = this.q1.shift(); + this.q2.push(elem); + } + return this.q1.shift(); + } else { + while(this.q2.length > 1) { + var elem = this.q2.shift(); + this.q1.push(elem); + } + return this.q2.shift(); + } + }; + + top() { + if(this.q1.length === 0 && this.q2.length === 0) + return null; + + if(this.q1.length > 0) { + var elem = this.pop(); + this.q2.push(elem); + return elem; + } else { + var elem = this.pop(); + this.q1.push(elem); + return elem; + } + }; + + empty() { + return this.q1.length == 0 && this.q2.length === 0; + }; +} + +var main = function() { + test(); +} + +var test = function () { + var myStack = new MyStack(); + myStack.push(4); + myStack.push(3); + myStack.push(2); + myStack.push(1); + assert.equal(myStack.pop(), 1); + assert.equal(myStack.top(), 2); + myStack.push(1); + assert.equal(myStack.top(), 1); + assert.equal(myStack.pop(), 1); + assert.equal(myStack.pop(), 2); + assert.equal(myStack.pop(), 3); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js b/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js new file mode 100644 index 0000000..51ed6cb --- /dev/null +++ b/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js @@ -0,0 +1,71 @@ +/* +Kth Largest Element in an Array +https://leetcode.com/problems/kth-largest-element-in-an-array/description/ + +Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. + +Example 1: + +Input: [3,2,1,5,6,4] and k = 2 +Output: 5 +Example 2: + +Input: [3,2,3,1,2,4,5,5,6] and k = 4 +Output: 4 +Note: +You may assume k is always valid, 1 ≤ k ≤ array's length. +*/ +const assert = require('assert'); + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var findKthLargest = function(nums, k) { + for(var i = Math.floor(nums.length/2) - 1; i >= 0; i--) { + heapify(nums, nums.length, i); + } + + for(var i = nums.length -1; i >= nums.length - k - 1 && i >= 0; i--) { + swap(nums, 0, i); + heapify(nums, i, 0); + } + + return nums[nums.length - k]; +} + +var heapify = function(nums, length, i) { + var left = 2 * i + 1; + var right = 2 * i + 2; + + if(left >= length) + return; + + if(nums[i] < nums[left] && (right >= length || nums[left] > nums[right])) { + swap(nums, left, i); + heapify(nums, length, left); + } else if(right < length && nums[right] > nums[i]) { + swap(nums, right, i) + heapify(nums, length, right) + } +} + +var swap = function(nums, a, b) { + const temp = nums[a]; + nums[a] = nums[b]; + nums[b] = temp; +} + +var main = function(nums) { + test(); +} + +function test() { + assert.equal(findKthLargest([3,2,1,5,6,4], 2), 5); + assert.equal(findKthLargest([3,2,3,1,2,4,5,5,6], 4), 4); + assert.equal(findKthLargest([0], 1), 0); + assert.equal(findKthLargest([], 1), undefined); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js b/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js new file mode 100644 index 0000000..9573e63 --- /dev/null +++ b/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js @@ -0,0 +1,90 @@ +/* +Linked List Cycle +https://leetcode.com/problems/linked-list-cycle-ii/description/ + +Given a linked list, return the node where the cycle begins. If there is no cycle, return null. + +Note: Do not modify the linked list. + +Follow up: +Can you solve it without using extra space? +*/ +const assert = require('assert'); +var ListNode = require('../UtilsClasses/ListNode').ListNode; + +// Optimal solution +/** +* @param {ListNode} head +* @return {ListNode} +*/ +var detectCycle = function(head) { + if (head === null) + return null; + + var slow = head; + var fast = head; + + while(fast.next !== null && fast.next.next !== null) { + slow = slow.next; + fast = fast.next.next; + if(fast == slow) { + var a = head; + var b = slow; + while(a !== b) { + a = a.next; + b = b.next; + } + return a; + } + } + return null; +}; + +// Naiver solution using a Set +var detectCycle2 = function(head) { + if(head === null || head.next === null) { + return null; + } + var setNodes = new Set(); + var iter = head; + while(iter !== null) { + if(setNodes.has(iter)) { + return iter; + } + setNodes.add(iter); + iter = iter.next + } + return null; +}; + +var main = function() { + test(); +} + +var test = function() { + const cycle = buildCycle(); + var list = cycle.list; + var nodeCycle = cycle.nodeCycle; + assert.equal(detectCycle(list), nodeCycle); +} + +function buildCycle() { + var node1 = ListNode.linkenList([1,2,3,4,5]); + var node2 = new ListNode(2); + var node3 = new ListNode(3); + var node4 = new ListNode(4); + var node5 = new ListNode(5); + + node1.next = node2; + node2.next = node3; + node3.next = node4; + node4.next = node5; + node5.next = node2; + + return { + list: node1, + nodeCycle: node2, + }; +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js b/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js new file mode 100644 index 0000000..290d9ea --- /dev/null +++ b/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js @@ -0,0 +1,69 @@ +/* +Longest Consecutive Sequence +https://leetcode.com/problems/longest-consecutive-sequence/ + +Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + +Your algorithm should run in O(n) complexity. + +Example: + +Input: [100, 4, 200, 1, 3, 2] +Output: 4 +Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. +*/ +const assert = require('assert'); + +/** + * @param {number[]} nums + * @return {number} + */ +var longestConsecutive = function(nums) { + if(nums.length === 0) + return 0; + var setNums = new Set(); + for(var i = 0; i < nums.length; i++) + setNums.add(nums[i]); + + var cons = 1; + var currentCons = 1; + for(var i = 0; i < nums.length; i++) { + var number = nums[i]; + if(setNums.has(number)) { + setNums.delete(number); + + var prevNum = number - 1; + while(setNums.has(prevNum)){ + currentCons++; + setNums.delete(prevNum); + prevNum--; + } + + var nextNum = number + 1; + while(setNums.has(nextNum)){ + currentCons++; + setNums.delete(nextNum); + nextNum++; + } + + if(currentCons > cons) + cons = currentCons + } + currentCons = 1; + } + return cons; +}; + +var main = function() { + test(); +} + +function test() { + assert.equal(longestConsecutive([100, 1, 200, 3, 2, 400, 201]), 3); + assert.equal(longestConsecutive([1,2,3,4, 100, 1, 200, 3, 2, 400, 201]), 4); + assert.equal(longestConsecutive([1, 400, 201, 403, 398]), 1); + assert.equal(longestConsecutive([]), 0); + assert.equal(longestConsecutive([2]), 1); +} + +module.exports.main diff --git a/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js b/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js new file mode 100644 index 0000000..74a2447 --- /dev/null +++ b/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js @@ -0,0 +1,80 @@ +/* +Longest Palindromic Substring +https://leetcode.com/problems/longest-palindromic-substring/description/ + +Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. + +Example 1: + +Input: "babad" +Output: "bab" +Note: "aba" is also a valid answer. +Example 2: + +Input: "cbbd" +Output: "bb" +*/ +const assert = require('assert'); + +/** + * @param {string} s + * @return {string} + */ +var longestPalindrome = function(str) { + if(str.length == 0) + return ""; + + var maxPal = 1; + var posPalStart = 0; + var currentPalStart = 0; + + for(var i = 1; i < str.length; i++) { + if(str.charAt(i - 1) == str.charAt(i)) { + currentPalStart = i - 1; + var currentPal = 2; + var iter = 1; + while(i - iter - 1 >= 0 && i + iter < str.length && str.charAt(i - iter - 1) == str.charAt(i + iter)) { + currentPalStart = i - iter - 1; + iter++; + currentPal += 2; + } + } + if(currentPal > maxPal) { + maxPal = currentPal; + posPalStart = currentPalStart; + } + } + + for(var i = 1; i < str.length - 1; i++) { + if(str.charAt(i - 1) == str.charAt(i + 1)) { + currentPal = 1; + var iter = 1; + while(i - iter >= 0 && i + iter < str.length && str.charAt(i - iter) == str.charAt(i + iter)) { + currentPalStart = i - iter; + iter++; + currentPal += 2; + } + } + if(currentPal > maxPal) { + maxPal = currentPal; + posPalStart = currentPalStart; + } + } + + return str.slice(posPalStart, posPalStart + maxPal); +} + +var main = function() { + test(); +} + +function test() { + assert.equal(longestPalindrome("pabcdcbte"), "bcdcb"); + assert.equal(longestPalindrome("bb"), "bb"); + assert.equal(longestPalindrome(""), ""); + assert.equal(longestPalindrome("bbb"), "bbb"); + assert.equal(longestPalindrome("bbbb"), "bbbb"); + assert.equal(longestPalindrome("ptabbbbat"), "tabbbbat"); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js b/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js new file mode 100644 index 0000000..c4f0168 --- /dev/null +++ b/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js @@ -0,0 +1,129 @@ +/* +Lowest Common Ancestor of a Binary Tree +https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ + +Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. + +According to the definition of LCA on Wikipedia: +“The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants +(where we allow a node to be a descendant of itself).” + +Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4] + + _______3______ + / \ + ___5__ ___1__ + / \ / \ + 6 _2 0 8 + / \ + 7 4 +Example 1: + +Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 +Output: 3 +Explanation: The LCA of nodes 5 and 1 is 3. +Example 2: + +Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 +Output: 5 +Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself + according to the LCA definition. +Note: + +All of the nodes' values will be unique. +p and q are different and both values will exist in the binary tree. +*/ +const assert = require('assert'); + +var TreeNode = require('../UtilsClasses/TreeNode').TreeNode; + +// Solution 1 +var lowestCommonAncestor = function(root, p, q) { + if(root === null) + return root; + if(p.val === root.val) + return p; + if(q.val === root.val) + return q; + + const left = lowestCommonAncestor(root.left, p, q); + const right = lowestCommonAncestor(root.right, p, q); + if(left !== null && right !== null) + return root; + return left !== null ? left : right; +}; + +// Solution 2 +var lowestCommonAncestor2 = function(root, p, q) { + var pathToP = pathTo(root, p.val); + var pathToQ = pathTo(root, q.val); + + if(pathToP.length === 0 || pathToQ === 0) + return null; + + var iter = 0; + while(iter < pathToP.length - 1 && iter < pathToQ.length - 1 && pathToP[iter + 1] === pathToQ[iter + 1]) { + if(root.left !== null && root.left.val === pathToP[iter + 1]) { + root = root.left; + } else { + root = root.right; + } + iter++; + } + + return root; +}; + +var pathTo = function(root, value) { + if(root === null) + return []; + + var list = [root.val]; + if(root.val === value) + return list; + + const left = pathTo(root.left, value); + if (left.length > 0) + return list.concat(left); + + const right = pathTo(root.right, value); + if(right.length > 0) + return list.concat(right); + + return []; +} + +var main = function() { + var root = new TreeNode(3); + + var right = new TreeNode(1); + right.left = new TreeNode(0); + right.right = new TreeNode(8); + root.right = right; + + var left = new TreeNode(5); + left.left = new TreeNode(6); + + var tempRight = new TreeNode(2); + tempRight.left = new TreeNode(7); + tempRight.right = new TreeNode(4); + left.right = tempRight; + + root.left = left; + + // _______3______ + // / \ + // ___5__ ___1__ + // / \ / \ + // 6 _2 0 8 + // / \ + // 7 4 + + console.log(lowestCommonAncestor(root, left, tempRight.right)); + console.log(lowestCommonAncestor(root, left, right)); + + console.log(lowestCommonAncestor2(root, left, tempRight.right)); + console.log(lowestCommonAncestor2(root, left, right)); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Majority_Element_Test.js b/LeetcodeProblemsTests/Majority_Element_Test.js new file mode 100644 index 0000000..f1114f8 --- /dev/null +++ b/LeetcodeProblemsTests/Majority_Element_Test.js @@ -0,0 +1,58 @@ +/* +Majority Element +https://leetcode.com/problems/majority-element/ + +Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. + +You may assume that the array is non-empty and the majority element always exist in the array. + +Example 1: + +Input: [3,2,3] +Output: 3 +Example 2: + +Input: [2,2,1,1,1,2,2] +Output: 2 + +Note: You should have a better solution than O(N) +*/ +const assert = require('assert'); + +/** + * @param {number[]} nums + * @return {number} + */ +var majorityElement = function(nums) { + if(nums.length === 0) + return -1; + + var candidate = nums[0]; + var proves = 1; + + for(var i = 1; i < nums.length; i++) { + if(nums[i] === candidate) + proves++; + else { + proves--; + if(proves === 0) { + candidate = nums[i]; + proves = 1; + } + } + } + + return candidate; +}; + +var main = function() { + test(); +} + +function test() { + assert.equal(majorityElement([2,2,3]), 2); + assert.equal(majorityElement([2,3,2]), 2); + assert.equal(majorityElement([1,1,1,2,3,45,1,2,4,1,1]), 1); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Maximal_Square_Test.js b/LeetcodeProblemsTests/Maximal_Square_Test.js new file mode 100644 index 0000000..014d4a8 --- /dev/null +++ b/LeetcodeProblemsTests/Maximal_Square_Test.js @@ -0,0 +1,82 @@ +/* +Maximal Square +https://leetcode.com/problems/maximal-square/ + +Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. + +Example: + +Input: + +1 0 1 0 0 +1 0 1 1 1 +1 1 1 1 1 +1 0 0 1 0 + +Output: 4 +*/ +const assert = require('assert'); + +/** + * @param {character[][]} matrix + * @return {number} + */ +var maximalSquare = function(matrix) { + var maxSquare = 0; + for(var i = 0; i < matrix.length; i++) { + for(var j = 0; j < matrix[0].length; j++) { + if(matrix[i][j] === "1") { // found a 1 + const currentMaxSideLength = getCurrentMaxSideLength(matrix, i, j); + if(currentMaxSideLength ** 2 > maxSquare) + maxSquare = currentMaxSideLength ** 2; + } + } + } + + return maxSquare; +}; + +var getCurrentMaxSideLength = function(matrix, i, j) { + var max = 1; + while(i + max < matrix.length && j + max < matrix[0].length) { + var lastRow = i + max; + var lastCol = j + max; + + // check last column + var iterRow = i; + while(iterRow <= lastRow){ + if(matrix[iterRow][lastCol] === "0") + return max; + + iterRow++; + } + + // check last row + var iterCol = j; + while(iterCol <= lastCol) { + if(matrix[lastRow][iterCol] === "0") + return max; + iterCol++; + } + + max++; + } + + return max; +} + +var main = function() { + test(); +} + +function test() { + assert.equal(maximalSquare([["1","0"]]), 1); + assert.equal(maximalSquare([["1"]]), 1); + assert.equal(maximalSquare([["0"]]), 0); + assert.equal( + maximalSquare([["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]), + 4 + ); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Maximun_Subarray_Test.js b/LeetcodeProblemsTests/Maximun_Subarray_Test.js new file mode 100644 index 0000000..c159a43 --- /dev/null +++ b/LeetcodeProblemsTests/Maximun_Subarray_Test.js @@ -0,0 +1,48 @@ +/* +Maximum Subarray +https://leetcode.com/problems/maximum-subarray + +Given an integer array nums, find the contiguous subarray (containing at least one number) +which has the largest sum and return its sum. + +Example: + +Input: [-2,1,-3,4,-1,2,1,-5,4], +Output: 6 +Explanation: [4,-1,2,1] has the largest sum = 6. +Follow up: + +*/ +const assert = require('assert'); + +var maxSubArray = function(nums) { + if(nums.length == 0) + return 0; + var maxSub = nums[0]; + var currentMax = nums[0]; + + for(var i = 1; i < nums.length; i++) { + currentMax = max(nums[i], currentMax + nums[i]); + if(currentMax > maxSub) + maxSub = currentMax; + } + + return maxSub; +}; + +var max = function(i, j) { + return (i > j) ? i : j; +} + +var main = function() { + test(); +} + +function test() { + assert.equal(maxSubArray([]), 0); + assert.equal(maxSubArray([-4]), -4); + assert.equal(maxSubArray([2]), 2); + assert.equal(maxSubArray([4,1,-1,4,5,6,7,-200]), 26); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Min_Stack_Test.js b/LeetcodeProblemsTests/Min_Stack_Test.js new file mode 100644 index 0000000..3ee0f78 --- /dev/null +++ b/LeetcodeProblemsTests/Min_Stack_Test.js @@ -0,0 +1,92 @@ +/* +Min Stack + +https://leetcode.com/problems/min-stack/description/ + +Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + +push(x) -- Push element x onto stack. +pop() -- Removes the element on top of the stack. +top() -- Get the top element. +getMin() -- Retrieve the minimum element in the stack. +Example: +MinStack minStack = new MinStack(); +minStack.push(-2); +minStack.push(0); +minStack.push(-3); +minStack.getMin(); --> Returns -3. +minStack.pop(); +minStack.top(); --> Returns 0. +minStack.getMin(); --> Returns -2. +*/ +const assert = require('assert'); + +class MinStack { + constructor() { + this.minStack = []; + this.stack = []; + this.countStack = 0; + this.countMinStack = 0; + } + + push(value) { + if(this.countStack === this.stack.length) + this.stack.push(value); + else + this.stack[this.countStack] = value; + this.countStack++; + + const min = this.getMin(); + if(min === null || min >= value) { + if(this.countMinStack === this.minStack.length) + this.minStack.push(value); + else + this.minStack[this.countMinStack] = value; + this.countMinStack++; + } + } + + pop() { + if(this.countStack === 0) + return null; + + var elem = this.stack[this.countStack - 1]; + this.countStack--; + + if(elem === this.minStack[this.countMinStack - 1]) + this.countMinStack--; + + return elem; + } + + top() { + if(this.countStack === 0) + return null; + + return this.stack[this.countStack - 1]; + } + + getMin() { + if(this.countMinStack === 0) + return null; + + return this.minStack[this.countMinStack - 1] + } +} + +var main = function() { + test(); +} + +function test() { + var minStack = new MinStack(); + minStack.push(-2); + minStack.push(0); + minStack.push(-3); + assert.equal(minStack.getMin(), -3); + assert.equal(minStack.pop(), -3); + assert.equal(minStack.top(), 0); + assert.equal(minStack.getMin(), -2); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js b/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js new file mode 100644 index 0000000..2769963 --- /dev/null +++ b/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js @@ -0,0 +1,80 @@ +/* +Minimum Window Substring +https://leetcode.com/problems/minimum-window-substring/ + +Given a string S and a string T, find the minimum window in S which will contain all the characters in T +in complexity O(n). + +Example: + +Input: S = "ADOBECODEBANC", T = "ABC" +Output: "BANC" +Note: + +If there is no such window in S that covers all characters in T, return the empty string "". +If there is such window, you are guaranteed that there will always be only one unique minimum window in S. +*/ +const assert = require('assert'); + +var minWindow = function(s, t) { + if(t.length === 0 || s.length < t.length) + return ""; + + var start = 0; + var end = 0; + var solutionStart, solutionEnd; + var hashT = getHash(t); + var currentHash = {}; + var currentCount = 0; + while(end < s.length) { + const letter = s.charAt(end); + if(hashT[letter]) { + currentHash[letter] = (currentHash[letter]) ? currentHash[letter] + 1 : 1; + if(currentHash[letter] <= hashT[letter]) + currentCount++; + if(currentCount === t.length) { + while(hashT[s[start]] === undefined || currentHash[s[start]] > hashT[s[start]]) { + if(currentHash[s[start]] !== undefined) + currentHash[s[start]] = currentHash[s[start]] - 1; + + start++; + } + if(solutionEnd === undefined || end - start < solutionEnd - solutionStart) { + solutionStart = start; + solutionEnd = end; + } + + currentHash[s[start]] = currentHash[s[start]] - 1; + start++; + currentCount--; + } + } + end++; + } + + return s.slice(solutionStart, solutionEnd + 1); +}; + +var getHash = function(t) { + var hash = {}; + for(var i = 0; i < t.length; i++) { + const letter = t.charAt(i); + hash[letter] = (hash[letter]) ? hash[letter] + 1 : 1; + } + return hash; +} + +var main = function() { + test(); +} + +function test() { + assert.equal(minWindow("ADOBECODEBANC", "ABC"), "BANC"); + assert.equal(minWindow("caaec", "cae"), "aec"); + assert.equal(minWindow("bbacbb", "ab"), "ba"); + assert.equal(minWindow("abba", "b"), "b"); + assert.equal(minWindow("abba", "a"), "a"); + assert.equal(minWindow("abba", ""), ""); +} + +module.exports.main diff --git a/LeetcodeProblemsTests/NQueens_Test.js b/LeetcodeProblemsTests/NQueens_Test.js new file mode 100644 index 0000000..f78d3b8 --- /dev/null +++ b/LeetcodeProblemsTests/NQueens_Test.js @@ -0,0 +1,98 @@ +/* +NQueens +https://leetcode.com/problems/n-queens/description/ + +Example: + +Input: 4 +Output: [ + [".Q..", // Solution 1 + "...Q", + "Q...", + "..Q."], + + ["..Q.", // Solution 2 + "Q...", + "...Q", + ".Q.."] +] +Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. +*/ +const assert = require('assert'); + +/** + * @param {number} n + * @return {string[][]} + */ +var solveNQueens = function(n) { + var sol = []; + solveNQueensAux(n, 0, new Set(), new Set(), new Set(), [], sol); + return parseSolutions(sol, n); +}; + +var solveNQueensAux = function(n, row, diagonalDiffs, diagonalSums, cols, currentSol, sol) { + if(row == n) { + sol.push(currentSol); + return; + } + + for(var i = 0; i < n; i++) { + const diagonalDiff = i - row; + const diagonalSum = i + row; + if(!diagonalDiffs.has(diagonalDiff) && !cols.has(i) && !diagonalSums.has(diagonalSum)) { + diagonalDiffs.add(diagonalDiff); + diagonalSums.add(diagonalSum); + cols.add(i); + solveNQueensAux(n, row + 1, diagonalDiffs, diagonalSums, cols, [...currentSol, ...[[row, i]]], sol); + cols.delete(i); + diagonalDiffs.delete(diagonalDiff); + diagonalSums.delete(diagonalSum); + } + } +} + +var parseSolutions = function(sols, n) { + var matrixes = []; + for(var i = 0; i < sols.length; i++) { + var sol = sols[i]; + var matrix = []; + for(var row = 0; row < n; row++) { + matrix[row] = [] + const queenPos = sol[row]; + for(var col = 0; col < n; col++) { + matrix[row] += (queenPos[1] == col) ? "Q" : "."; + } + } + + matrixes.push(matrix); + } + + return matrixes; +} + +var main = function(n) { + printMatrixes(solveNQueens(4), 4); + printMatrixes(solveNQueens(5), 5); + printMatrixes(solveNQueens(6), 6); +} + +var test = function() { +} + +var printMatrixes = function(matrixes, n) { + console.log("Start solution of n: " + n); + for(var i = 0; i < matrixes.length; i++) { + printMatrix(matrixes[i]); + } + console.log("End solution of n: " + n); +} + +var printMatrix = function(matrix) { + console.log("------------"); + for(var i = 0; i < matrix.length; i++) { + console.log(matrix[i]); + } + console.log("------------"); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Number_of_Islands_Test.js b/LeetcodeProblemsTests/Number_of_Islands_Test.js new file mode 100644 index 0000000..248ea49 --- /dev/null +++ b/LeetcodeProblemsTests/Number_of_Islands_Test.js @@ -0,0 +1,83 @@ +/* +Number of Islands +https://leetcode.com/problems/number-of-islands/ + +Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and +is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. + +Example 1: + +Input: +11110 +11010 +11000 +00000 + +Output: 1 +Example 2: + +Input: +11000 +11000 +00100 +00011 + +Output: 3 +*/ +const assert = require('assert'); + +/* + * @param {character[][]} grid + * @return {number} + */ +var numIslands = function(grid) { + if(grid.length === 0) + return 0; + + var countIslands = 0; + const rowsCount = grid.length; + const columnsCount = grid[0].length; + for(var i = 0; i < rowsCount; i++) { + for(var j = 0; j < columnsCount; j++) { + if(grid[i][j] == 1) { + countIslands++; + colorIsland(grid, i, j, rowsCount, columnsCount); + } + } + } + + return countIslands; +}; + +var colorIsland = function(grid, i, j, rowsCount, columnsCount) { + if(i < 0 || j < 0 || i >= rowsCount || j >= columnsCount || grid[i][j] == 0) + return; + + grid[i][j] = 0; + + colorIsland(grid, i - 1, j, rowsCount, columnsCount); + colorIsland(grid, i + 1, j, rowsCount, columnsCount); + colorIsland(grid, i, j - 1, rowsCount, columnsCount); + colorIsland(grid, i, j + 1, rowsCount, columnsCount); +} + +var main = function() { + test(); +} + +function test() { + assert.equal(numIslands([[1]]), 1); + assert.equal(numIslands([]), 0); + assert.equal(numIslands( + [ + ["1","1","1","1","0"], + ["1","1","0","1","0"], + ["1","1","0","0","0"], + ["0","0","0","0","0"] + ], + ), + 1 + ); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js b/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js new file mode 100644 index 0000000..a6c367a --- /dev/null +++ b/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js @@ -0,0 +1,49 @@ +/* +Number of Segments in a String +https://leetcode.com/problems/number-of-segments-in-a-string/description/ + +Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. + +Please note that the string does not contain any non-printable characters. + +Example: + +Input: "Hello, my name is John" +Output: 5 +*/ +const assert = require('assert'); + +/** + * @param {string} s + * @return {number} + */ +var countSegments = function(s) { + var count = 0; + var i = 0; + + while(i < s.length) { + if(s[i] !== " ") { + count++; + while(i < s.length && s[i] !== " ") + i++; + } + i++; + } + + return count; +}; + +function main() { + test(); +} + +function test() { + assert.equal(countSegments(" "), 0); + assert.equal(countSegments(" "), 0); + assert.equal(countSegments("ab cd ef"), 3); + assert.equal(countSegments(" ab cd ef"), 3); + assert.equal(countSegments("ab cd ef "), 3); + assert.equal(countSegments(" ab cd ef "), 3); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Permutations_II_Test.js b/LeetcodeProblemsTests/Permutations_II_Test.js new file mode 100644 index 0000000..22093fe --- /dev/null +++ b/LeetcodeProblemsTests/Permutations_II_Test.js @@ -0,0 +1,80 @@ +/* +Permutations II +https://leetcode.com/problems/permutations-ii/ + +Given a collection of numbers that might contain duplicates, return all possible unique permutations. + +Example: + +Input: [1,1,2] +Output: +[ + [1,1,2], + [1,2,1], + [2,1,1] +] +*/ +const assert = require('assert'); + +var permuteUnique = function(nums) { + var map = {}; + for(var i = 0; i < nums.length; i++) { + var value = nums[i]; + map[value] = (map[value]) ? map[value] + 1 : 1; + } + + return permuteUniqueAux(nums.length, map, []); +}; + +var permuteUniqueAux = function(n, map, currentSol) { + if(currentSol.length === n) { + return [currentSol]; + } + + var ret = []; + for(var num in map) { + const occ = map[num]; + if(occ === 1) { + delete map[num]; + } else { + map[num] = occ -1 ; + } + ret = [...ret, ...permuteUniqueAux(n, map, currentSol.concat(num))]; + map[num] = occ; + } + + return ret; +}; + +var main = function() { + test(); +} + +function test() { + assert.deepEqual( + permuteUnique([1,1,2]), + [ [ '1', '1', '2' ], [ '1', '2', '1' ], [ '2', '1', '1' ] ] + ); + assert.deepEqual( + permuteUnique([1,3,2,1]), + [ + [ '1', '1', '2', '3' ], + [ '1', '1', '3', '2' ], + [ '1', '2', '1', '3' ], + [ '1', '2', '3', '1' ], + [ '1', '3', '1', '2' ], + [ '1', '3', '2', '1' ], + [ '2', '1', '1', '3' ], + [ '2', '1', '3', '1' ], + [ '2', '3', '1', '1' ], + [ '3', '1', '1', '2' ], + [ '3', '1', '2', '1' ], + [ '3', '2', '1', '1' ] + ] + ); + assert.deepEqual(permuteUnique([]), [ [] ]); + + assert.deepEqual(permuteUnique([1,1]), [ [ '1', '1' ] ]); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Permutations_Test.js b/LeetcodeProblemsTests/Permutations_Test.js new file mode 100644 index 0000000..f04f128 --- /dev/null +++ b/LeetcodeProblemsTests/Permutations_Test.js @@ -0,0 +1,62 @@ +/* +Permutations +https://leetcode.com/problems/permutations/ + +Given a collection of distinct integers, return all possible permutations. + +Example: + +Input: [1,2,3] +Output: +[ + [1,2,3], + [1,3,2], + [2,1,3], + [2,3,1], + [3,1,2], + [3,2,1] +] +*/ +const assert = require('assert'); + +var permute = function(nums) { + return permuteAux(nums, 0, [], new Set()); +}; + +var permuteAux = function(nums, pos, currentSol, set) { + if(pos === nums.length) { + return [currentSol]; + } + var ret = []; + for(var i = 0; i < nums.length; i++) { + if(!set.has(nums[i])) { + set.add(nums[i]) + var sol = permuteAux(nums, pos + 1, currentSol.concat(nums[i]), set); + ret = [...ret, ...sol]; + set.delete(nums[i]); + } + } + return ret; +} + +var main = function() { test(); +} + +function test() { + // assert.deepEqual( + assert.deepEqual(permute([]), [ [] ]); + assert.deepEqual(permute([1]), [ [ 1 ] ]); + assert.deepEqual( + permute([1,2,3]), + [ + [ 1, 2, 3 ], + [ 1, 3, 2 ], + [ 2, 1, 3 ], + [ 2, 3, 1 ], + [ 3, 1, 2 ], + [ 3, 2, 1 ] + ] + ); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js b/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js new file mode 100644 index 0000000..e9fccc5 --- /dev/null +++ b/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js @@ -0,0 +1,56 @@ +const assert = require('assert'); + +// Permutations without +var subsetWithoutDuplicates = function(nums) { + if(nums.lenght == 0){ + return; + } + var solution = []; + subsetWithoutDuplicatesAux(nums, [], solution); + return solution; +} + +var subsetWithoutDuplicatesAux = function(nums, current, sol) { + if(nums.length == 0){ + sol.push(current); + } + + var setNums = new Set(); + + nums.forEach((value, index) => { + if(setNums.has(value)) { + return; + } + setNums.add(value); + var newCurrent = [...current, value] + + var newNum = nums.filter(function(num, idx) { return index !== idx}); + subsetWithoutDuplicatesAux(newNum, newCurrent, sol); + }) +} + +function main() { + test(); +} + +var test = function() { + assert.deepEqual( + subsetWithoutDuplicates([1,1,2,3]), + [ + [ 1, 1, 2, 3 ], + [ 1, 1, 3, 2 ], + [ 1, 2, 1, 3 ], + [ 1, 2, 3, 1 ], + [ 1, 3, 1, 2 ], + [ 1, 3, 2, 1 ], + [ 2, 1, 1, 3 ], + [ 2, 1, 3, 1 ], + [ 2, 3, 1, 1 ], + [ 3, 1, 1, 2 ], + [ 3, 1, 2, 1 ], + [ 3, 2, 1, 1 ] + ] + ); +} +main(); +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js b/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js new file mode 100644 index 0000000..b5b0a1b --- /dev/null +++ b/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js @@ -0,0 +1,62 @@ +/* +Permutations withuot duplicates +https://leetcode.com/problems/permutations/description/ + +Given a collection of distinct integers, return all possible permutations. + +Example: + +Input: [1,2,3] +Output: +[ + [1,2,3], + [1,3,2], + [2,1,3], + [2,3,1], + [3,1,2], + [3,2,1] +] +*/ +const assert = require('assert'); + +// Permutations wihto +var subsetWithDuplicates = function(nums) { + if(nums.lenght == 0){ + return; + } + var solution = []; + subsetWithDuplicatesAux(nums, [], solution); + return solution; +} + +var subsetWithDuplicatesAux = function(nums, current, sol) { + if(nums.length == 0){ + sol.push(current); + } + + for(var i = 0; i < nums.length; i++) { + var newCurrent = [...current, nums[i]] + var newNums = nums.filter(function(num, index) { return index !== i }); + subsetWithDuplicatesAux(newNums, newCurrent, sol); + } +} + +function main() { + test(); +} + +var test = function() { + assert.deepEqual( + subsetWithDuplicates([1,2,3]), + [ + [ 1, 2, 3 ], + [ 1, 3, 2 ], + [ 2, 1, 3 ], + [ 2, 3, 1 ], + [ 3, 1, 2 ], + [ 3, 2, 1 ] + ] + ); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js b/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js new file mode 100644 index 0000000..3aaedf0 --- /dev/null +++ b/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js @@ -0,0 +1,106 @@ +/* +Regular Expression Matching +https://leetcode.com/problems/regular-expression-matching/description/ + +Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. + +'.' Matches any single character. +'*' Matches zero or more of the preceding element. +The matching should cover the entire input string (not partial). + +Note: + +s could be empty and contains only lowercase letters a-z. +p could be empty and contains only lowercase letters a-z, and characters like . or *. +Example 1: + +Input: +s = "aa" +p = "a" +Output: false +Explanation: "a" does not match the entire string "aa". +Example 2: + +Input: +s = "aa" +p = "a*" +Output: true +Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa". +Example 3: + +Input: +s = "ab" +p = ".*" +Output: true +Explanation: ".*" means "zero or more (*) of any character (.)". +Example 4: + +Input: +s = "aab" +p = "c*a*b" +Output: true +Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab". +Example 5: + +Input: +s = "mississippi" +p = "mis*is*p*." +Output: false + + * @param {*} s + * @param {*} p + */ +const assert = require('assert'); + +var isMatch = function(s, p) { + return isMatchAux(s, p, 0, 0); +}; + +var isMatchAux = function(str, pattern, posStr, posPat) { + if(posStr == str.length) + return posPat == pattern.length || canBeZero(pattern, posPat); + + if(posPat < pattern.length - 1 && pattern.charAt(posPat + 1) == "*") { + const valuePattern = pattern.charAt(posPat); + posPat = posPat + 2; + + if (isMatchAux(str, pattern, posStr, posPat)) { // 0 matches + return true + } + + while(posStr < str.length && (str.charAt(posStr) === valuePattern || valuePattern === ".")) { + if(isMatchAux(str, pattern, posStr + 1, posPat)) { + return true; + } + posStr++; + } + } else if(str.charAt(posStr) === pattern.charAt(posPat) || pattern.charAt(posPat) === ".") { + return isMatchAux(str, pattern, posStr + 1, posPat + 1); + } + + return false; +} + +var canBeZero = function(pattern, posPat) { + while(posPat < pattern.length && pattern.charAt(posPat) == "*" || + posPat < pattern.length - 1 && pattern.charAt(posPat + 1) == "*") { + posPat++; + } + + return posPat == pattern.length; +} + +var main = function(){ + test(); +} + +var test = function(n) { + assert.equal(isMatch("aa", "a"), false); + assert.equal(isMatch("aa", "a*"), true); + assert.equal(isMatch("a","ab*"), true); + assert.equal(isMatch("ab", ".*"), true); + assert.equal(isMatch("aab", "c*a*b"), true); + assert.equal(isMatch("mississippi", "mis*is*p*."), false); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js b/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js new file mode 100644 index 0000000..fdb4fab --- /dev/null +++ b/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js @@ -0,0 +1,84 @@ +/* +Remove Invalid Parentheses +https://leetcode.com/problems/remove-invalid-parentheses/ + +Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results. + +Note: The input string may contain letters other than the parentheses ( and ). + +Example 1: + +Input: "()())()" +Output: ["()()()", "(())()"] +Example 2: + +Input: "(a)())()" +Output: ["(a)()()", "(a())()"] +Example 3: + +Input: ")(" +Output: [""] +*/ +const assert = require('assert'); + +/** + * @param {string} s + * @return {string[]} + */ +var removeInvalidParentheses = function(s) { + var queue = []; + var visited = new Set(); + queue.push(s); + var result = []; + var found = false; + + while(queue.length !== 0) { + var str = queue.shift(); + if(isValid(str)) { + result.push(str); + found = true; + } else if(!found){ + for(var i = 0; i < s.length; i++) { + if(str[i] === "(" || str[i] === ")") { + var subStr = str.slice(0, i) + str.slice(i + 1, s.length); + if(!visited.has(subStr)) { + queue.push(subStr); + visited.add(subStr); + } + } + } + } + } + + return result; +}; + +var isValid = function(s) { + var leftCount = 0; + var iter = 0; + while(iter < s.length) { + if(s[iter] === "(") + leftCount++; + else if(s[iter] === ")") { + leftCount--; + if(leftCount < 0) + return false; + } + iter++; + } + + return leftCount === 0; +} + +var main = function() { + test(); +} + +var test = function(n) { + assert.equal(removeInvalidParentheses("))))(()"), "()"); + assert.equal(removeInvalidParentheses("(()"), "()"); + assert.equal(removeInvalidParentheses("(d))()"), "(d)()"); + assert.equal(removeInvalidParentheses("(())"), "(())"); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js b/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js new file mode 100644 index 0000000..2394963 --- /dev/null +++ b/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js @@ -0,0 +1,53 @@ +/* +Restore IP Addresses +https://leetcode.com/problems/restore-ip-addresses/description/ + +Given a string containing only digits, restore it by returning all possible valid IP address combinations. + +Example: + +Input: "25525511135" +Output: ["255.255.11.135", "255.255.111.35"] +*/ +const assert = require('assert'); + +var restoreIpAddresses = function(s) { + var restore = restoreInputBits("", s, 4); + + var ret = []; + for(var i = 0; i < restore.length; i++) { + ret.push(restore[i].join(".")); + } + + return ret; +}; + +var restoreInputBits = function(partial, s, num) { + if(s.length == 0 && num == 0 ) + return [partial]; + if(s.length < num || s.length > num * 3 || num == 0) + return []; + + const oneNum = restoreInputBits([...partial, s.slice(0, 1)], s.slice(1), num - 1); + + if(s.length === 1 || s.slice(0, 1) === "0") + return oneNum + + const twoNums = restoreInputBits([...partial, s.slice(0, 2)], s.slice(2), num - 1); + if(s.length === 2 || s.slice(0, 3) > 255) + return [...oneNum, ...twoNums] + + const threeNums = restoreInputBits([...partial, s.slice(0, 3)], s.slice(3), num - 1); + return [...oneNum, ...twoNums, ...threeNums]; +} + +var main = function() { + test(); +} + +var test = function(n) { + assert.deepEqual(restoreIpAddresses("010010"), [ '0.10.0.10', '0.100.1.0']); + assert.deepEqual(restoreIpAddresses("25525511135"), [ '255.255.11.135', '255.255.111.35' ]); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Reverse_String_II_Test.js b/LeetcodeProblemsTests/Reverse_String_II_Test.js new file mode 100644 index 0000000..d277483 --- /dev/null +++ b/LeetcodeProblemsTests/Reverse_String_II_Test.js @@ -0,0 +1,53 @@ +/* +Reverse String II +https://leetcode.com/problems/reverse-string-ii/description/ + +Given a string and an integer k, you need to reverse the first k characters for every 2k characters counting from the start of the string. If there are less than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original. +Example: +Input: s = "abcdefg", k = 2 +Output: "bacdfeg" +Restrictions: +The string consists of lower English letters only. +Length of the given string and k will in the range [1, 10000] +*/ +const assert = require('assert'); + +var reverseStr = function(s, k) { + if(k <= 1) + return s; + var ret = ""; + for(var iterK = 0; iterK * k < s.length; iterK = iterK + 2) { + const start = iterK * k; + const end = start + k - 1; + + ret += reverse(s, start, end); + ret += s.slice(end + 1, k * (iterK + 2)); + } + + return ret; +}; + +var reverse = function(s, start, end) { + var ret = ""; + if(end >= s.length) + end = s.length - 1; + + while(start <= end) { + ret += s.charAt(end); + end--; + } + return ret; +} + +var main = function(){ + test(); +} + +var test = function(n) { + assert.equal(reverseStr("abcdefg", 2), "bacdfeg"); + assert.equal(reverseStr("abcdefg", 3), "cbadefg"); + assert.equal(reverseStr("abcdefg", 1), "abcdefg"); + assert.equal(reverseStr("abcdefg", 0), "abcdefg"); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Same_Tree_Test.js b/LeetcodeProblemsTests/Same_Tree_Test.js new file mode 100644 index 0000000..31b8664 --- /dev/null +++ b/LeetcodeProblemsTests/Same_Tree_Test.js @@ -0,0 +1,57 @@ +/* +Same Tree +https://leetcode.com/problems/same-tree/description/ + +Given two binary trees, write a function to check if they are the same or not. +Two binary trees are considered the same if they are structurally identical and the nodes have the same value. + +Example 1: + +Input: 1 1 + / \ / \ + 2 3 2 3 + + [1,2,3], [1,2,3] + +Output: true +Example 2: + +Input: 1 1 + / \ + 2 2 + + [1,2], [1,null,2] + +Output: false +Example 3: + +Input: 1 1 + / \ / \ + 2 1 1 2 + + [1,2,1], [1,1,2] + +Output: false +*/ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} p + * @param {TreeNode} q + * @return {boolean} + */ +var isSameTree = function(p, q) { + if(p === null) + return q === null; + + if(q === null || p.val !== q.val) + return false; + + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); +}; diff --git a/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js b/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js new file mode 100644 index 0000000..d095215 --- /dev/null +++ b/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js @@ -0,0 +1,65 @@ +/* +Search in Rotated Sorted Array +https://leetcode.com/problems/search-in-rotated-sorted-array/ + +Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. +(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). + +You are given a target value to search. If found in the array return its index, otherwise return -1. + +You may assume no duplicate exists in the array. + +Your algorithm's runtime complexity must be in the order of O(log n). + +Example 1: + +Input: nums = [4,5,6,7,0,1,2], target = 0 +Output: 4 +Example 2: + +Input: nums = [4,5,6,7,0,1,2], target = 3 +Output: -1 + +*/ +const assert = require('assert'); + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var search = function(nums, target) { + return searchAux(nums, target, 0, nums.length -1); +}; + +var searchAux = function(nums, target, start, end) { + if (start > end) + return - 1; + var middle = Math.trunc((start + end) /2); + + if(nums[middle] == target) { + return middle; + } + + if(nums[middle] < nums[nums.length - 1]) { // right part sorted + if(nums[middle] < target && nums[nums.length - 1] >= target) { + return searchAux(nums, target, middle + 1, end); + } + return searchAux(nums, target, start, middle - 1); + } else { // left part sorted + if(nums[0] <= target && nums[middle] > target) { + return searchAux(nums, target, start, middle - 1); + } + return searchAux(nums, target, middle + 1, end); + } +} + +var main = function(n) { + test(); +} + +var test = function() { + assert.equal(search([4,5,6,7,0,1,2], 5), 1); +} +main() +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js b/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js new file mode 100644 index 0000000..7085dc3 --- /dev/null +++ b/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js @@ -0,0 +1,64 @@ +/* +Search a 2D Matrix II +https://leetcode.com/problems/search-a-2d-matrix-ii/description/ + +Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: +Integers in each row are sorted in ascending from left to right. +Integers in each column are sorted in ascending from top to bottom. +Example: + Consider the following matrix: + [ + [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30] +] +Given target = 5, return true. +Given target = 20, return false. +*/ +const assert = require('assert'); + +/** +* @param {number[][]} matrix +* @param {number} target +* @return {boolean} +*/ +var searchMatrix = function(matrix, target) { + if (matrix.length == 0) + return false + var lastCol = matrix[0].length - 1; + var firstRow = 0; + + while(lastCol >= 0 && firstRow < matrix.length) { + if(matrix[firstRow][lastCol] == target) { + return true; + } else if(matrix[firstRow][lastCol] > target) { + lastCol--; + } else { + firstRow++; + } + } + + return false; +}; + +const matrix1 = [ + [1,4,7, 11,15], + [2,5,8, 12,19], + [3,6,9, 16,22], + [10,13,14, 17,24], + [18,21,23, 26,30] +]; + +var main = function(n) { + test(); +} + +var test = function(n) { + assert.equal(searchMatrix(matrix1, 5), true); + assert.equal(searchMatrix(matrix1, 0), false); + assert.equal(searchMatrix(matrix1, 15), true); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js b/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js new file mode 100644 index 0000000..0a0b835 --- /dev/null +++ b/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js @@ -0,0 +1,74 @@ +/* +Search a 2D Matrix +https://leetcode.com/problems/search-a-2d-matrix/description/ + +Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: + +Integers in each row are sorted from left to right. +The first integer of each row is greater than the last integer of the previous row. +Example 1: + +Input: +matrix = [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] +] +target = 3 +Output: true +Example 2: + +Input: +matrix = [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] +] +target = 13 +Output: false +*/ +const assert = require('assert'); + +/** + * @param {number[][]} matrix + * @param {number} target + * @return {boolean} + */ +var searchMatrix = function(matrix, target) { + if(matrix.length === 0) + return false; + return searchMatrixAux(matrix, 0, matrix.length - 1, target); +}; + +var searchMatrixAux = function(matrix, firstRow, lastRow, target) { + if(firstRow === lastRow) { + var iter = 0; + while(iter < matrix[0].length) { + if(matrix[firstRow][iter] === target) + return true; + iter++; + } + } else { + var middle = Math.floor((firstRow + lastRow) / 2); // 0 + if(target > matrix[middle][matrix[0].length - 1]) + return searchMatrixAux(matrix, middle + 1, lastRow, target) + else + return searchMatrixAux(matrix, firstRow, middle, target) + } + + return false; +}; + +var main = function(){ + test(); +} + +var test = function(n) { + assert.equal(searchMatrix([], 0), false); + assert.equal(searchMatrix([[1], [3]], 3), true); + assert.equal(searchMatrix([[1], [3]], 1), true); + const matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]]; + assert.equal(searchMatrix(matrix, 3), true); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js b/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js new file mode 100644 index 0000000..d92d8eb --- /dev/null +++ b/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js @@ -0,0 +1,124 @@ +/* +Set Matrix Zeroes +https://leetcode.com/problems/set-matrix-zeroes/ + +Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. + +Example 1: + +Input: +[ + [1,1,1], + [1,0,1], + [1,1,1] +] +Output: +[ + [1,0,1], + [0,0,0], + [1,0,1] +] +Example 2: + +Input: +[ + [0,1,2,0], + [3,4,5,2], + [1,3,1,5] +] +Output: +[ + [0,0,0,0], + [0,4,5,0], + [0,3,1,0] +] +Follow up: + +A straight forward solution using O(mn) space is probably a bad idea. +A simple improvement uses O(m + n) space, but still not the best solution. +Could you devise a constant space solution? +*/ + +const assert = require('assert'); + +/** + * @param {number[][]} matrix + * @return {void} Do not return anything, modify matrix in-place instead. + */ +var setZeroes = function(matrix) { + if(matrix.length === 0) + return; + + var pivotRow = -1; + var pivotCol = -1; + var iterRow = 0; + var iterCol = 0; + var found = false; + + // Find a pivot + while(!found && iterRow < matrix.length) { + iterCol = 0; + while(!found && iterCol < matrix[0].length) { + if(matrix[iterRow][iterCol] === 0) { + found = true + pivotRow = iterRow; + pivotCol = iterCol; + } + iterCol++; + } + iterRow++; + } + + if (!found) + return; + + // Update the Column value + for(var i = 0; i < matrix.length; i++) { + if(i == pivotRow) + continue + for(var j = 0; j < matrix[0].length; j++) { + if(j == pivotCol) + continue; + if(matrix[i][j] === 0) { + matrix[i][pivotCol] = 0; + matrix[pivotRow][j] = 0; + } + } + } + + for(var i = 0; i < matrix.length; i++) + if(matrix[i][pivotCol] === 0 && i !== pivotRow) + fillRow(matrix, i); + + for(var i = 0; i < matrix[0].length; i++) + if(matrix[pivotRow][i] === 0 && i !== pivotCol) + fillCol(matrix, i); + + fillCol(matrix, pivotCol); + fillRow(matrix, pivotRow); + + return matrix; +}; + +var fillRow = function(matrix, row) { + for(var i = 0; i < matrix[0].length; i++) + matrix[row][i] = 0; +} + +var fillCol = function(matrix, col) { + for(var i = 0; i < matrix.length; i++) + matrix[i][col] = 0; +} + +var main = function() { + test(); +} + +var test = function() { + assert.deepEqual( + setZeroes([[1,1,1],[1,0,1],[1,1,1]]), + [[1, 0, 1], [0, 0, 0], [1, 0, 1]] + ); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Simplify_Path_Test.js b/LeetcodeProblemsTests/Simplify_Path_Test.js new file mode 100644 index 0000000..fdb6d2f --- /dev/null +++ b/LeetcodeProblemsTests/Simplify_Path_Test.js @@ -0,0 +1,76 @@ +/* +Simplify Path +https://leetcode.com/problems/simplify-path/description/ + +Given an absolute path for a file (Unix-style), simplify it. + +For example, +path = "/home/", => "/home" +path = "/a/./b/../../c/", => "/c" +path = "/a/../../b/../c//.//", => "/c" +path = "/a//b////c/d//././/..", => "/a/b/c" + +In a UNIX-style file system, a period ('.') refers to the current directory, so it can be ignored in a simplified path. Additionally, a double period ("..") moves up a directory, so it cancels out whatever the last directory was. For more information, look here: https://en.wikipedia.org/wiki/Path_(computing)#Unix_style + +Corner Cases: + +Did you consider the case where path = "/../"? +In this case, you should return "/". +Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". +In this case, you should ignore redundant slashes and return "/home/foo". +*/ +const assert = require('assert'); + +var simplifyPath = function(path) { + var queue = []; + var iter = path.length - 1; + while(iter >= 0) { + if(path.charAt(iter) === "/") { + iter--; + } else if(path.slice(iter - 1, iter + 1) == "/.") { + iter -= 2; + } else if(path.slice(iter - 2, iter + 1) === "/..") { + iter -= 3; + queue.unshift("/.."); + } else { // it's a characteriter + const endChars = iter; + while(iter >= 0 && path.charAt(iter) !== "/") { + iter--; + } + if(queue.length > 0 && queue[0] === "/..") { + queue.shift(); + } else { + queue.push("/" + path.slice(iter + 1, endChars + 1)); + } + } + } + var ret = ""; + + while(queue.length > 0) { + elem = queue.shift(); + if(elem == "/..") { + while(queue.length > 0 && queue.shift == "/..") { + elem += "/.."; + } + elem = (queue.length > 0) ? elem : ""; + } else { + ret = elem + ret; + } + } + return (ret.length == 0) ? "/" : ret; +}; + +var main = function(){ + test(); +} + +var test = function() { + assert.equal(simplifyPath("/../c"), "/c"); + assert.equal(simplifyPath("/.."), "/"); + assert.equal(simplifyPath("/home/"), "/home"); // => "/home" + assert.equal(simplifyPath("/a/./b/../../c/"), "/c"); // => "/c" + assert.equal(simplifyPath("/a/../../b/../c//.//"), "/c"); // => "/c" + assert.equal(simplifyPath("/a//b////c/d//././/.."), "/a/b/c") // => "/a/b/c" +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Spiral_Matrix_Test.js b/LeetcodeProblemsTests/Spiral_Matrix_Test.js new file mode 100644 index 0000000..b3e293a --- /dev/null +++ b/LeetcodeProblemsTests/Spiral_Matrix_Test.js @@ -0,0 +1,83 @@ +/* +Spiral Matrix +https://leetcode.com/problems/spiral-matrix/description/ + +Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. + +Example 1: + +Input: +[ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] +] +Output: [1,2,3,6,9,8,7,4,5] +Example 2: + +Input: +[ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9,10,11,12] +] +Output: [1,2,3,4,8,12,11,10,9,5,6,7] +*/ +const assert = require('assert'); + +/** + * @param {number[][]} matrix + * @return {number[]} + */ + +var spiralOrder = function(matrix) { + if(matrix.length === 0) + return []; + + var retArray = []; + const rowLength = matrix.length; + const colLength = matrix[0].length; + const countRectangles = Math.ceil(Math.min(colLength, rowLength)/2) + for(var i = 0; i < countRectangles; i++) + printRect(matrix, i, rowLength, colLength, retArray); + + return retArray; +}; + +var printRect = function(matrix, i, rowLength, colLength, retArray) { + const firstRow = i; + const firstCol = i; + const lastRow = rowLength - i - 1; + const lastCol = colLength - i - 1; + + for(var col = firstCol; col <= lastCol; col++) { + retArray.push(matrix[firstRow][col]); + } + for(var row = firstRow + 1; row <= lastRow; row++) { + retArray.push(matrix[row][lastCol]); + } + if(firstRow === lastRow || firstCol === lastCol) { + return; + } + for(var col = lastCol - 1; col >= firstCol; col--) { + retArray.push(matrix[lastRow][col]); + } + for(var row = lastRow - 1; row > firstRow; row--) { + retArray.push(matrix[row][firstCol]); + } +} + +var main = function() { + const matrix = [ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] + ] + + assert.deepEqual( + spiralOrder(matrix), + [1, 2, 3, 6, 9, 8, 7, 4, 5] + ) +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js b/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js new file mode 100644 index 0000000..0f75e13 --- /dev/null +++ b/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js @@ -0,0 +1,74 @@ + +/* +Subarray Sum Equals K +https://leetcode.com/problems/subarray-sum-equals-k/ + +Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. + +Example 1: +Input:nums = [1,1,1], k = 2 +Output: 2 +Note: +The length of the array is in range [1, 20,000]. +The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. +*/ +const assert = require('assert'); + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ + + // Solution 1 +var subarraySum = function(nums, k) { + var ret = 0; + for(var i = 0; i < nums.length; i++) { + var count = 0; + for(var j = i; j < nums.length; j++) { + count += nums[j]; + if(count === k) + ret++; + } + } + + return ret; +}; + + +// Solution 2 +var subarraySum2 = function(nums, k) { + if(nums.length === 0) + return 0; + + var sums = []; + sums[0] = 0; + var count = 0; + for(var i = 0; i < nums.length; i++) { + count += nums[i]; + sums[i + 1] = count; + } + + var ret = 0; + for(var i = 0; i < sums.length - 1; i++) { + for(var j = i + 1; j < sums.length; j++) { + if(sums[j] - sums[i] === k) + ret++; + } + } + + return ret; +}; + +var main = function() { + test(); +} + +var test = function() { + assert.strictEqual(subarraySum([1,1,1], 2), 2); + assert.strictEqual(subarraySum([1], 0), 0); + assert.strictEqual(subarraySum([0], 0), 1); + assert.strictEqual(subarraySum([0,0,0,0,0], 0), 15); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Subsets_Test.js b/LeetcodeProblemsTests/Subsets_Test.js new file mode 100644 index 0000000..014ab43 --- /dev/null +++ b/LeetcodeProblemsTests/Subsets_Test.js @@ -0,0 +1,58 @@ +/* +Subsets +https://leetcode.com/problems/subsets/description/ + +Given a set of distinct integers, nums, return all possible subsets (the power set). + +Note: The solution set must not contain duplicate subsets. + +Example: + +Input: nums = [1,2,3] +Output: +[ + [3], + [1], + [2], + [1,2,3], + [1,3], + [2,3], + [1,2], + [] +] +*/ + +const assert = require('assert'); + +var subsets = function(nums) { + var ret = []; + + subsetByPosition = function (nums, position, current) { + if(position == nums.length) { + return [current]; + } + var currentRight = current.slice().concat([nums[position]]); + return subsetByPosition(nums, position + 1, currentRight).concat(subsetByPosition(nums, position + 1, current)); + } + + return subsetByPosition(nums, 0, []); +}; + +function main() { + test(); +} + +function test() { + assert.deepEqual(subsets([]), [[]]); + assert.deepEqual(subsets([1]), [[1], []]); + assert.deepEqual( + subsets([1,2]), + [[1, 2], [1], [2], []] + ); + assert.deepEqual( + subsets([1, 2, 3]), + [[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []] + ); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js b/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js new file mode 100644 index 0000000..2146a45 --- /dev/null +++ b/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js @@ -0,0 +1,52 @@ +/* +Sum of Square Numbers +https://leetcode.com/problems/sum-of-square-numbers/description/ + +Given a non-negative integer c, your task is to decide whether there're two integers a and b such that a2 + b2 = c. + +Example 1: +Input: 5 +Output: True +Explanation: 1 * 1 + 2 * 2 = 5 + +Example 2: +Input: 3 +Output: False +*/ + +const assert = require('assert'); + +/** + * @param {number} c + * @return {boolean} + */ +var judgeSquareSum = function(c) { + var iter = 0; + var set = new Set(); + while(iter ** 2 <= c) { + var square = iter * iter; + if(square * 2 === c || set.has(c - square)) + return true; + + set.add(square); + iter++; + } + + return false; +}; + +var main = function() { + test(); +} + +var test = function() { + assert.strictEqual(judgeSquareSum(0), true); + assert.strictEqual(judgeSquareSum(1), true); + assert.strictEqual(judgeSquareSum(5), true); + assert.strictEqual(judgeSquareSum(16), true); + assert.strictEqual(judgeSquareSum(24), false); + assert.strictEqual(judgeSquareSum(25), true); +} + +module.exports.main = main; + diff --git a/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js b/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js new file mode 100644 index 0000000..54c1faf --- /dev/null +++ b/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js @@ -0,0 +1,63 @@ +/* +Swap Nodes in Pairs +https://leetcode.com/problems/swap-nodes-in-pairs/ + +Given a linked list, swap every two adjacent nodes and return its head. + +Example: + +Given 1->2->3->4, you should return the list as 2->1->4->3. +Note: + +Your algorithm should use only constant extra space. +You may not modify the values in the list's nodes, only nodes itself may be changed. +*/ +const assert = require('assert'); +const ListNode = require('../UtilsClasses/ListNode').ListNode; +const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var swapPairs = function(head) { + if(head === null || head.next === null) + return head + var previous = null; + var current = head; + var following = (head.next != null) ? head.next.next : null; + head = head.next; + + while(current !== null && current.next !== null) { + var next = current.next; + next.next = current; + if(previous != null) + previous.next = next; + current.next = following; + previous = current; + current = following; + following = (current !== null && current.next != null) ? current.next.next : null; + } + + return head; +}; + +var main = function() { + test(); +} + +var test = function () { + ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1,2,3,4])), [2,1,4,3]); + ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([])), []); + ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1])), [1]); + ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1,2])), [2, 1]); +} + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/Symmetric_Tree_Test.js b/LeetcodeProblemsTests/Symmetric_Tree_Test.js new file mode 100644 index 0000000..76b365f --- /dev/null +++ b/LeetcodeProblemsTests/Symmetric_Tree_Test.js @@ -0,0 +1,51 @@ +/* +Symmetric Tree +https://leetcode.com/problems/symmetric-tree/description/ + +Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + +For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + + 1 + / \ + 2 2 + / \ / \ +3 4 4 3 +But the following [1,2,2,null,3,null,3] is not: + 1 + / \ + 2 2 + \ \ + 3 3 +Note: +Bonus points if you could solve it both recursively and iteratively. +*/ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @return {boolean} + */ +var isSymmetric = function(root) { + if(root === null) + return true; + return isSymetricAux(root.left, root.right); +}; + +var isSymetricAux = function(root1, root2) { + if(root1 === null) + return root2 === null; + + if(root2 === null || root1.val !== root2.val) { + return false; + } + + return isSymetricAux(root1.left, root2.right) && isSymetricAux(root1.right, root2.left); +} diff --git a/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js b/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js new file mode 100644 index 0000000..363a14a --- /dev/null +++ b/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js @@ -0,0 +1,86 @@ + +class TicTacToe { + constructor() { + this.matrix = []; + for(var i = 0; i < 3; i++) { + this.matrix[i] = []; + for(var j = 0; j < 3; j++) { + this.matrix[i][j] = "-"; + } + } + }; + + validToken(token) { + if (token == "X" || token == "0" || token == "-") { + return true; + } + console.log("Token is invalid"); + return false; + } + + addToken(x, y, token) { + // Check valid positions + if(this.validToken(token)) { + this.matrix[x][y] = token; + } + }; + + printBoard() { + for(var row = 0; row < 3; row ++) { + console.log(this.matrix[row][0] + "|" + + this.matrix[row][1] + "|" + + this.matrix[row][2]); // Check new line; + } + } + + isBoardFull() { + for(var row = 0; row < 3; row ++) { + for(var col = 0; col < 3; col ++) { + if(this.matrix[row][col] === "-") { + console.log("Is not full"); + return false; + } + } + } + console.log("Is full"); + return true; + } + + makeMove() { + if(this.isBoardFull()) { + throw "Error Board is Full"; + } + for(var row = 0; row < 3; row ++) { + for(var col = 0; col < 3; col ++) { + if(this.matrix[row][col] === "-") { + this.addToken(row, col, "0"); + } + } + } + } +} + +var main = function() { + console.log("TBD"); +} + +module.exports.main = main; + +ticTacToe = new TicTacToe(); +ticTacToe.isBoardFull(); +ticTacToe.addToken(0,1,"X"); +ticTacToe.printBoard(); +var iter = 0; +while(iter < 8) { + ticTacToe.makeMove(); + iter++; +} + +console.log("after 8 moves"); +ticTacToe.isBoardFull(); +ticTacToe.printBoard(); +ticTacToe.makeMove(); + +ticTacToe.printBoard(); +ticTacToe.addToken(0,0,"X"); +ticTacToe.printBoard(); diff --git a/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js b/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js new file mode 100644 index 0000000..3bf1c2c --- /dev/null +++ b/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js @@ -0,0 +1,133 @@ + +/* +Unique Binary Search Trees +https://leetcode.com/problems/unique-binary-search-trees/description/ + +Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? + +Example: + +Input: 3 +Output: 5 +Explanation: +Given n = 3, there are a total of 5 unique BST's: + + 1 3 3 2 1 + \ / / / \ \ + 3 2 1 1 3 2 + / / \ \ + 2 1 2 3 + + +DP Solution: https://www.programcreek.com/2014/05/leetcode-unique-binary-search-trees-java/ +*/ + +const assert = require('assert'); + +// Solution 3 using DP +var numTrees3 = function (n) { + if (n == 0) + return 0 + + var map = []; + map[0] = 1; + map[1] = 1; + + for(var i = 2; i <= n; i++) { + var currentI = 0; + for(var j = 0; j < i; j++) { + currentI += map[j] * map[i - j - 1]; + } + map[i] = currentI; + } + + return map[n]; +} + +// Solution 2 (Solution 1 + Memoization) +var numTrees2 = function(n) { + var memo = {}; + return numTreesAux2(1, n, memo); +}; + +var numTreesAux2 = function(leftMin, leftMax, memo) { + const keyMemo = buildKey(leftMin, leftMax); + if(memo[keyMemo]) + return memo[keyMemo] + + if(leftMin > leftMax) + return 0; + + if(leftMin === leftMax) + return 1; + + var count = 0; + for(var i = leftMin; i <= leftMax; i++){ + const left = numTreesAux2(leftMin, i - 1, memo); + const right = numTreesAux2(i + 1, leftMax, memo); + + if(left > 0 && right > 0) { + count += left * right; + } else { + count += (left > 0) ? left : right; + } + } + + memo[keyMemo] = count; + return count; +} + +var buildKey = function(a, b) { + return a + "-" + b; +} + + +// Solution 1 +var numTrees1 = function(n) { + return numTreesAux1(1, n); +}; + +var numTreesAux1 = function(leftMin, leftMax) { + if(leftMin > leftMax) + return 0; + + if(leftMin === leftMax) + return 1; + + var count = 0; + for(var i = leftMin; i <= leftMax; i++){ + const left = numTreesAux1(leftMin, i - 1); + const right = numTreesAux1(i + 1, leftMax); + + if(left > 0 && right > 0) { + count += left * right; + } else { + count += (left > 0) ? left : right; + } + } + + return count; +} + +var main = function() { + test(); +} + +var test = function () { + assert.strictEqual(numTrees1(1), 1); + assert.strictEqual(numTrees1(2), 2); + assert.strictEqual(numTrees1(3), 5); + assert.strictEqual(numTrees1(5), 42); + + assert.strictEqual(numTrees2(1), 1); + assert.strictEqual(numTrees2(2), 2); + assert.strictEqual(numTrees2(3), 5); + assert.strictEqual(numTrees2(5), 42); + + assert.strictEqual(numTrees3(1), 1); + assert.strictEqual(numTrees3(2), 2); + assert.strictEqual(numTrees3(3), 5); + assert.strictEqual(numTrees3(5), 42); +} + +module.exports.main = main \ No newline at end of file diff --git a/LeetcodeProblemsTests/Unique_Paths_Test.js b/LeetcodeProblemsTests/Unique_Paths_Test.js new file mode 100644 index 0000000..0a0092e --- /dev/null +++ b/LeetcodeProblemsTests/Unique_Paths_Test.js @@ -0,0 +1,108 @@ +/* +Unique Paths +https://leetcode.com/problems/unique-paths/description/ + +A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). + +The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). + +How many possible unique paths are there? + +Example 1: + +Input: m = 3, n = 2 +Output: 3 +Explanation: +From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: +1. Right -> Right -> Down +2. Right -> Down -> Right +3. Down -> Right -> Right +Example 2: + +Input: m = 7, n = 3 +Output: 28 + +*/ + +// Solution 1 +// This solution is a naive solution implementing a binary tree and visiting each node. +const assert = require('assert'); + +var uniquePaths1 = function(m, n) { + return uniquePathsAux(0, 0, m, n) +}; + +var uniquePathsAux = function(row, col, rowLength, colLength) { + if(row >= rowLength || col >= colLength) { + return 0; + } + if(row == rowLength - 1 && col == colLength - 1) { + return 1; + } + + return uniquePathsAux(row + 1, col, rowLength, colLength) + + uniquePathsAux(row, col + 1, rowLength, colLength) +}; + +// Solution 2 +// This solution is solution 1 but memoized. +var uniquePaths2 = function(m, n) { + var memo = {}; + return uniquePathsAux2(0, 0, m, n, memo) +}; + +var uniquePathsAux2 = function(row, col, rowLength, colLength, memo) { + if(memo[memoKey(row, col)]) { + return memo[row + "-" + col]; + } + if(row >= rowLength || col >= colLength) { + return 0; + } + if(row == rowLength - 1 && col == colLength - 1) { + return 1; + } + + var result = uniquePathsAux(row + 1, col, rowLength, colLength, memo) + + uniquePathsAux(row, col + 1, rowLength, colLength, memo); + memo[memoKey(row, col)] = result; + return result; +}; + +var memoKey = function(row, col) { + return row + "-" + col; +} + +// Solution 3 +// This solution uses Dinamic Programming +var uniquePaths3 = function(m, n) { + var matrix = []; + for(var i = 0; i < m; i++) { + matrix[i] = []; + for(var j = 0; j < n; j++) { + if(i == 0 || j == 0) { + matrix[i][j] = 1; + } else{ + matrix[i][j] = 0; + } + } + } + + for(var row = 1; row < m; row++) { + for(var col = 1; col < n; col++) { + matrix[row][col] = matrix[row - 1][col] + matrix[row][col - 1] + } + } + + return matrix[m - 1][n - 1]; +}; + +var main = function() { + test(); +} + +var test = function() { + assert.strictEqual(uniquePaths1(10,4), 220); + assert.strictEqual(uniquePaths1(3,2), 3); +} + +module.exports.main = main; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Valid_Parentheses_Test.js b/LeetcodeProblemsTests/Valid_Parentheses_Test.js new file mode 100644 index 0000000..f4d5bc0 --- /dev/null +++ b/LeetcodeProblemsTests/Valid_Parentheses_Test.js @@ -0,0 +1,73 @@ +/* +Valid Parentheses +https://leetcode.com/problems/valid-parentheses/description/ + +Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + +An input string is valid if: + +Open brackets must be closed by the same type of brackets. +Open brackets must be closed in the correct order. +Note that an empty string is also considered valid. + +Example 1: + +Input: "()" +Output: true +Example 2: + +Input: "()[]{}" +Output: true +Example 3: + +Input: "(]" +Output: false +Example 4: + +Input: "([)]" +Output: false +Example 5: + +Input: "{[]}" +Output: true +*/ + +const assert = require('assert'); + +var isValid = function(s) { + var stack = []; + for(var i = 0; i < s.length; i++) { + var elem = s.charAt(i); + if(elem === ")" || elem === "]" || elem === "}") { + if(stack.length === 0) + return false; + var lasPar = stack.shift(); + if(!valid(lasPar, elem)) + return false; + } else { + stack.unshift(elem); + } + } + + return stack.length === 0; +}; + +var valid = function(parOpen, parClose) { + return parOpen === "(" && parClose === ")" || + parOpen === "[" && parClose === "]" || + parOpen === "{" && parClose === "}"; +} + +var main = function(){ + test(); +} + +var test = function () { + assert.strictEqual(isValid(""), true); + assert.strictEqual(isValid("()"), true); + assert.strictEqual(isValid("([)]"), false); + assert.strictEqual(isValid("{[()]}{[()]}"), true); + assert.strictEqual(isValid("{[())()]}"), false); +} + +module.exports.main = main diff --git a/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js b/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js new file mode 100644 index 0000000..4576c3c --- /dev/null +++ b/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js @@ -0,0 +1,80 @@ +/* +Verify Preorder Serialization of a Binary Tree +https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/ + +One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #. + + _9_ + / \ + 3 2 + / \ / \ + 4 1 # 6 +/ \ / \ / \ +# # # # # # +For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node. + +Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree. + +Each comma separated value in the string must be either an integer or a character '#' representing null pointer. + +You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3". + +Example 1: + +Input: "9,3,4,#,#,1,#,#,2,#,6,#,#" +Output: true +Example 2: +Input: "1,#" +Output: false +Example 3: + +Input: "9,#,#,1" +Output: false +*/ +const assert = require('assert'); + +/** + * @param {string} preorder + * @return {boolean} + */ +var isValidSerialization = function(preorder) { + if(preorder.length === 0) + return true; + + if(preorder.charAt(0) === "#") + return preorder.length === 1; + + var countP = 2; + var iter = 1; + while(iter <= preorder.length && preorder.charAt(iter - 1) !== ",") + iter++; + + while(countP > 0 && iter < preorder.length) { + if(preorder.charAt(iter) === "#") { + countP--; + iter += 2; + } else { + countP++; + iter += 2; + while(iter <= preorder.length && preorder.charAt(iter - 1) !== ",") + iter++; + } + } + + return countP === 0 && iter >= preorder.length; +}; + +var main = function() { + test(); +} + +var test = function() { + assert.strictEqual(isValidSerialization(""), true); + assert.strictEqual(isValidSerialization(""), true); + assert.strictEqual(isValidSerialization("#"), true); + assert.strictEqual(isValidSerialization("9,3,4,#,#,1,#,#,2,#,6,#,#"), true); + assert.strictEqual(isValidSerialization("9,#,92,#,#"), true); + assert.strictEqual(isValidSerialization("9,3,4,#,#,1,#,#,#,2,#,6,#,#"), false); +}; + +module.exports.main = main; diff --git a/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js b/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js new file mode 100644 index 0000000..c36fa4d --- /dev/null +++ b/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js @@ -0,0 +1,104 @@ +/* +Merge k Sorted Lists +https://leetcode.com/problems/merge-k-sorted-lists/ + +Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + +Example: + +Input: +[ + 1->4->5, + 1->3->4, + 2->6 +] +Output: 1->1->2->3->4->4->5->6 +*/ +const assert = require('assert'); +const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); + +var ListNode = require('../UtilsClasses/ListNode').ListNode; + +var mergeKLists = function(lists) { + if(lists.length === 0) + return null; + + var queue = []; + for(var i = 0; i < lists.length; i++) + queue.push(lists[i]); + + while(queue.length > 1) { + list1 = queue.shift(); + list2 = queue.shift(); + queue.push(mergeLists(list1, list2)); + } + + return queue.shift(); +}; + +var mergeLists = function(list1, list2) { + if(list1 === null) { + return list2; + } else if(list2 === null) + return list1; + + var iter1 = list1; + var iter2 = list2; + var head; + + if(iter1.val < iter2.val) { + head = iter1; + iter1 = iter1.next + } else { + head = iter2; + iter2 = iter2.next; + } + + var iterHead = head; + while(iter1 !== null && iter2 !== null) { + if(iter1.val < iter2.val) { + iterHead.next = iter1; + iter1 = iter1.next; + } else { + iterHead.next = iter2; + iter2 = iter2.next; + } + iterHead = iterHead.next; + iterHead.next = null; + } + + if(iter1 !== null) { + iterHead.next = iter1; + } else if(iter2 !== null) { + iterHead.next = iter2; + } + + return head; +} + +var main = function() { + test(); +} + +function test() { + assert.deepEqual(mergeKLists([]), null); + assert.deepEqual( + mergeKLists([null]), + null + ); + assert.deepEqual( + mergeKLists([null, null]), + null + ); + + var list1 = ListNode.linkenList([1,2,3]); + var list2 = ListNode.linkenList([2,3,4]); + var list3 = ListNode.linkenList([5,6]); + var list4 = ListNode.linkenList([1,5]); + ListNodeTestHelper.assertList( + mergeKLists([list1, list2, list3, list4]), + [1, 1, 2, 2, 3, 3, 4, 5, 5, 6] + ); +} + +module.exports.main = main; \ No newline at end of file From 49438a3882b7a6166e910f58a7e681c84a549a96 Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 30 Aug 2020 23:10:07 -0400 Subject: [PATCH 02/11] Move tests to its own files Round 1 --- ...Best_Time_To_Buy_And_Sell_Stock_II_Test.js | 63 +------- LeetcodeProblemsTests/Binary_Gap_Test.js | 68 +-------- LeetcodeProblemsTests/Clone_Graph_Test.js | 100 +------------ LeetcodeProblemsTests/Coin_Change_Test.js | 109 +------------- ...rom_Preorder_and_Inorder_Traversal_Test.js | 67 +-------- .../Deletion_Distance_Test.js | 116 +-------------- .../Design_Circular_Deque_Test.js | 139 +----------------- LeetcodeProblemsTests/Edit_Distance_Test.js | 108 +------------- 8 files changed, 22 insertions(+), 748 deletions(-) diff --git a/LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js b/LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js index 1179880..4fa85a9 100644 --- a/LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js +++ b/LeetcodeProblemsTests/Best_Time_To_Buy_And_Sell_Stock_II_Test.js @@ -1,68 +1,9 @@ -/* -https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ -Best Time to Buy and Sell Stock II - -Say you have an array for which the ith element is the price of a given stock on day i. - -Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). - -Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). - -Example 1: - -Input: [7,1,5,3,6,4] -Output: 7 -Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. - Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. -Example 2: - -Input: [1,2,3,4,5] -Output: 4 -Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. - Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are - engaging multiple transactions at the same time. You must sell before buying again. -Example 3: - -Input: [7,6,4,3,1] -Output: 0 -Explanation: In this case, no transaction is done, i.e. max profit = 0. -*/ const assert = require('assert'); - -/** - * @param {number[]} prices - * @return {number} - */ -var maxProfit = function(prices) { - var profit = 0; - var iter = 0; - - while(iter < prices.length) { - while(iter < prices.length - 1 && prices[iter] > prices[iter + 1]) { - iter++; - } - const buy = prices[iter]; - iter++; - while(iter < prices.length - 1 && prices[iter] < prices[iter + 1]) { - iter++; - } - - if(iter < prices.length) { - const sell = prices[iter]; - profit = profit + sell - buy; - } - } - - return profit; -}; - -var main = function() { - test(); -} +const maxProfit = require('../LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II').maxProfit; function test() { assert.equal(maxProfit([7,1,5,3,6,4]), 7); assert.equal(maxProfit([7,1,5,3320,6,4]), 3319); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Binary_Gap_Test.js b/LeetcodeProblemsTests/Binary_Gap_Test.js index 0385125..033cf4d 100644 --- a/LeetcodeProblemsTests/Binary_Gap_Test.js +++ b/LeetcodeProblemsTests/Binary_Gap_Test.js @@ -1,73 +1,9 @@ -/* -Binary Gap -https://leetcode.com/problems/binary-gap/description/ - -Given a positive integer N, find and return the longest distance between two consecutive 1's in the binary representation of N. - -If there aren't two consecutive 1's, return 0. - -Example 1: - -Input: 22 -Output: 2 -Explanation: -22 in binary is 0b10110. -In the binary representation of 22, there are three ones, and two consecutive pairs of 1's. -The first consecutive pair of 1's have distance 2. -The second consecutive pair of 1's have distance 1. -The answer is the largest of these two distances, which is 2. -Example 2: - -Input: 5 -Output: 2 -Explanation: -5 in binary is 0b101. -Example 3: - -Input: 6 -Output: 1 -Explanation: -6 in binary is 0b110. -Example 4: - -Input: 8 -Output: 0 -Explanation: -8 in binary is 0b1000. -There aren't any consecutive pairs of 1's in the binary representation of 8, so we return 0. -*/ const assert = require('assert'); - -/** - * @param {number} N - * @return {number} - */ -var binaryGap = function(N) { - var maxDist = 0; - var currentDist = 0; - while(N > 0) { - const bit = N % 2; - N >>= 1; - if(bit === 1) { - currentDist = 1; - while(N > 0 && N % 2 === 0 ) { - currentDist++; - N >>= 1; - } - if(N !== 0 && currentDist > maxDist) - maxDist = currentDist; - } - } - return maxDist; -}; - -var main = function() { - test(); -} +const binaryGap = require('../LeetcodeProblems/Binary_Gap').binaryGap; function test() { assert.equal(binaryGap(22), 2); // 10110 assert.equal(binaryGap(8), 0); // 1000 } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Clone_Graph_Test.js b/LeetcodeProblemsTests/Clone_Graph_Test.js index ee74cdd..ea8b26b 100644 --- a/LeetcodeProblemsTests/Clone_Graph_Test.js +++ b/LeetcodeProblemsTests/Clone_Graph_Test.js @@ -1,99 +1,5 @@ -/* -Clone Graph -https://leetcode.com/problems/clone-graph/description/ - -Given the head of a graph, return a deep copy (clone) of the graph. Each node in the graph contains a label (int) and a list (List[UndirectedGraphNode]) of its neighbors. There is an edge between the given node and each of the nodes in its neighbors. - - -OJ's undirected graph serialization (so you can understand error output): -Nodes are labeled uniquely. - -We use # as a separator for each node, and , as a separator for node label and each neighbor of the node. - - -As an example, consider the serialized graph {0,1,2#1,2#2,2}. - -The graph has a total of three nodes, and therefore contains three parts as separated by #. - -First node is labeled as 0. Connect node 0 to both nodes 1 and 2. -Second node is labeled as 1. Connect node 1 to node 2. -Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. - - -Visually, the graph looks like the following: - - 1 - / \ - / \ - 0 --- 2 - / \ - \_/ -Note: The information about the tree serialization is only meant so that you can understand error output if you get a wrong answer. -You don't need to understand the serialization to solve the problem. -*/ - -/** - * Definition for undirected graph. - * function UndirectedGraphNode(label) { - * this.label = label; - * this.neighbors = []; // Array of UndirectedGraphNode - * } - */ - - -// SOLUTION 1 Using DFS -/** - * @param {UndirectedGraphNode} graph - * @return {UndirectedGraphNode} - */ -var cloneGraph = function(graph) { - if(!graph) - return graph; - - return dfs(graph, {}); -}; - -var dfs = function(graph, visited) { - if(visited[graph.label]) - return visited[graph.label]; - - var newNode = new UndirectedGraphNode(graph.label); - visited[newNode.label] = newNode; - - for(var i = 0; i < graph.neighbors.length; i++) { - const neighbor = dfs(graph.neighbors[i], visited); - newNode.neighbors.push(neighbor); - } - - return newNode; +var test = function() { + // TODO } -// SOLUTION 2 Using DFS -var cloneGraphBFS = function(graph) { - if(graph === null) - return graph; - - var visitedMap = {}; - var queue = [graph]; - var copyReturn = new UndirectedGraphNode(graph.label); - visitedMap[graph.label] = copyReturn; - - while(queue.length > 0) { - var node = queue.shift(); - var nodeCopied = visitedMap[node.label]; - - for(var i = 0; i < node.neighbors.length; i++) { - var neighbor = node.neighbors[i]; - - if(!visitedMap[neighbor.label]) { - var copyNeighbor = new UndirectedGraphNode(neighbor.label); - visitedMap[neighbor.label] = copyNeighbor; - queue.push(neighbor); - } - - nodeCopied.neighbors.push(visitedMap[neighbor.label]); - } - } - - return copyReturn; -} +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Coin_Change_Test.js b/LeetcodeProblemsTests/Coin_Change_Test.js index 716465c..ffce9af 100644 --- a/LeetcodeProblemsTests/Coin_Change_Test.js +++ b/LeetcodeProblemsTests/Coin_Change_Test.js @@ -1,110 +1,5 @@ -/* -Coin Change -https://leetcode.com/problems/coin-change/ - -You are given coins of different denominations and a total amount of money amount. -Write a function to compute the fewest number of coins that you need to make up that amount. -If that amount of money cannot be made up by any combination of the coins, return -1. - -Example 1: - -Input: coins = [1, 2, 5], amount = 11 -Output: 3 -Explanation: 11 = 5 + 5 + 1 -Example 2: - -Input: coins = [2], amount = 3 -Output: -1 -Note: -You may assume that you have an infinite number of each kind of coin. -*/ const assert = require('assert'); - -// Solution 3 -var coinChange = function(coins, amount) { - var memo = []; - for(var i = 0; i <= amount; i++) - memo[i] = Number.POSITIVE_INFINITY; - - memo[0] = 0; - for(var i = 0; i < coins.length; i++) { - const coin = coins[i]; - for(var j = coin; j < memo.length; j++) - memo[j] = min2(memo[j], memo[j - coin] + 1); - } - - return (memo[amount] == Number.POSITIVE_INFINITY) ? -1 : memo[amount]; -}; - -var min2 = function(a, b) { - return (a < b) ? a : b; -} - -// Solution 2 -var buildMemoKey = function(position, amount) { - return position + "-" + amount; -} - -var coinChange2 = function(coins, amount) { - var memo = {}; - var solution = coinChangeAux2(coins, amount, 0, memo, Number.POSITIVE_INFINITY); - return solution == Number.POSITIVE_INFINITY ? -1 : solution; -}; - -var coinChangeAux2 = function(coins, amount, pos, memo) { - var key = buildMemoKey(pos, amount); - if(memo[key]) - return memo[key]; - - if(amount < 0) { - return Number.POSITIVE_INFINITY; - } else if(amount == 0) { - return 0; - } else if(pos >= coins.length) { - return Number.POSITIVE_INFINITY; - } - - var left = coinChangeAux2(coins, amount, pos + 1, memo); - var middle = 1 + coinChangeAux2(coins, amount - coins[pos], pos + 1, memo); - var right = 1 + coinChangeAux2(coins, amount - coins[pos], pos, memo); - - var solution = min(left, middle, right); - memo[key] = solution; - return solution; -} - -// Solution 1 naive -var coinChange1 = function(coins, amount) { - var solution = coinChangeAux1(coins, amount, 0); - return solution == Number.POSITIVE_INFINITY ? -1 : solution; -}; - -var coinChangeAux1 = function(coins, amount, pos) { - if(amount < 0) { - return Number.POSITIVE_INFINITY; - } else if(amount == 0) { - return 0; - } else if(pos >= coins.length) { - return Number.POSITIVE_INFINITY; - } - - var left = coinChangeAux1(coins, amount, pos + 1); - var middle = 1 + coinChangeAux1(coins, amount - coins[pos], pos + 1); - var right = 1 + coinChangeAux1(coins, amount - coins[pos], pos); - - var partialSol = min(left, middle, right); - return partialSol; -} - -var min = function(a, b, c) { - if(a < b) - return (a < c) ? a : c; - return (b < c) ? b : c; -} - -function main() { - test(); -} +const coinChange = require('../LeetcodeProblems/Coin_Change').coinChange; function test() { assert.equal(coinChange([], 3), -1); @@ -114,4 +9,4 @@ function test() { assert.equal(coinChange([370, 417, 408, 156, 143, 434, 168, 83, 177, 280, 117], 9953), 24); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js b/LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js index da702cc..72ec134 100644 --- a/LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js +++ b/LeetcodeProblemsTests/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal_Test.js @@ -1,70 +1,9 @@ -/* -Construct Binary Tree from Preorder and Inorder Traversal -https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ - -Given preorder and inorder traversal of a tree, construct the binary tree. - -Note: -You may assume that duplicates do not exist in the tree. - -For example, given - -preorder = [3,9,20,15,7] -inorder = [9,3,15,20,7] -Return the following binary tree: - - 3 - / \ - 9 20 - / \ - 15 7 -*/ - -/** - * Definition for a binary tree node. - * function TreeNode(val) { - * this.val = val; - * this.left = this.right = null; - * } - */ const assert = require('assert'); - -var TreeNode = require('../UtilsClasses/TreeNode').TreeNode; - -/** - * @param {number[]} preorder - * @param {number[]} inorder - * @return {TreeNode} - */ -var buildTree = function(preorder, inorder) { - if(preorder === null || inorder === null || preorder.length !== inorder.length) - return nil; - - return buildTreeAux(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); -}; - -var buildTreeAux = function(preorder, pl, ph, inorder, il, ih) { - if(pl > ph || il > ih) - return null; - - const rootValue = preorder[pl]; - var countElementsLeft = 0; - while(inorder[il + countElementsLeft] !== rootValue) - countElementsLeft++; - - var ret = new TreeNode(rootValue); - ret.left = buildTreeAux(preorder, pl + 1, pl + countElementsLeft, inorder, il, il + countElementsLeft - 1); - ret.right = buildTreeAux(preorder, pl + countElementsLeft + 1, ph, inorder, il + countElementsLeft + 1, ih); - - return ret; -} - -var main = function() { - test(); -} +var buildTree = require('../LeetcodeProblems/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal').buildTree; function test() { + // TODO console.log(buildTree([3,9,20,15,7], [9,3,15,20,7])); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Deletion_Distance_Test.js b/LeetcodeProblemsTests/Deletion_Distance_Test.js index 2714fb3..2d9d0f3 100644 --- a/LeetcodeProblemsTests/Deletion_Distance_Test.js +++ b/LeetcodeProblemsTests/Deletion_Distance_Test.js @@ -1,115 +1,7 @@ -/* -Deletion Distance -The deletion distance of two strings is the minimum number of characters you need to delete in the two strings in order to get the same string. For instance, the deletion distance between "heat" and "hit" is 3: - -By deleting 'e' and 'a' in "heat", and 'i' in "hit", we get the string "ht" in both cases. -We cannot get the same string from both strings by deleting 2 letters or fewer. -Given the strings str1 and str2, write an efficient function deletionDistance that returns the deletion distance between them. Explain how your function works, and analyze its time and space complexities. - -input: str1 = "dog", str2 = "frog" -output: 3 - -input: str1 = "some", str2 = "some" -output: 0 - -input: str1 = "some", str2 = "thing" -output: 9 - -input: str1 = "", str2 = "" -output: 0 -*/ const assert = require('assert'); - -// Solution 3 Using DP -var deletionDistanceDP = function(str1, str2) { - if(str1.length === 0) - return str2.length; - if(str2.length === 0) - return str1.length; - - var matrix = []; - for(var i = 0; i <= str1.length; i++) { - matrix[i] = []; - for(var j = 0; j <= str2.length; j++) { - if(i === 0) { - matrix[i][j] = j; - } else if(j == 0) { - matrix[i][j] = i; - } else if(str1[i - 1] === str2[j - 1]) { - matrix[i][j] = matrix[i - 1][j - 1]; - } else { - matrix[i][j] = 1 + min(matrix[i - 1][j], matrix[i][j - 1]); - } - } - } - - return matrix[str1.length][str2.length]; -} - -// Solution 2 Using memoization -var deletionDistance2 = function(str1, str2) { - var memo = {}; - return deletionDistanceAux2(str1, str2, 0, 0, memo); -} - -var deletionDistanceAux2 = function(str1, str2, pos1, pos2, memo) { - const valueCashed = getValue(pos1, pos2, memo); - if(valueCashed !== undefined) - return valueCashed; - var result; - - if(str1.length === pos1) - result = str2.length - pos2; - else if(str2.length === pos2) - result = str1.length - pos1; - else if(str1[pos1] === str2[pos2]) - result = deletionDistanceAux2(str1, str2, pos1 + 1, pos2 + 1, memo); - else - result = 1 + min(deletionDistanceAux2(str1, str2, pos1, pos2 + 1, memo), deletionDistanceAux2(str1, str2, pos1 + 1, pos2, memo)) - - return setValue(pos1, pos2, result, memo); -} - -var getMemoKey = function(pos1, pos2) { - return pos1 + "-" + pos2; -} - -var getValue = function(pos1, pos2, memo) { - const memoKey = getMemoKey(pos1, pos2); - return memo[memoKey]; -} - -var setValue = function(pos1, pos2, value, memo) { - const memoKey = getMemoKey(pos1, pos2); - memo[memoKey] = value; - return value; -} - -// Solution 1 naive -var deletionDistance = function(str1, str2) { - return deletionDistanceAux(str1, str2, 0, 0); -} - -var deletionDistanceAux = function(str1, str2, pos1, pos2) { - if(str1.length === pos1) - return str2.length - pos2; - - if(str2.length === pos2) - return str1.length - pos1; - - if(str1[pos1] === str2[pos2]) - return deletionDistanceAux(str1, str2, pos1 + 1, pos2 + 1); - - return 1 + min(deletionDistanceAux(str1, str2, pos1, pos2 + 1), deletionDistanceAux(str1, str2, pos1 + 1, pos2)); -} - -var min = function(a, b) { - return (a < b) ? a : b; -} - -function main() { - test(); -} +var deletionDistance = require('../LeetcodeProblems/Deletion_Distance').deletionDistance; +var deletionDistance2 = require('../LeetcodeProblems/Deletion_Distance').deletionDistance2; +var deletionDistanceDP = require('../LeetcodeProblems/Deletion_Distance').deletionDistanceDP; function test() { assert.equal(deletionDistance("dog", "frog"), 3); @@ -128,4 +20,4 @@ function test() { assert.equal(deletionDistanceDP("", ""), 0); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Design_Circular_Deque_Test.js b/LeetcodeProblemsTests/Design_Circular_Deque_Test.js index 60dace9..6d0a6ea 100644 --- a/LeetcodeProblemsTests/Design_Circular_Deque_Test.js +++ b/LeetcodeProblemsTests/Design_Circular_Deque_Test.js @@ -1,140 +1,5 @@ -/* -Design Circular Deque -https://leetcode.com/problems/design-circular-deque/description/ - -Design your implementation of the circular double-ended queue (deque). - -Your implementation should support following operations: - -MyCircularDeque(k): Constructor, set the size of the deque to be k. -insertFront(): Adds an item at the front of Deque. Return true if the operation is successful. -insertLast(): Adds an item at the rear of Deque. Return true if the operation is successful. -deleteFront(): Deletes an item from the front of Deque. Return true if the operation is successful. -deleteLast(): Deletes an item from the rear of Deque. Return true if the operation is successful. -getFront(): Gets the front item from the Deque. If the deque is empty, return -1. -getRear(): Gets the last item from Deque. If the deque is empty, return -1. -isEmpty(): Checks whether Deque is empty or not. -isFull(): Checks whether Deque is full or not. - -Example: - -MyCircularDeque circularDeque = new MycircularDeque(3); // set the size to be 3 -circularDeque.insertLast(1); // return true -circularDeque.insertLast(2); // return true -circularDeque.insertFront(3); // return true -circularDeque.insertFront(4); // return false, the queue is full -circularDeque.getRear(); // return 2 -circularDeque.isFull(); // return true -circularDeque.deleteLast(); // return true -circularDeque.insertFront(4); // return true -circularDeque.getFront(); // return 4 - -Note: - -All values will be in the range of [0, 1000]. -The number of operations will be in the range of [1, 1000]. -Please do not use the built-in Deque library. -*/ const assert = require('assert'); - -/** - * Initialize your data structure here. Set the size of the deque to be k. - * @param {number} k - */ -var MyCircularDeque = function(k) { - this.queue = []; - this.maxSize = k; -}; - -/** -* Adds an item at the front of Deque. Return true if the operation is successful. -* @param {number} value -* @return {boolean} -*/ -MyCircularDeque.prototype.insertFront = function(value) { - if(this.isFull()) - return false; - - this.queue.unshift(value); - return true; -}; - -/** -* Adds an item at the rear of Deque. Return true if the operation is successful. -* @param {number} value -* @return {boolean} -*/ -MyCircularDeque.prototype.insertLast = function(value) { - if(this.isFull()) - return false; - - this.queue[this.queue.length] = value; - return true; -}; - -/** -* Deletes an item from the front of Deque. Return true if the operation is successful. -* @return {boolean} -*/ -MyCircularDeque.prototype.deleteFront = function() { - if(this.isEmpty()) - return false; - - this.queue.shift(1); - return true; -}; - -/** -* Deletes an item from the rear of Deque. Return true if the operation is successful. -* @return {boolean} -*/ -MyCircularDeque.prototype.deleteLast = function() { - if(this.isEmpty()) - return false; - - this.queue.splice(this.queue.length - 1, 1); - return true; -}; - -/** -* Get the front item from the deque. -* @return {number} -*/ -MyCircularDeque.prototype.getFront = function() { - if(this.isEmpty()) - return -1; - return this.queue[0]; -}; - -/** -* Get the last item from the deque. -* @return {number} -*/ -MyCircularDeque.prototype.getRear = function() { - if(this.isEmpty()) - return -1; - return this.queue[this.queue.length - 1]; -}; - -/** -* Checks whether the circular deque is empty or not. -* @return {boolean} -*/ -MyCircularDeque.prototype.isEmpty = function() { - return this.queue.length === 0; -}; - -/** -* Checks whether the circular deque is full or not. -* @return {boolean} -*/ -MyCircularDeque.prototype.isFull = function() { - return this.queue.length === this.maxSize; -}; - -var main = function(){ - test(); -}; +var MyCircularDeque = require('../LeetcodeProblems/Design_Circular_Deque').MyCircularDeque; var test = function() { const obj = new MyCircularDeque(3); @@ -149,4 +14,4 @@ var test = function() { assert.equal(obj.getFront(), 4); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Edit_Distance_Test.js b/LeetcodeProblemsTests/Edit_Distance_Test.js index c337677..b466527 100644 --- a/LeetcodeProblemsTests/Edit_Distance_Test.js +++ b/LeetcodeProblemsTests/Edit_Distance_Test.js @@ -1,106 +1,6 @@ -/* -Edit Distance -https://leetcode.com/problems/edit-distance/ - -Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2. - -You have the following 3 operations permitted on a word: - -Insert a character -Delete a character -Replace a character -Example 1: - -Input: word1 = "horse", word2 = "ros" -Output: 3 -Explanation: -horse -> rorse (replace 'h' with 'r') -rorse -> rose (remove 'r') -rose -> ros (remove 'e') -Example 2: - -Input: word1 = "intention", word2 = "execution" -Output: 5 -Explanation: -intention -> inention (remove 't') -inention -> enention (replace 'i' with 'e') -enention -> exention (replace 'n' with 'x') -exention -> exection (replace 'n' with 'c') -exection -> execution (insert 'u') -*/ const assert = require('assert'); - -// Optimal solution -var minDistance = function(word1, word2) { - var matrix = []; - for(var i = 0; i <= word1.length; i++) { - matrix[i] = []; - for(var j = 0; j <= word2.length; j++) { - if(i === 0) - matrix[i][j] = j; - else if(j === 0) - matrix[i][j] = i; - else - matrix[i][j] = 0; - } - }; - - for(var i = 1; i <= word1.length; i++) { - for(var j = 1; j <= word2.length; j++) { - if(word1.charAt(i - 1) === word2.charAt(j - 1)) { - matrix[i][j] = matrix[i - 1][j - 1]; - } else { - matrix[i][j] = 1 + min( - matrix[i - 1][j - 1], - matrix[i - 1][j], // add - matrix[i][j - 1] // remove - ); - } - } - } - - return matrix[word1.length][word2.length]; -}; - -var min = function(a, b, c) { - if(a < b) { - return (a < c) ? a : c; - } - return (b < c) ? b : c; -} - -//Solution 2 -var minDistance2 = function(word1, word2) { - return minDistanceAux(word1, word2, 0, 0); -} - -var minDistanceAux = function(word1, word2, iter1, iter2) { - if(word1.length === iter1) - return word2.length - iter2; - - if(word2.length === iter2) - return word1.length - iter1; - - if(word1.charAt(iter1) === word2.charAt(iter2)) - return minDistanceAux(word1, word2, iter1 + 1, iter2 + 1); - - return 1 + min( - minDistanceAux(word1, word2, iter1 + 1, iter2 + 1), - minDistanceAux(word1, word2, iter1, iter2 + 1), // add - minDistanceAux(word1, word2, iter1 + 1, iter2 ) // delete - ) -}; - -var min = function(a, b, c) { - if(a < b) - return (a < c) ? a : c; - - return (b < c) ? b : c; -} - -var main = function() { - test(); -} +var minDistance = require('../LeetcodeProblems/Edit_Distance').minDistance; +var minDistance2 = require('../LeetcodeProblems/Edit_Distance').minDistance2; function test() { assert.equal(minDistance("ros", "horse"), 3); @@ -109,5 +9,5 @@ function test() { assert.equal(minDistance2("ros", "horse"), 3); assert.equal(minDistance2("intention", "execution"), 5); } - -module.exports.main = main; +test(); +module.exports.test = test; From 4a82a5b65d37d1761d7b4b623b2521afda72fc5d Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 30 Aug 2020 23:14:13 -0400 Subject: [PATCH 03/11] remove uselessrequires --- LeetcodeProblems/3Sum.js | 25 +------------- LeetcodeProblems/Add_Two_Numbers.js | 33 ++----------------- LeetcodeProblems/Award_Budget_Cuts.js | 19 +---------- LeetcodeProblems/Backspace_String_Compare.js | 20 ++--------- .../Best_Time_To_Buy_And_Sell_Stock_II.js | 3 +- LeetcodeProblems/Binary_Gap.js | 12 +------ LeetcodeProblems/Clone_Graph.js | 1 - LeetcodeProblems/Coin_Change.js | 15 +-------- ...ree_from_Preorder_and_Inorder_Traversal.js | 12 +------ LeetcodeProblems/Deletion_Distance.js | 6 ++-- LeetcodeProblems/Design_Circular_Deque.js | 20 +---------- LeetcodeProblems/Edit_Distance.js | 16 ++------- LeetcodeProblems/Escape_The_Ghosts.js | 1 - LeetcodeProblems/Flood_Fill.js | 2 +- LeetcodeProblems/Group_Anagrams.js | 2 +- .../Implement_stack_using_queues.js | 2 +- .../Kth_Largest_Element_in_an_Array.js | 2 +- LeetcodeProblems/Linked_List_Cycle_II.js | 2 +- .../Longest_Consecutive_Sequence.js | 2 +- .../Longest_Palindromic_Substring.js | 2 +- ...Lowest_Common_Ancestor_of_a_Binary_Tree.js | 2 +- LeetcodeProblems/Majority_Element.js | 2 +- LeetcodeProblems/Maximal_Square.js | 2 +- LeetcodeProblems/Maximun_Subarray.js | 2 +- LeetcodeProblems/Min_Stack.js | 2 +- LeetcodeProblems/Minimum_Window_Substring.js | 2 +- LeetcodeProblems/NQueens.js | 2 +- LeetcodeProblems/Number_of_Islands.js | 2 +- .../Number_of_Segments_in_a_String.js | 2 +- LeetcodeProblems/Permutations.js | 2 +- LeetcodeProblems/Permutations_II.js | 2 +- .../Permutations_With_Duplicates.js | 2 +- .../Permutations_Without_Duplicates.js | 2 +- .../Regular_Expression_Matching.js | 2 +- .../Remove_Invalid_Parentheses.js | 2 +- LeetcodeProblems/Restore_IP_Addresses.js | 2 +- LeetcodeProblems/Reverse_String_II.js | 2 +- .../SearchIng_Rotated_Sorted_Array.js | 2 +- LeetcodeProblems/Search_a_2D_Matrix.js | 2 +- LeetcodeProblems/Search_a_2D_Matrix_II.js | 2 +- LeetcodeProblems/Set_Matrix_Zeroes.js | 2 +- LeetcodeProblems/Simplify_Path.js | 2 +- LeetcodeProblems/Spiral_Matrix.js | 2 +- LeetcodeProblems/Subarray_Sum_Equals_K.js | 2 +- LeetcodeProblems/Subsets.js | 2 +- LeetcodeProblems/Sum_Of_Square_Numbers.js | 2 +- LeetcodeProblems/Swap_Nodes_In_Pairs.js | 2 +- .../Unique_Binary_Search_Trees.js | 2 +- LeetcodeProblems/Unique_Paths.js | 2 +- LeetcodeProblems/Valid_Parentheses.js | 2 +- ...Preorder_Serialization_of_a_Binary_Tree.js | 2 +- LeetcodeProblems/merge_k_sorted_lists.js | 2 +- 52 files changed, 56 insertions(+), 205 deletions(-) diff --git a/LeetcodeProblems/3Sum.js b/LeetcodeProblems/3Sum.js index e5aee95..c5d4ec8 100644 --- a/LeetcodeProblems/3Sum.js +++ b/LeetcodeProblems/3Sum.js @@ -18,7 +18,6 @@ A solution set is: [-1, -1, 2] ] */ -const assert = require('assert'); /** * @param {number[]} nums @@ -49,26 +48,4 @@ var threeSum = function(nums) { return ret; }; -var main = function() { - test(); -} - -var test = function () { - assert.deepEqual(threeSum([]), []); - assert.deepEqual(threeSum([0]), []); - assert.deepEqual(threeSum([0, 0]), []); - assert.deepEqual( - threeSum([0, 0, 0]), - [[0, 0, 0]] - ); - assert.deepEqual( - threeSum([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]), - [[0, 0, 0]] - ); - assert.deepEqual( - threeSum([-1, 0, 1, 2, -1, -4]), - [ [ -1, 2, -1 ], [ 0, 1, -1 ] ] - ); -} - -module.exports.main = main; +module.exports.threeSum = threeSum; diff --git a/LeetcodeProblems/Add_Two_Numbers.js b/LeetcodeProblems/Add_Two_Numbers.js index 53a00c1..958448f 100644 --- a/LeetcodeProblems/Add_Two_Numbers.js +++ b/LeetcodeProblems/Add_Two_Numbers.js @@ -21,10 +21,8 @@ Explanation: 342 + 465 = 807. * this.next = null; * } */ -const assert = require('assert'); -const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); var ListNode = require('../UtilsClasses/ListNode').ListNode; - + /** * @param {ListNode} l1 * @param {ListNode} l2 @@ -64,31 +62,4 @@ var addTwoNumbers = function(l1, l2) { return head; }; -var main = function() { - test(); -} - -function test() { - const list1 = ListNode.linkenList([1,2,3,4]); - const list2 = ListNode.linkenList([1,2,3,4]); - ListNodeTestHelper.assertList( - addTwoNumbers(list1, list2), - [2, 4, 6, 8] - ); - - const list3 = ListNode.linkenList([1]); - const list4 = ListNode.linkenList([1,2]); - ListNodeTestHelper.assertList( - addTwoNumbers(list3, list4), - [2, 2] - ); - - const list5 = ListNode.linkenList([]); - const list6 = ListNode.linkenList([1,2]); - ListNodeTestHelper.assertList( - addTwoNumbers(list5, list6), - [1, 2] - ); -} - -module.exports.main = main; +module.exports.addTwoNumbers = addTwoNumbers; diff --git a/LeetcodeProblems/Award_Budget_Cuts.js b/LeetcodeProblems/Award_Budget_Cuts.js index 1a8ad15..b9efb99 100644 --- a/LeetcodeProblems/Award_Budget_Cuts.js +++ b/LeetcodeProblems/Award_Budget_Cuts.js @@ -29,8 +29,6 @@ Constraints: [output] double */ -const assert = require('assert'); - var cutAwardBadges = function(nums, newBadge) { var currentBadge = 0; for(var i = 0; i < nums.length; i++) @@ -66,19 +64,4 @@ var findCap = function(nums, currentBadge, newBadge) { return nums[iter] + (-diff) / iter; } -var main = function() { - test(); -} - -function test() { - assert.deepEqual( - cutAwardBadges([2, 100, 50, 120, 1000], 190), - [ 47, 47, 47, 47, 2 ] - ); - assert.deepEqual( - cutAwardBadges([2, 100, 50, 120, 1000], 5), - [ 1, 1, 1, 1, 1 ] - ); -} - -module.exports.main = main; +module.exports.cutAwardBadges = cutAwardBadges; diff --git a/LeetcodeProblems/Backspace_String_Compare.js b/LeetcodeProblems/Backspace_String_Compare.js index 67c4126..f7051af 100644 --- a/LeetcodeProblems/Backspace_String_Compare.js +++ b/LeetcodeProblems/Backspace_String_Compare.js @@ -31,7 +31,6 @@ Follow up: Can you solve it in O(N) time and O(1) space? */ -const assert = require('assert'); /** * @param {string} S @@ -106,20 +105,5 @@ var backspaceCompare2 = function(S, T) { return stackS.length === 0 && stackT.length === 0; }; -var main = function() { - test(); -} - -function test() { - assert.equal(backspaceCompare("ab#c", "ad#c"), true); // true - assert.equal(backspaceCompare("ab##", "c#d#"), true); // true - assert.equal(backspaceCompare("a##c", "#a#c"), true); // true - assert.equal(backspaceCompare("a#c", "b"), false); // false - - assert.equal(backspaceCompare2("ab#c", "ad#c"), true); // true - assert.equal(backspaceCompare2("ab##", "c#d#"), true); // true - assert.equal(backspaceCompare2("a##c", "#a#c"), true); // true - assert.equal(backspaceCompare2("a#c", "b"), false); // false -} - -module.exports.main = main; +module.exports.backspaceCompare = backspaceCompare; +module.exports.backspaceCompare2 = backspaceCompare2; diff --git a/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js b/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js index 1179880..0c4230c 100644 --- a/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js +++ b/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js @@ -27,7 +27,6 @@ Input: [7,6,4,3,1] Output: 0 Explanation: In this case, no transaction is done, i.e. max profit = 0. */ -const assert = require('assert'); /** * @param {number[]} prices @@ -65,4 +64,4 @@ function test() { assert.equal(maxProfit([7,1,5,3320,6,4]), 3319); } -module.exports.main = main; \ No newline at end of file +module.exports.maxProfit = maxProfit; \ No newline at end of file diff --git a/LeetcodeProblems/Binary_Gap.js b/LeetcodeProblems/Binary_Gap.js index 0385125..4b07e8c 100644 --- a/LeetcodeProblems/Binary_Gap.js +++ b/LeetcodeProblems/Binary_Gap.js @@ -36,7 +36,6 @@ Explanation: 8 in binary is 0b1000. There aren't any consecutive pairs of 1's in the binary representation of 8, so we return 0. */ -const assert = require('assert'); /** * @param {number} N @@ -61,13 +60,4 @@ var binaryGap = function(N) { return maxDist; }; -var main = function() { - test(); -} - -function test() { - assert.equal(binaryGap(22), 2); // 10110 - assert.equal(binaryGap(8), 0); // 1000 -} - -module.exports.main = main; +module.exports.binaryGap = binaryGap; diff --git a/LeetcodeProblems/Clone_Graph.js b/LeetcodeProblems/Clone_Graph.js index ee74cdd..0531e8d 100644 --- a/LeetcodeProblems/Clone_Graph.js +++ b/LeetcodeProblems/Clone_Graph.js @@ -40,7 +40,6 @@ You don't need to understand the serialization to solve the problem. * } */ - // SOLUTION 1 Using DFS /** * @param {UndirectedGraphNode} graph diff --git a/LeetcodeProblems/Coin_Change.js b/LeetcodeProblems/Coin_Change.js index 716465c..51ca9a0 100644 --- a/LeetcodeProblems/Coin_Change.js +++ b/LeetcodeProblems/Coin_Change.js @@ -18,7 +18,6 @@ Output: -1 Note: You may assume that you have an infinite number of each kind of coin. */ -const assert = require('assert'); // Solution 3 var coinChange = function(coins, amount) { @@ -102,16 +101,4 @@ var min = function(a, b, c) { return (b < c) ? b : c; } -function main() { - test(); -} - -function test() { - assert.equal(coinChange([], 3), -1); - assert.equal(coinChange([2], 3), -1); - assert.equal(coinChange([1, 2, 5], 11), 3); - assert.equal(coinChange([3, 7, 405, 436], 8839), 25); - assert.equal(coinChange([370, 417, 408, 156, 143, 434, 168, 83, 177, 280, 117], 9953), 24); -} - -module.exports.main = main; \ No newline at end of file +module.exports.coinChange = coinChange; diff --git a/LeetcodeProblems/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal.js b/LeetcodeProblems/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal.js index da702cc..03a5dc1 100644 --- a/LeetcodeProblems/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal.js +++ b/LeetcodeProblems/Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal.js @@ -27,8 +27,6 @@ Return the following binary tree: * this.left = this.right = null; * } */ -const assert = require('assert'); - var TreeNode = require('../UtilsClasses/TreeNode').TreeNode; /** @@ -59,12 +57,4 @@ var buildTreeAux = function(preorder, pl, ph, inorder, il, ih) { return ret; } -var main = function() { - test(); -} - -function test() { - console.log(buildTree([3,9,20,15,7], [9,3,15,20,7])); -} - -module.exports.main = main +module.exports.buildTree = buildTree diff --git a/LeetcodeProblems/Deletion_Distance.js b/LeetcodeProblems/Deletion_Distance.js index 2714fb3..d06352a 100644 --- a/LeetcodeProblems/Deletion_Distance.js +++ b/LeetcodeProblems/Deletion_Distance.js @@ -18,7 +18,6 @@ output: 9 input: str1 = "", str2 = "" output: 0 */ -const assert = require('assert'); // Solution 3 Using DP var deletionDistanceDP = function(str1, str2) { @@ -128,4 +127,7 @@ function test() { assert.equal(deletionDistanceDP("", ""), 0); } -module.exports.main = main +module.exports.deletionDistance = deletionDistance; +module.exports.deletionDistance2 = deletionDistance2; +module.exports.deletionDistanceDP = deletionDistanceDP; + diff --git a/LeetcodeProblems/Design_Circular_Deque.js b/LeetcodeProblems/Design_Circular_Deque.js index 60dace9..df6a123 100644 --- a/LeetcodeProblems/Design_Circular_Deque.js +++ b/LeetcodeProblems/Design_Circular_Deque.js @@ -35,7 +35,6 @@ All values will be in the range of [0, 1000]. The number of operations will be in the range of [1, 1000]. Please do not use the built-in Deque library. */ -const assert = require('assert'); /** * Initialize your data structure here. Set the size of the deque to be k. @@ -132,21 +131,4 @@ MyCircularDeque.prototype.isFull = function() { return this.queue.length === this.maxSize; }; -var main = function(){ - test(); -}; - -var test = function() { - const obj = new MyCircularDeque(3); - assert.equal(obj.insertLast(1), true); - assert.equal(obj.insertLast(2), true); - assert.equal(obj.insertFront(3), true); - assert.equal(obj.insertFront(4), false); - assert.equal(obj.getRear(), 2); - assert.equal(obj.isFull(), true); - assert.equal(obj.deleteLast(), true); - assert.equal(obj.insertFront(4), true); - assert.equal(obj.getFront(), 4); -} - -module.exports.main = main; +module.exports.MyCircularDeque = MyCircularDeque; diff --git a/LeetcodeProblems/Edit_Distance.js b/LeetcodeProblems/Edit_Distance.js index c337677..73d4e47 100644 --- a/LeetcodeProblems/Edit_Distance.js +++ b/LeetcodeProblems/Edit_Distance.js @@ -28,7 +28,6 @@ enention -> exention (replace 'n' with 'x') exention -> exection (replace 'n' with 'c') exection -> execution (insert 'u') */ -const assert = require('assert'); // Optimal solution var minDistance = function(word1, word2) { @@ -98,16 +97,5 @@ var min = function(a, b, c) { return (b < c) ? b : c; } -var main = function() { - test(); -} - -function test() { - assert.equal(minDistance("ros", "horse"), 3); - assert.equal(minDistance("intention", "execution"), 5); - - assert.equal(minDistance2("ros", "horse"), 3); - assert.equal(minDistance2("intention", "execution"), 5); -} - -module.exports.main = main; +module.exports.minDistance = minDistance; +module.exports.minDistance2 = minDistance2; diff --git a/LeetcodeProblems/Escape_The_Ghosts.js b/LeetcodeProblems/Escape_The_Ghosts.js index 3e8ee10..fa8e775 100644 --- a/LeetcodeProblems/Escape_The_Ghosts.js +++ b/LeetcodeProblems/Escape_The_Ghosts.js @@ -36,7 +36,6 @@ Note: All points have coordinates with absolute value <= 10000. The number of ghosts will not exceed 100. */ -const assert = require('assert'); /** * @param {number[][]} ghosts diff --git a/LeetcodeProblems/Flood_Fill.js b/LeetcodeProblems/Flood_Fill.js index 14ed4e3..ad6c010 100644 --- a/LeetcodeProblems/Flood_Fill.js +++ b/LeetcodeProblems/Flood_Fill.js @@ -28,7 +28,7 @@ The length of image and image[0] will be in the range [1, 50]. The given starting pixel will satisfy 0 <= sr < image.length and 0 <= sc < image[0].length. The value of each color in image[i][j] and newColor will be an integer in [0, 65535]. */ -const assert = require('assert'); + var floodFill = function(image, sr, sc, newColor) { var oldColor = image[sr][sc]; diff --git a/LeetcodeProblems/Group_Anagrams.js b/LeetcodeProblems/Group_Anagrams.js index 230af77..25dbb3c 100644 --- a/LeetcodeProblems/Group_Anagrams.js +++ b/LeetcodeProblems/Group_Anagrams.js @@ -18,7 +18,7 @@ Note: All inputs will be in lowercase. The order of your output does not matter. */ -const assert = require('assert'); + var groupAnagrams = function(strs) { var ret = []; diff --git a/LeetcodeProblems/Implement_stack_using_queues.js b/LeetcodeProblems/Implement_stack_using_queues.js index 9f33c41..6e21144 100644 --- a/LeetcodeProblems/Implement_stack_using_queues.js +++ b/LeetcodeProblems/Implement_stack_using_queues.js @@ -23,7 +23,7 @@ You must use only standard operations of a queue -- which means only push to bac Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). */ -const assert = require('assert'); + class MyStack { constructor() { this.q1 = []; diff --git a/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js b/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js index 51ed6cb..22d0223 100644 --- a/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js +++ b/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js @@ -15,7 +15,7 @@ Output: 4 Note: You may assume k is always valid, 1 ≤ k ≤ array's length. */ -const assert = require('assert'); + /** * @param {number[]} nums diff --git a/LeetcodeProblems/Linked_List_Cycle_II.js b/LeetcodeProblems/Linked_List_Cycle_II.js index 9573e63..bbacfa9 100644 --- a/LeetcodeProblems/Linked_List_Cycle_II.js +++ b/LeetcodeProblems/Linked_List_Cycle_II.js @@ -9,7 +9,7 @@ Note: Do not modify the linked list. Follow up: Can you solve it without using extra space? */ -const assert = require('assert'); + var ListNode = require('../UtilsClasses/ListNode').ListNode; // Optimal solution diff --git a/LeetcodeProblems/Longest_Consecutive_Sequence.js b/LeetcodeProblems/Longest_Consecutive_Sequence.js index 290d9ea..a0b9e62 100644 --- a/LeetcodeProblems/Longest_Consecutive_Sequence.js +++ b/LeetcodeProblems/Longest_Consecutive_Sequence.js @@ -12,7 +12,7 @@ Input: [100, 4, 200, 1, 3, 2] Output: 4 Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. */ -const assert = require('assert'); + /** * @param {number[]} nums diff --git a/LeetcodeProblems/Longest_Palindromic_Substring.js b/LeetcodeProblems/Longest_Palindromic_Substring.js index 74a2447..cdf14a9 100644 --- a/LeetcodeProblems/Longest_Palindromic_Substring.js +++ b/LeetcodeProblems/Longest_Palindromic_Substring.js @@ -14,7 +14,7 @@ Example 2: Input: "cbbd" Output: "bb" */ -const assert = require('assert'); + /** * @param {string} s diff --git a/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js b/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js index c4f0168..e041008 100644 --- a/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js +++ b/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js @@ -33,7 +33,7 @@ Note: All of the nodes' values will be unique. p and q are different and both values will exist in the binary tree. */ -const assert = require('assert'); + var TreeNode = require('../UtilsClasses/TreeNode').TreeNode; diff --git a/LeetcodeProblems/Majority_Element.js b/LeetcodeProblems/Majority_Element.js index f1114f8..1d7258f 100644 --- a/LeetcodeProblems/Majority_Element.js +++ b/LeetcodeProblems/Majority_Element.js @@ -17,7 +17,7 @@ Output: 2 Note: You should have a better solution than O(N) */ -const assert = require('assert'); + /** * @param {number[]} nums diff --git a/LeetcodeProblems/Maximal_Square.js b/LeetcodeProblems/Maximal_Square.js index 014d4a8..d43dfb7 100644 --- a/LeetcodeProblems/Maximal_Square.js +++ b/LeetcodeProblems/Maximal_Square.js @@ -15,7 +15,7 @@ Input: Output: 4 */ -const assert = require('assert'); + /** * @param {character[][]} matrix diff --git a/LeetcodeProblems/Maximun_Subarray.js b/LeetcodeProblems/Maximun_Subarray.js index c159a43..4f321e0 100644 --- a/LeetcodeProblems/Maximun_Subarray.js +++ b/LeetcodeProblems/Maximun_Subarray.js @@ -13,7 +13,7 @@ Explanation: [4,-1,2,1] has the largest sum = 6. Follow up: */ -const assert = require('assert'); + var maxSubArray = function(nums) { if(nums.length == 0) diff --git a/LeetcodeProblems/Min_Stack.js b/LeetcodeProblems/Min_Stack.js index 3ee0f78..f510abc 100644 --- a/LeetcodeProblems/Min_Stack.js +++ b/LeetcodeProblems/Min_Stack.js @@ -19,7 +19,7 @@ minStack.pop(); minStack.top(); --> Returns 0. minStack.getMin(); --> Returns -2. */ -const assert = require('assert'); + class MinStack { constructor() { diff --git a/LeetcodeProblems/Minimum_Window_Substring.js b/LeetcodeProblems/Minimum_Window_Substring.js index 2769963..3ad13fe 100644 --- a/LeetcodeProblems/Minimum_Window_Substring.js +++ b/LeetcodeProblems/Minimum_Window_Substring.js @@ -14,7 +14,7 @@ Note: If there is no such window in S that covers all characters in T, return the empty string "". If there is such window, you are guaranteed that there will always be only one unique minimum window in S. */ -const assert = require('assert'); + var minWindow = function(s, t) { if(t.length === 0 || s.length < t.length) diff --git a/LeetcodeProblems/NQueens.js b/LeetcodeProblems/NQueens.js index f78d3b8..d0bbd14 100644 --- a/LeetcodeProblems/NQueens.js +++ b/LeetcodeProblems/NQueens.js @@ -18,7 +18,7 @@ Output: [ ] Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. */ -const assert = require('assert'); + /** * @param {number} n diff --git a/LeetcodeProblems/Number_of_Islands.js b/LeetcodeProblems/Number_of_Islands.js index 248ea49..b9e3150 100644 --- a/LeetcodeProblems/Number_of_Islands.js +++ b/LeetcodeProblems/Number_of_Islands.js @@ -24,7 +24,7 @@ Input: Output: 3 */ -const assert = require('assert'); + /* * @param {character[][]} grid diff --git a/LeetcodeProblems/Number_of_Segments_in_a_String.js b/LeetcodeProblems/Number_of_Segments_in_a_String.js index a6c367a..5c0e05c 100644 --- a/LeetcodeProblems/Number_of_Segments_in_a_String.js +++ b/LeetcodeProblems/Number_of_Segments_in_a_String.js @@ -11,7 +11,7 @@ Example: Input: "Hello, my name is John" Output: 5 */ -const assert = require('assert'); + /** * @param {string} s diff --git a/LeetcodeProblems/Permutations.js b/LeetcodeProblems/Permutations.js index f04f128..e7adc08 100644 --- a/LeetcodeProblems/Permutations.js +++ b/LeetcodeProblems/Permutations.js @@ -17,7 +17,7 @@ Output: [3,2,1] ] */ -const assert = require('assert'); + var permute = function(nums) { return permuteAux(nums, 0, [], new Set()); diff --git a/LeetcodeProblems/Permutations_II.js b/LeetcodeProblems/Permutations_II.js index 22093fe..6145b56 100644 --- a/LeetcodeProblems/Permutations_II.js +++ b/LeetcodeProblems/Permutations_II.js @@ -14,7 +14,7 @@ Output: [2,1,1] ] */ -const assert = require('assert'); + var permuteUnique = function(nums) { var map = {}; diff --git a/LeetcodeProblems/Permutations_With_Duplicates.js b/LeetcodeProblems/Permutations_With_Duplicates.js index e9fccc5..688df4b 100644 --- a/LeetcodeProblems/Permutations_With_Duplicates.js +++ b/LeetcodeProblems/Permutations_With_Duplicates.js @@ -1,4 +1,4 @@ -const assert = require('assert'); + // Permutations without var subsetWithoutDuplicates = function(nums) { diff --git a/LeetcodeProblems/Permutations_Without_Duplicates.js b/LeetcodeProblems/Permutations_Without_Duplicates.js index b5b0a1b..06e4977 100644 --- a/LeetcodeProblems/Permutations_Without_Duplicates.js +++ b/LeetcodeProblems/Permutations_Without_Duplicates.js @@ -17,7 +17,7 @@ Output: [3,2,1] ] */ -const assert = require('assert'); + // Permutations wihto var subsetWithDuplicates = function(nums) { diff --git a/LeetcodeProblems/Regular_Expression_Matching.js b/LeetcodeProblems/Regular_Expression_Matching.js index 3aaedf0..ca357c4 100644 --- a/LeetcodeProblems/Regular_Expression_Matching.js +++ b/LeetcodeProblems/Regular_Expression_Matching.js @@ -50,7 +50,7 @@ Output: false * @param {*} s * @param {*} p */ -const assert = require('assert'); + var isMatch = function(s, p) { return isMatchAux(s, p, 0, 0); diff --git a/LeetcodeProblems/Remove_Invalid_Parentheses.js b/LeetcodeProblems/Remove_Invalid_Parentheses.js index fdb4fab..2197999 100644 --- a/LeetcodeProblems/Remove_Invalid_Parentheses.js +++ b/LeetcodeProblems/Remove_Invalid_Parentheses.js @@ -19,7 +19,7 @@ Example 3: Input: ")(" Output: [""] */ -const assert = require('assert'); + /** * @param {string} s diff --git a/LeetcodeProblems/Restore_IP_Addresses.js b/LeetcodeProblems/Restore_IP_Addresses.js index 2394963..0dcae65 100644 --- a/LeetcodeProblems/Restore_IP_Addresses.js +++ b/LeetcodeProblems/Restore_IP_Addresses.js @@ -9,7 +9,7 @@ Example: Input: "25525511135" Output: ["255.255.11.135", "255.255.111.35"] */ -const assert = require('assert'); + var restoreIpAddresses = function(s) { var restore = restoreInputBits("", s, 4); diff --git a/LeetcodeProblems/Reverse_String_II.js b/LeetcodeProblems/Reverse_String_II.js index d277483..66d7cd6 100644 --- a/LeetcodeProblems/Reverse_String_II.js +++ b/LeetcodeProblems/Reverse_String_II.js @@ -10,7 +10,7 @@ Restrictions: The string consists of lower English letters only. Length of the given string and k will in the range [1, 10000] */ -const assert = require('assert'); + var reverseStr = function(s, k) { if(k <= 1) diff --git a/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js b/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js index d095215..a4753ee 100644 --- a/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js +++ b/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js @@ -21,7 +21,7 @@ Input: nums = [4,5,6,7,0,1,2], target = 3 Output: -1 */ -const assert = require('assert'); + /** * @param {number[]} nums diff --git a/LeetcodeProblems/Search_a_2D_Matrix.js b/LeetcodeProblems/Search_a_2D_Matrix.js index 0a0b835..9251b9e 100644 --- a/LeetcodeProblems/Search_a_2D_Matrix.js +++ b/LeetcodeProblems/Search_a_2D_Matrix.js @@ -27,7 +27,7 @@ matrix = [ target = 13 Output: false */ -const assert = require('assert'); + /** * @param {number[][]} matrix diff --git a/LeetcodeProblems/Search_a_2D_Matrix_II.js b/LeetcodeProblems/Search_a_2D_Matrix_II.js index 7085dc3..f3ffba1 100644 --- a/LeetcodeProblems/Search_a_2D_Matrix_II.js +++ b/LeetcodeProblems/Search_a_2D_Matrix_II.js @@ -17,7 +17,7 @@ Example: Given target = 5, return true. Given target = 20, return false. */ -const assert = require('assert'); + /** * @param {number[][]} matrix diff --git a/LeetcodeProblems/Set_Matrix_Zeroes.js b/LeetcodeProblems/Set_Matrix_Zeroes.js index d92d8eb..0abbf86 100644 --- a/LeetcodeProblems/Set_Matrix_Zeroes.js +++ b/LeetcodeProblems/Set_Matrix_Zeroes.js @@ -39,7 +39,7 @@ A simple improvement uses O(m + n) space, but still not the best solution. Could you devise a constant space solution? */ -const assert = require('assert'); + /** * @param {number[][]} matrix diff --git a/LeetcodeProblems/Simplify_Path.js b/LeetcodeProblems/Simplify_Path.js index fdb6d2f..a462e14 100644 --- a/LeetcodeProblems/Simplify_Path.js +++ b/LeetcodeProblems/Simplify_Path.js @@ -19,7 +19,7 @@ In this case, you should return "/". Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". In this case, you should ignore redundant slashes and return "/home/foo". */ -const assert = require('assert'); + var simplifyPath = function(path) { var queue = []; diff --git a/LeetcodeProblems/Spiral_Matrix.js b/LeetcodeProblems/Spiral_Matrix.js index b3e293a..21a4453 100644 --- a/LeetcodeProblems/Spiral_Matrix.js +++ b/LeetcodeProblems/Spiral_Matrix.js @@ -23,7 +23,7 @@ Input: ] Output: [1,2,3,4,8,12,11,10,9,5,6,7] */ -const assert = require('assert'); + /** * @param {number[][]} matrix diff --git a/LeetcodeProblems/Subarray_Sum_Equals_K.js b/LeetcodeProblems/Subarray_Sum_Equals_K.js index 0f75e13..d761e46 100644 --- a/LeetcodeProblems/Subarray_Sum_Equals_K.js +++ b/LeetcodeProblems/Subarray_Sum_Equals_K.js @@ -12,7 +12,7 @@ Note: The length of the array is in range [1, 20,000]. The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. */ -const assert = require('assert'); + /** * @param {number[]} nums diff --git a/LeetcodeProblems/Subsets.js b/LeetcodeProblems/Subsets.js index 014ab43..ddff800 100644 --- a/LeetcodeProblems/Subsets.js +++ b/LeetcodeProblems/Subsets.js @@ -22,7 +22,7 @@ Output: ] */ -const assert = require('assert'); + var subsets = function(nums) { var ret = []; diff --git a/LeetcodeProblems/Sum_Of_Square_Numbers.js b/LeetcodeProblems/Sum_Of_Square_Numbers.js index 2146a45..f897ed0 100644 --- a/LeetcodeProblems/Sum_Of_Square_Numbers.js +++ b/LeetcodeProblems/Sum_Of_Square_Numbers.js @@ -14,7 +14,7 @@ Input: 3 Output: False */ -const assert = require('assert'); + /** * @param {number} c diff --git a/LeetcodeProblems/Swap_Nodes_In_Pairs.js b/LeetcodeProblems/Swap_Nodes_In_Pairs.js index 54c1faf..e1a98c3 100644 --- a/LeetcodeProblems/Swap_Nodes_In_Pairs.js +++ b/LeetcodeProblems/Swap_Nodes_In_Pairs.js @@ -12,7 +12,7 @@ Note: Your algorithm should use only constant extra space. You may not modify the values in the list's nodes, only nodes itself may be changed. */ -const assert = require('assert'); + const ListNode = require('../UtilsClasses/ListNode').ListNode; const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); diff --git a/LeetcodeProblems/Unique_Binary_Search_Trees.js b/LeetcodeProblems/Unique_Binary_Search_Trees.js index 3bf1c2c..4b8726b 100644 --- a/LeetcodeProblems/Unique_Binary_Search_Trees.js +++ b/LeetcodeProblems/Unique_Binary_Search_Trees.js @@ -22,7 +22,7 @@ Given n = 3, there are a total of 5 unique BST's: DP Solution: https://www.programcreek.com/2014/05/leetcode-unique-binary-search-trees-java/ */ -const assert = require('assert'); + // Solution 3 using DP var numTrees3 = function (n) { diff --git a/LeetcodeProblems/Unique_Paths.js b/LeetcodeProblems/Unique_Paths.js index 0a0092e..b8e9290 100644 --- a/LeetcodeProblems/Unique_Paths.js +++ b/LeetcodeProblems/Unique_Paths.js @@ -26,7 +26,7 @@ Output: 28 // Solution 1 // This solution is a naive solution implementing a binary tree and visiting each node. -const assert = require('assert'); + var uniquePaths1 = function(m, n) { return uniquePathsAux(0, 0, m, n) diff --git a/LeetcodeProblems/Valid_Parentheses.js b/LeetcodeProblems/Valid_Parentheses.js index f4d5bc0..3702004 100644 --- a/LeetcodeProblems/Valid_Parentheses.js +++ b/LeetcodeProblems/Valid_Parentheses.js @@ -32,7 +32,7 @@ Input: "{[]}" Output: true */ -const assert = require('assert'); + var isValid = function(s) { var stack = []; diff --git a/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js b/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js index 4576c3c..1d6be1a 100644 --- a/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js +++ b/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js @@ -31,7 +31,7 @@ Example 3: Input: "9,#,#,1" Output: false */ -const assert = require('assert'); + /** * @param {string} preorder diff --git a/LeetcodeProblems/merge_k_sorted_lists.js b/LeetcodeProblems/merge_k_sorted_lists.js index c36fa4d..7e92a8b 100644 --- a/LeetcodeProblems/merge_k_sorted_lists.js +++ b/LeetcodeProblems/merge_k_sorted_lists.js @@ -14,7 +14,7 @@ Input: ] Output: 1->1->2->3->4->4->5->6 */ -const assert = require('assert'); + const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); var ListNode = require('../UtilsClasses/ListNode').ListNode; From e400414b43701e5d02ecebb6d429f3074db1eae3 Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 30 Aug 2020 23:35:37 -0400 Subject: [PATCH 04/11] Move tests to its own files Round 2 --- LeetcodeProblemsTests/Edit_Distance_Test.js | 2 +- .../Escape_The_Ghosts_Test.js | 66 +--------- LeetcodeProblemsTests/Flood_Fill_Test.js | 59 +-------- .../Generate_Parenthesis_Test.js | 95 +------------- LeetcodeProblemsTests/Group_Anagrams_Test.js | 54 +------- .../Implement_stack_using_queues_Test.js | 83 +------------ .../Kth_Largest_Element_in_an_Array_Test.js | 63 +--------- .../Linked_List_Cycle_II_Test.js | 62 +--------- .../Longest_Consecutive_Sequence_Test.js | 60 +-------- .../Longest_Palindromic_Substring_Test.js | 70 +---------- ...t_Common_Ancestor_of_a_Binary_Tree_Test.js | 98 +-------------- .../Majority_Element_Test.js | 51 +------- LeetcodeProblemsTests/Maximal_Square_Test.js | 71 +---------- .../Maximun_Subarray_Test.js | 40 +----- LeetcodeProblemsTests/Min_Stack_Test.js | 80 +----------- .../Minimum_Window_Substring_Test.js | 70 +---------- LeetcodeProblemsTests/NQueens_Test.js | 77 +----------- .../Number_of_Islands_Test.js | 67 +--------- .../Number_of_Segments_in_a_String_Test.js | 39 +----- LeetcodeProblemsTests/Permutations_II_Test.js | 53 +------- LeetcodeProblemsTests/Permutations_Test.js | 45 +------ .../Permutations_With_Duplicates_Test.js | 37 +----- .../Permutations_Without_Duplicates_Test.js | 47 +------ .../Regular_Expression_Matching_Test.js | 98 +-------------- .../Remove_Invalid_Parentheses_Test.js | 78 +----------- .../Restore_IP_Addresses_Test.js | 49 +------- .../Reverse_String_II_Test.js | 47 +------ LeetcodeProblemsTests/Same_Tree_Test.js | 60 +-------- .../SearchIng_Rotated_Sorted_Array_Test.js | 62 +--------- .../Search_a_2D_Matrix_II_Test.js | 59 +-------- .../Search_a_2D_Matrix_Test.js | 67 +--------- .../Set_Matrix_Zeroes_Test.js | 116 +----------------- LeetcodeProblemsTests/Simplify_Path_Test.js | 66 +--------- LeetcodeProblemsTests/Spiral_Matrix_Test.js | 71 +---------- .../Subarray_Sum_Equals_K_Test.js | 66 +--------- LeetcodeProblemsTests/Subsets_Test.js | 44 +------ .../Sum_Of_Square_Numbers_Test.js | 42 +------ .../Swap_Nodes_In_Pairs_Test.js | 53 +------- LeetcodeProblemsTests/Symmetric_Tree_Test.js | 54 +------- LeetcodeProblemsTests/Tic_Tac_Toe_Test.js | 87 +------------ .../Unique_Binary_Search_Trees_Test.js | 115 +---------------- LeetcodeProblemsTests/Unique_Paths_Test.js | 102 +-------------- .../Valid_Parentheses_Test.js | 64 +--------- ...der_Serialization_of_a_Binary_Tree_Test.js | 70 +---------- .../merge_k_sorted_lists_Test.js | 80 +----------- 45 files changed, 68 insertions(+), 2871 deletions(-) diff --git a/LeetcodeProblemsTests/Edit_Distance_Test.js b/LeetcodeProblemsTests/Edit_Distance_Test.js index b466527..7a02e8a 100644 --- a/LeetcodeProblemsTests/Edit_Distance_Test.js +++ b/LeetcodeProblemsTests/Edit_Distance_Test.js @@ -9,5 +9,5 @@ function test() { assert.equal(minDistance2("ros", "horse"), 3); assert.equal(minDistance2("intention", "execution"), 5); } -test(); + module.exports.test = test; diff --git a/LeetcodeProblemsTests/Escape_The_Ghosts_Test.js b/LeetcodeProblemsTests/Escape_The_Ghosts_Test.js index 3e8ee10..59c23e2 100644 --- a/LeetcodeProblemsTests/Escape_The_Ghosts_Test.js +++ b/LeetcodeProblemsTests/Escape_The_Ghosts_Test.js @@ -1,68 +1,6 @@ -/* -Escape The Ghosts -https://leetcode.com/problems/escape-the-ghosts/description/ -You are playing a simplified Pacman game. You start at the point (0, 0), and your destination is (target[0], target[1]). There are several ghosts on the map, the i-th ghost starts at (ghosts[i][0], ghosts[i][1]). - -Each turn, you and all ghosts simultaneously *may* move in one of 4 cardinal directions: north, east, west, or south, going from the previous point to a new point 1 unit of distance away. - -You escape if and only if you can reach the target before any ghost reaches you (for any given moves the ghosts may take.) If you reach any square (including the target) at the same time as a ghost, it doesn't count as an escape. - -Return True if and only if it is possible to escape. - -Example 1: -Input: -ghosts = [[1, 0], [0, 3]] -target = [0, 1] -Output: true -Explanation: -You can directly reach the destination (0, 1) at time 1, while the ghosts located at (1, 0) or (0, 3) have no way to catch up with you. -Example 2: -Input: -ghosts = [[1, 0]] -target = [2, 0] -Output: false -Explanation: -You need to reach the destination (2, 0), but the ghost at (1, 0) lies between you and the destination. -Example 3: -Input: -ghosts = [[2, 0]] -target = [1, 0] -Output: false -Explanation: -The ghost can reach the target at the same time as you. -Note: - -All points have coordinates with absolute value <= 10000. -The number of ghosts will not exceed 100. -*/ const assert = require('assert'); - -/** - * @param {number[][]} ghosts - * @param {number[]} target - * @return {boolean} - */ -var escapeGhosts = function(ghosts, target) { - var distancePacman = getDistance([0,0], target); - for(ghost in ghosts) { - const distanceGhost = getDistance(ghosts[ghost], target); - if(distancePacman > distanceGhost) - return false - } - - return true; -}; - -var getDistance = function(a, b) { - const horizontalMoves = Math.abs(a[0] - b[0]); - const verticalMoves = Math.abs(a[1] - b[1]); - return horizontalMoves + verticalMoves; -} - -var main = function() { - test(); -} +var escapeGhosts = require('../LeetcodeProblems/Escape_The_Ghosts').escapeGhosts; function test() { assert.equal(escapeGhosts([[1, 0], [0, 3]], [0, 1]), true); @@ -70,4 +8,4 @@ function test() { assert.equal(escapeGhosts([[2, 0]], [1, 0]), true); } -module.exports.main = main \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Flood_Fill_Test.js b/LeetcodeProblemsTests/Flood_Fill_Test.js index 14ed4e3..37bab1c 100644 --- a/LeetcodeProblemsTests/Flood_Fill_Test.js +++ b/LeetcodeProblemsTests/Flood_Fill_Test.js @@ -1,62 +1,5 @@ -/* -Flood Fill -https://leetcode.com/problems/flood-fill/description/ - -An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535). - -Given a coordinate (sr, sc) representing the starting pixel (row and column) of the flood fill, and a pixel value newColor, "flood fill" the image. - -To perform a "flood fill", consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, -plus any pixels connected 4-directionally to those pixels (also with the same color as the starting pixel), and so on. -Replace the color of all of the aforementioned pixels with the newColor. - -At the end, return the modified image. - -Example 1: -Input: -image = [[1,1,1],[1,1,0],[1,0,1]] -sr = 1, sc = 1, newColor = 2 -Output: [[2,2,2],[2,2,0],[2,0,1]] -Explanation: -From the center of the image (with position (sr, sc) = (1, 1)), all pixels connected -by a path of the same color as the starting pixel are colored with the new color. -Note the bottom corner is not colored 2, because it is not 4-directionally connected -to the starting pixel. -Note: - -The length of image and image[0] will be in the range [1, 50]. -The given starting pixel will satisfy 0 <= sr < image.length and 0 <= sc < image[0].length. -The value of each color in image[i][j] and newColor will be an integer in [0, 65535]. -*/ const assert = require('assert'); -var floodFill = function(image, sr, sc, newColor) { - var oldColor = image[sr][sc]; - - if(newColor == oldColor) - return image; - - image[sr][sc] = newColor; - - if(sr > 0 && image[sr - 1][sc] == oldColor) - floodFill(image, sr - 1, sc, newColor); //Left - - if(sc > 0 && image[sr][sc - 1] == oldColor) - floodFill(image, sr, sc - 1, newColor); //Up - - if(sr < image.length - 1 && image[sr + 1][sc] == oldColor) - floodFill(image, sr + 1, sc, newColor); //Down - - if(sc < image[0].length - 1 && image[sr][sc + 1] == oldColor) - floodFill(image, sr, sc + 1, newColor); // Right - - return image; -}; - -function main() { - test(); -} - function test() { assert.deepEqual( [ [ 2, 2, 2 ], [ 2, 2, 0 ], [ 2, 0, 1 ] ], @@ -64,4 +7,4 @@ function test() { ); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Generate_Parenthesis_Test.js b/LeetcodeProblemsTests/Generate_Parenthesis_Test.js index 323b6ef..ea8b26b 100644 --- a/LeetcodeProblemsTests/Generate_Parenthesis_Test.js +++ b/LeetcodeProblemsTests/Generate_Parenthesis_Test.js @@ -1,94 +1,5 @@ -/* -Generate Parentheses -https://leetcode.com/problems/generate-parentheses - -Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. - -For example, given n = 3, a solution set is: - -[ - "((()))", - "(()())", - "(())()", - "()(())", - "()()()" -] -*/ - -// ************************************************ Approach1 ************************************************ -var generateParenthesisApproach1 = function(n) { - if(n === 0) - return []; - - var str = "(".repeat(n); - sol = []; - - genParAux(str, 0, 0, sol) - return sol; -}; - -var genParAux = function(str, position, leftParentheses, sol) { - if(position === str.length) { - var ret = str + ")".repeat(leftParentheses); - sol.push(ret); - return; - } - - genParAux(str, position + 1, leftParentheses + 1, sol); // Don't insert anything - if(leftParentheses === 0) - return; - - for(var i = 1; i <= leftParentheses; i++) { - var parString = ")".repeat(i); - var partSol = str.slice(0, position) + parString + str.slice(position); // Insert i parentheses in the position - genParAux(partSol, position + i + 1, leftParentheses - i + 1, sol); - } -} - -// ************************************************ Approach2 ************************************************ -var generateParenthesisApproach2 = function(n) { - if(n === 0) - return []; - - var sol = []; - genParAuxApproach2("", 0, 0, 0, n * 2, sol) - return sol; -} - -var genParAuxApproach2 = function(str, leftPar, rightPar, index, totalCharCount, sol) { - if(index === totalCharCount) { - if(rightPar === leftPar) - sol.push(str); - - return; - } - - var strLeft = insertAt(str, index, "("); - genParAuxApproach2(strLeft, leftPar + 1, rightPar, index + 1, totalCharCount, sol); - - if(rightPar === leftPar) - return; - - var strRight = insertAt(str, index, ")"); - genParAuxApproach2(strRight, leftPar, rightPar + 1, index + 1, totalCharCount, sol); -} - -var insertAt = function(str, position, value) { - return str.slice(0, position) + value + str.slice(position); -} - -function main() { - console.log("Approach 1"); - [0, 1, 2, 3].forEach(function(elem) { - console.log(`${elem}: ${generateParenthesisApproach2(elem)}`); - }) - - console.log("-------------"); - - console.log("Approach 2"); - [0, 1, 2, 3].forEach(function(elem) { - console.log(`${elem}: ${generateParenthesisApproach2(elem)}`); - }) +var test = function() { + // TODO } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Group_Anagrams_Test.js b/LeetcodeProblemsTests/Group_Anagrams_Test.js index 230af77..8f14cd5 100644 --- a/LeetcodeProblemsTests/Group_Anagrams_Test.js +++ b/LeetcodeProblemsTests/Group_Anagrams_Test.js @@ -1,57 +1,5 @@ -/* -Group Anagrams -https://leetcode.com/problems/group-anagrams/description/ - -Given an array of strings, group anagrams together. - -Example: - -Input: ["eat", "tea", "tan", "ate", "nat", "bat"], -Output: -[ - ["ate","eat","tea"], - ["nat","tan"], - ["bat"] -] -Note: - -All inputs will be in lowercase. -The order of your output does not matter. -*/ const assert = require('assert'); -var groupAnagrams = function(strs) { - var ret = []; - var hashMap = {}; - for(var i = 0; i < strs.length; i++) { - const elem = strs[i]; - const elemSorted = sortString(strs[i]); - - if(hashMap[elemSorted]) { - hashMap[elemSorted].push(elem); - } else { - hashMap[elemSorted] = [elem]; - } - } - - for(key in hashMap) - ret.push(hashMap[key]); - - - return ret; -}; - -var sortString = function(str) { - if(str.length === 0) - return str; - - return str.split("").sort().join(""); -} - -var main = function() { - test(); -} - function test() { assert.deepEqual( groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]), @@ -59,4 +7,4 @@ function test() { ) } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js b/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js index 9f33c41..fa32b3a 100644 --- a/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js +++ b/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js @@ -1,85 +1,4 @@ -/* -Implement Stack using Queues -URL: https://leetcode.com/problems/implement-stack-using-queues/description/ - -Implement the following operations of a stack using queues. - -push(x) -- Push element x onto stack. -pop() -- Removes the element on top of the stack. -top() -- Get the top element. -empty() -- Return whether the stack is empty. -Example: - -MyStack stack = new MyStack(); - -stack.push(1); -stack.push(2); -stack.top(); // returns 2 -stack.pop(); // returns 2 -stack.empty(); // returns false -Notes: - -You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid. -Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. -You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). -*/ const assert = require('assert'); -class MyStack { - constructor() { - this.q1 = []; - this.q2 = []; - }; - - push(elem) { - if(this.q1.length > 0) { - this.q1.push(elem); - } else { - this.q2.push(elem); - } - }; - - pop() { - if(this.q1.length === 0 && this.q2.length === 0) - return null; - - if(this.q1.length > 0) { - while(this.q1.length > 1) { - var elem = this.q1.shift(); - this.q2.push(elem); - } - return this.q1.shift(); - } else { - while(this.q2.length > 1) { - var elem = this.q2.shift(); - this.q1.push(elem); - } - return this.q2.shift(); - } - }; - - top() { - if(this.q1.length === 0 && this.q2.length === 0) - return null; - - if(this.q1.length > 0) { - var elem = this.pop(); - this.q2.push(elem); - return elem; - } else { - var elem = this.pop(); - this.q1.push(elem); - return elem; - } - }; - - empty() { - return this.q1.length == 0 && this.q2.length === 0; - }; -} - -var main = function() { - test(); -} var test = function () { var myStack = new MyStack(); @@ -96,4 +15,4 @@ var test = function () { assert.equal(myStack.pop(), 3); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js b/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js index 51ed6cb..8b0909b 100644 --- a/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js +++ b/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js @@ -1,66 +1,5 @@ -/* -Kth Largest Element in an Array -https://leetcode.com/problems/kth-largest-element-in-an-array/description/ - -Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. - -Example 1: - -Input: [3,2,1,5,6,4] and k = 2 -Output: 5 -Example 2: - -Input: [3,2,3,1,2,4,5,5,6] and k = 4 -Output: 4 -Note: -You may assume k is always valid, 1 ≤ k ≤ array's length. -*/ const assert = require('assert'); -/** - * @param {number[]} nums - * @param {number} k - * @return {number} - */ -var findKthLargest = function(nums, k) { - for(var i = Math.floor(nums.length/2) - 1; i >= 0; i--) { - heapify(nums, nums.length, i); - } - - for(var i = nums.length -1; i >= nums.length - k - 1 && i >= 0; i--) { - swap(nums, 0, i); - heapify(nums, i, 0); - } - - return nums[nums.length - k]; -} - -var heapify = function(nums, length, i) { - var left = 2 * i + 1; - var right = 2 * i + 2; - - if(left >= length) - return; - - if(nums[i] < nums[left] && (right >= length || nums[left] > nums[right])) { - swap(nums, left, i); - heapify(nums, length, left); - } else if(right < length && nums[right] > nums[i]) { - swap(nums, right, i) - heapify(nums, length, right) - } -} - -var swap = function(nums, a, b) { - const temp = nums[a]; - nums[a] = nums[b]; - nums[b] = temp; -} - -var main = function(nums) { - test(); -} - function test() { assert.equal(findKthLargest([3,2,1,5,6,4], 2), 5); assert.equal(findKthLargest([3,2,3,1,2,4,5,5,6], 4), 4); @@ -68,4 +7,4 @@ function test() { assert.equal(findKthLargest([], 1), undefined); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js b/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js index 9573e63..ff699d8 100644 --- a/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js +++ b/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js @@ -1,66 +1,6 @@ -/* -Linked List Cycle -https://leetcode.com/problems/linked-list-cycle-ii/description/ - -Given a linked list, return the node where the cycle begins. If there is no cycle, return null. - -Note: Do not modify the linked list. - -Follow up: -Can you solve it without using extra space? -*/ const assert = require('assert'); var ListNode = require('../UtilsClasses/ListNode').ListNode; -// Optimal solution -/** -* @param {ListNode} head -* @return {ListNode} -*/ -var detectCycle = function(head) { - if (head === null) - return null; - - var slow = head; - var fast = head; - - while(fast.next !== null && fast.next.next !== null) { - slow = slow.next; - fast = fast.next.next; - if(fast == slow) { - var a = head; - var b = slow; - while(a !== b) { - a = a.next; - b = b.next; - } - return a; - } - } - return null; -}; - -// Naiver solution using a Set -var detectCycle2 = function(head) { - if(head === null || head.next === null) { - return null; - } - var setNodes = new Set(); - var iter = head; - while(iter !== null) { - if(setNodes.has(iter)) { - return iter; - } - setNodes.add(iter); - iter = iter.next - } - return null; -}; - -var main = function() { - test(); -} - var test = function() { const cycle = buildCycle(); var list = cycle.list; @@ -87,4 +27,4 @@ function buildCycle() { }; } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js b/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js index 290d9ea..da2663b 100644 --- a/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js +++ b/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js @@ -1,63 +1,5 @@ -/* -Longest Consecutive Sequence -https://leetcode.com/problems/longest-consecutive-sequence/ - -Given an unsorted array of integers, find the length of the longest consecutive elements sequence. - -Your algorithm should run in O(n) complexity. - -Example: - -Input: [100, 4, 200, 1, 3, 2] -Output: 4 -Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. -*/ const assert = require('assert'); -/** - * @param {number[]} nums - * @return {number} - */ -var longestConsecutive = function(nums) { - if(nums.length === 0) - return 0; - var setNums = new Set(); - for(var i = 0; i < nums.length; i++) - setNums.add(nums[i]); - - var cons = 1; - var currentCons = 1; - for(var i = 0; i < nums.length; i++) { - var number = nums[i]; - if(setNums.has(number)) { - setNums.delete(number); - - var prevNum = number - 1; - while(setNums.has(prevNum)){ - currentCons++; - setNums.delete(prevNum); - prevNum--; - } - - var nextNum = number + 1; - while(setNums.has(nextNum)){ - currentCons++; - setNums.delete(nextNum); - nextNum++; - } - - if(currentCons > cons) - cons = currentCons - } - currentCons = 1; - } - return cons; -}; - -var main = function() { - test(); -} - function test() { assert.equal(longestConsecutive([100, 1, 200, 3, 2, 400, 201]), 3); assert.equal(longestConsecutive([1,2,3,4, 100, 1, 200, 3, 2, 400, 201]), 4); @@ -66,4 +8,4 @@ function test() { assert.equal(longestConsecutive([2]), 1); } -module.exports.main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js b/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js index 74a2447..39a92bf 100644 --- a/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js +++ b/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js @@ -1,73 +1,5 @@ -/* -Longest Palindromic Substring -https://leetcode.com/problems/longest-palindromic-substring/description/ - -Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. - -Example 1: - -Input: "babad" -Output: "bab" -Note: "aba" is also a valid answer. -Example 2: - -Input: "cbbd" -Output: "bb" -*/ const assert = require('assert'); -/** - * @param {string} s - * @return {string} - */ -var longestPalindrome = function(str) { - if(str.length == 0) - return ""; - - var maxPal = 1; - var posPalStart = 0; - var currentPalStart = 0; - - for(var i = 1; i < str.length; i++) { - if(str.charAt(i - 1) == str.charAt(i)) { - currentPalStart = i - 1; - var currentPal = 2; - var iter = 1; - while(i - iter - 1 >= 0 && i + iter < str.length && str.charAt(i - iter - 1) == str.charAt(i + iter)) { - currentPalStart = i - iter - 1; - iter++; - currentPal += 2; - } - } - if(currentPal > maxPal) { - maxPal = currentPal; - posPalStart = currentPalStart; - } - } - - for(var i = 1; i < str.length - 1; i++) { - if(str.charAt(i - 1) == str.charAt(i + 1)) { - currentPal = 1; - var iter = 1; - while(i - iter >= 0 && i + iter < str.length && str.charAt(i - iter) == str.charAt(i + iter)) { - currentPalStart = i - iter; - iter++; - currentPal += 2; - } - } - if(currentPal > maxPal) { - maxPal = currentPal; - posPalStart = currentPalStart; - } - } - - return str.slice(posPalStart, posPalStart + maxPal); -} - -var main = function() { - test(); -} - function test() { assert.equal(longestPalindrome("pabcdcbte"), "bcdcb"); assert.equal(longestPalindrome("bb"), "bb"); @@ -77,4 +9,4 @@ function test() { assert.equal(longestPalindrome("ptabbbbat"), "tabbbbat"); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js b/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js index c4f0168..e59d26f 100644 --- a/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js +++ b/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js @@ -1,101 +1,9 @@ -/* -Lowest Common Ancestor of a Binary Tree -https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ - -Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. - -According to the definition of LCA on Wikipedia: -“The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants -(where we allow a node to be a descendant of itself).” - -Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4] - - _______3______ - / \ - ___5__ ___1__ - / \ / \ - 6 _2 0 8 - / \ - 7 4 -Example 1: - -Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 -Output: 3 -Explanation: The LCA of nodes 5 and 1 is 3. -Example 2: - -Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 -Output: 5 -Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself - according to the LCA definition. -Note: - -All of the nodes' values will be unique. -p and q are different and both values will exist in the binary tree. -*/ const assert = require('assert'); - var TreeNode = require('../UtilsClasses/TreeNode').TreeNode; -// Solution 1 -var lowestCommonAncestor = function(root, p, q) { - if(root === null) - return root; - if(p.val === root.val) - return p; - if(q.val === root.val) - return q; - - const left = lowestCommonAncestor(root.left, p, q); - const right = lowestCommonAncestor(root.right, p, q); - if(left !== null && right !== null) - return root; - return left !== null ? left : right; -}; - -// Solution 2 -var lowestCommonAncestor2 = function(root, p, q) { - var pathToP = pathTo(root, p.val); - var pathToQ = pathTo(root, q.val); - - if(pathToP.length === 0 || pathToQ === 0) - return null; - - var iter = 0; - while(iter < pathToP.length - 1 && iter < pathToQ.length - 1 && pathToP[iter + 1] === pathToQ[iter + 1]) { - if(root.left !== null && root.left.val === pathToP[iter + 1]) { - root = root.left; - } else { - root = root.right; - } - iter++; - } - - return root; -}; - -var pathTo = function(root, value) { - if(root === null) - return []; - - var list = [root.val]; - if(root.val === value) - return list; - - const left = pathTo(root.left, value); - if (left.length > 0) - return list.concat(left); - - const right = pathTo(root.right, value); - if(right.length > 0) - return list.concat(right); - - return []; -} - -var main = function() { +var test = function() { var root = new TreeNode(3); - + var right = new TreeNode(1); right.left = new TreeNode(0); right.right = new TreeNode(8); @@ -126,4 +34,4 @@ var main = function() { console.log(lowestCommonAncestor2(root, left, right)); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Majority_Element_Test.js b/LeetcodeProblemsTests/Majority_Element_Test.js index f1114f8..8ca4a3e 100644 --- a/LeetcodeProblemsTests/Majority_Element_Test.js +++ b/LeetcodeProblemsTests/Majority_Element_Test.js @@ -1,58 +1,9 @@ -/* -Majority Element -https://leetcode.com/problems/majority-element/ - -Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. - -You may assume that the array is non-empty and the majority element always exist in the array. - -Example 1: - -Input: [3,2,3] -Output: 3 -Example 2: - -Input: [2,2,1,1,1,2,2] -Output: 2 - -Note: You should have a better solution than O(N) -*/ const assert = require('assert'); -/** - * @param {number[]} nums - * @return {number} - */ -var majorityElement = function(nums) { - if(nums.length === 0) - return -1; - - var candidate = nums[0]; - var proves = 1; - - for(var i = 1; i < nums.length; i++) { - if(nums[i] === candidate) - proves++; - else { - proves--; - if(proves === 0) { - candidate = nums[i]; - proves = 1; - } - } - } - - return candidate; -}; - -var main = function() { - test(); -} - function test() { assert.equal(majorityElement([2,2,3]), 2); assert.equal(majorityElement([2,3,2]), 2); assert.equal(majorityElement([1,1,1,2,3,45,1,2,4,1,1]), 1); } -module.exports.main = main +module.exports.test = test diff --git a/LeetcodeProblemsTests/Maximal_Square_Test.js b/LeetcodeProblemsTests/Maximal_Square_Test.js index 014d4a8..e76fd04 100644 --- a/LeetcodeProblemsTests/Maximal_Square_Test.js +++ b/LeetcodeProblemsTests/Maximal_Square_Test.js @@ -1,74 +1,5 @@ -/* -Maximal Square -https://leetcode.com/problems/maximal-square/ - -Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. - -Example: - -Input: - -1 0 1 0 0 -1 0 1 1 1 -1 1 1 1 1 -1 0 0 1 0 - -Output: 4 -*/ const assert = require('assert'); -/** - * @param {character[][]} matrix - * @return {number} - */ -var maximalSquare = function(matrix) { - var maxSquare = 0; - for(var i = 0; i < matrix.length; i++) { - for(var j = 0; j < matrix[0].length; j++) { - if(matrix[i][j] === "1") { // found a 1 - const currentMaxSideLength = getCurrentMaxSideLength(matrix, i, j); - if(currentMaxSideLength ** 2 > maxSquare) - maxSquare = currentMaxSideLength ** 2; - } - } - } - - return maxSquare; -}; - -var getCurrentMaxSideLength = function(matrix, i, j) { - var max = 1; - while(i + max < matrix.length && j + max < matrix[0].length) { - var lastRow = i + max; - var lastCol = j + max; - - // check last column - var iterRow = i; - while(iterRow <= lastRow){ - if(matrix[iterRow][lastCol] === "0") - return max; - - iterRow++; - } - - // check last row - var iterCol = j; - while(iterCol <= lastCol) { - if(matrix[lastRow][iterCol] === "0") - return max; - iterCol++; - } - - max++; - } - - return max; -} - -var main = function() { - test(); -} - function test() { assert.equal(maximalSquare([["1","0"]]), 1); assert.equal(maximalSquare([["1"]]), 1); @@ -79,4 +10,4 @@ function test() { ); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Maximun_Subarray_Test.js b/LeetcodeProblemsTests/Maximun_Subarray_Test.js index c159a43..5f2e552 100644 --- a/LeetcodeProblemsTests/Maximun_Subarray_Test.js +++ b/LeetcodeProblemsTests/Maximun_Subarray_Test.js @@ -1,43 +1,5 @@ -/* -Maximum Subarray -https://leetcode.com/problems/maximum-subarray - -Given an integer array nums, find the contiguous subarray (containing at least one number) -which has the largest sum and return its sum. - -Example: - -Input: [-2,1,-3,4,-1,2,1,-5,4], -Output: 6 -Explanation: [4,-1,2,1] has the largest sum = 6. -Follow up: - -*/ const assert = require('assert'); -var maxSubArray = function(nums) { - if(nums.length == 0) - return 0; - var maxSub = nums[0]; - var currentMax = nums[0]; - - for(var i = 1; i < nums.length; i++) { - currentMax = max(nums[i], currentMax + nums[i]); - if(currentMax > maxSub) - maxSub = currentMax; - } - - return maxSub; -}; - -var max = function(i, j) { - return (i > j) ? i : j; -} - -var main = function() { - test(); -} - function test() { assert.equal(maxSubArray([]), 0); assert.equal(maxSubArray([-4]), -4); @@ -45,4 +7,4 @@ function test() { assert.equal(maxSubArray([4,1,-1,4,5,6,7,-200]), 26); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Min_Stack_Test.js b/LeetcodeProblemsTests/Min_Stack_Test.js index 3ee0f78..d4a52e0 100644 --- a/LeetcodeProblemsTests/Min_Stack_Test.js +++ b/LeetcodeProblemsTests/Min_Stack_Test.js @@ -1,83 +1,5 @@ -/* -Min Stack - -https://leetcode.com/problems/min-stack/description/ - -Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. - -push(x) -- Push element x onto stack. -pop() -- Removes the element on top of the stack. -top() -- Get the top element. -getMin() -- Retrieve the minimum element in the stack. -Example: -MinStack minStack = new MinStack(); -minStack.push(-2); -minStack.push(0); -minStack.push(-3); -minStack.getMin(); --> Returns -3. -minStack.pop(); -minStack.top(); --> Returns 0. -minStack.getMin(); --> Returns -2. -*/ const assert = require('assert'); -class MinStack { - constructor() { - this.minStack = []; - this.stack = []; - this.countStack = 0; - this.countMinStack = 0; - } - - push(value) { - if(this.countStack === this.stack.length) - this.stack.push(value); - else - this.stack[this.countStack] = value; - this.countStack++; - - const min = this.getMin(); - if(min === null || min >= value) { - if(this.countMinStack === this.minStack.length) - this.minStack.push(value); - else - this.minStack[this.countMinStack] = value; - this.countMinStack++; - } - } - - pop() { - if(this.countStack === 0) - return null; - - var elem = this.stack[this.countStack - 1]; - this.countStack--; - - if(elem === this.minStack[this.countMinStack - 1]) - this.countMinStack--; - - return elem; - } - - top() { - if(this.countStack === 0) - return null; - - return this.stack[this.countStack - 1]; - } - - getMin() { - if(this.countMinStack === 0) - return null; - - return this.minStack[this.countMinStack - 1] - } -} - -var main = function() { - test(); -} - function test() { var minStack = new MinStack(); minStack.push(-2); @@ -89,4 +11,4 @@ function test() { assert.equal(minStack.getMin(), -2); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js b/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js index 2769963..f6ef8b6 100644 --- a/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js +++ b/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js @@ -1,73 +1,5 @@ -/* -Minimum Window Substring -https://leetcode.com/problems/minimum-window-substring/ - -Given a string S and a string T, find the minimum window in S which will contain all the characters in T -in complexity O(n). - -Example: - -Input: S = "ADOBECODEBANC", T = "ABC" -Output: "BANC" -Note: - -If there is no such window in S that covers all characters in T, return the empty string "". -If there is such window, you are guaranteed that there will always be only one unique minimum window in S. -*/ const assert = require('assert'); -var minWindow = function(s, t) { - if(t.length === 0 || s.length < t.length) - return ""; - - var start = 0; - var end = 0; - var solutionStart, solutionEnd; - var hashT = getHash(t); - var currentHash = {}; - var currentCount = 0; - while(end < s.length) { - const letter = s.charAt(end); - if(hashT[letter]) { - currentHash[letter] = (currentHash[letter]) ? currentHash[letter] + 1 : 1; - if(currentHash[letter] <= hashT[letter]) - currentCount++; - if(currentCount === t.length) { - while(hashT[s[start]] === undefined || currentHash[s[start]] > hashT[s[start]]) { - if(currentHash[s[start]] !== undefined) - currentHash[s[start]] = currentHash[s[start]] - 1; - - start++; - } - if(solutionEnd === undefined || end - start < solutionEnd - solutionStart) { - solutionStart = start; - solutionEnd = end; - } - - currentHash[s[start]] = currentHash[s[start]] - 1; - start++; - currentCount--; - } - } - end++; - } - - return s.slice(solutionStart, solutionEnd + 1); -}; - -var getHash = function(t) { - var hash = {}; - for(var i = 0; i < t.length; i++) { - const letter = t.charAt(i); - hash[letter] = (hash[letter]) ? hash[letter] + 1 : 1; - } - return hash; -} - -var main = function() { - test(); -} - function test() { assert.equal(minWindow("ADOBECODEBANC", "ABC"), "BANC"); assert.equal(minWindow("caaec", "cae"), "aec"); @@ -77,4 +9,4 @@ function test() { assert.equal(minWindow("abba", ""), ""); } -module.exports.main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/NQueens_Test.js b/LeetcodeProblemsTests/NQueens_Test.js index f78d3b8..68d3653 100644 --- a/LeetcodeProblemsTests/NQueens_Test.js +++ b/LeetcodeProblemsTests/NQueens_Test.js @@ -1,84 +1,11 @@ -/* -NQueens -https://leetcode.com/problems/n-queens/description/ - -Example: - -Input: 4 -Output: [ - [".Q..", // Solution 1 - "...Q", - "Q...", - "..Q."], - - ["..Q.", // Solution 2 - "Q...", - "...Q", - ".Q.."] -] -Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above. -*/ const assert = require('assert'); -/** - * @param {number} n - * @return {string[][]} - */ -var solveNQueens = function(n) { - var sol = []; - solveNQueensAux(n, 0, new Set(), new Set(), new Set(), [], sol); - return parseSolutions(sol, n); -}; - -var solveNQueensAux = function(n, row, diagonalDiffs, diagonalSums, cols, currentSol, sol) { - if(row == n) { - sol.push(currentSol); - return; - } - - for(var i = 0; i < n; i++) { - const diagonalDiff = i - row; - const diagonalSum = i + row; - if(!diagonalDiffs.has(diagonalDiff) && !cols.has(i) && !diagonalSums.has(diagonalSum)) { - diagonalDiffs.add(diagonalDiff); - diagonalSums.add(diagonalSum); - cols.add(i); - solveNQueensAux(n, row + 1, diagonalDiffs, diagonalSums, cols, [...currentSol, ...[[row, i]]], sol); - cols.delete(i); - diagonalDiffs.delete(diagonalDiff); - diagonalSums.delete(diagonalSum); - } - } -} - -var parseSolutions = function(sols, n) { - var matrixes = []; - for(var i = 0; i < sols.length; i++) { - var sol = sols[i]; - var matrix = []; - for(var row = 0; row < n; row++) { - matrix[row] = [] - const queenPos = sol[row]; - for(var col = 0; col < n; col++) { - matrix[row] += (queenPos[1] == col) ? "Q" : "."; - } - } - - matrixes.push(matrix); - } - - return matrixes; -} - -var main = function(n) { +var test = function() { printMatrixes(solveNQueens(4), 4); printMatrixes(solveNQueens(5), 5); printMatrixes(solveNQueens(6), 6); } -var test = function() { -} - var printMatrixes = function(matrixes, n) { console.log("Start solution of n: " + n); for(var i = 0; i < matrixes.length; i++) { @@ -95,4 +22,4 @@ var printMatrix = function(matrix) { console.log("------------"); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Number_of_Islands_Test.js b/LeetcodeProblemsTests/Number_of_Islands_Test.js index 248ea49..e91364a 100644 --- a/LeetcodeProblemsTests/Number_of_Islands_Test.js +++ b/LeetcodeProblemsTests/Number_of_Islands_Test.js @@ -1,70 +1,5 @@ -/* -Number of Islands -https://leetcode.com/problems/number-of-islands/ - -Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and -is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. - -Example 1: - -Input: -11110 -11010 -11000 -00000 - -Output: 1 -Example 2: - -Input: -11000 -11000 -00100 -00011 - -Output: 3 -*/ const assert = require('assert'); -/* - * @param {character[][]} grid - * @return {number} - */ -var numIslands = function(grid) { - if(grid.length === 0) - return 0; - - var countIslands = 0; - const rowsCount = grid.length; - const columnsCount = grid[0].length; - for(var i = 0; i < rowsCount; i++) { - for(var j = 0; j < columnsCount; j++) { - if(grid[i][j] == 1) { - countIslands++; - colorIsland(grid, i, j, rowsCount, columnsCount); - } - } - } - - return countIslands; -}; - -var colorIsland = function(grid, i, j, rowsCount, columnsCount) { - if(i < 0 || j < 0 || i >= rowsCount || j >= columnsCount || grid[i][j] == 0) - return; - - grid[i][j] = 0; - - colorIsland(grid, i - 1, j, rowsCount, columnsCount); - colorIsland(grid, i + 1, j, rowsCount, columnsCount); - colorIsland(grid, i, j - 1, rowsCount, columnsCount); - colorIsland(grid, i, j + 1, rowsCount, columnsCount); -} - -var main = function() { - test(); -} - function test() { assert.equal(numIslands([[1]]), 1); assert.equal(numIslands([]), 0); @@ -80,4 +15,4 @@ function test() { ); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js b/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js index a6c367a..287dd43 100644 --- a/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js +++ b/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js @@ -1,42 +1,5 @@ -/* -Number of Segments in a String -https://leetcode.com/problems/number-of-segments-in-a-string/description/ - -Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. - -Please note that the string does not contain any non-printable characters. - -Example: - -Input: "Hello, my name is John" -Output: 5 -*/ const assert = require('assert'); -/** - * @param {string} s - * @return {number} - */ -var countSegments = function(s) { - var count = 0; - var i = 0; - - while(i < s.length) { - if(s[i] !== " ") { - count++; - while(i < s.length && s[i] !== " ") - i++; - } - i++; - } - - return count; -}; - -function main() { - test(); -} - function test() { assert.equal(countSegments(" "), 0); assert.equal(countSegments(" "), 0); @@ -46,4 +9,4 @@ function test() { assert.equal(countSegments(" ab cd ef "), 3); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Permutations_II_Test.js b/LeetcodeProblemsTests/Permutations_II_Test.js index 22093fe..ce3398c 100644 --- a/LeetcodeProblemsTests/Permutations_II_Test.js +++ b/LeetcodeProblemsTests/Permutations_II_Test.js @@ -1,55 +1,5 @@ -/* -Permutations II -https://leetcode.com/problems/permutations-ii/ - -Given a collection of numbers that might contain duplicates, return all possible unique permutations. - -Example: - -Input: [1,1,2] -Output: -[ - [1,1,2], - [1,2,1], - [2,1,1] -] -*/ const assert = require('assert'); -var permuteUnique = function(nums) { - var map = {}; - for(var i = 0; i < nums.length; i++) { - var value = nums[i]; - map[value] = (map[value]) ? map[value] + 1 : 1; - } - - return permuteUniqueAux(nums.length, map, []); -}; - -var permuteUniqueAux = function(n, map, currentSol) { - if(currentSol.length === n) { - return [currentSol]; - } - - var ret = []; - for(var num in map) { - const occ = map[num]; - if(occ === 1) { - delete map[num]; - } else { - map[num] = occ -1 ; - } - ret = [...ret, ...permuteUniqueAux(n, map, currentSol.concat(num))]; - map[num] = occ; - } - - return ret; -}; - -var main = function() { - test(); -} - function test() { assert.deepEqual( permuteUnique([1,1,2]), @@ -73,8 +23,7 @@ function test() { ] ); assert.deepEqual(permuteUnique([]), [ [] ]); - assert.deepEqual(permuteUnique([1,1]), [ [ '1', '1' ] ]); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Permutations_Test.js b/LeetcodeProblemsTests/Permutations_Test.js index f04f128..60fc82e 100644 --- a/LeetcodeProblemsTests/Permutations_Test.js +++ b/LeetcodeProblemsTests/Permutations_Test.js @@ -1,49 +1,6 @@ -/* -Permutations -https://leetcode.com/problems/permutations/ - -Given a collection of distinct integers, return all possible permutations. - -Example: - -Input: [1,2,3] -Output: -[ - [1,2,3], - [1,3,2], - [2,1,3], - [2,3,1], - [3,1,2], - [3,2,1] -] -*/ const assert = require('assert'); -var permute = function(nums) { - return permuteAux(nums, 0, [], new Set()); -}; - -var permuteAux = function(nums, pos, currentSol, set) { - if(pos === nums.length) { - return [currentSol]; - } - var ret = []; - for(var i = 0; i < nums.length; i++) { - if(!set.has(nums[i])) { - set.add(nums[i]) - var sol = permuteAux(nums, pos + 1, currentSol.concat(nums[i]), set); - ret = [...ret, ...sol]; - set.delete(nums[i]); - } - } - return ret; -} - -var main = function() { test(); -} - function test() { - // assert.deepEqual( assert.deepEqual(permute([]), [ [] ]); assert.deepEqual(permute([1]), [ [ 1 ] ]); assert.deepEqual( @@ -59,4 +16,4 @@ function test() { ); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js b/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js index e9fccc5..fc3a74e 100644 --- a/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js +++ b/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js @@ -1,38 +1,5 @@ const assert = require('assert'); -// Permutations without -var subsetWithoutDuplicates = function(nums) { - if(nums.lenght == 0){ - return; - } - var solution = []; - subsetWithoutDuplicatesAux(nums, [], solution); - return solution; -} - -var subsetWithoutDuplicatesAux = function(nums, current, sol) { - if(nums.length == 0){ - sol.push(current); - } - - var setNums = new Set(); - - nums.forEach((value, index) => { - if(setNums.has(value)) { - return; - } - setNums.add(value); - var newCurrent = [...current, value] - - var newNum = nums.filter(function(num, idx) { return index !== idx}); - subsetWithoutDuplicatesAux(newNum, newCurrent, sol); - }) -} - -function main() { - test(); -} - var test = function() { assert.deepEqual( subsetWithoutDuplicates([1,1,2,3]), @@ -52,5 +19,5 @@ var test = function() { ] ); } -main(); -module.exports.main = main; \ No newline at end of file + +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js b/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js index b5b0a1b..ad58586 100644 --- a/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js +++ b/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js @@ -1,50 +1,5 @@ -/* -Permutations withuot duplicates -https://leetcode.com/problems/permutations/description/ - -Given a collection of distinct integers, return all possible permutations. - -Example: - -Input: [1,2,3] -Output: -[ - [1,2,3], - [1,3,2], - [2,1,3], - [2,3,1], - [3,1,2], - [3,2,1] -] -*/ const assert = require('assert'); -// Permutations wihto -var subsetWithDuplicates = function(nums) { - if(nums.lenght == 0){ - return; - } - var solution = []; - subsetWithDuplicatesAux(nums, [], solution); - return solution; -} - -var subsetWithDuplicatesAux = function(nums, current, sol) { - if(nums.length == 0){ - sol.push(current); - } - - for(var i = 0; i < nums.length; i++) { - var newCurrent = [...current, nums[i]] - var newNums = nums.filter(function(num, index) { return index !== i }); - subsetWithDuplicatesAux(newNums, newCurrent, sol); - } -} - -function main() { - test(); -} - var test = function() { assert.deepEqual( subsetWithDuplicates([1,2,3]), @@ -59,4 +14,4 @@ var test = function() { ); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js b/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js index 3aaedf0..480dddc 100644 --- a/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js +++ b/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js @@ -1,100 +1,6 @@ -/* -Regular Expression Matching -https://leetcode.com/problems/regular-expression-matching/description/ - -Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. - -'.' Matches any single character. -'*' Matches zero or more of the preceding element. -The matching should cover the entire input string (not partial). - -Note: - -s could be empty and contains only lowercase letters a-z. -p could be empty and contains only lowercase letters a-z, and characters like . or *. -Example 1: - -Input: -s = "aa" -p = "a" -Output: false -Explanation: "a" does not match the entire string "aa". -Example 2: - -Input: -s = "aa" -p = "a*" -Output: true -Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa". -Example 3: - -Input: -s = "ab" -p = ".*" -Output: true -Explanation: ".*" means "zero or more (*) of any character (.)". -Example 4: - -Input: -s = "aab" -p = "c*a*b" -Output: true -Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab". -Example 5: - -Input: -s = "mississippi" -p = "mis*is*p*." -Output: false - - * @param {*} s - * @param {*} p - */ const assert = require('assert'); -var isMatch = function(s, p) { - return isMatchAux(s, p, 0, 0); -}; - -var isMatchAux = function(str, pattern, posStr, posPat) { - if(posStr == str.length) - return posPat == pattern.length || canBeZero(pattern, posPat); - - if(posPat < pattern.length - 1 && pattern.charAt(posPat + 1) == "*") { - const valuePattern = pattern.charAt(posPat); - posPat = posPat + 2; - - if (isMatchAux(str, pattern, posStr, posPat)) { // 0 matches - return true - } - - while(posStr < str.length && (str.charAt(posStr) === valuePattern || valuePattern === ".")) { - if(isMatchAux(str, pattern, posStr + 1, posPat)) { - return true; - } - posStr++; - } - } else if(str.charAt(posStr) === pattern.charAt(posPat) || pattern.charAt(posPat) === ".") { - return isMatchAux(str, pattern, posStr + 1, posPat + 1); - } - - return false; -} - -var canBeZero = function(pattern, posPat) { - while(posPat < pattern.length && pattern.charAt(posPat) == "*" || - posPat < pattern.length - 1 && pattern.charAt(posPat + 1) == "*") { - posPat++; - } - - return posPat == pattern.length; -} - -var main = function(){ - test(); -} - -var test = function(n) { +var test = function() { assert.equal(isMatch("aa", "a"), false); assert.equal(isMatch("aa", "a*"), true); assert.equal(isMatch("a","ab*"), true); @@ -103,4 +9,4 @@ var test = function(n) { assert.equal(isMatch("mississippi", "mis*is*p*."), false); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js b/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js index fdb4fab..477802d 100644 --- a/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js +++ b/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js @@ -1,84 +1,10 @@ -/* -Remove Invalid Parentheses -https://leetcode.com/problems/remove-invalid-parentheses/ - -Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results. - -Note: The input string may contain letters other than the parentheses ( and ). - -Example 1: - -Input: "()())()" -Output: ["()()()", "(())()"] -Example 2: - -Input: "(a)())()" -Output: ["(a)()()", "(a())()"] -Example 3: - -Input: ")(" -Output: [""] -*/ const assert = require('assert'); -/** - * @param {string} s - * @return {string[]} - */ -var removeInvalidParentheses = function(s) { - var queue = []; - var visited = new Set(); - queue.push(s); - var result = []; - var found = false; - - while(queue.length !== 0) { - var str = queue.shift(); - if(isValid(str)) { - result.push(str); - found = true; - } else if(!found){ - for(var i = 0; i < s.length; i++) { - if(str[i] === "(" || str[i] === ")") { - var subStr = str.slice(0, i) + str.slice(i + 1, s.length); - if(!visited.has(subStr)) { - queue.push(subStr); - visited.add(subStr); - } - } - } - } - } - - return result; -}; - -var isValid = function(s) { - var leftCount = 0; - var iter = 0; - while(iter < s.length) { - if(s[iter] === "(") - leftCount++; - else if(s[iter] === ")") { - leftCount--; - if(leftCount < 0) - return false; - } - iter++; - } - - return leftCount === 0; -} - -var main = function() { - test(); -} - -var test = function(n) { +var test = function() { assert.equal(removeInvalidParentheses("))))(()"), "()"); assert.equal(removeInvalidParentheses("(()"), "()"); assert.equal(removeInvalidParentheses("(d))()"), "(d)()"); assert.equal(removeInvalidParentheses("(())"), "(())"); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js b/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js index 2394963..5bcc3d2 100644 --- a/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js +++ b/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js @@ -1,53 +1,8 @@ -/* -Restore IP Addresses -https://leetcode.com/problems/restore-ip-addresses/description/ - -Given a string containing only digits, restore it by returning all possible valid IP address combinations. - -Example: - -Input: "25525511135" -Output: ["255.255.11.135", "255.255.111.35"] -*/ const assert = require('assert'); -var restoreIpAddresses = function(s) { - var restore = restoreInputBits("", s, 4); - - var ret = []; - for(var i = 0; i < restore.length; i++) { - ret.push(restore[i].join(".")); - } - - return ret; -}; - -var restoreInputBits = function(partial, s, num) { - if(s.length == 0 && num == 0 ) - return [partial]; - if(s.length < num || s.length > num * 3 || num == 0) - return []; - - const oneNum = restoreInputBits([...partial, s.slice(0, 1)], s.slice(1), num - 1); - - if(s.length === 1 || s.slice(0, 1) === "0") - return oneNum - - const twoNums = restoreInputBits([...partial, s.slice(0, 2)], s.slice(2), num - 1); - if(s.length === 2 || s.slice(0, 3) > 255) - return [...oneNum, ...twoNums] - - const threeNums = restoreInputBits([...partial, s.slice(0, 3)], s.slice(3), num - 1); - return [...oneNum, ...twoNums, ...threeNums]; -} - -var main = function() { - test(); -} - -var test = function(n) { +var test = function() { assert.deepEqual(restoreIpAddresses("010010"), [ '0.10.0.10', '0.100.1.0']); assert.deepEqual(restoreIpAddresses("25525511135"), [ '255.255.11.135', '255.255.111.35' ]); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Reverse_String_II_Test.js b/LeetcodeProblemsTests/Reverse_String_II_Test.js index d277483..685faba 100644 --- a/LeetcodeProblemsTests/Reverse_String_II_Test.js +++ b/LeetcodeProblemsTests/Reverse_String_II_Test.js @@ -1,53 +1,10 @@ -/* -Reverse String II -https://leetcode.com/problems/reverse-string-ii/description/ - -Given a string and an integer k, you need to reverse the first k characters for every 2k characters counting from the start of the string. If there are less than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original. -Example: -Input: s = "abcdefg", k = 2 -Output: "bacdfeg" -Restrictions: -The string consists of lower English letters only. -Length of the given string and k will in the range [1, 10000] -*/ const assert = require('assert'); -var reverseStr = function(s, k) { - if(k <= 1) - return s; - var ret = ""; - for(var iterK = 0; iterK * k < s.length; iterK = iterK + 2) { - const start = iterK * k; - const end = start + k - 1; - - ret += reverse(s, start, end); - ret += s.slice(end + 1, k * (iterK + 2)); - } - - return ret; -}; - -var reverse = function(s, start, end) { - var ret = ""; - if(end >= s.length) - end = s.length - 1; - - while(start <= end) { - ret += s.charAt(end); - end--; - } - return ret; -} - -var main = function(){ - test(); -} - -var test = function(n) { +var test = function() { assert.equal(reverseStr("abcdefg", 2), "bacdfeg"); assert.equal(reverseStr("abcdefg", 3), "cbadefg"); assert.equal(reverseStr("abcdefg", 1), "abcdefg"); assert.equal(reverseStr("abcdefg", 0), "abcdefg"); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Same_Tree_Test.js b/LeetcodeProblemsTests/Same_Tree_Test.js index 31b8664..ea8b26b 100644 --- a/LeetcodeProblemsTests/Same_Tree_Test.js +++ b/LeetcodeProblemsTests/Same_Tree_Test.js @@ -1,57 +1,5 @@ -/* -Same Tree -https://leetcode.com/problems/same-tree/description/ +var test = function() { + // TODO +} -Given two binary trees, write a function to check if they are the same or not. -Two binary trees are considered the same if they are structurally identical and the nodes have the same value. - -Example 1: - -Input: 1 1 - / \ / \ - 2 3 2 3 - - [1,2,3], [1,2,3] - -Output: true -Example 2: - -Input: 1 1 - / \ - 2 2 - - [1,2], [1,null,2] - -Output: false -Example 3: - -Input: 1 1 - / \ / \ - 2 1 1 2 - - [1,2,1], [1,1,2] - -Output: false -*/ - -/** - * Definition for a binary tree node. - * function TreeNode(val) { - * this.val = val; - * this.left = this.right = null; - * } - */ -/** - * @param {TreeNode} p - * @param {TreeNode} q - * @return {boolean} - */ -var isSameTree = function(p, q) { - if(p === null) - return q === null; - - if(q === null || p.val !== q.val) - return false; - - return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); -}; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js b/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js index d095215..45c4485 100644 --- a/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js +++ b/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js @@ -1,65 +1,7 @@ -/* -Search in Rotated Sorted Array -https://leetcode.com/problems/search-in-rotated-sorted-array/ - -Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. -(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). - -You are given a target value to search. If found in the array return its index, otherwise return -1. - -You may assume no duplicate exists in the array. - -Your algorithm's runtime complexity must be in the order of O(log n). - -Example 1: - -Input: nums = [4,5,6,7,0,1,2], target = 0 -Output: 4 -Example 2: - -Input: nums = [4,5,6,7,0,1,2], target = 3 -Output: -1 - -*/ const assert = require('assert'); -/** - * @param {number[]} nums - * @param {number} target - * @return {number} - */ -var search = function(nums, target) { - return searchAux(nums, target, 0, nums.length -1); -}; - -var searchAux = function(nums, target, start, end) { - if (start > end) - return - 1; - var middle = Math.trunc((start + end) /2); - - if(nums[middle] == target) { - return middle; - } - - if(nums[middle] < nums[nums.length - 1]) { // right part sorted - if(nums[middle] < target && nums[nums.length - 1] >= target) { - return searchAux(nums, target, middle + 1, end); - } - return searchAux(nums, target, start, middle - 1); - } else { // left part sorted - if(nums[0] <= target && nums[middle] > target) { - return searchAux(nums, target, start, middle - 1); - } - return searchAux(nums, target, middle + 1, end); - } -} - -var main = function(n) { - test(); -} - var test = function() { assert.equal(search([4,5,6,7,0,1,2], 5), 1); } -main() -module.exports.main = main; + +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js b/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js index 7085dc3..e6eb870 100644 --- a/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js +++ b/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js @@ -1,64 +1,9 @@ -/* -Search a 2D Matrix II -https://leetcode.com/problems/search-a-2d-matrix-ii/description/ - -Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: -Integers in each row are sorted in ascending from left to right. -Integers in each column are sorted in ascending from top to bottom. -Example: - Consider the following matrix: - [ - [1, 4, 7, 11, 15], - [2, 5, 8, 12, 19], - [3, 6, 9, 16, 22], - [10, 13, 14, 17, 24], - [18, 21, 23, 26, 30] -] -Given target = 5, return true. -Given target = 20, return false. -*/ const assert = require('assert'); -/** -* @param {number[][]} matrix -* @param {number} target -* @return {boolean} -*/ -var searchMatrix = function(matrix, target) { - if (matrix.length == 0) - return false - var lastCol = matrix[0].length - 1; - var firstRow = 0; - - while(lastCol >= 0 && firstRow < matrix.length) { - if(matrix[firstRow][lastCol] == target) { - return true; - } else if(matrix[firstRow][lastCol] > target) { - lastCol--; - } else { - firstRow++; - } - } - - return false; -}; - -const matrix1 = [ - [1,4,7, 11,15], - [2,5,8, 12,19], - [3,6,9, 16,22], - [10,13,14, 17,24], - [18,21,23, 26,30] -]; - -var main = function(n) { - test(); -} - -var test = function(n) { +var test = function() { assert.equal(searchMatrix(matrix1, 5), true); assert.equal(searchMatrix(matrix1, 0), false); assert.equal(searchMatrix(matrix1, 15), true); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js b/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js index 0a0b835..7dbe29d 100644 --- a/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js +++ b/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js @@ -1,69 +1,6 @@ -/* -Search a 2D Matrix -https://leetcode.com/problems/search-a-2d-matrix/description/ - -Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: - -Integers in each row are sorted from left to right. -The first integer of each row is greater than the last integer of the previous row. -Example 1: - -Input: -matrix = [ - [1, 3, 5, 7], - [10, 11, 16, 20], - [23, 30, 34, 50] -] -target = 3 -Output: true -Example 2: - -Input: -matrix = [ - [1, 3, 5, 7], - [10, 11, 16, 20], - [23, 30, 34, 50] -] -target = 13 -Output: false -*/ const assert = require('assert'); -/** - * @param {number[][]} matrix - * @param {number} target - * @return {boolean} - */ -var searchMatrix = function(matrix, target) { - if(matrix.length === 0) - return false; - return searchMatrixAux(matrix, 0, matrix.length - 1, target); -}; - -var searchMatrixAux = function(matrix, firstRow, lastRow, target) { - if(firstRow === lastRow) { - var iter = 0; - while(iter < matrix[0].length) { - if(matrix[firstRow][iter] === target) - return true; - iter++; - } - } else { - var middle = Math.floor((firstRow + lastRow) / 2); // 0 - if(target > matrix[middle][matrix[0].length - 1]) - return searchMatrixAux(matrix, middle + 1, lastRow, target) - else - return searchMatrixAux(matrix, firstRow, middle, target) - } - - return false; -}; - -var main = function(){ - test(); -} - -var test = function(n) { +var test = function() { assert.equal(searchMatrix([], 0), false); assert.equal(searchMatrix([[1], [3]], 3), true); assert.equal(searchMatrix([[1], [3]], 1), true); @@ -71,4 +8,4 @@ var test = function(n) { assert.equal(searchMatrix(matrix, 3), true); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js b/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js index d92d8eb..6b628dc 100644 --- a/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js +++ b/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js @@ -1,119 +1,5 @@ -/* -Set Matrix Zeroes -https://leetcode.com/problems/set-matrix-zeroes/ - -Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. - -Example 1: - -Input: -[ - [1,1,1], - [1,0,1], - [1,1,1] -] -Output: -[ - [1,0,1], - [0,0,0], - [1,0,1] -] -Example 2: - -Input: -[ - [0,1,2,0], - [3,4,5,2], - [1,3,1,5] -] -Output: -[ - [0,0,0,0], - [0,4,5,0], - [0,3,1,0] -] -Follow up: - -A straight forward solution using O(mn) space is probably a bad idea. -A simple improvement uses O(m + n) space, but still not the best solution. -Could you devise a constant space solution? -*/ - const assert = require('assert'); -/** - * @param {number[][]} matrix - * @return {void} Do not return anything, modify matrix in-place instead. - */ -var setZeroes = function(matrix) { - if(matrix.length === 0) - return; - - var pivotRow = -1; - var pivotCol = -1; - var iterRow = 0; - var iterCol = 0; - var found = false; - - // Find a pivot - while(!found && iterRow < matrix.length) { - iterCol = 0; - while(!found && iterCol < matrix[0].length) { - if(matrix[iterRow][iterCol] === 0) { - found = true - pivotRow = iterRow; - pivotCol = iterCol; - } - iterCol++; - } - iterRow++; - } - - if (!found) - return; - - // Update the Column value - for(var i = 0; i < matrix.length; i++) { - if(i == pivotRow) - continue - for(var j = 0; j < matrix[0].length; j++) { - if(j == pivotCol) - continue; - if(matrix[i][j] === 0) { - matrix[i][pivotCol] = 0; - matrix[pivotRow][j] = 0; - } - } - } - - for(var i = 0; i < matrix.length; i++) - if(matrix[i][pivotCol] === 0 && i !== pivotRow) - fillRow(matrix, i); - - for(var i = 0; i < matrix[0].length; i++) - if(matrix[pivotRow][i] === 0 && i !== pivotCol) - fillCol(matrix, i); - - fillCol(matrix, pivotCol); - fillRow(matrix, pivotRow); - - return matrix; -}; - -var fillRow = function(matrix, row) { - for(var i = 0; i < matrix[0].length; i++) - matrix[row][i] = 0; -} - -var fillCol = function(matrix, col) { - for(var i = 0; i < matrix.length; i++) - matrix[i][col] = 0; -} - -var main = function() { - test(); -} - var test = function() { assert.deepEqual( setZeroes([[1,1,1],[1,0,1],[1,1,1]]), @@ -121,4 +7,4 @@ var test = function() { ); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Simplify_Path_Test.js b/LeetcodeProblemsTests/Simplify_Path_Test.js index fdb6d2f..f0f60a0 100644 --- a/LeetcodeProblemsTests/Simplify_Path_Test.js +++ b/LeetcodeProblemsTests/Simplify_Path_Test.js @@ -1,69 +1,5 @@ -/* -Simplify Path -https://leetcode.com/problems/simplify-path/description/ - -Given an absolute path for a file (Unix-style), simplify it. - -For example, -path = "/home/", => "/home" -path = "/a/./b/../../c/", => "/c" -path = "/a/../../b/../c//.//", => "/c" -path = "/a//b////c/d//././/..", => "/a/b/c" - -In a UNIX-style file system, a period ('.') refers to the current directory, so it can be ignored in a simplified path. Additionally, a double period ("..") moves up a directory, so it cancels out whatever the last directory was. For more information, look here: https://en.wikipedia.org/wiki/Path_(computing)#Unix_style - -Corner Cases: - -Did you consider the case where path = "/../"? -In this case, you should return "/". -Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". -In this case, you should ignore redundant slashes and return "/home/foo". -*/ const assert = require('assert'); -var simplifyPath = function(path) { - var queue = []; - var iter = path.length - 1; - while(iter >= 0) { - if(path.charAt(iter) === "/") { - iter--; - } else if(path.slice(iter - 1, iter + 1) == "/.") { - iter -= 2; - } else if(path.slice(iter - 2, iter + 1) === "/..") { - iter -= 3; - queue.unshift("/.."); - } else { // it's a characteriter - const endChars = iter; - while(iter >= 0 && path.charAt(iter) !== "/") { - iter--; - } - if(queue.length > 0 && queue[0] === "/..") { - queue.shift(); - } else { - queue.push("/" + path.slice(iter + 1, endChars + 1)); - } - } - } - var ret = ""; - - while(queue.length > 0) { - elem = queue.shift(); - if(elem == "/..") { - while(queue.length > 0 && queue.shift == "/..") { - elem += "/.."; - } - elem = (queue.length > 0) ? elem : ""; - } else { - ret = elem + ret; - } - } - return (ret.length == 0) ? "/" : ret; -}; - -var main = function(){ - test(); -} - var test = function() { assert.equal(simplifyPath("/../c"), "/c"); assert.equal(simplifyPath("/.."), "/"); @@ -73,4 +9,4 @@ var test = function() { assert.equal(simplifyPath("/a//b////c/d//././/.."), "/a/b/c") // => "/a/b/c" } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Spiral_Matrix_Test.js b/LeetcodeProblemsTests/Spiral_Matrix_Test.js index b3e293a..c8af84e 100644 --- a/LeetcodeProblemsTests/Spiral_Matrix_Test.js +++ b/LeetcodeProblemsTests/Spiral_Matrix_Test.js @@ -1,73 +1,6 @@ -/* -Spiral Matrix -https://leetcode.com/problems/spiral-matrix/description/ - -Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. - -Example 1: - -Input: -[ - [ 1, 2, 3 ], - [ 4, 5, 6 ], - [ 7, 8, 9 ] -] -Output: [1,2,3,6,9,8,7,4,5] -Example 2: - -Input: -[ - [1, 2, 3, 4], - [5, 6, 7, 8], - [9,10,11,12] -] -Output: [1,2,3,4,8,12,11,10,9,5,6,7] -*/ const assert = require('assert'); -/** - * @param {number[][]} matrix - * @return {number[]} - */ - -var spiralOrder = function(matrix) { - if(matrix.length === 0) - return []; - - var retArray = []; - const rowLength = matrix.length; - const colLength = matrix[0].length; - const countRectangles = Math.ceil(Math.min(colLength, rowLength)/2) - for(var i = 0; i < countRectangles; i++) - printRect(matrix, i, rowLength, colLength, retArray); - - return retArray; -}; - -var printRect = function(matrix, i, rowLength, colLength, retArray) { - const firstRow = i; - const firstCol = i; - const lastRow = rowLength - i - 1; - const lastCol = colLength - i - 1; - - for(var col = firstCol; col <= lastCol; col++) { - retArray.push(matrix[firstRow][col]); - } - for(var row = firstRow + 1; row <= lastRow; row++) { - retArray.push(matrix[row][lastCol]); - } - if(firstRow === lastRow || firstCol === lastCol) { - return; - } - for(var col = lastCol - 1; col >= firstCol; col--) { - retArray.push(matrix[lastRow][col]); - } - for(var row = lastRow - 1; row > firstRow; row--) { - retArray.push(matrix[row][firstCol]); - } -} - -var main = function() { +var test = function() { const matrix = [ [ 1, 2, 3 ], [ 4, 5, 6 ], @@ -80,4 +13,4 @@ var main = function() { ) } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js b/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js index 0f75e13..0c5e9d8 100644 --- a/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js +++ b/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js @@ -1,69 +1,5 @@ - -/* -Subarray Sum Equals K -https://leetcode.com/problems/subarray-sum-equals-k/ - -Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. - -Example 1: -Input:nums = [1,1,1], k = 2 -Output: 2 -Note: -The length of the array is in range [1, 20,000]. -The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. -*/ const assert = require('assert'); -/** - * @param {number[]} nums - * @param {number} k - * @return {number} - */ - - // Solution 1 -var subarraySum = function(nums, k) { - var ret = 0; - for(var i = 0; i < nums.length; i++) { - var count = 0; - for(var j = i; j < nums.length; j++) { - count += nums[j]; - if(count === k) - ret++; - } - } - - return ret; -}; - - -// Solution 2 -var subarraySum2 = function(nums, k) { - if(nums.length === 0) - return 0; - - var sums = []; - sums[0] = 0; - var count = 0; - for(var i = 0; i < nums.length; i++) { - count += nums[i]; - sums[i + 1] = count; - } - - var ret = 0; - for(var i = 0; i < sums.length - 1; i++) { - for(var j = i + 1; j < sums.length; j++) { - if(sums[j] - sums[i] === k) - ret++; - } - } - - return ret; -}; - -var main = function() { - test(); -} - var test = function() { assert.strictEqual(subarraySum([1,1,1], 2), 2); assert.strictEqual(subarraySum([1], 0), 0); @@ -71,4 +7,4 @@ var test = function() { assert.strictEqual(subarraySum([0,0,0,0,0], 0), 15); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Subsets_Test.js b/LeetcodeProblemsTests/Subsets_Test.js index 014ab43..aa0789d 100644 --- a/LeetcodeProblemsTests/Subsets_Test.js +++ b/LeetcodeProblemsTests/Subsets_Test.js @@ -1,47 +1,5 @@ -/* -Subsets -https://leetcode.com/problems/subsets/description/ - -Given a set of distinct integers, nums, return all possible subsets (the power set). - -Note: The solution set must not contain duplicate subsets. - -Example: - -Input: nums = [1,2,3] -Output: -[ - [3], - [1], - [2], - [1,2,3], - [1,3], - [2,3], - [1,2], - [] -] -*/ - const assert = require('assert'); -var subsets = function(nums) { - var ret = []; - - subsetByPosition = function (nums, position, current) { - if(position == nums.length) { - return [current]; - } - var currentRight = current.slice().concat([nums[position]]); - return subsetByPosition(nums, position + 1, currentRight).concat(subsetByPosition(nums, position + 1, current)); - } - - return subsetByPosition(nums, 0, []); -}; - -function main() { - test(); -} - function test() { assert.deepEqual(subsets([]), [[]]); assert.deepEqual(subsets([1]), [[1], []]); @@ -55,4 +13,4 @@ function test() { ); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js b/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js index 2146a45..09a2198 100644 --- a/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js +++ b/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js @@ -1,44 +1,5 @@ -/* -Sum of Square Numbers -https://leetcode.com/problems/sum-of-square-numbers/description/ - -Given a non-negative integer c, your task is to decide whether there're two integers a and b such that a2 + b2 = c. - -Example 1: -Input: 5 -Output: True -Explanation: 1 * 1 + 2 * 2 = 5 - -Example 2: -Input: 3 -Output: False -*/ - const assert = require('assert'); -/** - * @param {number} c - * @return {boolean} - */ -var judgeSquareSum = function(c) { - var iter = 0; - var set = new Set(); - while(iter ** 2 <= c) { - var square = iter * iter; - if(square * 2 === c || set.has(c - square)) - return true; - - set.add(square); - iter++; - } - - return false; -}; - -var main = function() { - test(); -} - var test = function() { assert.strictEqual(judgeSquareSum(0), true); assert.strictEqual(judgeSquareSum(1), true); @@ -48,5 +9,4 @@ var test = function() { assert.strictEqual(judgeSquareSum(25), true); } -module.exports.main = main; - +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js b/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js index 54c1faf..6e886d0 100644 --- a/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js +++ b/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js @@ -1,58 +1,7 @@ -/* -Swap Nodes in Pairs -https://leetcode.com/problems/swap-nodes-in-pairs/ - -Given a linked list, swap every two adjacent nodes and return its head. - -Example: - -Given 1->2->3->4, you should return the list as 2->1->4->3. -Note: - -Your algorithm should use only constant extra space. -You may not modify the values in the list's nodes, only nodes itself may be changed. -*/ const assert = require('assert'); const ListNode = require('../UtilsClasses/ListNode').ListNode; const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); -/** - * Definition for singly-linked list. - * function ListNode(val) { - * this.val = val; - * this.next = null; - * } - */ -/** - * @param {ListNode} head - * @return {ListNode} - */ -var swapPairs = function(head) { - if(head === null || head.next === null) - return head - var previous = null; - var current = head; - var following = (head.next != null) ? head.next.next : null; - head = head.next; - - while(current !== null && current.next !== null) { - var next = current.next; - next.next = current; - if(previous != null) - previous.next = next; - current.next = following; - previous = current; - current = following; - following = (current !== null && current.next != null) ? current.next.next : null; - } - - return head; -}; - -var main = function() { - test(); -} - var test = function () { ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1,2,3,4])), [2,1,4,3]); ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([])), []); @@ -60,4 +9,4 @@ var test = function () { ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1,2])), [2, 1]); } -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Symmetric_Tree_Test.js b/LeetcodeProblemsTests/Symmetric_Tree_Test.js index 76b365f..1805f10 100644 --- a/LeetcodeProblemsTests/Symmetric_Tree_Test.js +++ b/LeetcodeProblemsTests/Symmetric_Tree_Test.js @@ -1,51 +1,5 @@ -/* -Symmetric Tree -https://leetcode.com/problems/symmetric-tree/description/ +var test = function() { + // TODO +} -Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). - -For example, this binary tree [1,2,2,3,4,4,3] is symmetric: - - 1 - / \ - 2 2 - / \ / \ -3 4 4 3 -But the following [1,2,2,null,3,null,3] is not: - 1 - / \ - 2 2 - \ \ - 3 3 -Note: -Bonus points if you could solve it both recursively and iteratively. -*/ - -/** - * Definition for a binary tree node. - * function TreeNode(val) { - * this.val = val; - * this.left = this.right = null; - * } - */ - -/** - * @param {TreeNode} root - * @return {boolean} - */ -var isSymmetric = function(root) { - if(root === null) - return true; - return isSymetricAux(root.left, root.right); -}; - -var isSymetricAux = function(root1, root2) { - if(root1 === null) - return root2 === null; - - if(root2 === null || root1.val !== root2.val) { - return false; - } - - return isSymetricAux(root1.left, root2.right) && isSymetricAux(root1.right, root2.left); -} +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js b/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js index 363a14a..d2a3aff 100644 --- a/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js +++ b/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js @@ -1,86 +1,5 @@ - -class TicTacToe { - constructor() { - this.matrix = []; - for(var i = 0; i < 3; i++) { - this.matrix[i] = []; - for(var j = 0; j < 3; j++) { - this.matrix[i][j] = "-"; - } - } - }; - - validToken(token) { - if (token == "X" || token == "0" || token == "-") { - return true; - } - console.log("Token is invalid"); - return false; - } - - addToken(x, y, token) { - // Check valid positions - if(this.validToken(token)) { - this.matrix[x][y] = token; - } - }; - - printBoard() { - for(var row = 0; row < 3; row ++) { - console.log(this.matrix[row][0] + "|" - + this.matrix[row][1] + "|" - + this.matrix[row][2]); // Check new line; - } - } - - isBoardFull() { - for(var row = 0; row < 3; row ++) { - for(var col = 0; col < 3; col ++) { - if(this.matrix[row][col] === "-") { - console.log("Is not full"); - return false; - } - } - } - console.log("Is full"); - return true; - } - - makeMove() { - if(this.isBoardFull()) { - throw "Error Board is Full"; - } - for(var row = 0; row < 3; row ++) { - for(var col = 0; col < 3; col ++) { - if(this.matrix[row][col] === "-") { - this.addToken(row, col, "0"); - } - } - } - } +var test = function() { + // TODO } -var main = function() { - console.log("TBD"); -} - -module.exports.main = main; - -ticTacToe = new TicTacToe(); -ticTacToe.isBoardFull(); -ticTacToe.addToken(0,1,"X"); -ticTacToe.printBoard(); -var iter = 0; -while(iter < 8) { - ticTacToe.makeMove(); - iter++; -} - -console.log("after 8 moves"); -ticTacToe.isBoardFull(); -ticTacToe.printBoard(); -ticTacToe.makeMove(); - -ticTacToe.printBoard(); -ticTacToe.addToken(0,0,"X"); -ticTacToe.printBoard(); +module.exports.test = test; \ No newline at end of file diff --git a/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js b/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js index 3bf1c2c..a44a4c4 100644 --- a/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js +++ b/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js @@ -1,118 +1,5 @@ - -/* -Unique Binary Search Trees -https://leetcode.com/problems/unique-binary-search-trees/description/ - -Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? - -Example: - -Input: 3 -Output: 5 -Explanation: -Given n = 3, there are a total of 5 unique BST's: - - 1 3 3 2 1 - \ / / / \ \ - 3 2 1 1 3 2 - / / \ \ - 2 1 2 3 - - -DP Solution: https://www.programcreek.com/2014/05/leetcode-unique-binary-search-trees-java/ -*/ - const assert = require('assert'); -// Solution 3 using DP -var numTrees3 = function (n) { - if (n == 0) - return 0 - - var map = []; - map[0] = 1; - map[1] = 1; - - for(var i = 2; i <= n; i++) { - var currentI = 0; - for(var j = 0; j < i; j++) { - currentI += map[j] * map[i - j - 1]; - } - map[i] = currentI; - } - - return map[n]; -} - -// Solution 2 (Solution 1 + Memoization) -var numTrees2 = function(n) { - var memo = {}; - return numTreesAux2(1, n, memo); -}; - -var numTreesAux2 = function(leftMin, leftMax, memo) { - const keyMemo = buildKey(leftMin, leftMax); - if(memo[keyMemo]) - return memo[keyMemo] - - if(leftMin > leftMax) - return 0; - - if(leftMin === leftMax) - return 1; - - var count = 0; - for(var i = leftMin; i <= leftMax; i++){ - const left = numTreesAux2(leftMin, i - 1, memo); - const right = numTreesAux2(i + 1, leftMax, memo); - - if(left > 0 && right > 0) { - count += left * right; - } else { - count += (left > 0) ? left : right; - } - } - - memo[keyMemo] = count; - return count; -} - -var buildKey = function(a, b) { - return a + "-" + b; -} - - -// Solution 1 -var numTrees1 = function(n) { - return numTreesAux1(1, n); -}; - -var numTreesAux1 = function(leftMin, leftMax) { - if(leftMin > leftMax) - return 0; - - if(leftMin === leftMax) - return 1; - - var count = 0; - for(var i = leftMin; i <= leftMax; i++){ - const left = numTreesAux1(leftMin, i - 1); - const right = numTreesAux1(i + 1, leftMax); - - if(left > 0 && right > 0) { - count += left * right; - } else { - count += (left > 0) ? left : right; - } - } - - return count; -} - -var main = function() { - test(); -} - var test = function () { assert.strictEqual(numTrees1(1), 1); assert.strictEqual(numTrees1(2), 2); @@ -130,4 +17,4 @@ var test = function () { assert.strictEqual(numTrees3(5), 42); } -module.exports.main = main \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Unique_Paths_Test.js b/LeetcodeProblemsTests/Unique_Paths_Test.js index 0a0092e..600569e 100644 --- a/LeetcodeProblemsTests/Unique_Paths_Test.js +++ b/LeetcodeProblemsTests/Unique_Paths_Test.js @@ -1,108 +1,8 @@ -/* -Unique Paths -https://leetcode.com/problems/unique-paths/description/ - -A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). - -The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). - -How many possible unique paths are there? - -Example 1: - -Input: m = 3, n = 2 -Output: 3 -Explanation: -From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: -1. Right -> Right -> Down -2. Right -> Down -> Right -3. Down -> Right -> Right -Example 2: - -Input: m = 7, n = 3 -Output: 28 - -*/ - -// Solution 1 -// This solution is a naive solution implementing a binary tree and visiting each node. const assert = require('assert'); -var uniquePaths1 = function(m, n) { - return uniquePathsAux(0, 0, m, n) -}; - -var uniquePathsAux = function(row, col, rowLength, colLength) { - if(row >= rowLength || col >= colLength) { - return 0; - } - if(row == rowLength - 1 && col == colLength - 1) { - return 1; - } - - return uniquePathsAux(row + 1, col, rowLength, colLength) + - uniquePathsAux(row, col + 1, rowLength, colLength) -}; - -// Solution 2 -// This solution is solution 1 but memoized. -var uniquePaths2 = function(m, n) { - var memo = {}; - return uniquePathsAux2(0, 0, m, n, memo) -}; - -var uniquePathsAux2 = function(row, col, rowLength, colLength, memo) { - if(memo[memoKey(row, col)]) { - return memo[row + "-" + col]; - } - if(row >= rowLength || col >= colLength) { - return 0; - } - if(row == rowLength - 1 && col == colLength - 1) { - return 1; - } - - var result = uniquePathsAux(row + 1, col, rowLength, colLength, memo) + - uniquePathsAux(row, col + 1, rowLength, colLength, memo); - memo[memoKey(row, col)] = result; - return result; -}; - -var memoKey = function(row, col) { - return row + "-" + col; -} - -// Solution 3 -// This solution uses Dinamic Programming -var uniquePaths3 = function(m, n) { - var matrix = []; - for(var i = 0; i < m; i++) { - matrix[i] = []; - for(var j = 0; j < n; j++) { - if(i == 0 || j == 0) { - matrix[i][j] = 1; - } else{ - matrix[i][j] = 0; - } - } - } - - for(var row = 1; row < m; row++) { - for(var col = 1; col < n; col++) { - matrix[row][col] = matrix[row - 1][col] + matrix[row][col - 1] - } - } - - return matrix[m - 1][n - 1]; -}; - -var main = function() { - test(); -} - var test = function() { assert.strictEqual(uniquePaths1(10,4), 220); assert.strictEqual(uniquePaths1(3,2), 3); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Valid_Parentheses_Test.js b/LeetcodeProblemsTests/Valid_Parentheses_Test.js index f4d5bc0..767f909 100644 --- a/LeetcodeProblemsTests/Valid_Parentheses_Test.js +++ b/LeetcodeProblemsTests/Valid_Parentheses_Test.js @@ -1,67 +1,5 @@ -/* -Valid Parentheses -https://leetcode.com/problems/valid-parentheses/description/ - -Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. - -An input string is valid if: - -Open brackets must be closed by the same type of brackets. -Open brackets must be closed in the correct order. -Note that an empty string is also considered valid. - -Example 1: - -Input: "()" -Output: true -Example 2: - -Input: "()[]{}" -Output: true -Example 3: - -Input: "(]" -Output: false -Example 4: - -Input: "([)]" -Output: false -Example 5: - -Input: "{[]}" -Output: true -*/ - const assert = require('assert'); -var isValid = function(s) { - var stack = []; - for(var i = 0; i < s.length; i++) { - var elem = s.charAt(i); - if(elem === ")" || elem === "]" || elem === "}") { - if(stack.length === 0) - return false; - var lasPar = stack.shift(); - if(!valid(lasPar, elem)) - return false; - } else { - stack.unshift(elem); - } - } - - return stack.length === 0; -}; - -var valid = function(parOpen, parClose) { - return parOpen === "(" && parClose === ")" || - parOpen === "[" && parClose === "]" || - parOpen === "{" && parClose === "}"; -} - -var main = function(){ - test(); -} - var test = function () { assert.strictEqual(isValid(""), true); assert.strictEqual(isValid("()"), true); @@ -70,4 +8,4 @@ var test = function () { assert.strictEqual(isValid("{[())()]}"), false); } -module.exports.main = main +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js b/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js index 4576c3c..51eaabc 100644 --- a/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js +++ b/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js @@ -1,73 +1,5 @@ -/* -Verify Preorder Serialization of a Binary Tree -https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/ - -One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #. - - _9_ - / \ - 3 2 - / \ / \ - 4 1 # 6 -/ \ / \ / \ -# # # # # # -For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node. - -Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree. - -Each comma separated value in the string must be either an integer or a character '#' representing null pointer. - -You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3". - -Example 1: - -Input: "9,3,4,#,#,1,#,#,2,#,6,#,#" -Output: true -Example 2: -Input: "1,#" -Output: false -Example 3: - -Input: "9,#,#,1" -Output: false -*/ const assert = require('assert'); -/** - * @param {string} preorder - * @return {boolean} - */ -var isValidSerialization = function(preorder) { - if(preorder.length === 0) - return true; - - if(preorder.charAt(0) === "#") - return preorder.length === 1; - - var countP = 2; - var iter = 1; - while(iter <= preorder.length && preorder.charAt(iter - 1) !== ",") - iter++; - - while(countP > 0 && iter < preorder.length) { - if(preorder.charAt(iter) === "#") { - countP--; - iter += 2; - } else { - countP++; - iter += 2; - while(iter <= preorder.length && preorder.charAt(iter - 1) !== ",") - iter++; - } - } - - return countP === 0 && iter >= preorder.length; -}; - -var main = function() { - test(); -} - var test = function() { assert.strictEqual(isValidSerialization(""), true); assert.strictEqual(isValidSerialization(""), true); @@ -77,4 +9,4 @@ var test = function() { assert.strictEqual(isValidSerialization("9,3,4,#,#,1,#,#,#,2,#,6,#,#"), false); }; -module.exports.main = main; +module.exports.test = test; diff --git a/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js b/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js index c36fa4d..9c6f63b 100644 --- a/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js +++ b/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js @@ -1,85 +1,7 @@ -/* -Merge k Sorted Lists -https://leetcode.com/problems/merge-k-sorted-lists/ - -Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. - -Example: - -Input: -[ - 1->4->5, - 1->3->4, - 2->6 -] -Output: 1->1->2->3->4->4->5->6 -*/ const assert = require('assert'); const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); - var ListNode = require('../UtilsClasses/ListNode').ListNode; -var mergeKLists = function(lists) { - if(lists.length === 0) - return null; - - var queue = []; - for(var i = 0; i < lists.length; i++) - queue.push(lists[i]); - - while(queue.length > 1) { - list1 = queue.shift(); - list2 = queue.shift(); - queue.push(mergeLists(list1, list2)); - } - - return queue.shift(); -}; - -var mergeLists = function(list1, list2) { - if(list1 === null) { - return list2; - } else if(list2 === null) - return list1; - - var iter1 = list1; - var iter2 = list2; - var head; - - if(iter1.val < iter2.val) { - head = iter1; - iter1 = iter1.next - } else { - head = iter2; - iter2 = iter2.next; - } - - var iterHead = head; - while(iter1 !== null && iter2 !== null) { - if(iter1.val < iter2.val) { - iterHead.next = iter1; - iter1 = iter1.next; - } else { - iterHead.next = iter2; - iter2 = iter2.next; - } - iterHead = iterHead.next; - iterHead.next = null; - } - - if(iter1 !== null) { - iterHead.next = iter1; - } else if(iter2 !== null) { - iterHead.next = iter2; - } - - return head; -} - -var main = function() { - test(); -} - function test() { assert.deepEqual(mergeKLists([]), null); assert.deepEqual( @@ -101,4 +23,4 @@ function test() { ); } -module.exports.main = main; \ No newline at end of file +module.exports.test = test; From 125ff74590a15093574b865b87e9e72cbf536fbc Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 6 Sep 2020 11:31:19 -0400 Subject: [PATCH 05/11] Move tests to its own files Round 3 --- LeetcodeProblems/Deletion_Distance.js | 22 ------------------- LeetcodeProblems/Flood_Fill.js | 13 +---------- LeetcodeProblems/Generate_Parenthesis.js | 16 +------------- LeetcodeProblems/Group_Anagrams.js | 14 +----------- .../Regular_Expression_Matching.js | 2 +- .../Remove_Invalid_Parentheses.js | 2 +- LeetcodeProblems/Restore_IP_Addresses.js | 2 +- LeetcodeProblems/Reverse_String_II.js | 2 +- LeetcodeProblems/Search_a_2D_Matrix.js | 2 +- LeetcodeProblems/Search_a_2D_Matrix_II.js | 2 +- 10 files changed, 9 insertions(+), 68 deletions(-) diff --git a/LeetcodeProblems/Deletion_Distance.js b/LeetcodeProblems/Deletion_Distance.js index d06352a..6e7dbd0 100644 --- a/LeetcodeProblems/Deletion_Distance.js +++ b/LeetcodeProblems/Deletion_Distance.js @@ -106,28 +106,6 @@ var min = function(a, b) { return (a < b) ? a : b; } -function main() { - test(); -} - -function test() { - assert.equal(deletionDistance("dog", "frog"), 3); - assert.equal(deletionDistance("some", "some"), 0); - assert.equal(deletionDistance("some", "thing"), 9); - assert.equal(deletionDistance("", ""), 0); - - assert.equal(deletionDistance2("dog", "frog"), 3); - assert.equal(deletionDistance2("some", "some"), 0); - assert.equal(deletionDistance2("some", "thing"), 9); - assert.equal(deletionDistance2("", ""), 0); - - assert.equal(deletionDistanceDP("dog", "frog"), 3); - assert.equal(deletionDistanceDP("some", "some"), 0); - assert.equal(deletionDistanceDP("some", "thing"), 9); - assert.equal(deletionDistanceDP("", ""), 0); -} - module.exports.deletionDistance = deletionDistance; module.exports.deletionDistance2 = deletionDistance2; module.exports.deletionDistanceDP = deletionDistanceDP; - diff --git a/LeetcodeProblems/Flood_Fill.js b/LeetcodeProblems/Flood_Fill.js index ad6c010..09dc6ee 100644 --- a/LeetcodeProblems/Flood_Fill.js +++ b/LeetcodeProblems/Flood_Fill.js @@ -53,15 +53,4 @@ var floodFill = function(image, sr, sc, newColor) { return image; }; -function main() { - test(); -} - -function test() { - assert.deepEqual( - [ [ 2, 2, 2 ], [ 2, 2, 0 ], [ 2, 0, 1 ] ], - floodFill([[1,1,1],[1,1,0],[1,0,1]], 1, 1, 2) - ); -} - -module.exports.main = main; +module.exports.floodFill = floodFill; diff --git a/LeetcodeProblems/Generate_Parenthesis.js b/LeetcodeProblems/Generate_Parenthesis.js index 323b6ef..2ee7df5 100644 --- a/LeetcodeProblems/Generate_Parenthesis.js +++ b/LeetcodeProblems/Generate_Parenthesis.js @@ -77,18 +77,4 @@ var insertAt = function(str, position, value) { return str.slice(0, position) + value + str.slice(position); } -function main() { - console.log("Approach 1"); - [0, 1, 2, 3].forEach(function(elem) { - console.log(`${elem}: ${generateParenthesisApproach2(elem)}`); - }) - - console.log("-------------"); - - console.log("Approach 2"); - [0, 1, 2, 3].forEach(function(elem) { - console.log(`${elem}: ${generateParenthesisApproach2(elem)}`); - }) -} - -module.exports.main = main +module.exports.generateParenthesisApproach2 = generateParenthesisApproach2; diff --git a/LeetcodeProblems/Group_Anagrams.js b/LeetcodeProblems/Group_Anagrams.js index 25dbb3c..b205bb2 100644 --- a/LeetcodeProblems/Group_Anagrams.js +++ b/LeetcodeProblems/Group_Anagrams.js @@ -19,7 +19,6 @@ All inputs will be in lowercase. The order of your output does not matter. */ - var groupAnagrams = function(strs) { var ret = []; var hashMap = {}; @@ -48,15 +47,4 @@ var sortString = function(str) { return str.split("").sort().join(""); } -var main = function() { - test(); -} - -function test() { - assert.deepEqual( - groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]), - [ [ 'eat', 'tea', 'ate' ], [ 'tan', 'nat' ], [ 'bat' ] ] - ) -} - -module.exports.main = main; +module.exports.groupAnagrams = groupAnagrams; diff --git a/LeetcodeProblems/Regular_Expression_Matching.js b/LeetcodeProblems/Regular_Expression_Matching.js index ca357c4..44d561d 100644 --- a/LeetcodeProblems/Regular_Expression_Matching.js +++ b/LeetcodeProblems/Regular_Expression_Matching.js @@ -94,7 +94,7 @@ var main = function(){ test(); } -var test = function(n) { +var test = function() { assert.equal(isMatch("aa", "a"), false); assert.equal(isMatch("aa", "a*"), true); assert.equal(isMatch("a","ab*"), true); diff --git a/LeetcodeProblems/Remove_Invalid_Parentheses.js b/LeetcodeProblems/Remove_Invalid_Parentheses.js index 2197999..997f117 100644 --- a/LeetcodeProblems/Remove_Invalid_Parentheses.js +++ b/LeetcodeProblems/Remove_Invalid_Parentheses.js @@ -74,7 +74,7 @@ var main = function() { test(); } -var test = function(n) { +var test = function() { assert.equal(removeInvalidParentheses("))))(()"), "()"); assert.equal(removeInvalidParentheses("(()"), "()"); assert.equal(removeInvalidParentheses("(d))()"), "(d)()"); diff --git a/LeetcodeProblems/Restore_IP_Addresses.js b/LeetcodeProblems/Restore_IP_Addresses.js index 0dcae65..361ada2 100644 --- a/LeetcodeProblems/Restore_IP_Addresses.js +++ b/LeetcodeProblems/Restore_IP_Addresses.js @@ -45,7 +45,7 @@ var main = function() { test(); } -var test = function(n) { +var test = function() { assert.deepEqual(restoreIpAddresses("010010"), [ '0.10.0.10', '0.100.1.0']); assert.deepEqual(restoreIpAddresses("25525511135"), [ '255.255.11.135', '255.255.111.35' ]); } diff --git a/LeetcodeProblems/Reverse_String_II.js b/LeetcodeProblems/Reverse_String_II.js index 66d7cd6..b086c43 100644 --- a/LeetcodeProblems/Reverse_String_II.js +++ b/LeetcodeProblems/Reverse_String_II.js @@ -43,7 +43,7 @@ var main = function(){ test(); } -var test = function(n) { +var test = function() { assert.equal(reverseStr("abcdefg", 2), "bacdfeg"); assert.equal(reverseStr("abcdefg", 3), "cbadefg"); assert.equal(reverseStr("abcdefg", 1), "abcdefg"); diff --git a/LeetcodeProblems/Search_a_2D_Matrix.js b/LeetcodeProblems/Search_a_2D_Matrix.js index 9251b9e..35c14e1 100644 --- a/LeetcodeProblems/Search_a_2D_Matrix.js +++ b/LeetcodeProblems/Search_a_2D_Matrix.js @@ -63,7 +63,7 @@ var main = function(){ test(); } -var test = function(n) { +var test = function() { assert.equal(searchMatrix([], 0), false); assert.equal(searchMatrix([[1], [3]], 3), true); assert.equal(searchMatrix([[1], [3]], 1), true); diff --git a/LeetcodeProblems/Search_a_2D_Matrix_II.js b/LeetcodeProblems/Search_a_2D_Matrix_II.js index f3ffba1..db0b3bc 100644 --- a/LeetcodeProblems/Search_a_2D_Matrix_II.js +++ b/LeetcodeProblems/Search_a_2D_Matrix_II.js @@ -55,7 +55,7 @@ var main = function(n) { test(); } -var test = function(n) { +var test = function() { assert.equal(searchMatrix(matrix1, 5), true); assert.equal(searchMatrix(matrix1, 0), false); assert.equal(searchMatrix(matrix1, 15), true); From b0c1bed33c254ebc228ab8090ce2ba5acef6bb47 Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 6 Sep 2020 11:40:38 -0400 Subject: [PATCH 06/11] Move tests to its own files Round 4 --- LeetcodeProblems/Flood_Fill.js | 1 - .../Implement_stack_using_queues.js | 21 +----------- .../Kth_Largest_Element_in_an_Array.js | 13 +------- LeetcodeProblems/Linked_List_Cycle_II.js | 32 +------------------ .../Longest_Consecutive_Sequence.js | 15 +-------- LeetcodeProblemsTests/Flood_Fill_Test.js | 1 + LeetcodeProblemsTests/Group_Anagrams_Test.js | 1 + .../Implement_stack_using_queues_Test.js | 1 + .../Kth_Largest_Element_in_an_Array_Test.js | 1 + .../Linked_List_Cycle_II_Test.js | 1 + .../Longest_Consecutive_Sequence_Test.js | 1 + 11 files changed, 10 insertions(+), 78 deletions(-) diff --git a/LeetcodeProblems/Flood_Fill.js b/LeetcodeProblems/Flood_Fill.js index 09dc6ee..93ee923 100644 --- a/LeetcodeProblems/Flood_Fill.js +++ b/LeetcodeProblems/Flood_Fill.js @@ -29,7 +29,6 @@ The given starting pixel will satisfy 0 <= sr < image.length and 0 <= sc < image The value of each color in image[i][j] and newColor will be an integer in [0, 65535]. */ - var floodFill = function(image, sr, sc, newColor) { var oldColor = image[sr][sc]; diff --git a/LeetcodeProblems/Implement_stack_using_queues.js b/LeetcodeProblems/Implement_stack_using_queues.js index 6e21144..a604cf2 100644 --- a/LeetcodeProblems/Implement_stack_using_queues.js +++ b/LeetcodeProblems/Implement_stack_using_queues.js @@ -77,23 +77,4 @@ class MyStack { }; } -var main = function() { - test(); -} - -var test = function () { - var myStack = new MyStack(); - myStack.push(4); - myStack.push(3); - myStack.push(2); - myStack.push(1); - assert.equal(myStack.pop(), 1); - assert.equal(myStack.top(), 2); - myStack.push(1); - assert.equal(myStack.top(), 1); - assert.equal(myStack.pop(), 1); - assert.equal(myStack.pop(), 2); - assert.equal(myStack.pop(), 3); -} - -module.exports.main = main; +module.exports.MyStack = MyStack; \ No newline at end of file diff --git a/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js b/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js index 22d0223..3f669b5 100644 --- a/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js +++ b/LeetcodeProblems/Kth_Largest_Element_in_an_Array.js @@ -57,15 +57,4 @@ var swap = function(nums, a, b) { nums[b] = temp; } -var main = function(nums) { - test(); -} - -function test() { - assert.equal(findKthLargest([3,2,1,5,6,4], 2), 5); - assert.equal(findKthLargest([3,2,3,1,2,4,5,5,6], 4), 4); - assert.equal(findKthLargest([0], 1), 0); - assert.equal(findKthLargest([], 1), undefined); -} - -module.exports.main = main; +module.exports.findKthLargest = findKthLargest; diff --git a/LeetcodeProblems/Linked_List_Cycle_II.js b/LeetcodeProblems/Linked_List_Cycle_II.js index bbacfa9..311932c 100644 --- a/LeetcodeProblems/Linked_List_Cycle_II.js +++ b/LeetcodeProblems/Linked_List_Cycle_II.js @@ -57,34 +57,4 @@ var detectCycle2 = function(head) { return null; }; -var main = function() { - test(); -} - -var test = function() { - const cycle = buildCycle(); - var list = cycle.list; - var nodeCycle = cycle.nodeCycle; - assert.equal(detectCycle(list), nodeCycle); -} - -function buildCycle() { - var node1 = ListNode.linkenList([1,2,3,4,5]); - var node2 = new ListNode(2); - var node3 = new ListNode(3); - var node4 = new ListNode(4); - var node5 = new ListNode(5); - - node1.next = node2; - node2.next = node3; - node3.next = node4; - node4.next = node5; - node5.next = node2; - - return { - list: node1, - nodeCycle: node2, - }; -} - -module.exports.main = main; +module.exports.detectCycle = detectCycle; diff --git a/LeetcodeProblems/Longest_Consecutive_Sequence.js b/LeetcodeProblems/Longest_Consecutive_Sequence.js index a0b9e62..0381cbb 100644 --- a/LeetcodeProblems/Longest_Consecutive_Sequence.js +++ b/LeetcodeProblems/Longest_Consecutive_Sequence.js @@ -13,7 +13,6 @@ Output: 4 Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. */ - /** * @param {number[]} nums * @return {number} @@ -54,16 +53,4 @@ var longestConsecutive = function(nums) { return cons; }; -var main = function() { - test(); -} - -function test() { - assert.equal(longestConsecutive([100, 1, 200, 3, 2, 400, 201]), 3); - assert.equal(longestConsecutive([1,2,3,4, 100, 1, 200, 3, 2, 400, 201]), 4); - assert.equal(longestConsecutive([1, 400, 201, 403, 398]), 1); - assert.equal(longestConsecutive([]), 0); - assert.equal(longestConsecutive([2]), 1); -} - -module.exports.main +module.exports.longestConsecutive = longestConsecutive; diff --git a/LeetcodeProblemsTests/Flood_Fill_Test.js b/LeetcodeProblemsTests/Flood_Fill_Test.js index 37bab1c..e99050f 100644 --- a/LeetcodeProblemsTests/Flood_Fill_Test.js +++ b/LeetcodeProblemsTests/Flood_Fill_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const floodFill = require('../LeetcodeProblems/Flood_Fill').floodFill; function test() { assert.deepEqual( diff --git a/LeetcodeProblemsTests/Group_Anagrams_Test.js b/LeetcodeProblemsTests/Group_Anagrams_Test.js index 8f14cd5..b8c9e43 100644 --- a/LeetcodeProblemsTests/Group_Anagrams_Test.js +++ b/LeetcodeProblemsTests/Group_Anagrams_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const groupAnagrams = require('../LeetcodeProblems/Group_Anagrams').groupAnagrams; function test() { assert.deepEqual( diff --git a/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js b/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js index fa32b3a..131d63c 100644 --- a/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js +++ b/LeetcodeProblemsTests/Implement_stack_using_queues_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const MyStack = require('../LeetcodeProblems/Implement_stack_using_queues').MyStack; var test = function () { var myStack = new MyStack(); diff --git a/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js b/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js index 8b0909b..17ac1f2 100644 --- a/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js +++ b/LeetcodeProblemsTests/Kth_Largest_Element_in_an_Array_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const findKthLargest = require('../LeetcodeProblems/Kth_Largest_Element_in_an_Array').findKthLargest; function test() { assert.equal(findKthLargest([3,2,1,5,6,4], 2), 5); diff --git a/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js b/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js index ff699d8..e4873bf 100644 --- a/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js +++ b/LeetcodeProblemsTests/Linked_List_Cycle_II_Test.js @@ -1,5 +1,6 @@ const assert = require('assert'); var ListNode = require('../UtilsClasses/ListNode').ListNode; +const detectCycle = require('../LeetcodeProblems/Linked_List_Cycle_II').detectCycle; var test = function() { const cycle = buildCycle(); diff --git a/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js b/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js index da2663b..f1ef053 100644 --- a/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js +++ b/LeetcodeProblemsTests/Longest_Consecutive_Sequence_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const longestConsecutive = require('../LeetcodeProblems/Longest_Consecutive_Sequence').longestConsecutive; function test() { assert.equal(longestConsecutive([100, 1, 200, 3, 2, 400, 201]), 3); From b68f155e638b1d3e6577d1c7b806db95e5cecb44 Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 6 Sep 2020 17:46:51 -0400 Subject: [PATCH 07/11] Move tests to its own files Round 5 --- .../Longest_Palindromic_Substring.js | 16 +-------- ...Lowest_Common_Ancestor_of_a_Binary_Tree.js | 36 ++----------------- LeetcodeProblems/Majority_Element.js | 12 +------ LeetcodeProblems/Maximal_Square.js | 16 +-------- LeetcodeProblems/Maximun_Subarray.js | 13 +------ LeetcodeProblems/Min_Stack.js | 17 +-------- LeetcodeProblems/Minimum_Window_Substring.js | 15 +------- LeetcodeProblems/NQueens.js | 27 +------------- LeetcodeProblems/merge_k_sorted_lists.js | 27 +------------- .../Longest_Palindromic_Substring_Test.js | 1 + ...t_Common_Ancestor_of_a_Binary_Tree_Test.js | 2 ++ .../Majority_Element_Test.js | 1 + LeetcodeProblemsTests/Maximal_Square_Test.js | 1 + .../Maximun_Subarray_Test.js | 3 +- LeetcodeProblemsTests/Min_Stack_Test.js | 1 + .../Minimum_Window_Substring_Test.js | 1 + LeetcodeProblemsTests/NQueens_Test.js | 3 ++ .../merge_k_sorted_lists_Test.js | 1 + 18 files changed, 23 insertions(+), 170 deletions(-) diff --git a/LeetcodeProblems/Longest_Palindromic_Substring.js b/LeetcodeProblems/Longest_Palindromic_Substring.js index cdf14a9..8c32bec 100644 --- a/LeetcodeProblems/Longest_Palindromic_Substring.js +++ b/LeetcodeProblems/Longest_Palindromic_Substring.js @@ -15,7 +15,6 @@ Input: "cbbd" Output: "bb" */ - /** * @param {string} s * @return {string} @@ -64,17 +63,4 @@ var longestPalindrome = function(str) { return str.slice(posPalStart, posPalStart + maxPal); } -var main = function() { - test(); -} - -function test() { - assert.equal(longestPalindrome("pabcdcbte"), "bcdcb"); - assert.equal(longestPalindrome("bb"), "bb"); - assert.equal(longestPalindrome(""), ""); - assert.equal(longestPalindrome("bbb"), "bbb"); - assert.equal(longestPalindrome("bbbb"), "bbbb"); - assert.equal(longestPalindrome("ptabbbbat"), "tabbbbat"); -} - -module.exports.main = main +module.exports.longestPalindrome = longestPalindrome diff --git a/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js b/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js index e041008..1d6c129 100644 --- a/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js +++ b/LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js @@ -93,37 +93,5 @@ var pathTo = function(root, value) { return []; } -var main = function() { - var root = new TreeNode(3); - - var right = new TreeNode(1); - right.left = new TreeNode(0); - right.right = new TreeNode(8); - root.right = right; - - var left = new TreeNode(5); - left.left = new TreeNode(6); - - var tempRight = new TreeNode(2); - tempRight.left = new TreeNode(7); - tempRight.right = new TreeNode(4); - left.right = tempRight; - - root.left = left; - - // _______3______ - // / \ - // ___5__ ___1__ - // / \ / \ - // 6 _2 0 8 - // / \ - // 7 4 - - console.log(lowestCommonAncestor(root, left, tempRight.right)); - console.log(lowestCommonAncestor(root, left, right)); - - console.log(lowestCommonAncestor2(root, left, tempRight.right)); - console.log(lowestCommonAncestor2(root, left, right)); -} - -module.exports.main = main; +module.exports.lowestCommonAncestor = lowestCommonAncestor; +module.exports.lowestCommonAncestor2 = lowestCommonAncestor2; diff --git a/LeetcodeProblems/Majority_Element.js b/LeetcodeProblems/Majority_Element.js index 1d7258f..3b48dda 100644 --- a/LeetcodeProblems/Majority_Element.js +++ b/LeetcodeProblems/Majority_Element.js @@ -45,14 +45,4 @@ var majorityElement = function(nums) { return candidate; }; -var main = function() { - test(); -} - -function test() { - assert.equal(majorityElement([2,2,3]), 2); - assert.equal(majorityElement([2,3,2]), 2); - assert.equal(majorityElement([1,1,1,2,3,45,1,2,4,1,1]), 1); -} - -module.exports.main = main +module.exports.majorityElement = majorityElement; diff --git a/LeetcodeProblems/Maximal_Square.js b/LeetcodeProblems/Maximal_Square.js index d43dfb7..b0a45fc 100644 --- a/LeetcodeProblems/Maximal_Square.js +++ b/LeetcodeProblems/Maximal_Square.js @@ -65,18 +65,4 @@ var getCurrentMaxSideLength = function(matrix, i, j) { return max; } -var main = function() { - test(); -} - -function test() { - assert.equal(maximalSquare([["1","0"]]), 1); - assert.equal(maximalSquare([["1"]]), 1); - assert.equal(maximalSquare([["0"]]), 0); - assert.equal( - maximalSquare([["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]), - 4 - ); -} - -module.exports.main = main +module.exports.maximalSquare = maximalSquare; diff --git a/LeetcodeProblems/Maximun_Subarray.js b/LeetcodeProblems/Maximun_Subarray.js index 4f321e0..b05309c 100644 --- a/LeetcodeProblems/Maximun_Subarray.js +++ b/LeetcodeProblems/Maximun_Subarray.js @@ -34,15 +34,4 @@ var max = function(i, j) { return (i > j) ? i : j; } -var main = function() { - test(); -} - -function test() { - assert.equal(maxSubArray([]), 0); - assert.equal(maxSubArray([-4]), -4); - assert.equal(maxSubArray([2]), 2); - assert.equal(maxSubArray([4,1,-1,4,5,6,7,-200]), 26); -} - -module.exports.main = main; \ No newline at end of file +module.exports.maxSubArray = maxSubArray; diff --git a/LeetcodeProblems/Min_Stack.js b/LeetcodeProblems/Min_Stack.js index f510abc..0ee04fc 100644 --- a/LeetcodeProblems/Min_Stack.js +++ b/LeetcodeProblems/Min_Stack.js @@ -74,19 +74,4 @@ class MinStack { } } -var main = function() { - test(); -} - -function test() { - var minStack = new MinStack(); - minStack.push(-2); - minStack.push(0); - minStack.push(-3); - assert.equal(minStack.getMin(), -3); - assert.equal(minStack.pop(), -3); - assert.equal(minStack.top(), 0); - assert.equal(minStack.getMin(), -2); -} - -module.exports.main = main; \ No newline at end of file +module.exports.MinStack = MinStack; diff --git a/LeetcodeProblems/Minimum_Window_Substring.js b/LeetcodeProblems/Minimum_Window_Substring.js index 3ad13fe..24beeab 100644 --- a/LeetcodeProblems/Minimum_Window_Substring.js +++ b/LeetcodeProblems/Minimum_Window_Substring.js @@ -64,17 +64,4 @@ var getHash = function(t) { return hash; } -var main = function() { - test(); -} - -function test() { - assert.equal(minWindow("ADOBECODEBANC", "ABC"), "BANC"); - assert.equal(minWindow("caaec", "cae"), "aec"); - assert.equal(minWindow("bbacbb", "ab"), "ba"); - assert.equal(minWindow("abba", "b"), "b"); - assert.equal(minWindow("abba", "a"), "a"); - assert.equal(minWindow("abba", ""), ""); -} - -module.exports.main +module.exports.minWindow = minWindow; diff --git a/LeetcodeProblems/NQueens.js b/LeetcodeProblems/NQueens.js index d0bbd14..2f2674f 100644 --- a/LeetcodeProblems/NQueens.js +++ b/LeetcodeProblems/NQueens.js @@ -70,29 +70,4 @@ var parseSolutions = function(sols, n) { return matrixes; } -var main = function(n) { - printMatrixes(solveNQueens(4), 4); - printMatrixes(solveNQueens(5), 5); - printMatrixes(solveNQueens(6), 6); -} - -var test = function() { -} - -var printMatrixes = function(matrixes, n) { - console.log("Start solution of n: " + n); - for(var i = 0; i < matrixes.length; i++) { - printMatrix(matrixes[i]); - } - console.log("End solution of n: " + n); -} - -var printMatrix = function(matrix) { - console.log("------------"); - for(var i = 0; i < matrix.length; i++) { - console.log(matrix[i]); - } - console.log("------------"); -} - -module.exports.main = main; +module.exports.solveNQueens = solveNQueens; diff --git a/LeetcodeProblems/merge_k_sorted_lists.js b/LeetcodeProblems/merge_k_sorted_lists.js index 7e92a8b..ab07395 100644 --- a/LeetcodeProblems/merge_k_sorted_lists.js +++ b/LeetcodeProblems/merge_k_sorted_lists.js @@ -76,29 +76,4 @@ var mergeLists = function(list1, list2) { return head; } -var main = function() { - test(); -} - -function test() { - assert.deepEqual(mergeKLists([]), null); - assert.deepEqual( - mergeKLists([null]), - null - ); - assert.deepEqual( - mergeKLists([null, null]), - null - ); - - var list1 = ListNode.linkenList([1,2,3]); - var list2 = ListNode.linkenList([2,3,4]); - var list3 = ListNode.linkenList([5,6]); - var list4 = ListNode.linkenList([1,5]); - ListNodeTestHelper.assertList( - mergeKLists([list1, list2, list3, list4]), - [1, 1, 2, 2, 3, 3, 4, 5, 5, 6] - ); -} - -module.exports.main = main; \ No newline at end of file +module.exports.mergeKLists = mergeKLists; diff --git a/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js b/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js index 39a92bf..c177ff4 100644 --- a/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js +++ b/LeetcodeProblemsTests/Longest_Palindromic_Substring_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const longestPalindrome = require('../LeetcodeProblems/Longest_Palindromic_Substring').longestPalindrome; function test() { assert.equal(longestPalindrome("pabcdcbte"), "bcdcb"); diff --git a/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js b/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js index e59d26f..dc66300 100644 --- a/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js +++ b/LeetcodeProblemsTests/Lowest_Common_Ancestor_of_a_Binary_Tree_Test.js @@ -1,5 +1,7 @@ const assert = require('assert'); var TreeNode = require('../UtilsClasses/TreeNode').TreeNode; +const lowestCommonAncestor = require('../LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree').lowestCommonAncestor; +const lowestCommonAncestor2 = require('../LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree').lowestCommonAncestor2; var test = function() { var root = new TreeNode(3); diff --git a/LeetcodeProblemsTests/Majority_Element_Test.js b/LeetcodeProblemsTests/Majority_Element_Test.js index 8ca4a3e..6d573b1 100644 --- a/LeetcodeProblemsTests/Majority_Element_Test.js +++ b/LeetcodeProblemsTests/Majority_Element_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const majorityElement = require('../LeetcodeProblems/Majority_Element').majorityElement; function test() { assert.equal(majorityElement([2,2,3]), 2); diff --git a/LeetcodeProblemsTests/Maximal_Square_Test.js b/LeetcodeProblemsTests/Maximal_Square_Test.js index e76fd04..accb1cc 100644 --- a/LeetcodeProblemsTests/Maximal_Square_Test.js +++ b/LeetcodeProblemsTests/Maximal_Square_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const maximalSquare = require('../LeetcodeProblems/Maximal_Square').maximalSquare; function test() { assert.equal(maximalSquare([["1","0"]]), 1); diff --git a/LeetcodeProblemsTests/Maximun_Subarray_Test.js b/LeetcodeProblemsTests/Maximun_Subarray_Test.js index 5f2e552..434b43b 100644 --- a/LeetcodeProblemsTests/Maximun_Subarray_Test.js +++ b/LeetcodeProblemsTests/Maximun_Subarray_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const maxSubArray = require('../LeetcodeProblems/Maximun_Subarray').maxSubArray; function test() { assert.equal(maxSubArray([]), 0); @@ -7,4 +8,4 @@ function test() { assert.equal(maxSubArray([4,1,-1,4,5,6,7,-200]), 26); } -module.exports.test = test; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Min_Stack_Test.js b/LeetcodeProblemsTests/Min_Stack_Test.js index d4a52e0..0f608f2 100644 --- a/LeetcodeProblemsTests/Min_Stack_Test.js +++ b/LeetcodeProblemsTests/Min_Stack_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const MinStack = require('../LeetcodeProblems/Min_Stack').MinStack; function test() { var minStack = new MinStack(); diff --git a/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js b/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js index f6ef8b6..602a944 100644 --- a/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js +++ b/LeetcodeProblemsTests/Minimum_Window_Substring_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const minWindow = require('../LeetcodeProblems/Minimum_Window_Substring').minWindow; function test() { assert.equal(minWindow("ADOBECODEBANC", "ABC"), "BANC"); diff --git a/LeetcodeProblemsTests/NQueens_Test.js b/LeetcodeProblemsTests/NQueens_Test.js index 68d3653..bb9fdb9 100644 --- a/LeetcodeProblemsTests/NQueens_Test.js +++ b/LeetcodeProblemsTests/NQueens_Test.js @@ -1,4 +1,7 @@ const assert = require('assert'); +const solveNQueens = require('../LeetcodeProblems/NQueens').solveNQueens; + +// TODO: Add assertions var test = function() { printMatrixes(solveNQueens(4), 4); diff --git a/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js b/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js index 9c6f63b..42d0a89 100644 --- a/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js +++ b/LeetcodeProblemsTests/merge_k_sorted_lists_Test.js @@ -1,6 +1,7 @@ const assert = require('assert'); const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); var ListNode = require('../UtilsClasses/ListNode').ListNode; +const mergeKLists = require('../LeetcodeProblems/merge_k_sorted_lists').mergeKLists; function test() { assert.deepEqual(mergeKLists([]), null); From d3a194977a1e426b5826d39e29d44c71d69fc80d Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 6 Sep 2020 17:57:48 -0400 Subject: [PATCH 08/11] Move tests to its own files Round 6 --- LeetcodeProblems/Number_of_Islands.js | 21 +----------- .../Number_of_Segments_in_a_String.js | 15 +-------- LeetcodeProblems/Permutations.js | 23 +------------ LeetcodeProblems/Permutations_II.js | 33 +------------------ .../Permutations_With_Duplicates.js | 26 +-------------- .../Permutations_Without_Duplicates.js | 31 ++++------------- .../Regular_Expression_Matching.js | 15 +-------- .../Remove_Invalid_Parentheses.js | 14 +------- LeetcodeProblems/Restore_IP_Addresses.js | 12 +------ LeetcodeProblems/Reverse_String_II.js | 14 +------- .../Number_of_Islands_Test.js | 1 + .../Number_of_Segments_in_a_String_Test.js | 1 + LeetcodeProblemsTests/Permutations_II_Test.js | 1 + LeetcodeProblemsTests/Permutations_Test.js | 1 + .../Permutations_With_Duplicates_Test.js | 1 + .../Permutations_Without_Duplicates_Test.js | 3 +- .../Regular_Expression_Matching_Test.js | 1 + .../Remove_Invalid_Parentheses_Test.js | 1 + .../Restore_IP_Addresses_Test.js | 1 + .../Reverse_String_II_Test.js | 1 + 20 files changed, 26 insertions(+), 190 deletions(-) diff --git a/LeetcodeProblems/Number_of_Islands.js b/LeetcodeProblems/Number_of_Islands.js index b9e3150..705dd63 100644 --- a/LeetcodeProblems/Number_of_Islands.js +++ b/LeetcodeProblems/Number_of_Islands.js @@ -61,23 +61,4 @@ var colorIsland = function(grid, i, j, rowsCount, columnsCount) { colorIsland(grid, i, j + 1, rowsCount, columnsCount); } -var main = function() { - test(); -} - -function test() { - assert.equal(numIslands([[1]]), 1); - assert.equal(numIslands([]), 0); - assert.equal(numIslands( - [ - ["1","1","1","1","0"], - ["1","1","0","1","0"], - ["1","1","0","0","0"], - ["0","0","0","0","0"] - ], - ), - 1 - ); -} - -module.exports.main = main; \ No newline at end of file +module.exports.numIslands = numIslands; diff --git a/LeetcodeProblems/Number_of_Segments_in_a_String.js b/LeetcodeProblems/Number_of_Segments_in_a_String.js index 5c0e05c..cb33afb 100644 --- a/LeetcodeProblems/Number_of_Segments_in_a_String.js +++ b/LeetcodeProblems/Number_of_Segments_in_a_String.js @@ -33,17 +33,4 @@ var countSegments = function(s) { return count; }; -function main() { - test(); -} - -function test() { - assert.equal(countSegments(" "), 0); - assert.equal(countSegments(" "), 0); - assert.equal(countSegments("ab cd ef"), 3); - assert.equal(countSegments(" ab cd ef"), 3); - assert.equal(countSegments("ab cd ef "), 3); - assert.equal(countSegments(" ab cd ef "), 3); -} - -module.exports.main = main +module.exports.countSegments = countSegments; diff --git a/LeetcodeProblems/Permutations.js b/LeetcodeProblems/Permutations.js index e7adc08..478eda6 100644 --- a/LeetcodeProblems/Permutations.js +++ b/LeetcodeProblems/Permutations.js @@ -18,7 +18,6 @@ Output: ] */ - var permute = function(nums) { return permuteAux(nums, 0, [], new Set()); }; @@ -39,24 +38,4 @@ var permuteAux = function(nums, pos, currentSol, set) { return ret; } -var main = function() { test(); -} - -function test() { - // assert.deepEqual( - assert.deepEqual(permute([]), [ [] ]); - assert.deepEqual(permute([1]), [ [ 1 ] ]); - assert.deepEqual( - permute([1,2,3]), - [ - [ 1, 2, 3 ], - [ 1, 3, 2 ], - [ 2, 1, 3 ], - [ 2, 3, 1 ], - [ 3, 1, 2 ], - [ 3, 2, 1 ] - ] - ); -} - -module.exports.main = main; +module.exports.permute = permute; diff --git a/LeetcodeProblems/Permutations_II.js b/LeetcodeProblems/Permutations_II.js index 6145b56..ba86bb5 100644 --- a/LeetcodeProblems/Permutations_II.js +++ b/LeetcodeProblems/Permutations_II.js @@ -46,35 +46,4 @@ var permuteUniqueAux = function(n, map, currentSol) { return ret; }; -var main = function() { - test(); -} - -function test() { - assert.deepEqual( - permuteUnique([1,1,2]), - [ [ '1', '1', '2' ], [ '1', '2', '1' ], [ '2', '1', '1' ] ] - ); - assert.deepEqual( - permuteUnique([1,3,2,1]), - [ - [ '1', '1', '2', '3' ], - [ '1', '1', '3', '2' ], - [ '1', '2', '1', '3' ], - [ '1', '2', '3', '1' ], - [ '1', '3', '1', '2' ], - [ '1', '3', '2', '1' ], - [ '2', '1', '1', '3' ], - [ '2', '1', '3', '1' ], - [ '2', '3', '1', '1' ], - [ '3', '1', '1', '2' ], - [ '3', '1', '2', '1' ], - [ '3', '2', '1', '1' ] - ] - ); - assert.deepEqual(permuteUnique([]), [ [] ]); - - assert.deepEqual(permuteUnique([1,1]), [ [ '1', '1' ] ]); -} - -module.exports.main = main; \ No newline at end of file +module.exports.permuteUnique = permuteUnique; diff --git a/LeetcodeProblems/Permutations_With_Duplicates.js b/LeetcodeProblems/Permutations_With_Duplicates.js index 688df4b..3746a24 100644 --- a/LeetcodeProblems/Permutations_With_Duplicates.js +++ b/LeetcodeProblems/Permutations_With_Duplicates.js @@ -29,28 +29,4 @@ var subsetWithoutDuplicatesAux = function(nums, current, sol) { }) } -function main() { - test(); -} - -var test = function() { - assert.deepEqual( - subsetWithoutDuplicates([1,1,2,3]), - [ - [ 1, 1, 2, 3 ], - [ 1, 1, 3, 2 ], - [ 1, 2, 1, 3 ], - [ 1, 2, 3, 1 ], - [ 1, 3, 1, 2 ], - [ 1, 3, 2, 1 ], - [ 2, 1, 1, 3 ], - [ 2, 1, 3, 1 ], - [ 2, 3, 1, 1 ], - [ 3, 1, 1, 2 ], - [ 3, 1, 2, 1 ], - [ 3, 2, 1, 1 ] - ] - ); -} -main(); -module.exports.main = main; \ No newline at end of file +module.exports.subsetWithoutDuplicates = subsetWithoutDuplicates; diff --git a/LeetcodeProblems/Permutations_Without_Duplicates.js b/LeetcodeProblems/Permutations_Without_Duplicates.js index 06e4977..3a0463f 100644 --- a/LeetcodeProblems/Permutations_Without_Duplicates.js +++ b/LeetcodeProblems/Permutations_Without_Duplicates.js @@ -18,18 +18,17 @@ Output: ] */ - -// Permutations wihto -var subsetWithDuplicates = function(nums) { +// Permutations without Duplicates +var subsetWithoutDuplicates = function(nums) { if(nums.lenght == 0){ return; } var solution = []; - subsetWithDuplicatesAux(nums, [], solution); + subsetWithoutDuplicatesAux(nums, [], solution); return solution; } -var subsetWithDuplicatesAux = function(nums, current, sol) { +var subsetWithoutDuplicatesAux = function(nums, current, sol) { if(nums.length == 0){ sol.push(current); } @@ -37,26 +36,8 @@ var subsetWithDuplicatesAux = function(nums, current, sol) { for(var i = 0; i < nums.length; i++) { var newCurrent = [...current, nums[i]] var newNums = nums.filter(function(num, index) { return index !== i }); - subsetWithDuplicatesAux(newNums, newCurrent, sol); + subsetWithoutDuplicatesAux(newNums, newCurrent, sol); } } - -function main() { - test(); -} - -var test = function() { - assert.deepEqual( - subsetWithDuplicates([1,2,3]), - [ - [ 1, 2, 3 ], - [ 1, 3, 2 ], - [ 2, 1, 3 ], - [ 2, 3, 1 ], - [ 3, 1, 2 ], - [ 3, 2, 1 ] - ] - ); -} -module.exports.main = main; \ No newline at end of file +module.exports.subsetWithoutDuplicates = subsetWithoutDuplicates; diff --git a/LeetcodeProblems/Regular_Expression_Matching.js b/LeetcodeProblems/Regular_Expression_Matching.js index 44d561d..67ed0ae 100644 --- a/LeetcodeProblems/Regular_Expression_Matching.js +++ b/LeetcodeProblems/Regular_Expression_Matching.js @@ -90,17 +90,4 @@ var canBeZero = function(pattern, posPat) { return posPat == pattern.length; } -var main = function(){ - test(); -} - -var test = function() { - assert.equal(isMatch("aa", "a"), false); - assert.equal(isMatch("aa", "a*"), true); - assert.equal(isMatch("a","ab*"), true); - assert.equal(isMatch("ab", ".*"), true); - assert.equal(isMatch("aab", "c*a*b"), true); - assert.equal(isMatch("mississippi", "mis*is*p*."), false); -} - -module.exports.main = main; +module.exports.isMatch = isM.isMatch; diff --git a/LeetcodeProblems/Remove_Invalid_Parentheses.js b/LeetcodeProblems/Remove_Invalid_Parentheses.js index 997f117..8d193f5 100644 --- a/LeetcodeProblems/Remove_Invalid_Parentheses.js +++ b/LeetcodeProblems/Remove_Invalid_Parentheses.js @@ -20,7 +20,6 @@ Input: ")(" Output: [""] */ - /** * @param {string} s * @return {string[]} @@ -70,15 +69,4 @@ var isValid = function(s) { return leftCount === 0; } -var main = function() { - test(); -} - -var test = function() { - assert.equal(removeInvalidParentheses("))))(()"), "()"); - assert.equal(removeInvalidParentheses("(()"), "()"); - assert.equal(removeInvalidParentheses("(d))()"), "(d)()"); - assert.equal(removeInvalidParentheses("(())"), "(())"); -} - -module.exports.main = main; \ No newline at end of file +module.exports.removeInvalidParentheses = removeInvalidParentheses; diff --git a/LeetcodeProblems/Restore_IP_Addresses.js b/LeetcodeProblems/Restore_IP_Addresses.js index 361ada2..578b970 100644 --- a/LeetcodeProblems/Restore_IP_Addresses.js +++ b/LeetcodeProblems/Restore_IP_Addresses.js @@ -10,7 +10,6 @@ Input: "25525511135" Output: ["255.255.11.135", "255.255.111.35"] */ - var restoreIpAddresses = function(s) { var restore = restoreInputBits("", s, 4); @@ -41,13 +40,4 @@ var restoreInputBits = function(partial, s, num) { return [...oneNum, ...twoNums, ...threeNums]; } -var main = function() { - test(); -} - -var test = function() { - assert.deepEqual(restoreIpAddresses("010010"), [ '0.10.0.10', '0.100.1.0']); - assert.deepEqual(restoreIpAddresses("25525511135"), [ '255.255.11.135', '255.255.111.35' ]); -} - -module.exports.main = main +module.exports.restoreIpAddresses = restoreIpAddresses; diff --git a/LeetcodeProblems/Reverse_String_II.js b/LeetcodeProblems/Reverse_String_II.js index b086c43..429520f 100644 --- a/LeetcodeProblems/Reverse_String_II.js +++ b/LeetcodeProblems/Reverse_String_II.js @@ -11,7 +11,6 @@ The string consists of lower English letters only. Length of the given string and k will in the range [1, 10000] */ - var reverseStr = function(s, k) { if(k <= 1) return s; @@ -39,15 +38,4 @@ var reverse = function(s, start, end) { return ret; } -var main = function(){ - test(); -} - -var test = function() { - assert.equal(reverseStr("abcdefg", 2), "bacdfeg"); - assert.equal(reverseStr("abcdefg", 3), "cbadefg"); - assert.equal(reverseStr("abcdefg", 1), "abcdefg"); - assert.equal(reverseStr("abcdefg", 0), "abcdefg"); -} - -module.exports.main = main +module.exports.reverseStr = reverseStr; diff --git a/LeetcodeProblemsTests/Number_of_Islands_Test.js b/LeetcodeProblemsTests/Number_of_Islands_Test.js index e91364a..d28ac2c 100644 --- a/LeetcodeProblemsTests/Number_of_Islands_Test.js +++ b/LeetcodeProblemsTests/Number_of_Islands_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const numIslands = require('../LeetcodeProblems/Number_of_Islands').numIslands; function test() { assert.equal(numIslands([[1]]), 1); diff --git a/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js b/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js index 287dd43..51fd2b4 100644 --- a/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js +++ b/LeetcodeProblemsTests/Number_of_Segments_in_a_String_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const countSegments = require('../LeetcodeProblems/Number_of_Segments_in_a_String').countSegments; function test() { assert.equal(countSegments(" "), 0); diff --git a/LeetcodeProblemsTests/Permutations_II_Test.js b/LeetcodeProblemsTests/Permutations_II_Test.js index ce3398c..5c802df 100644 --- a/LeetcodeProblemsTests/Permutations_II_Test.js +++ b/LeetcodeProblemsTests/Permutations_II_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const permuteUnique = require('../LeetcodeProblems/Permutations_II').permuteUnique; function test() { assert.deepEqual( diff --git a/LeetcodeProblemsTests/Permutations_Test.js b/LeetcodeProblemsTests/Permutations_Test.js index 60fc82e..2c8ab25 100644 --- a/LeetcodeProblemsTests/Permutations_Test.js +++ b/LeetcodeProblemsTests/Permutations_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const permute = require('../LeetcodeProblems/Permutations').permute; function test() { assert.deepEqual(permute([]), [ [] ]); diff --git a/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js b/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js index fc3a74e..d9f6e09 100644 --- a/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js +++ b/LeetcodeProblemsTests/Permutations_With_Duplicates_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const subsetWithoutDuplicates = require('../LeetcodeProblems/Permutations_With_Duplicates').subsetWithoutDuplicates; var test = function() { assert.deepEqual( diff --git a/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js b/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js index ad58586..4340221 100644 --- a/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js +++ b/LeetcodeProblemsTests/Permutations_Without_Duplicates_Test.js @@ -1,8 +1,9 @@ const assert = require('assert'); +const subsetWithoutDuplicates = require('../LeetcodeProblems/Permutations_Without_Duplicates').subsetWithoutDuplicates; var test = function() { assert.deepEqual( - subsetWithDuplicates([1,2,3]), + subsetWithoutDuplicates([1,2,3]), [ [ 1, 2, 3 ], [ 1, 3, 2 ], diff --git a/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js b/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js index 480dddc..3e01fa4 100644 --- a/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js +++ b/LeetcodeProblemsTests/Regular_Expression_Matching_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const isMatch = require('../LeetcodeProblems/Regular_Expression_Matching').isMatch; var test = function() { assert.equal(isMatch("aa", "a"), false); diff --git a/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js b/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js index 477802d..9ab47a7 100644 --- a/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js +++ b/LeetcodeProblemsTests/Remove_Invalid_Parentheses_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const removeInvalidParentheses = require('../LeetcodeProblems/Remove_Invalid_Parentheses').removeInvalidParentheses; var test = function() { assert.equal(removeInvalidParentheses("))))(()"), "()"); diff --git a/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js b/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js index 5bcc3d2..3905d19 100644 --- a/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js +++ b/LeetcodeProblemsTests/Restore_IP_Addresses_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const restoreIpAddresses = require('../LeetcodeProblems/Restore_IP_Addresses').restoreIpAddresses; var test = function() { assert.deepEqual(restoreIpAddresses("010010"), [ '0.10.0.10', '0.100.1.0']); diff --git a/LeetcodeProblemsTests/Reverse_String_II_Test.js b/LeetcodeProblemsTests/Reverse_String_II_Test.js index 685faba..37169da 100644 --- a/LeetcodeProblemsTests/Reverse_String_II_Test.js +++ b/LeetcodeProblemsTests/Reverse_String_II_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const reverseStr = require('../LeetcodeProblems/Reverse_String_II').reverseStr; var test = function() { assert.equal(reverseStr("abcdefg", 2), "bacdfeg"); From 142a6a4f135d975181c1a035372352bd242df263 Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 6 Sep 2020 18:25:18 -0400 Subject: [PATCH 09/11] Move tests to its own files Round 7 --- .../Best_Time_To_Buy_And_Sell_Stock_II.js | 9 ----- LeetcodeProblems/Escape_The_Ghosts.js | 12 +------ .../SearchIng_Rotated_Sorted_Array.js | 10 +----- LeetcodeProblems/Search_a_2D_Matrix.js | 15 +------- LeetcodeProblems/Search_a_2D_Matrix_II.js | 21 +----------- LeetcodeProblems/Set_Matrix_Zeroes.js | 15 +------- LeetcodeProblems/Simplify_Path.js | 15 +------- LeetcodeProblems/Spiral_Matrix.js | 15 +------- LeetcodeProblems/Subarray_Sum_Equals_K.js | 13 +------ LeetcodeProblems/Subsets.js | 19 +---------- LeetcodeProblems/Sum_Of_Square_Numbers.js | 18 +--------- LeetcodeProblems/Swap_Nodes_In_Pairs.js | 16 +-------- LeetcodeProblems/Tic_Tac_Toe.js | 34 ++++--------------- .../Unique_Binary_Search_Trees.js | 27 ++------------- LeetcodeProblems/Unique_Paths.js | 15 ++------ LeetcodeProblems/Valid_Parentheses.js | 16 +-------- ...Preorder_Serialization_of_a_Binary_Tree.js | 15 +------- .../SearchIng_Rotated_Sorted_Array_Test.js | 1 + .../Search_a_2D_Matrix_II_Test.js | 9 +++++ .../Search_a_2D_Matrix_Test.js | 1 + .../Set_Matrix_Zeroes_Test.js | 1 + LeetcodeProblemsTests/Simplify_Path_Test.js | 1 + LeetcodeProblemsTests/Spiral_Matrix_Test.js | 1 + .../Subarray_Sum_Equals_K_Test.js | 1 + LeetcodeProblemsTests/Subsets_Test.js | 1 + .../Sum_Of_Square_Numbers_Test.js | 1 + .../Swap_Nodes_In_Pairs_Test.js | 1 + LeetcodeProblemsTests/Symmetric_Tree_Test.js | 2 +- LeetcodeProblemsTests/Tic_Tac_Toe_Test.js | 24 +++++++++++-- .../Unique_Binary_Search_Trees_Test.js | 3 ++ LeetcodeProblemsTests/Unique_Paths_Test.js | 9 +++++ .../Valid_Parentheses_Test.js | 1 + ...der_Serialization_of_a_Binary_Tree_Test.js | 1 + 33 files changed, 81 insertions(+), 262 deletions(-) diff --git a/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js b/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js index 0c4230c..0dd7138 100644 --- a/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js +++ b/LeetcodeProblems/Best_Time_To_Buy_And_Sell_Stock_II.js @@ -55,13 +55,4 @@ var maxProfit = function(prices) { return profit; }; -var main = function() { - test(); -} - -function test() { - assert.equal(maxProfit([7,1,5,3,6,4]), 7); - assert.equal(maxProfit([7,1,5,3320,6,4]), 3319); -} - module.exports.maxProfit = maxProfit; \ No newline at end of file diff --git a/LeetcodeProblems/Escape_The_Ghosts.js b/LeetcodeProblems/Escape_The_Ghosts.js index fa8e775..06c5a53 100644 --- a/LeetcodeProblems/Escape_The_Ghosts.js +++ b/LeetcodeProblems/Escape_The_Ghosts.js @@ -59,14 +59,4 @@ var getDistance = function(a, b) { return horizontalMoves + verticalMoves; } -var main = function() { - test(); -} - -function test() { - assert.equal(escapeGhosts([[1, 0], [0, 3]], [0, 1]), true); - assert.equal(escapeGhosts([[1, 0]], [2, 0]), false); - assert.equal(escapeGhosts([[2, 0]], [1, 0]), true); -} - -module.exports.main = main \ No newline at end of file +module.exports.escapeGhosts = escapeGhosts; diff --git a/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js b/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js index a4753ee..702f357 100644 --- a/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js +++ b/LeetcodeProblems/SearchIng_Rotated_Sorted_Array.js @@ -54,12 +54,4 @@ var searchAux = function(nums, target, start, end) { } } -var main = function(n) { - test(); -} - -var test = function() { - assert.equal(search([4,5,6,7,0,1,2], 5), 1); -} -main() -module.exports.main = main; +module.exports.search = search; diff --git a/LeetcodeProblems/Search_a_2D_Matrix.js b/LeetcodeProblems/Search_a_2D_Matrix.js index 35c14e1..6348c4c 100644 --- a/LeetcodeProblems/Search_a_2D_Matrix.js +++ b/LeetcodeProblems/Search_a_2D_Matrix.js @@ -28,7 +28,6 @@ target = 13 Output: false */ - /** * @param {number[][]} matrix * @param {number} target @@ -58,17 +57,5 @@ var searchMatrixAux = function(matrix, firstRow, lastRow, target) { return false; }; - -var main = function(){ - test(); -} - -var test = function() { - assert.equal(searchMatrix([], 0), false); - assert.equal(searchMatrix([[1], [3]], 3), true); - assert.equal(searchMatrix([[1], [3]], 1), true); - const matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,50]]; - assert.equal(searchMatrix(matrix, 3), true); -} -module.exports.main = main; +module.exports.searchMatrix = searchMatrix; diff --git a/LeetcodeProblems/Search_a_2D_Matrix_II.js b/LeetcodeProblems/Search_a_2D_Matrix_II.js index db0b3bc..c96c95d 100644 --- a/LeetcodeProblems/Search_a_2D_Matrix_II.js +++ b/LeetcodeProblems/Search_a_2D_Matrix_II.js @@ -18,7 +18,6 @@ Given target = 5, return true. Given target = 20, return false. */ - /** * @param {number[][]} matrix * @param {number} target @@ -43,22 +42,4 @@ var searchMatrix = function(matrix, target) { return false; }; -const matrix1 = [ - [1,4,7, 11,15], - [2,5,8, 12,19], - [3,6,9, 16,22], - [10,13,14, 17,24], - [18,21,23, 26,30] -]; - -var main = function(n) { - test(); -} - -var test = function() { - assert.equal(searchMatrix(matrix1, 5), true); - assert.equal(searchMatrix(matrix1, 0), false); - assert.equal(searchMatrix(matrix1, 15), true); -} - -module.exports.main = main; +module.exports.searchMatrix = searchMatrix; diff --git a/LeetcodeProblems/Set_Matrix_Zeroes.js b/LeetcodeProblems/Set_Matrix_Zeroes.js index 0abbf86..908411a 100644 --- a/LeetcodeProblems/Set_Matrix_Zeroes.js +++ b/LeetcodeProblems/Set_Matrix_Zeroes.js @@ -39,8 +39,6 @@ A simple improvement uses O(m + n) space, but still not the best solution. Could you devise a constant space solution? */ - - /** * @param {number[][]} matrix * @return {void} Do not return anything, modify matrix in-place instead. @@ -110,15 +108,4 @@ var fillCol = function(matrix, col) { matrix[i][col] = 0; } -var main = function() { - test(); -} - -var test = function() { - assert.deepEqual( - setZeroes([[1,1,1],[1,0,1],[1,1,1]]), - [[1, 0, 1], [0, 0, 0], [1, 0, 1]] - ); -} - -module.exports.main = main; +module.exports.setZeroes = setZeroes; diff --git a/LeetcodeProblems/Simplify_Path.js b/LeetcodeProblems/Simplify_Path.js index a462e14..70e17f7 100644 --- a/LeetcodeProblems/Simplify_Path.js +++ b/LeetcodeProblems/Simplify_Path.js @@ -60,17 +60,4 @@ var simplifyPath = function(path) { return (ret.length == 0) ? "/" : ret; }; -var main = function(){ - test(); -} - -var test = function() { - assert.equal(simplifyPath("/../c"), "/c"); - assert.equal(simplifyPath("/.."), "/"); - assert.equal(simplifyPath("/home/"), "/home"); // => "/home" - assert.equal(simplifyPath("/a/./b/../../c/"), "/c"); // => "/c" - assert.equal(simplifyPath("/a/../../b/../c//.//"), "/c"); // => "/c" - assert.equal(simplifyPath("/a//b////c/d//././/.."), "/a/b/c") // => "/a/b/c" -} - -module.exports.main = main +module.exports.simplifyPath = simplifyPath; diff --git a/LeetcodeProblems/Spiral_Matrix.js b/LeetcodeProblems/Spiral_Matrix.js index 21a4453..96f078e 100644 --- a/LeetcodeProblems/Spiral_Matrix.js +++ b/LeetcodeProblems/Spiral_Matrix.js @@ -67,17 +67,4 @@ var printRect = function(matrix, i, rowLength, colLength, retArray) { } } -var main = function() { - const matrix = [ - [ 1, 2, 3 ], - [ 4, 5, 6 ], - [ 7, 8, 9 ] - ] - - assert.deepEqual( - spiralOrder(matrix), - [1, 2, 3, 6, 9, 8, 7, 4, 5] - ) -} - -module.exports.main = main; +module.exports.spiralOrder = spiralOrder; diff --git a/LeetcodeProblems/Subarray_Sum_Equals_K.js b/LeetcodeProblems/Subarray_Sum_Equals_K.js index d761e46..1dca41c 100644 --- a/LeetcodeProblems/Subarray_Sum_Equals_K.js +++ b/LeetcodeProblems/Subarray_Sum_Equals_K.js @@ -60,15 +60,4 @@ var subarraySum2 = function(nums, k) { return ret; }; -var main = function() { - test(); -} - -var test = function() { - assert.strictEqual(subarraySum([1,1,1], 2), 2); - assert.strictEqual(subarraySum([1], 0), 0); - assert.strictEqual(subarraySum([0], 0), 1); - assert.strictEqual(subarraySum([0,0,0,0,0], 0), 15); -} - -module.exports.main = main; +module.exports.subarraySum = subarraySum; diff --git a/LeetcodeProblems/Subsets.js b/LeetcodeProblems/Subsets.js index ddff800..7b26f17 100644 --- a/LeetcodeProblems/Subsets.js +++ b/LeetcodeProblems/Subsets.js @@ -38,21 +38,4 @@ var subsets = function(nums) { return subsetByPosition(nums, 0, []); }; -function main() { - test(); -} - -function test() { - assert.deepEqual(subsets([]), [[]]); - assert.deepEqual(subsets([1]), [[1], []]); - assert.deepEqual( - subsets([1,2]), - [[1, 2], [1], [2], []] - ); - assert.deepEqual( - subsets([1, 2, 3]), - [[1, 2, 3], [1, 2], [1, 3], [1], [2, 3], [2], [3], []] - ); -} - -module.exports.main = main; +module.exports.subsets = subsets; diff --git a/LeetcodeProblems/Sum_Of_Square_Numbers.js b/LeetcodeProblems/Sum_Of_Square_Numbers.js index f897ed0..ae97bb9 100644 --- a/LeetcodeProblems/Sum_Of_Square_Numbers.js +++ b/LeetcodeProblems/Sum_Of_Square_Numbers.js @@ -14,8 +14,6 @@ Input: 3 Output: False */ - - /** * @param {number} c * @return {boolean} @@ -35,18 +33,4 @@ var judgeSquareSum = function(c) { return false; }; -var main = function() { - test(); -} - -var test = function() { - assert.strictEqual(judgeSquareSum(0), true); - assert.strictEqual(judgeSquareSum(1), true); - assert.strictEqual(judgeSquareSum(5), true); - assert.strictEqual(judgeSquareSum(16), true); - assert.strictEqual(judgeSquareSum(24), false); - assert.strictEqual(judgeSquareSum(25), true); -} - -module.exports.main = main; - +module.exports.judgeSquareSum = judgeSquareSum; diff --git a/LeetcodeProblems/Swap_Nodes_In_Pairs.js b/LeetcodeProblems/Swap_Nodes_In_Pairs.js index e1a98c3..0ee2002 100644 --- a/LeetcodeProblems/Swap_Nodes_In_Pairs.js +++ b/LeetcodeProblems/Swap_Nodes_In_Pairs.js @@ -13,9 +13,6 @@ Your algorithm should use only constant extra space. You may not modify the values in the list's nodes, only nodes itself may be changed. */ -const ListNode = require('../UtilsClasses/ListNode').ListNode; -const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); - /** * Definition for singly-linked list. * function ListNode(val) { @@ -49,15 +46,4 @@ var swapPairs = function(head) { return head; }; -var main = function() { - test(); -} - -var test = function () { - ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1,2,3,4])), [2,1,4,3]); - ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([])), []); - ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1])), [1]); - ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1,2])), [2, 1]); -} - -module.exports.main = main; +module.exports.swapPairs = swapPairs; diff --git a/LeetcodeProblems/Tic_Tac_Toe.js b/LeetcodeProblems/Tic_Tac_Toe.js index 363a14a..f3dcfc0 100644 --- a/LeetcodeProblems/Tic_Tac_Toe.js +++ b/LeetcodeProblems/Tic_Tac_Toe.js @@ -26,11 +26,13 @@ class TicTacToe { }; printBoard() { + console.log("-------"); for(var row = 0; row < 3; row ++) { console.log(this.matrix[row][0] + "|" + this.matrix[row][1] + "|" + this.matrix[row][2]); // Check new line; } + console.log("------- \n"); } isBoardFull() { @@ -46,41 +48,19 @@ class TicTacToe { return true; } - makeMove() { + makeMove(str) { if(this.isBoardFull()) { throw "Error Board is Full"; } for(var row = 0; row < 3; row ++) { for(var col = 0; col < 3; col ++) { if(this.matrix[row][col] === "-") { - this.addToken(row, col, "0"); + this.addToken(row, col, str); + return true; } - } + } } } } -var main = function() { - console.log("TBD"); -} - -module.exports.main = main; - -ticTacToe = new TicTacToe(); -ticTacToe.isBoardFull(); -ticTacToe.addToken(0,1,"X"); -ticTacToe.printBoard(); -var iter = 0; -while(iter < 8) { - ticTacToe.makeMove(); - iter++; -} - -console.log("after 8 moves"); -ticTacToe.isBoardFull(); -ticTacToe.printBoard(); -ticTacToe.makeMove(); - -ticTacToe.printBoard(); -ticTacToe.addToken(0,0,"X"); -ticTacToe.printBoard(); +module.exports.TicTacToe = TicTacToe; diff --git a/LeetcodeProblems/Unique_Binary_Search_Trees.js b/LeetcodeProblems/Unique_Binary_Search_Trees.js index 4b8726b..b469951 100644 --- a/LeetcodeProblems/Unique_Binary_Search_Trees.js +++ b/LeetcodeProblems/Unique_Binary_Search_Trees.js @@ -22,8 +22,6 @@ Given n = 3, there are a total of 5 unique BST's: DP Solution: https://www.programcreek.com/2014/05/leetcode-unique-binary-search-trees-java/ */ - - // Solution 3 using DP var numTrees3 = function (n) { if (n == 0) @@ -109,25 +107,6 @@ var numTreesAux1 = function(leftMin, leftMax) { return count; } -var main = function() { - test(); -} - -var test = function () { - assert.strictEqual(numTrees1(1), 1); - assert.strictEqual(numTrees1(2), 2); - assert.strictEqual(numTrees1(3), 5); - assert.strictEqual(numTrees1(5), 42); - - assert.strictEqual(numTrees2(1), 1); - assert.strictEqual(numTrees2(2), 2); - assert.strictEqual(numTrees2(3), 5); - assert.strictEqual(numTrees2(5), 42); - - assert.strictEqual(numTrees3(1), 1); - assert.strictEqual(numTrees3(2), 2); - assert.strictEqual(numTrees3(3), 5); - assert.strictEqual(numTrees3(5), 42); -} - -module.exports.main = main \ No newline at end of file +module.exports.numTrees1 = numTrees1; +module.exports.numTrees2 = numTrees2; +module.exports.numTrees3 = numTrees3; diff --git a/LeetcodeProblems/Unique_Paths.js b/LeetcodeProblems/Unique_Paths.js index b8e9290..b7ba36c 100644 --- a/LeetcodeProblems/Unique_Paths.js +++ b/LeetcodeProblems/Unique_Paths.js @@ -26,8 +26,6 @@ Output: 28 // Solution 1 // This solution is a naive solution implementing a binary tree and visiting each node. - - var uniquePaths1 = function(m, n) { return uniquePathsAux(0, 0, m, n) }; @@ -96,13 +94,6 @@ var uniquePaths3 = function(m, n) { return matrix[m - 1][n - 1]; }; -var main = function() { - test(); -} - -var test = function() { - assert.strictEqual(uniquePaths1(10,4), 220); - assert.strictEqual(uniquePaths1(3,2), 3); -} - -module.exports.main = main; \ No newline at end of file +module.exports.uniquePaths1 = uniquePaths1; +module.exports.uniquePaths2 = uniquePaths1; +module.exports.uniquePaths3 = uniquePaths3; diff --git a/LeetcodeProblems/Valid_Parentheses.js b/LeetcodeProblems/Valid_Parentheses.js index 3702004..c65f037 100644 --- a/LeetcodeProblems/Valid_Parentheses.js +++ b/LeetcodeProblems/Valid_Parentheses.js @@ -32,8 +32,6 @@ Input: "{[]}" Output: true */ - - var isValid = function(s) { var stack = []; for(var i = 0; i < s.length; i++) { @@ -58,16 +56,4 @@ var valid = function(parOpen, parClose) { parOpen === "{" && parClose === "}"; } -var main = function(){ - test(); -} - -var test = function () { - assert.strictEqual(isValid(""), true); - assert.strictEqual(isValid("()"), true); - assert.strictEqual(isValid("([)]"), false); - assert.strictEqual(isValid("{[()]}{[()]}"), true); - assert.strictEqual(isValid("{[())()]}"), false); -} - -module.exports.main = main +module.exports.isValid = isValid; diff --git a/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js b/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js index 1d6be1a..1fed956 100644 --- a/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js +++ b/LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree.js @@ -64,17 +64,4 @@ var isValidSerialization = function(preorder) { return countP === 0 && iter >= preorder.length; }; -var main = function() { - test(); -} - -var test = function() { - assert.strictEqual(isValidSerialization(""), true); - assert.strictEqual(isValidSerialization(""), true); - assert.strictEqual(isValidSerialization("#"), true); - assert.strictEqual(isValidSerialization("9,3,4,#,#,1,#,#,2,#,6,#,#"), true); - assert.strictEqual(isValidSerialization("9,#,92,#,#"), true); - assert.strictEqual(isValidSerialization("9,3,4,#,#,1,#,#,#,2,#,6,#,#"), false); -}; - -module.exports.main = main; +module.exports.isValidSerialization = isValidSerialization; diff --git a/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js b/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js index 45c4485..c0b0d38 100644 --- a/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js +++ b/LeetcodeProblemsTests/SearchIng_Rotated_Sorted_Array_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const search = require('../LeetcodeProblems/SearchIng_Rotated_Sorted_Array').search; var test = function() { assert.equal(search([4,5,6,7,0,1,2], 5), 1); diff --git a/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js b/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js index e6eb870..8491aba 100644 --- a/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js +++ b/LeetcodeProblemsTests/Search_a_2D_Matrix_II_Test.js @@ -1,4 +1,13 @@ const assert = require('assert'); +const searchMatrix = require('../LeetcodeProblems/Search_a_2D_Matrix_II').searchMatrix; + +const matrix1 = [ + [1,4,7, 11,15], + [2,5,8, 12,19], + [3,6,9, 16,22], + [10,13,14, 17,24], + [18,21,23, 26,30] +]; var test = function() { assert.equal(searchMatrix(matrix1, 5), true); diff --git a/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js b/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js index 7dbe29d..1c0a741 100644 --- a/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js +++ b/LeetcodeProblemsTests/Search_a_2D_Matrix_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const searchMatrix = require('../LeetcodeProblems/Search_a_2D_Matrix').searchMatrix; var test = function() { assert.equal(searchMatrix([], 0), false); diff --git a/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js b/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js index 6b628dc..494ec09 100644 --- a/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js +++ b/LeetcodeProblemsTests/Set_Matrix_Zeroes_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const setZeroes = require('../LeetcodeProblems/Set_Matrix_Zeroes').setZeroes; var test = function() { assert.deepEqual( diff --git a/LeetcodeProblemsTests/Simplify_Path_Test.js b/LeetcodeProblemsTests/Simplify_Path_Test.js index f0f60a0..f34a896 100644 --- a/LeetcodeProblemsTests/Simplify_Path_Test.js +++ b/LeetcodeProblemsTests/Simplify_Path_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const simplifyPath = require('../LeetcodeProblems/Simplify_Path').simplifyPath; var test = function() { assert.equal(simplifyPath("/../c"), "/c"); diff --git a/LeetcodeProblemsTests/Spiral_Matrix_Test.js b/LeetcodeProblemsTests/Spiral_Matrix_Test.js index c8af84e..d7c9dd6 100644 --- a/LeetcodeProblemsTests/Spiral_Matrix_Test.js +++ b/LeetcodeProblemsTests/Spiral_Matrix_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const spiralOrder = require('../LeetcodeProblems/Spiral_Matrix').spiralOrder; var test = function() { const matrix = [ diff --git a/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js b/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js index 0c5e9d8..3edf120 100644 --- a/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js +++ b/LeetcodeProblemsTests/Subarray_Sum_Equals_K_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const subarraySum = require('../LeetcodeProblems/Subarray_Sum_Equals_K').subarraySum; var test = function() { assert.strictEqual(subarraySum([1,1,1], 2), 2); diff --git a/LeetcodeProblemsTests/Subsets_Test.js b/LeetcodeProblemsTests/Subsets_Test.js index aa0789d..f103e90 100644 --- a/LeetcodeProblemsTests/Subsets_Test.js +++ b/LeetcodeProblemsTests/Subsets_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const subsets = require('../LeetcodeProblems/Subsets').subsets; function test() { assert.deepEqual(subsets([]), [[]]); diff --git a/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js b/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js index 09a2198..41c777a 100644 --- a/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js +++ b/LeetcodeProblemsTests/Sum_Of_Square_Numbers_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const judgeSquareSum = require('../LeetcodeProblems/Sum_Of_Square_Numbers').judgeSquareSum; var test = function() { assert.strictEqual(judgeSquareSum(0), true); diff --git a/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js b/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js index 6e886d0..ef0785d 100644 --- a/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js +++ b/LeetcodeProblemsTests/Swap_Nodes_In_Pairs_Test.js @@ -1,6 +1,7 @@ const assert = require('assert'); const ListNode = require('../UtilsClasses/ListNode').ListNode; const ListNodeTestHelper = require('../utilsClasses/ListNodeTestHelper'); +const swapPairs = require('../LeetcodeProblems/Swap_Nodes_In_Pairs').swapPairs; var test = function () { ListNodeTestHelper.assertList(swapPairs(ListNode.linkenList([1,2,3,4])), [2,1,4,3]); diff --git a/LeetcodeProblemsTests/Symmetric_Tree_Test.js b/LeetcodeProblemsTests/Symmetric_Tree_Test.js index 1805f10..ea8b26b 100644 --- a/LeetcodeProblemsTests/Symmetric_Tree_Test.js +++ b/LeetcodeProblemsTests/Symmetric_Tree_Test.js @@ -1,5 +1,5 @@ var test = function() { // TODO -} +} module.exports.test = test; diff --git a/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js b/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js index d2a3aff..ef69075 100644 --- a/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js +++ b/LeetcodeProblemsTests/Tic_Tac_Toe_Test.js @@ -1,5 +1,25 @@ +const TicTacToe = require('../LeetcodeProblems/Tic_Tac_Toe').TicTacToe; + var test = function() { - // TODO + ticTacToe = new TicTacToe(); + ticTacToe.isBoardFull(); + ticTacToe.addToken(0, 1, "X"); + ticTacToe.printBoard(); + var iter = 0; + + while(iter < 8) { + console.log(iter); + const str = (iter % 2 == 0) ? "0" : "X" + ticTacToe.makeMove(str); + iter++; + } + + console.log("after 8 moves"); + ticTacToe.isBoardFull(); + ticTacToe.printBoard(); + + ticTacToe.addToken(0,0,"X"); + ticTacToe.printBoard(); } -module.exports.test = test; \ No newline at end of file +module.exports.test = test; diff --git a/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js b/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js index a44a4c4..604e489 100644 --- a/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js +++ b/LeetcodeProblemsTests/Unique_Binary_Search_Trees_Test.js @@ -1,4 +1,7 @@ const assert = require('assert'); +const numTrees1 = require('../LeetcodeProblems/Unique_Binary_Search_Trees').numTrees1; +const numTrees2 = require('../LeetcodeProblems/Unique_Binary_Search_Trees').numTrees2; +const numTrees3 = require('../LeetcodeProblems/Unique_Binary_Search_Trees').numTrees3; var test = function () { assert.strictEqual(numTrees1(1), 1); diff --git a/LeetcodeProblemsTests/Unique_Paths_Test.js b/LeetcodeProblemsTests/Unique_Paths_Test.js index 600569e..6334b95 100644 --- a/LeetcodeProblemsTests/Unique_Paths_Test.js +++ b/LeetcodeProblemsTests/Unique_Paths_Test.js @@ -1,8 +1,17 @@ const assert = require('assert'); +const uniquePaths1 = require('../LeetcodeProblems/Unique_Paths').uniquePaths1; +const uniquePaths2 = require('../LeetcodeProblems/Unique_Paths').uniquePaths2; +const uniquePaths3 = require('../LeetcodeProblems/Unique_Paths').uniquePaths3; var test = function() { assert.strictEqual(uniquePaths1(10,4), 220); assert.strictEqual(uniquePaths1(3,2), 3); + + assert.strictEqual(uniquePaths2(10,4), 220); + assert.strictEqual(uniquePaths2(3,2), 3); + + assert.strictEqual(uniquePaths3(10,4), 220); + assert.strictEqual(uniquePaths3(3,2), 3); } module.exports.test = test; diff --git a/LeetcodeProblemsTests/Valid_Parentheses_Test.js b/LeetcodeProblemsTests/Valid_Parentheses_Test.js index 767f909..7e3baee 100644 --- a/LeetcodeProblemsTests/Valid_Parentheses_Test.js +++ b/LeetcodeProblemsTests/Valid_Parentheses_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const isValid = require('../LeetcodeProblems/Valid_Parentheses').isValid; var test = function () { assert.strictEqual(isValid(""), true); diff --git a/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js b/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js index 51eaabc..9f8b65d 100644 --- a/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js +++ b/LeetcodeProblemsTests/Verify_Preorder_Serialization_of_a_Binary_Tree_Test.js @@ -1,4 +1,5 @@ const assert = require('assert'); +const isValidSerialization = require('../LeetcodeProblems/Verify_Preorder_Serialization_of_a_Binary_Tree').isValidSerialization; var test = function() { assert.strictEqual(isValidSerialization(""), true); From aff33a404d19a695a5dad4858efc1d84ce47edf5 Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 6 Sep 2020 18:37:56 -0400 Subject: [PATCH 10/11] Run all the tests successfully --- .../Regular_Expression_Matching.js | 2 +- Main.js | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/LeetcodeProblems/Regular_Expression_Matching.js b/LeetcodeProblems/Regular_Expression_Matching.js index 67ed0ae..b90d2aa 100644 --- a/LeetcodeProblems/Regular_Expression_Matching.js +++ b/LeetcodeProblems/Regular_Expression_Matching.js @@ -90,4 +90,4 @@ var canBeZero = function(pattern, posPat) { return posPat == pattern.length; } -module.exports.isMatch = isM.isMatch; +module.exports.isMatch = isMatch; diff --git a/Main.js b/Main.js index 532b015..82723cf 100644 --- a/Main.js +++ b/Main.js @@ -1,20 +1,20 @@ const fs = require('fs'); -const PROBLEMS_FOLDER = './LeetcodeProblems/'; +const TESTS_FOLDER = './LeetcodeProblemsTests/'; const REGEX_PATTERN_HIDDEN_FILES = /(^|\/)\.[^\/\.]/g; var main = async function() { try { const problems = await loadProblems(); - for(i in problems) { - console.log("Solving: " + problems[i] + ":"); - const problem = require(PROBLEMS_FOLDER + problems[i]); + for(i in problems) { + console.log("Solving: " + problems[i]); + const problem = require(TESTS_FOLDER + problems[i]); - if (typeof(problem.main) !=='undefined') { - problem.main(); - console.log("End of the solution for : " + problems[i] + ",\n\n"); + if (typeof(problem.test) !=='undefined') { + problem.test(); + console.log("End of the solution for : " + problems[i] + " \n\n"); } else { - console.warn(problem, "The problem " + problems[i] + " doesn't have a main method implemented."); + console.warn(problem, "The problem " + problems[i] + " doesn't have a test method implemented."); } } } catch (error) { @@ -24,7 +24,7 @@ var main = async function() { var loadProblems = () => { return new Promise(function (resolve, reject) { - fs.readdir(PROBLEMS_FOLDER, (error, files) => { + fs.readdir(TESTS_FOLDER, (error, files) => { if (error) { reject(error); } else { From 03905d43b3e45d0fbd9137171945de6a03516ef5 Mon Sep 17 00:00:00 2001 From: Ignacio Chiazzo Date: Sun, 6 Sep 2020 18:44:27 -0400 Subject: [PATCH 11/11] Update Readme for contributions --- README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 162bfd1..342de61 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,14 @@ Solutions of algorithm problems using Javascript. https://ignacio-chiazzo.github.io/Algorithms-Leetcode-Javascript/ -### Run Scripts +### Structure +The solutions are located under /LeetcodeProblems. Each solutions exports the main function(s) which to be tested. Each problem has a test file located under /LeetcodeProblemsTest. + -Each problem has a main function exported which prints some cases (Tests are going to be added soon 😉)). -To run a specific problem in your console run `node ` (e.g. `node LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js`). +### Run Scripts +To run all the test run `node Main.js` in the console. -You can also run all the problems by running the `Main.js` file. +To run a specific problem in your console, go to the file test, add the call to the test function (`test()` ) and run in the console `node ` (e.g. `node LeetcodeProblems/Lowest_Common_Ancestor_of_a_Binary_Tree.js`). ### Leetcode Problems @@ -80,3 +82,10 @@ You can also run all the problems by running the `Main.js` file. Other languages provides built-in classes (e.g Linked List, Tree, etc). This module contains util classes to use in your problems. +### Contributions + +If you want to contribute to this repo by adding a problem you should: + +1) Add the description of the problem at the top of the file. +2) Add a test file with some test cases. The test file must export a `test()` function which should run all the tests of the file. +3) Add your problem to the Readme so that your problem shows up in the list of solutions.