From 1b192f7e8e1cde8cdedf498a19e8bf8c8e07d388 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Mon, 2 May 2016 19:39:19 -0700 Subject: [PATCH 01/47] adding some more answers --- 51 N-Queens.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/51 N-Queens.js b/51 N-Queens.js index f6e91e9..f710e95 100644 --- a/51 N-Queens.js +++ b/51 N-Queens.js @@ -40,6 +40,10 @@ var helper = function(n, row, columnForRow, res){ var isValid = function(row, columnForRow){ for(var i = 0; i < row; i++){ + // 1. don't have to worry about values on the same column since it will onnly be set once + // 2. same column, columnForRow[row] === columnForRow[i] + // 3. checking both left and right diagonal, Math.abs(columnForRow[row] - columnForRow[i]) === row - i + // Math.abs(columnForRow[row] - columnForRow[i]) is checking both left and right diagonal if(columnForRow[row] === columnForRow[i] || Math.abs(columnForRow[row] - columnForRow[i]) === row - i){ return false; } From 3b706d49b95f789ed33f5dda77b77659f1177dbc Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Mon, 30 May 2016 14:57:57 -0700 Subject: [PATCH 02/47] add some more questions and memo --- 207 Course Schedule.js | 26 ++- 215 Kth Largest Element in an Array.py | 22 ++ 289. Game of Life.js | 67 ++++++ 300 Longest Increasing Subsequence.js | 23 ++ 335 Self Crossing.js | 22 ++ 37 Sudoku Solver.js | 0 4. Median of Two Sorted Arrays.js | 46 ++++ README.md | 294 +++++++++++++------------ Reverse Integer.js | 0 memo.txt | 2 + test.py | 22 ++ 11 files changed, 375 insertions(+), 149 deletions(-) create mode 100644 215 Kth Largest Element in an Array.py create mode 100644 289. Game of Life.js create mode 100644 300 Longest Increasing Subsequence.js create mode 100644 335 Self Crossing.js create mode 100644 37 Sudoku Solver.js create mode 100644 4. Median of Two Sorted Arrays.js create mode 100644 Reverse Integer.js create mode 100644 memo.txt create mode 100644 test.py diff --git a/207 Course Schedule.js b/207 Course Schedule.js index 1b4d16c..63d3216 100644 --- a/207 Course Schedule.js +++ b/207 Course Schedule.js @@ -8,17 +8,25 @@ * @return {boolean} */ + // http://www.cnblogs.com/Liok3187/p/4752700.html + var constructGraph = function(numNodes, pre) { var nodes = []; for (var i = 0; i < numNodes; i++) { var node = {}; node.neighbors = []; - nodes[i] = node; + nodes.push(node); } for (var j = 0; j < pre.length; j++) { - var s = pre[j][1]; - var d = pre[j][0]; - nodes[s].neighbors.push(nodes[d]); + var requiredCourse = pre[j][1]; + var course = pre[j][0]; + // pushing course that require required-course to it's neighbor + // when we go to the required-course, and traverse it's neighbors, we want to make sure that those neighbor doesn't have others that nodes + // that required those neighbor plus those neighbor's required-course + // example [1,0], [0,2], [2,1] + // 1 required 0, 0 required 2, and 2 required 1 + // it creates loop + nodes[requiredCourse].neighbors.push(nodes[course]); } return nodes; } @@ -42,9 +50,13 @@ var canFinish = function(numCourses, prerequisites) { var nodes = constructGraph(numCourses, prerequisites); for (var i = 0; i < nodes.length; i++) { - console.log('nodes i',nodes[i]) - var hasCycle = dfs(nodes[i], []); + var parent = []; + var hasCycle = dfs(nodes[i], parent); + + console.log(hasCycle, i, nodes[i], parent) if (hasCycle) return false; } return true; -}; \ No newline at end of file +}; + +canFinish(5, [[0,1],[1,2],[1,3],[1,4],[2,3]]) \ No newline at end of file diff --git a/215 Kth Largest Element in an Array.py b/215 Kth Largest Element in an Array.py new file mode 100644 index 0000000..f73c7e9 --- /dev/null +++ b/215 Kth Largest Element in an Array.py @@ -0,0 +1,22 @@ +class Solution(object): + def findKthLargest(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: int + """ + + pivot = random.choice(nums); + nums1, nums2 = [], [] + for num in nums: + if num > pivot: + nums1.append(num) + elif num < pivot: + nums2.append(num) + + if k <= len(nums1): + return self.findKthLargest(nums1, k) + if k > len(nums) - len(nums2): # draw a graph to visualize it! It's not in the top k assortment, but in the small section + return self.findKthLargest(nums2, k - (len(nums) - len(nums2))) + + return pivot \ No newline at end of file diff --git a/289. Game of Life.js b/289. Game of Life.js new file mode 100644 index 0000000..4f9e89a --- /dev/null +++ b/289. Game of Life.js @@ -0,0 +1,67 @@ +/** + * @param {number[][]} board + * @return {void} Do not return anything, modify board in-place instead. + */ +var gameOfLife = function(board) { + // 3 over-population or under population + // 2 means reproduction + // 1 is alive + // 0 is dead + // if mod 2 === 1 means the current state is alive else dead + + + var rows = board.length; + var cols = board[0].length; + + for(var i = 0; i < rows; i++) { + for(var j = 0; j < cols; j++) { + var cur = board[i][j]; + var count = 0; + + if(i - 1 >= 0 && j -1 >= 0 && (board[i - 1][j - 1])%2 === 1) { + count++; + } + if(i - 1 >= 0 && (board[i - 1][j])%2 === 1) { + count++; + } + if(i - 1 >= 0 && j + 1 < cols && (board[i - 1][j + 1])%2 === 1) { + count++; + } + if(j - 1 >= 0 && (board[i][j - 1])%2 === 1) { + count++; + } + if(j + 1 < cols && (board[i][j + 1])%2 === 1) { + count++; + } + if(i + 1 < rows && j - 1 >= 0 && (board[i + 1][j - 1])%2 === 1) { + count++; + } + if(i + 1 < rows && (board[i + 1][j])%2 === 1) { + count++; + } + if(i + 1 < rows && j + 1 < cols && (board[i + 1][j + 1])%2 === 1) { + count++; + } + + if(board[i][j] === 1) { + if(count > 3 || count < 2) { + board[i][j] = 3; + } + } else { + if(count === 3) { + board[i][j] = 2; + } + } + } + } + + for(i = 0; i < rows; i++) { + for(j = 0; j < cols; j++) { + if(board[i][j] === 3) { + board[i][j] = 0; + } else if(board[i][j] === 2) { + board[i][j] = 1; + } + } + } +}; \ No newline at end of file diff --git a/300 Longest Increasing Subsequence.js b/300 Longest Increasing Subsequence.js new file mode 100644 index 0000000..f09154e --- /dev/null +++ b/300 Longest Increasing Subsequence.js @@ -0,0 +1,23 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var lengthOfLIS = function(nums) { + var size = nums.length; + + if(size === 0) { + return 0; + } + + var dp = Array.from({length: size}, () => 1); + + for(var i = 0; i < size; i++) { + for(var j = 0; j < i; j++) { + if(nums[i] > nums[j]) { + dp[i] = Math.max(dp[i], dp[j] + 1); + } + } + } + + return Math.max.apply(null, dp); +}; \ No newline at end of file diff --git a/335 Self Crossing.js b/335 Self Crossing.js new file mode 100644 index 0000000..fa51554 --- /dev/null +++ b/335 Self Crossing.js @@ -0,0 +1,22 @@ +/** + * @param {number[]} x + * @return {boolean} + */ + +// http://www.cnblogs.com/grandyang/p/5216856.html +var isSelfCrossing = function(x) { + + for(var i = 3; i < x.length; i++) { + if (x[i] >= x[i - 2] && x[i - 3] >= x[i - 1]) { + return true; + } + if(i >= 4 && x[i-1] == x[i-3] && x[i] >= (x[i-2] - x[i-4])) { + return true; + } + if(i >= 5 && x[i-2] >= x[i-4] && x[i-3] >= x[i-1] && x[i-1] >= (x[i-3] - x[i-5]) && x[i] >= (x[i-2] - x[i-4])) { + return true; + } + } + + return false; +}; \ No newline at end of file diff --git a/37 Sudoku Solver.js b/37 Sudoku Solver.js new file mode 100644 index 0000000..e69de29 diff --git a/4. Median of Two Sorted Arrays.js b/4. Median of Two Sorted Arrays.js new file mode 100644 index 0000000..c740e91 --- /dev/null +++ b/4. Median of Two Sorted Arrays.js @@ -0,0 +1,46 @@ +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ + +// http://blog.csdn.net/yutianzuijin/article/details/11499917 +var findMedianSortedArrays = function(nums1, nums2) { + var m = nums1.length; + var n = nums2.length; + var total = m + n; + + if(total%2 === 1) { + return findKth(nums1, m, nums2, n, parseInt(total/2) + 1); + } else { + return (findKth(nums1, m, nums2, n, parseInt(total/2)) + findKth(nums1, m, nums2, n, parseInt(total/2) + 1))/2; + } +}; + + +function findKth(a, m, b, n, k) { + // always assume that m is equal or smaller than n + if(m > n) { + return findKth(b, n, a, m, k); + } + + if(m === 0) { + return b[k-1]; + } + + if(k === 1) { + return Math.min(a[0],b[0]); + } + + // divide k into two parts + var pa = Math.min(parseInt(k/2), m); + var pb = k - pa; + + if(a[pa - 1] < b[pb - 1]) { + return findKth(a.slice(pa), m - pa, b, n, k - pa); + } else if(a[pa - 1] > b[pb - 1]) { + return findKth(a, m, b.slice(pb), n - pb, k - pb); + } else { + return a[pa - 1]; + } +} \ No newline at end of file diff --git a/README.md b/README.md index 0be90c0..ca7b05c 100644 --- a/README.md +++ b/README.md @@ -1,142 +1,152 @@ -# leetcode-javascript -Leetcode Solutions using Javascript -By Chihung Yu -
-1 Two Sum.js
-100 Same Tree.js
-101 Symmetric Tree.js
-102 Binary Tree Level Order Traversal.js
-103 Binary Tree Zigzag Level Order Traversal.js
-104 Maximum Depth of Binary Tree.js
-105 Construct Binary Tree from Preorder and Inorder Traversal.js
-106 Construct Binary Tree from Inorder and Postorder Traversal.js
-107 Binary Tree Level Order Traversal II.js
-108 Convert Sorted Array to Binary Search Tree.js
-11 Container With Most Water.js
-110 Balanced Binary Tree.js
-111 Minimum Depth of Binary Tree.js
-112 Path Sum.js
-114 Flatten Binary Tree to Linked List.js
-116 Populating Next Right Pointers in Each Node.js
-118 Pascal's Triangle.js
-119 Pascal's Triangle II.js
-12 Integer to Roman.js
-120 Triangle.js
-121 Best Time to Buy and Sell Stock.js
-122 Best Time to Buy and Sell Stock II.js
-127 Word Ladder II.js
-129 Sum Root to Leaf Numbers.js
-13 Roman to Integer.js
-131 Palindrome Partitioning.js
-136 Single Number.js
-137 Single Number II.js
-139 Word Break.js
-14 Longest Common Prefix.js
-141 Linked List Cycle.js
-144 Binary Tree Preorder Traversal My Submissions Question.js
-15 3Sum.js
-150 Evaluate Reverse Polish Notation.js
-151 Reverse Words in a String.js
-152 Maximum Product Subarray.js
-153 Find Minimum in Rotated Sorted Array.js
-155 Min Stack.js
-16 3Sum Closest.js
-160 Intersection Of Two Linked Lists.js
-162 Find Peak Element.js
-165 Compare Version Numbers.js
-166 Fraction to Recurring Decimal.js
-168 Excel Sheet Column Title.js
-169 Majority Element.js
-17 Letter Combinations of a Phone Number.js
-171 Excel Sheet Column Number.js
-172 Factorial Trailing Zeroes.js
-173 Binary Search Tree Iterator.js
-179 Largest Number.js
-189 Rotate Array.js
-19 Remove Nth Node From End of List.js
-190 Reverse Bits.js
-191 Number of 1 Bits.js
-198 House Robber.js
-199 Binary Tree Right Side View.js
-2 Add Two Numbers.js
-20 Valid Parentheses.js
-200 Number of Islands.js
-201 Bitwise AND of Numbers Range.js
-202 Happy Number.js
-203 Remove Linked List Elements.js
-204 Count Primes.js
-205 Isomorphic Strings.js
-206 Reverse Linked List.js
-207 Course Schedule.js
-209 Minimum Size Subarray Sum.js
-21 Merge Two Sorted Lists.js
-211 Add and Search Word - Data structure design.js
-217 Contain Duplicate.js
-219 Contains Duplicate II.js
-22 Generate Parentheses.js
-223 Rectangle Area.js
-225 Implement Stack Using Queues.js
-226 Invert Binary Tree.js
-228 Summary Ranges.js
-229 Majority Element II.js
-231 Power of Two.js
-232 Implement Queue using Stacks.js
-234 Palindrome Linked List.js
-235 Lowest Common Ancestor Of a Binary Search Tree.js
-237 Delete Node in a Linked List.js
-24 Swap nodes in Pairs.js
-240 Search a 2D Matrix II.js
-241 Different Ways to Add Parentheses.js
-242 Valid Anagram.js
-26 Remove Duplicates from Sorted Array.js
-268 Missing Number.js
-27 Remove Element.js
-28 Implement strStr().js
-3 Longest Substring Without Repeating Characters.js
-31 Next Permutation.js
-318 Maximum Product of Word Lengths My Submissions Question.js
-34 Search for a Range.js
-35 Search Insert Position.js
-36 Valid Sudoku.js
-38 Count and Say.js
-39 Combination Sum.js
-40 combination Sum II.js
-43 Multiply Strings.js
-46 Permutations.js
-48 Rotate Image.js
-49 Anagrams.js
-49 Group Anagrams.js
-5 Longest Palindromic Substring.js
-50 Pow(x, n).js
-51 N-Queens.js
-53 Maximum Subarray.js
-54 Spiral Matrix.js
-55 Jump Game.js
-58 Length of Last Word.js
-59 Spiral Matrix II.js
-61 Rotate List.js
-62 Unique Paths.js
-63 Unique Paths II.js
-64 Minimum Path Sum.js
-66 Plus One.js
-67 Add Binary.js
-70 Climbing Stairs.js
-71 Simplify Path.js
-72 Edit Distance.js
-74 Search a 2D Matrix.js
-75 Sort Colors.js
-77 Combinations.js
-8 String to Integer (atoi).js
-80 Remove Duplicates from Sorted Array II.js
-81 Search in Rotated Sorted Array II.js
-82 Remove Duplicates from Sorted List II.js
-83 Remove Duplicates from Sorted List.js
-86 Partition List.js
-88 Merge Sorted Array.js
-9 Palindrome Number.js
-90 Subsets II.js
-91 Decode Ways.js
-92 Reverse Linked List II.js
-93 Restore IP Addresses.js
-94 Binary Tree Inorder Traversal.js
-98 Validate Binary Search Tree.js
\ No newline at end of file +1 Two Sum.js +100 Same Tree.js +101 Symmetric Tree.js +102 Binary Tree Level Order Traversal.js +103 Binary Tree Zigzag Level Order Traversal.js +104 Maximum Depth of Binary Tree.js +105 Construct Binary Tree from Preorder and Inorder Traversal.js +106 Construct Binary Tree from Inorder and Postorder Traversal.js +107 Binary Tree Level Order Traversal II.js +108 Convert Sorted Array to Binary Search Tree.js +11 Container With Most Water.js +110 Balanced Binary Tree.js +111 Minimum Depth of Binary Tree.js +112 Path Sum.js +114 Flatten Binary Tree to Linked List.js +116 Populating Next Right Pointers in Each Node.js +118 Pascal's Triangle.js +119 Pascal's Triangle II.js +12 Integer to Roman.js +120 Triangle.js +121 Best Time to Buy and Sell Stock.js +122 Best Time to Buy and Sell Stock II.js +127 Word Ladder.js +129 Sum Root to Leaf Numbers.js +13 Roman to Integer.js +131 Palindrome Partitioning.js +133 Clone Graph.js +136 Single Number.js +137 Single Number II.js +139 Word Break.js +14 Longest Common Prefix.js +141 Linked List Cycle.js +144 Binary Tree Preorder Traversal My Submissions Question.js +148 Sort List.js +15 3Sum.js +150 Evaluate Reverse Polish Notation.js +151 Reverse Words in a String.js +152 Maximum Product Subarray.js +153 Find Minimum in Rotated Sorted Array.js +155 Min Stack.js +16 3Sum Closest.js +160 Intersection Of Two Linked Lists.js +162 Find Peak Element.js +165 Compare Version Numbers.js +166 Fraction to Recurring Decimal.js +168 Excel Sheet Column Title.js +169 Majority Element.js +17 Letter Combinations of a Phone Number.js +171 Excel Sheet Column Number.js +172 Factorial Trailing Zeroes.js +173 Binary Search Tree Iterator.js +179 Largest Number.js +189 Rotate Array.js +19 Remove Nth Node From End of List.js +190 Reverse Bits.js +191 Number of 1 Bits.js +198 House Robber.js +199 Binary Tree Right Side View.js +2 Add Two Numbers.js +20 Valid Parentheses.js +200 Number of Islands.js +201 Bitwise AND of Numbers Range.js +202 Happy Number.js +203 Remove Linked List Elements.js +204 Count Primes.js +205 Isomorphic Strings.js +206 Reverse Linked List.js +207 Course Schedule.js +208 Implement Trie (Prefix Tree).js +209 Minimum Size Subarray Sum.js +21 Merge Two Sorted Lists.js +211 Add and Search Word - Data structure design.js +215 Kth Largest Element in an Array.py +217 Contain Duplicate.js +219 Contains Duplicate II.js +22 Generate Parentheses.js +220 Contains Duplicate III.js +223 Rectangle Area.js +225 Implement Stack Using Queues.js +226 Invert Binary Tree.js +228 Summary Ranges.js +229 Majority Element II.js +231 Power of Two.js +232 Implement Queue using Stacks.js +233 Number of Digit One.js +234 Palindrome Linked List.js +235 Lowest Common Ancestor Of a Binary Search Tree.js +237 Delete Node in a Linked List.js +24 Swap nodes in Pairs.js +240 Search a 2D Matrix II.js +241 Different Ways to Add Parentheses.js +242 Valid Anagram.js +26 Remove Duplicates from Sorted Array.js +268 Missing Number.js +27 Remove Element.js +279. Perfect Squares.js +28 Implement strStr().js +289. Game of Life.js +297 Serialize and Deserialize Binary Tree My Submissions Question.js +3 Longest Substring Without Repeating Characters.js +300 Longest Increasing Subsequence.js +31 Next Permutation.js +318 Maximum Product of Word Lengths My Submissions Question.js +322 Coin Change.js +335 Self Crossing.js +34 Search for a Range.js +35 Search Insert Position.js +36 Valid Sudoku.js +37 Sudoku Solver.js +38 Count and Say.js +39 Combination Sum.js +4. Median of Two Sorted Arrays.js +40 combination Sum II.js +43 Multiply Strings.js +46 Permutations.js +48 Rotate Image.js +49 Anagrams.js +49 Group Anagrams.js +5 Longest Palindromic Substring.js +50 Pow(x, n).js +51 N-Queens.js +53 Maximum Subarray.js +54 Spiral Matrix.js +55 Jump Game.js +58 Length of Last Word.js +59 Spiral Matrix II.js +61 Rotate List.js +62 Unique Paths.js +63 Unique Paths II.js +64 Minimum Path Sum.js +66 Plus One.js +67 Add Binary.js +70 Climbing Stairs.js +71 Simplify Path.js +72 Edit Distance.js +74 Search a 2D Matrix.js +75 Sort Colors.js +77 Combinations.js +8 String to Integer (atoi).js +80 Remove Duplicates from Sorted Array II.js +81 Search in Rotated Sorted Array II.js +82 Remove Duplicates from Sorted List II.js +83 Remove Duplicates from Sorted List.js +86 Partition List.js +88 Merge Sorted Array.js +9 Palindrome Number.js +90 Subsets II.js +91 Decode Ways.js +92 Reverse Linked List II.js +93 Restore IP Addresses.js +94 Binary Tree Inorder Traversal.js +98 Validate Binary Search Tree.js \ No newline at end of file diff --git a/Reverse Integer.js b/Reverse Integer.js new file mode 100644 index 0000000..e69de29 diff --git a/memo.txt b/memo.txt new file mode 100644 index 0000000..4fc3db6 --- /dev/null +++ b/memo.txt @@ -0,0 +1,2 @@ +Q: Find Kth smallest/largest in an on sort order +A: Use quick select! O(n) \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..f86a98e --- /dev/null +++ b/test.py @@ -0,0 +1,22 @@ +class Solution(object): + def increasingTriplet(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + a = b = None + for n in nums: + if a is None or a >= n: + a = n + print "a: ", a + elif b is None or b >= n: + b = n + print "b: ", b + else: + return True + return False + +foo = Solution() +print foo.increasingTriplet([1,2,3]) +print foo.increasingTriplet([3,2,1]) +print foo.increasingTriplet([1,1,2]) \ No newline at end of file From 9c2caa9d04ddb0a520b2cc0ce88cfbdfa3ef4e8b Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Mon, 30 May 2016 14:59:14 -0700 Subject: [PATCH 03/47] modify readme --- README.md | 306 +++++++++++++++++++++++++++--------------------------- 1 file changed, 154 insertions(+), 152 deletions(-) diff --git a/README.md b/README.md index ca7b05c..e876c20 100644 --- a/README.md +++ b/README.md @@ -1,152 +1,154 @@ -1 Two Sum.js -100 Same Tree.js -101 Symmetric Tree.js -102 Binary Tree Level Order Traversal.js -103 Binary Tree Zigzag Level Order Traversal.js -104 Maximum Depth of Binary Tree.js -105 Construct Binary Tree from Preorder and Inorder Traversal.js -106 Construct Binary Tree from Inorder and Postorder Traversal.js -107 Binary Tree Level Order Traversal II.js -108 Convert Sorted Array to Binary Search Tree.js -11 Container With Most Water.js -110 Balanced Binary Tree.js -111 Minimum Depth of Binary Tree.js -112 Path Sum.js -114 Flatten Binary Tree to Linked List.js -116 Populating Next Right Pointers in Each Node.js -118 Pascal's Triangle.js -119 Pascal's Triangle II.js -12 Integer to Roman.js -120 Triangle.js -121 Best Time to Buy and Sell Stock.js -122 Best Time to Buy and Sell Stock II.js -127 Word Ladder.js -129 Sum Root to Leaf Numbers.js -13 Roman to Integer.js -131 Palindrome Partitioning.js -133 Clone Graph.js -136 Single Number.js -137 Single Number II.js -139 Word Break.js -14 Longest Common Prefix.js -141 Linked List Cycle.js -144 Binary Tree Preorder Traversal My Submissions Question.js -148 Sort List.js -15 3Sum.js -150 Evaluate Reverse Polish Notation.js -151 Reverse Words in a String.js -152 Maximum Product Subarray.js -153 Find Minimum in Rotated Sorted Array.js -155 Min Stack.js -16 3Sum Closest.js -160 Intersection Of Two Linked Lists.js -162 Find Peak Element.js -165 Compare Version Numbers.js -166 Fraction to Recurring Decimal.js -168 Excel Sheet Column Title.js -169 Majority Element.js -17 Letter Combinations of a Phone Number.js -171 Excel Sheet Column Number.js -172 Factorial Trailing Zeroes.js -173 Binary Search Tree Iterator.js -179 Largest Number.js -189 Rotate Array.js -19 Remove Nth Node From End of List.js -190 Reverse Bits.js -191 Number of 1 Bits.js -198 House Robber.js -199 Binary Tree Right Side View.js -2 Add Two Numbers.js -20 Valid Parentheses.js -200 Number of Islands.js -201 Bitwise AND of Numbers Range.js -202 Happy Number.js -203 Remove Linked List Elements.js -204 Count Primes.js -205 Isomorphic Strings.js -206 Reverse Linked List.js -207 Course Schedule.js -208 Implement Trie (Prefix Tree).js -209 Minimum Size Subarray Sum.js -21 Merge Two Sorted Lists.js -211 Add and Search Word - Data structure design.js -215 Kth Largest Element in an Array.py -217 Contain Duplicate.js -219 Contains Duplicate II.js -22 Generate Parentheses.js -220 Contains Duplicate III.js -223 Rectangle Area.js -225 Implement Stack Using Queues.js -226 Invert Binary Tree.js -228 Summary Ranges.js -229 Majority Element II.js -231 Power of Two.js -232 Implement Queue using Stacks.js -233 Number of Digit One.js -234 Palindrome Linked List.js -235 Lowest Common Ancestor Of a Binary Search Tree.js -237 Delete Node in a Linked List.js -24 Swap nodes in Pairs.js -240 Search a 2D Matrix II.js -241 Different Ways to Add Parentheses.js -242 Valid Anagram.js -26 Remove Duplicates from Sorted Array.js -268 Missing Number.js -27 Remove Element.js -279. Perfect Squares.js -28 Implement strStr().js -289. Game of Life.js -297 Serialize and Deserialize Binary Tree My Submissions Question.js -3 Longest Substring Without Repeating Characters.js -300 Longest Increasing Subsequence.js -31 Next Permutation.js -318 Maximum Product of Word Lengths My Submissions Question.js -322 Coin Change.js -335 Self Crossing.js -34 Search for a Range.js -35 Search Insert Position.js -36 Valid Sudoku.js -37 Sudoku Solver.js -38 Count and Say.js -39 Combination Sum.js -4. Median of Two Sorted Arrays.js -40 combination Sum II.js -43 Multiply Strings.js -46 Permutations.js -48 Rotate Image.js -49 Anagrams.js -49 Group Anagrams.js -5 Longest Palindromic Substring.js -50 Pow(x, n).js -51 N-Queens.js -53 Maximum Subarray.js -54 Spiral Matrix.js -55 Jump Game.js -58 Length of Last Word.js -59 Spiral Matrix II.js -61 Rotate List.js -62 Unique Paths.js -63 Unique Paths II.js -64 Minimum Path Sum.js -66 Plus One.js -67 Add Binary.js -70 Climbing Stairs.js -71 Simplify Path.js -72 Edit Distance.js -74 Search a 2D Matrix.js -75 Sort Colors.js -77 Combinations.js -8 String to Integer (atoi).js -80 Remove Duplicates from Sorted Array II.js -81 Search in Rotated Sorted Array II.js -82 Remove Duplicates from Sorted List II.js -83 Remove Duplicates from Sorted List.js -86 Partition List.js -88 Merge Sorted Array.js -9 Palindrome Number.js -90 Subsets II.js -91 Decode Ways.js -92 Reverse Linked List II.js -93 Restore IP Addresses.js -94 Binary Tree Inorder Traversal.js -98 Validate Binary Search Tree.js \ No newline at end of file +Leetcode Problems in Javascript + +1 Two Sum
+100 Same Tree
+101 Symmetric Tree
+102 Binary Tree Level Order Traversal
+103 Binary Tree Zigzag Level Order Traversal
+104 Maximum Depth of Binary Tree
+105 Construct Binary Tree from Preorder and Inorder Traversal
+106 Construct Binary Tree from Inorder and Postorder Traversal
+107 Binary Tree Level Order Traversal II
+108 Convert Sorted Array to Binary Search Tree
+11 Container With Most Water
+110 Balanced Binary Tree
+111 Minimum Depth of Binary Tree
+112 Path Sum
+114 Flatten Binary Tree to Linked List
+116 Populating Next Right Pointers in Each Node
+118 Pascal's Triangle
+119 Pascal's Triangle II
+12 Integer to Roman
+120 Triangle
+121 Best Time to Buy and Sell Stock
+122 Best Time to Buy and Sell Stock II
+127 Word Ladder
+129 Sum Root to Leaf Numbers
+13 Roman to Integer
+131 Palindrome Partitioning
+133 Clone Graph
+136 Single Number
+137 Single Number II
+139 Word Break
+14 Longest Common Prefix
+141 Linked List Cycle
+144 Binary Tree Preorder Traversal My Submissions Question
+148 Sort List
+15 3Sum
+150 Evaluate Reverse Polish Notation
+151 Reverse Words in a String
+152 Maximum Product Subarray
+153 Find Minimum in Rotated Sorted Array
+155 Min Stack
+16 3Sum Closest
+160 Intersection Of Two Linked Lists
+162 Find Peak Element
+165 Compare Version Numbers
+166 Fraction to Recurring Decimal
+168 Excel Sheet Column Title
+169 Majority Element
+17 Letter Combinations of a Phone Number
+171 Excel Sheet Column Number
+172 Factorial Trailing Zeroes
+173 Binary Search Tree Iterator
+179 Largest Number
+189 Rotate Array
+19 Remove Nth Node From End of List
+190 Reverse Bits
+191 Number of 1 Bits
+198 House Robber
+199 Binary Tree Right Side View
+2 Add Two Numbers
+20 Valid Parentheses
+200 Number of Islands
+201 Bitwise AND of Numbers Range
+202 Happy Number
+203 Remove Linked List Elements
+204 Count Primes
+205 Isomorphic Strings
+206 Reverse Linked List
+207 Course Schedule
+208 Implement Trie (Prefix Tree)
+209 Minimum Size Subarray Sum
+21 Merge Two Sorted Lists
+211 Add and Search Word - Data structure design
+215 Kth Largest Element in an Array
+217 Contain Duplicate
+219 Contains Duplicate II
+22 Generate Parentheses
+220 Contains Duplicate III
+223 Rectangle Area
+225 Implement Stack Using Queues
+226 Invert Binary Tree
+228 Summary Ranges
+229 Majority Element II
+231 Power of Two
+232 Implement Queue using Stacks
+233 Number of Digit One
+234 Palindrome Linked List
+235 Lowest Common Ancestor Of a Binary Search Tree
+237 Delete Node in a Linked List
+24 Swap nodes in Pairs
+240 Search a 2D Matrix II
+241 Different Ways to Add Parentheses
+242 Valid Anagram
+26 Remove Duplicates from Sorted Array
+268 Missing Number
+27 Remove Element
+279. Perfect Squares
+28 Implement strStr()
+289. Game of Life
+297 Serialize and Deserialize Binary Tree My Submissions Question
+3 Longest Substring Without Repeating Characters
+300 Longest Increasing Subsequence
+31 Next Permutation
+318 Maximum Product of Word Lengths My Submissions Question
+322 Coin Change
+335 Self Crossing
+34 Search for a Range
+35 Search Insert Position
+36 Valid Sudoku
+37 Sudoku Solver
+38 Count and Say
+39 Combination Sum
+4. Median of Two Sorted Arrays
+40 combination Sum II
+43 Multiply Strings
+46 Permutations
+48 Rotate Image
+49 Anagrams
+49 Group Anagrams
+5 Longest Palindromic Substring
+50 Pow(x, n)
+51 N-Queens
+53 Maximum Subarray
+54 Spiral Matrix
+55 Jump Game
+58 Length of Last Word
+59 Spiral Matrix II
+61 Rotate List
+62 Unique Paths
+63 Unique Paths II
+64 Minimum Path Sum
+66 Plus One
+67 Add Binary
+70 Climbing Stairs
+71 Simplify Path
+72 Edit Distance
+74 Search a 2D Matrix
+75 Sort Colors
+77 Combinations
+8 String to Integer (atoi)
+80 Remove Duplicates from Sorted Array II
+81 Search in Rotated Sorted Array II
+82 Remove Duplicates from Sorted List II
+83 Remove Duplicates from Sorted List
+86 Partition List
+88 Merge Sorted Array
+9 Palindrome Number
+90 Subsets II
+91 Decode Ways
+92 Reverse Linked List II
+93 Restore IP Addresses
+94 Binary Tree Inorder Traversal
+98 Validate Binary Search Tree
\ No newline at end of file From 75ce46fa6200aab71e67f3a13338115fcd4ae64c Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Mon, 30 May 2016 15:51:18 -0700 Subject: [PATCH 04/47] add kth largest element in an array --- 215 Kth Largest Element in an Array.js | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 215 Kth Largest Element in an Array.js diff --git a/215 Kth Largest Element in an Array.js b/215 Kth Largest Element in an Array.js new file mode 100644 index 0000000..153ecb5 --- /dev/null +++ b/215 Kth Largest Element in an Array.js @@ -0,0 +1,33 @@ +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ + +// use quick select +var findKthLargest = function(nums, k) { + var smaller = []; + var larger = []; + var pivot = nums[parseInt(nums.length/2)]; + var pivotCnt = 0; + + for(var i = 0; i < nums.length; i++) { + var num = nums[i]; + + if(num > pivot) { + larger.push(num); + } else if(num < pivot) { + smaller.push(num); + } else { + pivotCnt++; + } + } + + if(k <= larger.length) { // if larger includes k + return findKthLargest(larger, k); + } else if(k - larger.length - pivotCnt <= 0) { // k is part of pivot + return pivot; + } else { // if smaller inclues k + return findKthLargest(smaller, k - larger.length - pivotCnt); + } +}; \ No newline at end of file From 07360649be84e11d4e03ad1ef3f6d29d226f9cd9 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sun, 19 Jun 2016 12:41:13 -0700 Subject: [PATCH 05/47] add some modification and new problem --- 2 Add Two Numbers.js | 11 ++++ ... Substring Without Repeating Characters.js | 11 ++-- 5 Longest Palindromic Substring.js | 63 +++++++++++++++++-- 9 Palindrome Number.js | 39 +++++++----- Jump Game II.js | 25 ++++++++ Reverse Integer.js | 25 ++++++++ find kth element in two arrays.js | 59 +++++++++++++++++ 7 files changed, 209 insertions(+), 24 deletions(-) create mode 100644 Jump Game II.js create mode 100644 find kth element in two arrays.js diff --git a/2 Add Two Numbers.js b/2 Add Two Numbers.js index 2a492bf..279acbc 100644 --- a/2 Add Two Numbers.js +++ b/2 Add Two Numbers.js @@ -1,3 +1,9 @@ +// You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + +// Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) +// Output: 7 -> 0 -> 8 + + /** * Definition for singly-linked list. * function ListNode(val) { @@ -10,6 +16,11 @@ * @param {ListNode} l2 * @return {ListNode} */ + + + +// value reverse helps to asslign the first digit or both linklist + var addTwoNumbers = function(l1, l2) { if(l1 === null || l2 === null){ return l1 || l2; diff --git a/3 Longest Substring Without Repeating Characters.js b/3 Longest Substring Without Repeating Characters.js index 2405d30..41f4575 100644 --- a/3 Longest Substring Without Repeating Characters.js +++ b/3 Longest Substring Without Repeating Characters.js @@ -2,6 +2,8 @@ * @param {string} s * @return {number} */ + + var lengthOfLongestSubstring = function(s) { if(s === null || s.length === 0){ return 0; @@ -11,16 +13,17 @@ var lengthOfLongestSubstring = function(s) { var len = 0; var maxLen = len; var start = 0; - + + // scan from left to right. for(var i = start; i < s.length; i++){ c = s[i]; if(map[c] !== undefined && map[c] >= start) { - start = map[c] + 1; - len = i - start; + start = map[c] + 1; // start new search with repeated word's last location + 1 + len = i - start; // real length -> from for example 3 to 5 is 3, so it's 5-3+1 and + 1 happens later } - len++; + len++; // real length -> from for example 3 to 5 is 3, so it's 5-3+1 and + 1 happens later if(len > maxLen){ maxLen = len; diff --git a/5 Longest Palindromic Substring.js b/5 Longest Palindromic Substring.js index b9f7bd7..10c8a59 100644 --- a/5 Longest Palindromic Substring.js +++ b/5 Longest Palindromic Substring.js @@ -1,23 +1,34 @@ +// Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. + /** * @param {string} s * @return {string} */ + + var longestPalindrome = function(s) { if(s === null || s.length === 0){ return ""; } var result = ""; + + // The reason to multiply by 2 is because + // Palindrome can be in two forms + // 1. abba There will be case which center has two idenitical charachter, + // And there will be maximum 2*n - 1 such case + // 2. aba There will be case which center has only one character + var len = 2*s.length - 1; + var left, right; - for(var i = (2*s.length) - 1; i--;){ - var left = parseInt(i/2); - var right = parseInt(i/2); + for(var i = 0; i < len; i++){ + left = right = parseInt(i/2); if(i%2 === 1){ right++; } - var str = lengthOfPalindrome(s,left,right); + var str = expandFromCenterAndCheckForPalindrome(s,left,right); if(str.length > result.length){ result = str; @@ -27,7 +38,49 @@ var longestPalindrome = function(s) { }; -var lengthOfPalindrome = function(s, left, right){ +// other implementation + +var longestPalindrome = function(s) { + if(s === null || s.length === 0){ + return ""; + } + + var result = ""; + + // The reason to multiply by 2 is because + // Palindrome can be in two forms + // 1. abba There will be case which center has two idenitical charachter, + // And there will be maximum 2*n - 1 such case + // 2. aba There will be case which center has only one character + var len = s.length; + var left, right; + + for(var i = 0; i < len; i++){ + left = right = i; + + var str = expandFromCenterAndCheckForPalindrome(s,left,right); + if(str.length > result.length){ + result = str; + } + var str = expandFromCenterAndCheckForPalindrome(s,left,right + 1); + if(str.length > result.length){ + result = str; + } + } + return result; +}; + + + +var expandFromCenterAndCheckForPalindrome = function(s, left, right){ + // in the case where left !== right + // that's the case "abba" + // which it checks for if b === b then a === a + + // in the case where left === right + // that's the case "aba" + // which it check if b === b as left === right + // then a === a while(left >= 0 && right < s.length && s[left] === s[right]){ left--; right++; diff --git a/9 Palindrome Number.js b/9 Palindrome Number.js index 86559ae..2fc423b 100644 --- a/9 Palindrome Number.js +++ b/9 Palindrome Number.js @@ -2,35 +2,44 @@ // Language: Javascript // Problem: https://leetcode.com/problems/palindrome-number/ // Author: Chihung Yu -/** - * Leetcode Question + +// Determine whether an integer is a palindrome. Do this without extra space. + + /** * @param {number} x * @return {boolean} */ - var isPalindrome = function(x) { - if(x < 0){ + if(x < 0) { return false; } var div = 1; - while(parseInt(x/div) >= 10){ - div *= 10; + // it means that the div is still a valid divider + // e.g 600 the divider should be 100 at maximum + // e.g. 90 the divider should be 10 at maximum + // e.g. 1 the divider should be a 1 at maximum + while(parseInt(x/div) >= 10) { + div *= 10; } - while(x !== 0){ - var l = parseInt(x/div); - var r = x%10; - - if(l !== r){ + var left, right; + + // when div === 1 it means the digit only has one value to examine + // e.g. 121 -> only 2 is left for examine which can be ignore + // e.g. 1 -> 1 + // e.g. 43234 -> 2 + while(div > 1) { + left = parseInt(x/div); + right = x%10; + if(left !== right) { return false; } - x = x % div; - x = parseInt(x/10); - - div = parseInt(div/100); + x = x%div; // remove the left most digit + x = parseInt(x/10); // remove the right most digit + div /= 100; } return true; diff --git a/Jump Game II.js b/Jump Game II.js new file mode 100644 index 0000000..575f437 --- /dev/null +++ b/Jump Game II.js @@ -0,0 +1,25 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var jump = function(nums) { + var curMax = 0; + var nJumps = 0; + var i = 0; + var n = nums.length; + + while(curMax < n - 1) { + var lastMax = curMax; + // go through covered area + for(; i <= lastMax; i++) { + curMax = Math.max(curMax, i+nums[i]); + } + nJumps++; + // if cannot make progress in the covered area, give up + if(lastMax === curMax) { + return -1; + } + } + + return nJumps; +}; \ No newline at end of file diff --git a/Reverse Integer.js b/Reverse Integer.js index e69de29..d9a8edb 100644 --- a/Reverse Integer.js +++ b/Reverse Integer.js @@ -0,0 +1,25 @@ +/** + * @param {number} x + * @return {number} + */ +var reverse = function(x) { + var isNeg = x < 0; + var result = 0; + + x = Math.abs(x); + + while(x) { + var lastDigit = x%10; + result *= 10; + result += lastDigit; + x = parseInt(x/10); + } + + result = isNeg ? -result : result; + + if(result > Math.pow(2,31) - 1 || result < -Math.pow(2,31)) { + return 0; + } + + return result; +}; \ No newline at end of file diff --git a/find kth element in two arrays.js b/find kth element in two arrays.js new file mode 100644 index 0000000..6c635f7 --- /dev/null +++ b/find kth element in two arrays.js @@ -0,0 +1,59 @@ +var findKth = (a1, a2, kth) => { + var alen1 = a1.length; + var alen2 = a2.length; + + if(alen1 > alen2) { + return findKth(a2, a1, kth); + } + + if(alen1 === 0) { + return a2[kth -1]; + } + + if(kth === 1) { + return Math.min(a1[0], a2[0]); + } + +// need to make sure that kth is not 1 as kth/2 = 0 + var p1 = Math.min(parseInt(kth/2), alen1); + var p2 = kth - p1; + + if(a1[p1 - 1] < a2[p2 - 1]) { + return findKth(a1.slice(p1), a2, kth - p1); + } else if(a1[p1 - 1] > a2[p2 - 1]) { + return findKth(a1, a2.slice(p2), kth - p2); + } else { + return a1[p1 - 1]; + } +} + + +// function findKth(a, aStart, aEnd, b, bStart, bEnd, kth) { +// // use array position rather than use slice to get array +// // always assume that m is equal or smaller than n +// var aLen = aEnd - aStart + 1; // same as a.length as index 3 - 3 = 0 but still it has one element compared to a.length === 0 has notthing +// var bLen = bEnd - bStart + 1; +// var mid; +// if(aLen > bLen) { +// return findKth(b, bStart, bEnd, a, aStart, aEnd, kth); +// } + +// if(aLen <= 0) { +// return b[kth - 1]; +// } + +// if(kth === 1) { +// return Math.min(a[aStart], b[bStart]); +// } + +// var k1 = Math.min(parseInt(kth/2), aLen); +// var k2 = kth - k1; + +// if(a[aStart + k1 - 1] < b[bStart + k2 - 1]) { +// return findKth(a, aStart + k1, aEnd, b, bStart, bEnd, kth -k1); +// } else if(a[aStart + k1 - 1] > b[bStart + k2 - 1]) { +// return findKth(a, aStart, aEnd, b, bStart + k2, bEnd, kth -k2); +// } else { +// return a[aStart + k1 -1]; +// } +// } \ No newline at end of file From 3fad038b20632e3cf57924a374494ab04e5b594a Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Mon, 27 Jun 2016 23:08:27 -0700 Subject: [PATCH 06/47] add some new files --- 10 Regular Expresion Matching.js | 74 ++++ 146 LRU Cache.js | 101 ++++++ 222. Count Complete Tree Nodes.js | 38 +++ ...Lowest Common Ancestor of a Binary Tree.js | 30 ++ 257 Binary Tree Paths.js | 53 +++ 263 Ugly Number.js | 27 ++ 264 Ugly Number II.js | 41 +++ 286 Walls and Gates.js | 73 ++++ 33 Search in Rotated Sorted Array.js | 44 +++ 5 Longest Palindromic Substring.js | 6 - 69 Sqrt(x).js | 30 ++ 96 Unique Binary Search Trees.js | 16 + Hackrank.js | 73 ++++ README.md | 316 +++++++++--------- String Encoding and Decoding.js | 30 ++ flatten nested array.js | 24 ++ 16 files changed, 818 insertions(+), 158 deletions(-) create mode 100644 10 Regular Expresion Matching.js create mode 100644 146 LRU Cache.js create mode 100644 222. Count Complete Tree Nodes.js create mode 100644 236 Lowest Common Ancestor of a Binary Tree.js create mode 100644 257 Binary Tree Paths.js create mode 100644 263 Ugly Number.js create mode 100644 264 Ugly Number II.js create mode 100644 286 Walls and Gates.js create mode 100644 33 Search in Rotated Sorted Array.js create mode 100644 69 Sqrt(x).js create mode 100644 96 Unique Binary Search Trees.js create mode 100644 Hackrank.js create mode 100644 String Encoding and Decoding.js create mode 100644 flatten nested array.js diff --git a/10 Regular Expresion Matching.js b/10 Regular Expresion Matching.js new file mode 100644 index 0000000..5cbe618 --- /dev/null +++ b/10 Regular Expresion Matching.js @@ -0,0 +1,74 @@ +// https://www.youtube.com/watch?v=l3hda49XcDE#t=211.113333 + +// 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). + +// The function prototype should be: +// bool isMatch(const char *s, const char *p) + +// Some examples: +// isMatch("aa","a") → false +// isMatch("aa","aa") → true +// isMatch("aaa","aa") → false +// isMatch("aa", "a*") → true +// isMatch("aa", ".*") → true +// isMatch("ab", ".*") → true +// isMatch("aab", "c*a*b") → true + + +/** + * @param {string} s + * @param {string} p + * @return {boolean} + */ +var isMatch = function(s, p) { + var m = s.length; + var n = p.length; + var dp = []; + + for(var i = 0; i <= m; i++) { + var tmp = []; + + for(var j = 0; j <= n; j++) { + tmp.push(false); + } + + dp.push(tmp); + } + + dp[0][0] = true; + + for(i = 0; i <= m; i++) { + for(j = 0; j <= n; j++) { + if(p[j-1] !== '.' && p[j-1] !== '*') { + if(i > 0 && s[i-1] === p[j-1] && dp[i-1][j-1]) { + dp[i][j] = true; + } + } else if(p[j-1] === '.') { + if(i > 0 && dp[i-1][j-1]) { + dp[i][j] = true; + } + } else if(j > 1) { // '*' cannot be the first element + if(dp[i][j-1] || dp[i][j-2]) { + dp[i][j] = true; + } else if(i > 0 && (p[j-2] == s[i-1] || p[j-2] == '.') && dp[i-1][j]) { + + // example + // xa and xa* + // s[i-1] === a + // p[j-2] === a + // a === a + // so we can now compare x, xa* + // and x here is dp[i-1][j] + dp[i][j] = true; + } + } + } + } + + return dp[m][n]; +}; \ No newline at end of file diff --git a/146 LRU Cache.js b/146 LRU Cache.js new file mode 100644 index 0000000..5a9a2f8 --- /dev/null +++ b/146 LRU Cache.js @@ -0,0 +1,101 @@ +// Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. + +// get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. +// set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. +class Node { + constructor(key, val) { + this.key = key; + this.val = val; + this.next = null; + this.prev = null; + } +} +/** + * @constructor + */ +var LRUCache = function(capacity) { + this.list = null; + this.map = new Map(); + this.head = null; + this.tail = null; + this.size = capacity; + this.curSize = 0; +}; + +/** + * @param {number} key + * @returns {number} + */ +LRUCache.prototype.get = function(key) { + if (!this.map.get(key)) { + return -1; + } + + let node = this.map.get(key); + + if (node === this.head) { + return node.val; + } + + // remove node from list + if (node === this.tail) { + this.tail.prev.next = null; + this.tail = this.tail.prev; + } else { + node.prev.next = node.next; + node.next.prev = node.prev; + } + + // insert node to head + node.next = this.head; + this.head.prev = node; + this.head = node; + + return node.val; +}; + +/** + * @param {number} key + * @param {number} value + * @returns {void} + */ +LRUCache.prototype.set = function(key, value) { + let newNode = new Node(key, value); + + if (this.curSize === 0) { + this.tail = newNode; + } else { + newNode.next = this.head; + this.head.prev = newNode; + } + + this.head = newNode; + this.curSize++; + + // update + if (this.map.get(key)) { + let oldNode = this.map.get(key); + + // remove node + if (oldNode === this.tail) { + this.tail = this.tail.prev; + this.tail.next = null; + } else { + oldNode.prev.next = oldNode.next; + oldNode.next.prev = oldNode.prev; + } + + this.curSize--; + + } else { + if (this.curSize > this.size) { + //delete tail + this.map.delete(this.tail.key); + this.tail = this.tail.prev; + this.tail.next = null; + this.curSize--; + } + } + + this.map.set(key, newNode); +}; \ No newline at end of file diff --git a/222. Count Complete Tree Nodes.js b/222. Count Complete Tree Nodes.js new file mode 100644 index 0000000..3e5fd75 --- /dev/null +++ b/222. Count Complete Tree Nodes.js @@ -0,0 +1,38 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var countNodes = function(root) { + return treeNodes(root); + + function treeNodes(node){ + if(!node){ + return 0; + }else{ + var leftDepth = 0; + var rightDepth = 0; + var leftChild = node.left; + while(leftChild){ + leftDepth++; + leftChild = leftChild.left; + } + var rightChild = node.right; + while(rightChild){ + rightDepth++; + rightChild = rightChild.right; + } + if(leftDepth === rightDepth){ + return Math.pow(2, leftDepth + 1) - 1; + }else{ + return treeNodes(node.left) + treeNodes(node.right) + 1; + } + } + } +}; \ No newline at end of file diff --git a/236 Lowest Common Ancestor of a Binary Tree.js b/236 Lowest Common Ancestor of a Binary Tree.js new file mode 100644 index 0000000..be7c6de --- /dev/null +++ b/236 Lowest Common Ancestor of a Binary Tree.js @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ + +// http://www.cnblogs.com/anne-vista/p/4815076.html +var lowestCommonAncestor = function(root, p, q) { + if(root === null || root === p || root === q) { + return root; + } + + var l = lowestCommonAncestor(root.left, p, q); + var r = lowestCommonAncestor(root.right, p, q); + + if(l !== null && r !== null) { + // p and q are on two different side of root node. + return root; + } + + return (l !== null) ? l : r; // either one of p, q is on one side OR p, q is not in l&r subtrees +}; diff --git a/257 Binary Tree Paths.js b/257 Binary Tree Paths.js new file mode 100644 index 0000000..2d656fb --- /dev/null +++ b/257 Binary Tree Paths.js @@ -0,0 +1,53 @@ +// Given a binary tree, return all root-to-leaf paths. + +// For example, given the following binary tree: + +// 1 +// / \ +// 2 3 +// \ +// 5 +// All root-to-leaf paths are: + +// ["1->2->5", "1->3"] + + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {string[]} + */ +var binaryTreePaths = function(root) { + var result = []; + + if(root !== null) { + traverse(root, [], result); + } + + return result; +}; + +var traverse = function(node, path, result) { + path.push(node.val); + + if(node.left || node.right) { + if(node.left) { + traverse(node.left, path, result); + path.pop(); + } + + if(node.right) { + traverse(node.right, path, result); + path.pop(); + } + // path.pop() + } else { + result.push(path.join("->")); + } +} \ No newline at end of file diff --git a/263 Ugly Number.js b/263 Ugly Number.js new file mode 100644 index 0000000..dc66c4f --- /dev/null +++ b/263 Ugly Number.js @@ -0,0 +1,27 @@ +// 263. Ugly Number + +// Write a program to check whether a given number is an ugly number. + +// Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7. + +// Note that 1 is typically treated as an ugly number. + +/** + * @param {number} num + * @return {boolean} + */ +var isUgly = function(num) { + while(num >= 2) { + if(num%2 === 0) { + num /= 2; + } else if(num%3 === 0) { + num /= 3; + } else if(num%5 === 0) { + num /= 5; + } else { + return false; + } + } + + return num === 1; +}; \ No newline at end of file diff --git a/264 Ugly Number II.js b/264 Ugly Number II.js new file mode 100644 index 0000000..56a8491 --- /dev/null +++ b/264 Ugly Number II.js @@ -0,0 +1,41 @@ +// 264. Ugly Number II + +// Write a program to find the n-th ugly number. + +// Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers. + +// Note that 1 is typically treated as an ugly number. + +/** + * @param {number} n + * @return {number} + */ +var nthUglyNumber = function(n) { + var uglys = [1]; + var p2 = 0; + var p3 = 0; + var p5 = 0; + + while(uglys.length < n) { + var ugly2 = uglys[p2]*2; + var ugly3 = uglys[p3]*3; + var ugly5 = uglys[p5]*5; + + var minV = Math.min(ugly2, ugly3, ugly5); + + if(minV === ugly2) { + p2++; + } + if(minV === ugly3) { + p3++; + } + if(minV === ugly5) { + p5++; + } + if(minV !== uglys[uglys.length - 1]) { + uglys.push(minV); + } + } + + return uglys[n-1]; +}; \ No newline at end of file diff --git a/286 Walls and Gates.js b/286 Walls and Gates.js new file mode 100644 index 0000000..6f32212 --- /dev/null +++ b/286 Walls and Gates.js @@ -0,0 +1,73 @@ +// https://segmentfault.com/a/1190000003906674 + +// You are given a m x n 2D grid initialized with these three possible values. + +// -1 - A wall or an obstacle. +// 0 - A gate. +// INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647. Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF. +// For example, given the 2D grid: + +// INF -1 0 INF +// INF INF INF -1 +// INF -1 INF -1 +// 0 -1 INF INF +// After running your function, the 2D grid should be: + +// 3 -1 0 1 +// 2 2 1 -1 +// 1 -1 2 -1 +// 0 -1 3 4 + + +public class Solution { + public void wallsAndGates(int[][] rooms) { + if(rooms.length == 0) return; + for(int i = 0; i < rooms.length; i++){ + for(int j = 0; j < rooms[0].length; j++){ + // 如果遇到一个门,从门开始广度优先搜索,标记连通的节点到自己的距离 + if(rooms[i][j] == 0) bfs(rooms, i, j); + } + } + } + + public void bfs(int[][] rooms, int i, int j){ + Queue queue = new LinkedList(); + queue.offer(i * rooms[0].length + j); + int dist = 0; + // 用一个集合记录已经访问过的点 + Set visited = new HashSet(); + visited.add(i * rooms[0].length + j); + while(!queue.isEmpty()){ + int size = queue.size(); + // 记录深度的搜索 + for(int k = 0; k < size; k++){ + Integer curr = queue.poll(); + int row = curr / rooms[0].length; + int col = curr % rooms[0].length; + // 选取之前标记的值和当前的距离的较小值 + rooms[row][col] = Math.min(rooms[row][col], dist); + int up = (row - 1) * rooms[0].length + col; + int down = (row + 1) * rooms[0].length + col; + int left = row * rooms[0].length + col - 1; + int right = row * rooms[0].length + col + 1; + if(row > 0 && rooms[row - 1][col] > 0 && !visited.contains(up)){ + queue.offer(up); + visited.add(up); + } + if(col > 0 && rooms[row][col - 1] > 0 && !visited.contains(left)){ + queue.offer(left); + visited.add(left); + } + if(row < rooms.length - 1 && rooms[row + 1][col] > 0 && !visited.contains(down)){ + queue.offer(down); + visited.add(down); + } + if(col < rooms[0].length - 1 && rooms[row][col + 1] > 0 && !visited.contains(right)){ + queue.offer(right); + visited.add(right); + } + } + dist++; + } + } +} \ No newline at end of file diff --git a/33 Search in Rotated Sorted Array.js b/33 Search in Rotated Sorted Array.js new file mode 100644 index 0000000..2fd6ce8 --- /dev/null +++ b/33 Search in Rotated Sorted Array.js @@ -0,0 +1,44 @@ +// Suppose a sorted array 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. + + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var search = function(nums, target) { + var left = 0; + var right = nums.length - 1; + + while(left <= right) { + var mid = parseInt((left + right)/2); + if(nums[mid] === target) { + return mid; + } + + if(nums[mid] >= nums[left]) { + + if(nums[left] <= target && target < nums[mid]) { + // in correct order + right = mid - 1; + } else { + left = mid + 1; + } + } else { + if(nums[mid] < target && target <= nums[right]) { + // in correct order + left = mid + 1; + } else { + right = mid - 1; + } + } + } + + return -1; +}; \ No newline at end of file diff --git a/5 Longest Palindromic Substring.js b/5 Longest Palindromic Substring.js index 10c8a59..74b60c3 100644 --- a/5 Longest Palindromic Substring.js +++ b/5 Longest Palindromic Substring.js @@ -46,12 +46,6 @@ var longestPalindrome = function(s) { } var result = ""; - - // The reason to multiply by 2 is because - // Palindrome can be in two forms - // 1. abba There will be case which center has two idenitical charachter, - // And there will be maximum 2*n - 1 such case - // 2. aba There will be case which center has only one character var len = s.length; var left, right; diff --git a/69 Sqrt(x).js b/69 Sqrt(x).js new file mode 100644 index 0000000..96387c7 --- /dev/null +++ b/69 Sqrt(x).js @@ -0,0 +1,30 @@ +/** +Implement int sqrt(int x). + +Compute and return the square root of x. +*/ +/** + * @param {number} x + * @return {number} + */ +var mySqrt = function(x) { + var start = 1, + end = x, + mid; + + if (x === 0) { + return 0; + } + + while (start + 1 < end) { + mid = start + parseInt((end - start) / 2); + + if (mid * mid <= x) { + start = mid; + } else { + end = mid; + } + } + + return start; +}; diff --git a/96 Unique Binary Search Trees.js b/96 Unique Binary Search Trees.js new file mode 100644 index 0000000..bbc5c9c --- /dev/null +++ b/96 Unique Binary Search Trees.js @@ -0,0 +1,16 @@ +/** + * @param {number} n + * @return {number} + */ +var numTrees = function(n) { + var result = [1, 1]; + + for (var i = 2; i <= n; i++) { + result[i] = 0; + for (var j = 0; j < i; j++) { + result[i] += result[j] * result[i - 1 - j]; + } + + } + return result[n]; +}; diff --git a/Hackrank.js b/Hackrank.js new file mode 100644 index 0000000..b6fc508 --- /dev/null +++ b/Hackrank.js @@ -0,0 +1,73 @@ + + + +process.stdin.resume(); +process.stdin.setEncoding("ascii"); +var input = ""; +process.stdin.on("data", function (chunk) { + input += chunk; +}); +process.stdin.on("end", function () { + actorsInOrder = input.split("\n"); + disambiguated = disambiguateActors(actorsInOrder); + for(var i = 0; i < disambiguated.length; i++) { + console.log(disambiguated[i]); + } +}); + +function disambiguateActors(actorsInOrder) { + // WRITE YOUR CODE HERE + var hash = {}; + + for(var i = 0; i < actorsInOrder.length; i++){ + var actor = actorsInOrder[i]; + if(hash[actor] !== undefined){ + hash[actor] += 1; + } else { + hash[actor] = 1; + } + } + + for(var i = actorsInOrder.length; i--;){ + actor = actorsInOrder[i]; + if(hash[actor] !== 1) { + var count = hash[actor] === -1 ? 1 : hash[actor]; + actorsInOrder[i] = postfixActorName(actor, count); + hash[actor] -= 1; + + if(hash[actor] === 1) { + hash[actor] = -1; + } + } + } + + for(var i = 0; i < actorsInOrder.length; i++){ + console.log(actorsInOrder[i]) + } + +} + +function postfixActorName(actorName, num) { + return actorName + " (" + convertNumberToRomanLetter(num) + ")"; +} + +function convertNumberToRomanLetter(num) { + var dict = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"]; + var val = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; + var result = ""; + + for(var i = 0; i < val.length; i++) { + var v = val[i]; + + if(num >= v) { + var count = parseInt(num/v); + num %= v; + + for(var j = 0; j < count; j++) { + result = result + dict[i]; + } + } + } + + return result; +} \ No newline at end of file diff --git a/README.md b/README.md index e876c20..49e4bc6 100644 --- a/README.md +++ b/README.md @@ -1,154 +1,166 @@ Leetcode Problems in Javascript -1 Two Sum
-100 Same Tree
-101 Symmetric Tree
-102 Binary Tree Level Order Traversal
-103 Binary Tree Zigzag Level Order Traversal
-104 Maximum Depth of Binary Tree
-105 Construct Binary Tree from Preorder and Inorder Traversal
-106 Construct Binary Tree from Inorder and Postorder Traversal
-107 Binary Tree Level Order Traversal II
-108 Convert Sorted Array to Binary Search Tree
-11 Container With Most Water
-110 Balanced Binary Tree
-111 Minimum Depth of Binary Tree
-112 Path Sum
-114 Flatten Binary Tree to Linked List
-116 Populating Next Right Pointers in Each Node
-118 Pascal's Triangle
-119 Pascal's Triangle II
-12 Integer to Roman
-120 Triangle
-121 Best Time to Buy and Sell Stock
-122 Best Time to Buy and Sell Stock II
-127 Word Ladder
-129 Sum Root to Leaf Numbers
-13 Roman to Integer
-131 Palindrome Partitioning
-133 Clone Graph
-136 Single Number
-137 Single Number II
-139 Word Break
-14 Longest Common Prefix
-141 Linked List Cycle
-144 Binary Tree Preorder Traversal My Submissions Question
-148 Sort List
-15 3Sum
-150 Evaluate Reverse Polish Notation
-151 Reverse Words in a String
-152 Maximum Product Subarray
-153 Find Minimum in Rotated Sorted Array
-155 Min Stack
-16 3Sum Closest
-160 Intersection Of Two Linked Lists
-162 Find Peak Element
-165 Compare Version Numbers
-166 Fraction to Recurring Decimal
-168 Excel Sheet Column Title
-169 Majority Element
-17 Letter Combinations of a Phone Number
-171 Excel Sheet Column Number
-172 Factorial Trailing Zeroes
-173 Binary Search Tree Iterator
-179 Largest Number
-189 Rotate Array
-19 Remove Nth Node From End of List
-190 Reverse Bits
-191 Number of 1 Bits
-198 House Robber
-199 Binary Tree Right Side View
-2 Add Two Numbers
-20 Valid Parentheses
-200 Number of Islands
-201 Bitwise AND of Numbers Range
-202 Happy Number
-203 Remove Linked List Elements
-204 Count Primes
-205 Isomorphic Strings
-206 Reverse Linked List
-207 Course Schedule
-208 Implement Trie (Prefix Tree)
-209 Minimum Size Subarray Sum
-21 Merge Two Sorted Lists
-211 Add and Search Word - Data structure design
-215 Kth Largest Element in an Array
-217 Contain Duplicate
-219 Contains Duplicate II
-22 Generate Parentheses
-220 Contains Duplicate III
-223 Rectangle Area
-225 Implement Stack Using Queues
-226 Invert Binary Tree
-228 Summary Ranges
-229 Majority Element II
-231 Power of Two
-232 Implement Queue using Stacks
-233 Number of Digit One
-234 Palindrome Linked List
-235 Lowest Common Ancestor Of a Binary Search Tree
-237 Delete Node in a Linked List
-24 Swap nodes in Pairs
-240 Search a 2D Matrix II
-241 Different Ways to Add Parentheses
-242 Valid Anagram
-26 Remove Duplicates from Sorted Array
-268 Missing Number
-27 Remove Element
-279. Perfect Squares
-28 Implement strStr()
-289. Game of Life
-297 Serialize and Deserialize Binary Tree My Submissions Question
-3 Longest Substring Without Repeating Characters
-300 Longest Increasing Subsequence
-31 Next Permutation
-318 Maximum Product of Word Lengths My Submissions Question
-322 Coin Change
-335 Self Crossing
-34 Search for a Range
-35 Search Insert Position
-36 Valid Sudoku
-37 Sudoku Solver
-38 Count and Say
-39 Combination Sum
-4. Median of Two Sorted Arrays
-40 combination Sum II
-43 Multiply Strings
-46 Permutations
-48 Rotate Image
-49 Anagrams
-49 Group Anagrams
-5 Longest Palindromic Substring
-50 Pow(x, n)
-51 N-Queens
-53 Maximum Subarray
-54 Spiral Matrix
-55 Jump Game
-58 Length of Last Word
-59 Spiral Matrix II
-61 Rotate List
-62 Unique Paths
-63 Unique Paths II
-64 Minimum Path Sum
-66 Plus One
-67 Add Binary
-70 Climbing Stairs
-71 Simplify Path
-72 Edit Distance
-74 Search a 2D Matrix
-75 Sort Colors
-77 Combinations
-8 String to Integer (atoi)
-80 Remove Duplicates from Sorted Array II
-81 Search in Rotated Sorted Array II
-82 Remove Duplicates from Sorted List II
-83 Remove Duplicates from Sorted List
-86 Partition List
-88 Merge Sorted Array
-9 Palindrome Number
-90 Subsets II
-91 Decode Ways
-92 Reverse Linked List II
-93 Restore IP Addresses
-94 Binary Tree Inorder Traversal
-98 Validate Binary Search Tree
\ No newline at end of file +1 Two Sum.js +10 Regular Expresion Matching.js +100 Same Tree.js +101 Symmetric Tree.js +102 Binary Tree Level Order Traversal.js +103 Binary Tree Zigzag Level Order Traversal.js +104 Maximum Depth of Binary Tree.js +105 Construct Binary Tree from Preorder and Inorder Traversal.js +106 Construct Binary Tree from Inorder and Postorder Traversal.js +107 Binary Tree Level Order Traversal II.js +108 Convert Sorted Array to Binary Search Tree.js +11 Container With Most Water.js +110 Balanced Binary Tree.js +111 Minimum Depth of Binary Tree.js +112 Path Sum.js +114 Flatten Binary Tree to Linked List.js +116 Populating Next Right Pointers in Each Node.js +118 Pascal's Triangle.js +119 Pascal's Triangle II.js +12 Integer to Roman.js +120 Triangle.js +121 Best Time to Buy and Sell Stock.js +122 Best Time to Buy and Sell Stock II.js +127 Word Ladder.js +129 Sum Root to Leaf Numbers.js +13 Roman to Integer.js +131 Palindrome Partitioning.js +133 Clone Graph.js +136 Single Number.js +137 Single Number II.js +139 Word Break.js +14 Longest Common Prefix.js +141 Linked List Cycle.js +144 Binary Tree Preorder Traversal My Submissions Question.js +146 LRU Cache.js +148 Sort List.js +15 3Sum.js +150 Evaluate Reverse Polish Notation.js +151 Reverse Words in a String.js +152 Maximum Product Subarray.js +153 Find Minimum in Rotated Sorted Array.js +155 Min Stack.js +16 3Sum Closest.js +160 Intersection Of Two Linked Lists.js +162 Find Peak Element.js +165 Compare Version Numbers.js +166 Fraction to Recurring Decimal.js +168 Excel Sheet Column Title.js +169 Majority Element.js +17 Letter Combinations of a Phone Number.js +171 Excel Sheet Column Number.js +172 Factorial Trailing Zeroes.js +173 Binary Search Tree Iterator.js +179 Largest Number.js +189 Rotate Array.js +19 Remove Nth Node From End of List.js +190 Reverse Bits.js +191 Number of 1 Bits.js +198 House Robber.js +199 Binary Tree Right Side View.js +2 Add Two Numbers.js +20 Valid Parentheses.js +200 Number of Islands.js +201 Bitwise AND of Numbers Range.js +202 Happy Number.js +203 Remove Linked List Elements.js +204 Count Primes.js +205 Isomorphic Strings.js +206 Reverse Linked List.js +207 Course Schedule.js +208 Implement Trie (Prefix Tree).js +209 Minimum Size Subarray Sum.js +21 Merge Two Sorted Lists.js +211 Add and Search Word - Data structure design.js +215 Kth Largest Element in an Array.js +215 Kth Largest Element in an Array.py +217 Contain Duplicate.js +219 Contains Duplicate II.js +22 Generate Parentheses.js +220 Contains Duplicate III.js +222. Count Complete Tree Nodes.js +223 Rectangle Area.js +225 Implement Stack Using Queues.js +226 Invert Binary Tree.js +228 Summary Ranges.js +229 Majority Element II.js +231 Power of Two.js +232 Implement Queue using Stacks.js +233 Number of Digit One.js +234 Palindrome Linked List.js +235 Lowest Common Ancestor Of a Binary Search Tree.js +236 Lowest Common Ancestor of a Binary Tree.js +237 Delete Node in a Linked List.js +24 Swap nodes in Pairs.js +240 Search a 2D Matrix II.js +241 Different Ways to Add Parentheses.js +242 Valid Anagram.js +257 Binary Tree Paths.js +26 Remove Duplicates from Sorted Array.js +263 Ugly Number.js +264 Ugly Number II.js +268 Missing Number.js +27 Remove Element.js +279. Perfect Squares.js +28 Implement strStr().js +286 Walls and Gates.js +289. Game of Life.js +297 Serialize and Deserialize Binary Tree My Submissions Question.js +3 Longest Substring Without Repeating Characters.js +300 Longest Increasing Subsequence.js +31 Next Permutation.js +318 Maximum Product of Word Lengths My Submissions Question.js +322 Coin Change.js +33 Search in Rotated Sorted Array.js +335 Self Crossing.js +34 Search for a Range.js +35 Search Insert Position.js +36 Valid Sudoku.js +37 Sudoku Solver.js +38 Count and Say.js +39 Combination Sum.js +4. Median of Two Sorted Arrays.js +40 combination Sum II.js +43 Multiply Strings.js +46 Permutations.js +48 Rotate Image.js +49 Anagrams.js +49 Group Anagrams.js +5 Longest Palindromic Substring.js +50 Pow(x, n).js +51 N-Queens.js +53 Maximum Subarray.js +54 Spiral Matrix.js +55 Jump Game.js +58 Length of Last Word.js +59 Spiral Matrix II.js +61 Rotate List.js +62 Unique Paths.js +63 Unique Paths II.js +64 Minimum Path Sum.js +66 Plus One.js +67 Add Binary.js +69 Sqrt(x).js +70 Climbing Stairs.js +71 Simplify Path.js +72 Edit Distance.js +74 Search a 2D Matrix.js +75 Sort Colors.js +77 Combinations.js +8 String to Integer (atoi).js +80 Remove Duplicates from Sorted Array II.js +81 Search in Rotated Sorted Array II.js +82 Remove Duplicates from Sorted List II.js +83 Remove Duplicates from Sorted List.js +86 Partition List.js +88 Merge Sorted Array.js +9 Palindrome Number.js +90 Subsets II.js +91 Decode Ways.js +92 Reverse Linked List II.js +93 Restore IP Addresses.js +94 Binary Tree Inorder Traversal.js +96 Unique Binary Search Trees.js +98 Validate Binary Search Tree.js \ No newline at end of file diff --git a/String Encoding and Decoding.js b/String Encoding and Decoding.js new file mode 100644 index 0000000..26c35e4 --- /dev/null +++ b/String Encoding and Decoding.js @@ -0,0 +1,30 @@ +public class Codec { + + // Encodes a list of strings to a single string. + public String encode(List strs) { + StringBuilder output = new StringBuilder(); + for(String str : strs){ + // 对于每个子串,先把其长度放在前面,用#隔开 + output.append(String.valueOf(str.length())+"#"); + // 再把子串本身放在后面 + output.append(str); + } + return output.toString(); + } + + // Decodes a single string to a list of strings. + public List decode(String s) { + List res = new LinkedList(); + int start = 0; + while(start < s.length()){ + // 找到从start开始的第一个#,这个#前面是长度 + int idx = s.indexOf('#', start); + int size = Integer.parseInt(s.substring(start, idx)); + // 根据这个长度截取子串 + res.add(s.substring(idx + 1, idx + size + 1)); + // 更新start为子串后面一个位置 + start = idx + size + 1; + } + return res; + } +} \ No newline at end of file diff --git a/flatten nested array.js b/flatten nested array.js new file mode 100644 index 0000000..21b9488 --- /dev/null +++ b/flatten nested array.js @@ -0,0 +1,24 @@ +var arr = [1,2,[3,4,[5,[6]],7],8,9]; + +function flatten(arr) { + return arr.reduce(function(self, el){ + var items = Array.isArray(el) ? flatten(el) : [el]; + return self.concat(items); + }, []); +} + +function flatten(array, result) { + result === undefined && (result = []); + + for (var i = 0, len = array.length; i < len; i++) { + if (Object.prototype.toString.call(array[i]) === '[object Array]') { + flatten(array[i], result); + } else { + result.push(array[i]); + } + } + + return result; +} + +console.log(flatten(arr)); \ No newline at end of file From 16776e379c3f6e176e032293bf0d6ba7d69fd956 Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Wed, 29 Jun 2016 17:49:20 -0700 Subject: [PATCH 07/47] Create Rate Limiter.js --- Rate Limiter.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Rate Limiter.js diff --git a/Rate Limiter.js b/Rate Limiter.js new file mode 100644 index 0000000..6540a13 --- /dev/null +++ b/Rate Limiter.js @@ -0,0 +1,28 @@ +function* generator() { + var rate = 5; + var per = 8; + var lastTime = Date.now(); + var allowance = rate; // unit: messages + + while(true) { + var currentTime = Date.now(); + var timeElapsed = (currentTime - lastTime)/1000; + var lastTime = currentTime; + var addedTime = timeElapsed*(rate/per); + + allowance += addedTime; + + + console.log('allowance',allowance, addedTime); + if(allowance > rate) { + allowance = rate; + } + + if (allowance < 1.0) { + yield false; + } else { + allowance -= 1.0; + yield true; + } + } +} From 93d9693888bffe7f035eeae8379f36d480afbff6 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Thu, 30 Jun 2016 23:06:44 -0700 Subject: [PATCH 08/47] add some more --- ...g with At Most Two Disctinct Characters.js | 46 ++++++++++++++ 314 Binary Tree Vertical Order Traversal.js | 63 +++++++++++++++++++ ...ring With At Most K Distinct Characters.js | 49 +++++++++++++++ 56. Merge Intervals.js | 40 ++++++++++++ 57. Insert Interval.js | 47 ++++++++++++++ 96 Unique Binary Search Trees.js | 33 ++++++++++ Javascript Closure Questions.js | 24 +++++++ README.md | 16 ++++- Rate Limiter.js | 57 +++++++++++------ 9 files changed, 354 insertions(+), 21 deletions(-) create mode 100644 159 Longest Substring with At Most Two Disctinct Characters.js create mode 100644 314 Binary Tree Vertical Order Traversal.js create mode 100644 340 Longest Substring With At Most K Distinct Characters.js create mode 100644 56. Merge Intervals.js create mode 100644 57. Insert Interval.js create mode 100644 Javascript Closure Questions.js diff --git a/159 Longest Substring with At Most Two Disctinct Characters.js b/159 Longest Substring with At Most Two Disctinct Characters.js new file mode 100644 index 0000000..2920d0d --- /dev/null +++ b/159 Longest Substring with At Most Two Disctinct Characters.js @@ -0,0 +1,46 @@ +// https://segmentfault.com/a/1190000003790746 + +/** + * @param {string} s + * @return {number} + */ +var lengthOfLongestSubstringTwoDistinct = function(s) { + var longestSubstr = ""; + var maxLength = 0; + var start = 0; + var map = new Map(); + + for(var i = 0; i < s.length; i++) { + var c = s.charAt(i); + + // if map already contains two distrinct chars and the char is new to the map + if(map.size > 1 && map.get(c) === undefined) { + var leftMost = s.length; + + // Calc substring len before the new char + if(i - start > maxLength) { + // Should not include i, since i is the new distinct char's index + longestSubstr = s.substring(start, i); + maxLength = longestSubstr.length; + } + + map.forEach((charIdx, key)=> { + if(charIdx < leftMost) { + leftMost = charIdx; + } + }); + + start = leftMost + 1; + map.delete(s[leftMost]); + } + + map.set(c, i); + } + + if(s.length - start > maxLength) { + longestSubstr = s.substring(start, s.length); + maxLength = longestSubstr.length; + } + + return maxLength; +}; diff --git a/314 Binary Tree Vertical Order Traversal.js b/314 Binary Tree Vertical Order Traversal.js new file mode 100644 index 0000000..a744f5e --- /dev/null +++ b/314 Binary Tree Vertical Order Traversal.js @@ -0,0 +1,63 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ + +var verticalOrder = function(root) { + var map = {}; + var queue = []; + var res = []; + // since iterating over map cannot ensure order + // we store min and max index for enforcing that + var minIdx = Infinity; + var maxIdx = -Infinity; + + if(root === null) { + return res; + } + + queue.push([0, root]); + while(queue.length > 0) { + var len = queue.length; + + for(var i = 0; i < len; i++) { + var data = queue.shift(); + var cur = data[1]; + var idx = data[0]; + + if(idx < minIdx) { + minIdx = idx; + } + if(idx > maxIdx) { + maxIdx = idx; + } + + map[idx] = map[idx] || []; + map[idx].push(cur.val); + + if(cur.left) { + queue.push([idx - 1, cur.left]); + } + if(cur.right) { + queue.push([idx + 1, cur.right]); + } + } + } + // since iterating over map cannot ensure order + for(i = minIdx; i <= maxIdx; i++) { + var key = i.toString(); + + if(map[key]) { + res.push(map[key]); + } + } + + return res; +}; \ No newline at end of file diff --git a/340 Longest Substring With At Most K Distinct Characters.js b/340 Longest Substring With At Most K Distinct Characters.js new file mode 100644 index 0000000..1223629 --- /dev/null +++ b/340 Longest Substring With At Most K Distinct Characters.js @@ -0,0 +1,49 @@ +/** + * @param {string} s + * @param {number} k + * @return {number} + */ +var lengthOfLongestSubstringKDistinct = function(s, k) { + var longestSubstr = ""; + var maxLength = 0; + var start = 0; + var map = new Map(); + + if(k === 0) { + return 0; + } + + for(var i = 0; i < s.length; i++) { + var c = s.charAt(i); + + // if map already contains two distrinct chars and the char is new to the map + if(map.size >= k && map.get(c) === undefined) { + var leftMost = s.length; + + // Calc substring len before the new char + if(i - start > maxLength) { + // Should not include i, since i is the new distinct char's index + longestSubstr = s.substring(start, i); + maxLength = longestSubstr.length; + } + + map.forEach((charIdx, key)=> { + if(charIdx < leftMost) { + leftMost = charIdx; + } + }); + + start = leftMost + 1; + map.delete(s[leftMost]); + } + + map.set(c, i); + } + + if(s.length - start > maxLength) { + longestSubstr = s.substring(start, s.length); + maxLength = longestSubstr.length; + } + + return maxLength; +}; \ No newline at end of file diff --git a/56. Merge Intervals.js b/56. Merge Intervals.js new file mode 100644 index 0000000..993b6b9 --- /dev/null +++ b/56. Merge Intervals.js @@ -0,0 +1,40 @@ +/** + * Definition for an interval. + * function Interval(start, end) { + * this.start = start; + * this.end = end; + * } + */ +/** + * @param {Interval[]} intervals + * @return {Interval[]} + */ +var merge = function(intervals) { + + // http://yucoding.blogspot.com/2013/01/leetcode-question-51-merge-intervals.html + + var result = []; + + if(!intervals || intervals.length === 0) { + return result; + } + + intervals.sort((a, b)=> { + return a.start > b.start ? 1 : -1; + }); + + result.push(intervals[0]); + + for(var i = 1; i < intervals.length; i++) { + var topOfResult = result[result.length - 1]; + var interval = intervals[i]; + + if(topOfResult.end >= interval.start) { + topOfResult.end = Math.max(topOfResult.end, interval.end); + } else { + result.push(interval); + } + } + + return result; +}; \ No newline at end of file diff --git a/57. Insert Interval.js b/57. Insert Interval.js new file mode 100644 index 0000000..891b984 --- /dev/null +++ b/57. Insert Interval.js @@ -0,0 +1,47 @@ +/** + * Definition for an interval. + * function Interval(start, end) { + * this.start = start; + * this.end = end; + * } + */ +/** + * @param {Interval[]} intervals + * @param {Interval} newInterval + * @return {Interval[]} + */ + +// http://bangbingsyb.blogspot.com/2014/11/leetcode-insert-interval.html +var insert = function(intervals, newInterval) { + var result = []; + // Easier to consider if two sections are not overlapped + // [s1, e1] [s2, e2] --> e2 < s1 or e1 < s2 + // once merged when two sections are overlapped, [min(s1,s2), max(e1,e2)] + + var isInsert = false; + + for(var i = 0; i < intervals.length; i++) { + var interval = intervals[i]; + + if(isInsert) { + result.push(interval); + } else if(newInterval.end < interval.start) { + result.push(newInterval); + result.push(interval); + isInsert = true; + } else if(newInterval.start <= interval.end && interval.start <= newInterval.end){ + + newInterval.start = Math.min(newInterval.start, interval.start); + newInterval.end = Math.max(newInterval.end, interval.end); + continue; + } else { + result.push(interval); + } + } + + if(!isInsert) { + result.push(newInterval); + } + + return result; +}; \ No newline at end of file diff --git a/96 Unique Binary Search Trees.js b/96 Unique Binary Search Trees.js index bbc5c9c..2c1f537 100644 --- a/96 Unique Binary Search Trees.js +++ b/96 Unique Binary Search Trees.js @@ -2,6 +2,7 @@ * @param {number} n * @return {number} */ + // https://www.youtube.com/watch?v=YDf982Lb84o var numTrees = function(n) { var result = [1, 1]; @@ -14,3 +15,35 @@ var numTrees = function(n) { } return result[n]; }; + + +// var numTrees = function(n) { +// var i, +// j, +// result = []; + +// result[0] = 1; +// result[1] = 1; + +// for (i = 2; i <= n; i++) { +// result[i] = 0; +// for (j = 0; j < i; j++) { +// result[i] += result[j] * result[i - 1 - j]; +// console.log(i, j, i - 1 - j, result) +// } + +// } +// return result[n]; +// }; + + +numTrees(4); + + +1, 2, 3, 4 + +j = r[0] +k = r[3] + +j = r[1] +k = r[2] \ No newline at end of file diff --git a/Javascript Closure Questions.js b/Javascript Closure Questions.js new file mode 100644 index 0000000..22e445a --- /dev/null +++ b/Javascript Closure Questions.js @@ -0,0 +1,24 @@ +// implement function add in such a way that: +// add() => 0 +// add(1)(2)() => 3 +// add(n0)(n1)...(nk)() => n0+n1+...+nk + +function add(val){ + var total = 0; + var result; + var step = function(val){ + if(val === undefined){ + result = total; + total = 0; + return result; + } else { + total += val; + } + + return step; + } + + result = step(val); + + return result; +} \ No newline at end of file diff --git a/README.md b/README.md index 49e4bc6..123e69a 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Leetcode Problems in Javascript 152 Maximum Product Subarray.js 153 Find Minimum in Rotated Sorted Array.js 155 Min Stack.js +159 Longest Substring with At Most Two Disctinct Characters.js 16 3Sum Closest.js 160 Intersection Of Two Linked Lists.js 162 Find Peak Element.js @@ -75,7 +76,6 @@ Leetcode Problems in Javascript 21 Merge Two Sorted Lists.js 211 Add and Search Word - Data structure design.js 215 Kth Largest Element in an Array.js -215 Kth Largest Element in an Array.py 217 Contain Duplicate.js 219 Contains Duplicate II.js 22 Generate Parentheses.js @@ -111,11 +111,13 @@ Leetcode Problems in Javascript 3 Longest Substring Without Repeating Characters.js 300 Longest Increasing Subsequence.js 31 Next Permutation.js +314 Binary Tree Vertical Order Traversal.js 318 Maximum Product of Word Lengths My Submissions Question.js 322 Coin Change.js 33 Search in Rotated Sorted Array.js 335 Self Crossing.js 34 Search for a Range.js +340 Longest Substring With At Most K Distinct Characters.js 35 Search Insert Position.js 36 Valid Sudoku.js 37 Sudoku Solver.js @@ -134,6 +136,8 @@ Leetcode Problems in Javascript 53 Maximum Subarray.js 54 Spiral Matrix.js 55 Jump Game.js +56. Merge Intervals.js +57. Insert Interval.js 58 Length of Last Word.js 59 Spiral Matrix II.js 61 Rotate List.js @@ -163,4 +167,12 @@ Leetcode Problems in Javascript 93 Restore IP Addresses.js 94 Binary Tree Inorder Traversal.js 96 Unique Binary Search Trees.js -98 Validate Binary Search Tree.js \ No newline at end of file +98 Validate Binary Search Tree.js +Hackrank.js +Javascript Closure Questions.js +Jump Game II.js +Rate Limiter.js +Reverse Integer.js +String Encoding and Decoding.js +find kth element in two arrays.js +flatten nested array.js \ No newline at end of file diff --git a/Rate Limiter.js b/Rate Limiter.js index 6540a13..06a3fd3 100644 --- a/Rate Limiter.js +++ b/Rate Limiter.js @@ -1,28 +1,47 @@ -function* generator() { - var rate = 5; - var per = 8; - var lastTime = Date.now(); - var allowance = rate; // unit: messages +var RATE = 5; +var PER = 8; +var SECOND_IN_MS = 1000; - while(true) { +function* RateLimiter(rate, per, cbFunc) { + var lastTime = Date.now(); + var rate = rate; + var per = per; + var allowance = rate; + + + while(true){ var currentTime = Date.now(); - var timeElapsed = (currentTime - lastTime)/1000; - var lastTime = currentTime; - var addedTime = timeElapsed*(rate/per); + var elapsedTime = (currentTime - lastTime)/SECOND_IN_MS; + lastTime = currentTime; + allowance += elapsedTime*(rate/per); - allowance += addedTime; - - console.log('allowance',allowance, addedTime); if(allowance > rate) { - allowance = rate; - } + allowance = rate; + } - if (allowance < 1.0) { - yield false; + if(allowance < 1.0) { + yield cbFunc(false); } else { - allowance -= 1.0; - yield true; + allowance -= 1; + yield cbFunc(true); } - } + } } + +var rl = RateLimiter(RATE, PER, function(output){ + console.log(output) +}); + +rl.next(); +rl.next(); +rl.next(); +rl.next(); +rl.next(); + +rl.next(); + +setTimeout(()=>{ + rl.next(); + rl.next(); +},PER/RATE*SECOND_IN_MS); \ No newline at end of file From 43b4e6cd4ec770044e8ebbac3c8d31ec4a6abffd Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Thu, 30 Jun 2016 23:07:26 -0700 Subject: [PATCH 09/47] add line break --- README.md | 352 +++++++++++++++++++++++++++--------------------------- 1 file changed, 176 insertions(+), 176 deletions(-) diff --git a/README.md b/README.md index 123e69a..5896a47 100644 --- a/README.md +++ b/README.md @@ -1,178 +1,178 @@ Leetcode Problems in Javascript -1 Two Sum.js -10 Regular Expresion Matching.js -100 Same Tree.js -101 Symmetric Tree.js -102 Binary Tree Level Order Traversal.js -103 Binary Tree Zigzag Level Order Traversal.js -104 Maximum Depth of Binary Tree.js -105 Construct Binary Tree from Preorder and Inorder Traversal.js -106 Construct Binary Tree from Inorder and Postorder Traversal.js -107 Binary Tree Level Order Traversal II.js -108 Convert Sorted Array to Binary Search Tree.js -11 Container With Most Water.js -110 Balanced Binary Tree.js -111 Minimum Depth of Binary Tree.js -112 Path Sum.js -114 Flatten Binary Tree to Linked List.js -116 Populating Next Right Pointers in Each Node.js -118 Pascal's Triangle.js -119 Pascal's Triangle II.js -12 Integer to Roman.js -120 Triangle.js -121 Best Time to Buy and Sell Stock.js -122 Best Time to Buy and Sell Stock II.js -127 Word Ladder.js -129 Sum Root to Leaf Numbers.js -13 Roman to Integer.js -131 Palindrome Partitioning.js -133 Clone Graph.js -136 Single Number.js -137 Single Number II.js -139 Word Break.js -14 Longest Common Prefix.js -141 Linked List Cycle.js -144 Binary Tree Preorder Traversal My Submissions Question.js -146 LRU Cache.js -148 Sort List.js -15 3Sum.js -150 Evaluate Reverse Polish Notation.js -151 Reverse Words in a String.js -152 Maximum Product Subarray.js -153 Find Minimum in Rotated Sorted Array.js -155 Min Stack.js -159 Longest Substring with At Most Two Disctinct Characters.js -16 3Sum Closest.js -160 Intersection Of Two Linked Lists.js -162 Find Peak Element.js -165 Compare Version Numbers.js -166 Fraction to Recurring Decimal.js -168 Excel Sheet Column Title.js -169 Majority Element.js -17 Letter Combinations of a Phone Number.js -171 Excel Sheet Column Number.js -172 Factorial Trailing Zeroes.js -173 Binary Search Tree Iterator.js -179 Largest Number.js -189 Rotate Array.js -19 Remove Nth Node From End of List.js -190 Reverse Bits.js -191 Number of 1 Bits.js -198 House Robber.js -199 Binary Tree Right Side View.js -2 Add Two Numbers.js -20 Valid Parentheses.js -200 Number of Islands.js -201 Bitwise AND of Numbers Range.js -202 Happy Number.js -203 Remove Linked List Elements.js -204 Count Primes.js -205 Isomorphic Strings.js -206 Reverse Linked List.js -207 Course Schedule.js -208 Implement Trie (Prefix Tree).js -209 Minimum Size Subarray Sum.js -21 Merge Two Sorted Lists.js -211 Add and Search Word - Data structure design.js -215 Kth Largest Element in an Array.js -217 Contain Duplicate.js -219 Contains Duplicate II.js -22 Generate Parentheses.js -220 Contains Duplicate III.js -222. Count Complete Tree Nodes.js -223 Rectangle Area.js -225 Implement Stack Using Queues.js -226 Invert Binary Tree.js -228 Summary Ranges.js -229 Majority Element II.js -231 Power of Two.js -232 Implement Queue using Stacks.js -233 Number of Digit One.js -234 Palindrome Linked List.js -235 Lowest Common Ancestor Of a Binary Search Tree.js -236 Lowest Common Ancestor of a Binary Tree.js -237 Delete Node in a Linked List.js -24 Swap nodes in Pairs.js -240 Search a 2D Matrix II.js -241 Different Ways to Add Parentheses.js -242 Valid Anagram.js -257 Binary Tree Paths.js -26 Remove Duplicates from Sorted Array.js -263 Ugly Number.js -264 Ugly Number II.js -268 Missing Number.js -27 Remove Element.js -279. Perfect Squares.js -28 Implement strStr().js -286 Walls and Gates.js -289. Game of Life.js -297 Serialize and Deserialize Binary Tree My Submissions Question.js -3 Longest Substring Without Repeating Characters.js -300 Longest Increasing Subsequence.js -31 Next Permutation.js -314 Binary Tree Vertical Order Traversal.js -318 Maximum Product of Word Lengths My Submissions Question.js -322 Coin Change.js -33 Search in Rotated Sorted Array.js -335 Self Crossing.js -34 Search for a Range.js -340 Longest Substring With At Most K Distinct Characters.js -35 Search Insert Position.js -36 Valid Sudoku.js -37 Sudoku Solver.js -38 Count and Say.js -39 Combination Sum.js -4. Median of Two Sorted Arrays.js -40 combination Sum II.js -43 Multiply Strings.js -46 Permutations.js -48 Rotate Image.js -49 Anagrams.js -49 Group Anagrams.js -5 Longest Palindromic Substring.js -50 Pow(x, n).js -51 N-Queens.js -53 Maximum Subarray.js -54 Spiral Matrix.js -55 Jump Game.js -56. Merge Intervals.js -57. Insert Interval.js -58 Length of Last Word.js -59 Spiral Matrix II.js -61 Rotate List.js -62 Unique Paths.js -63 Unique Paths II.js -64 Minimum Path Sum.js -66 Plus One.js -67 Add Binary.js -69 Sqrt(x).js -70 Climbing Stairs.js -71 Simplify Path.js -72 Edit Distance.js -74 Search a 2D Matrix.js -75 Sort Colors.js -77 Combinations.js -8 String to Integer (atoi).js -80 Remove Duplicates from Sorted Array II.js -81 Search in Rotated Sorted Array II.js -82 Remove Duplicates from Sorted List II.js -83 Remove Duplicates from Sorted List.js -86 Partition List.js -88 Merge Sorted Array.js -9 Palindrome Number.js -90 Subsets II.js -91 Decode Ways.js -92 Reverse Linked List II.js -93 Restore IP Addresses.js -94 Binary Tree Inorder Traversal.js -96 Unique Binary Search Trees.js -98 Validate Binary Search Tree.js -Hackrank.js -Javascript Closure Questions.js -Jump Game II.js -Rate Limiter.js -Reverse Integer.js -String Encoding and Decoding.js -find kth element in two arrays.js -flatten nested array.js \ No newline at end of file +1 Two Sum.js
+10 Regular Expresion Matching.js
+100 Same Tree.js
+101 Symmetric Tree.js
+102 Binary Tree Level Order Traversal.js
+103 Binary Tree Zigzag Level Order Traversal.js
+104 Maximum Depth of Binary Tree.js
+105 Construct Binary Tree from Preorder and Inorder Traversal.js
+106 Construct Binary Tree from Inorder and Postorder Traversal.js
+107 Binary Tree Level Order Traversal II.js
+108 Convert Sorted Array to Binary Search Tree.js
+11 Container With Most Water.js
+110 Balanced Binary Tree.js
+111 Minimum Depth of Binary Tree.js
+112 Path Sum.js
+114 Flatten Binary Tree to Linked List.js
+116 Populating Next Right Pointers in Each Node.js
+118 Pascal's Triangle.js
+119 Pascal's Triangle II.js
+12 Integer to Roman.js
+120 Triangle.js
+121 Best Time to Buy and Sell Stock.js
+122 Best Time to Buy and Sell Stock II.js
+127 Word Ladder.js
+129 Sum Root to Leaf Numbers.js
+13 Roman to Integer.js
+131 Palindrome Partitioning.js
+133 Clone Graph.js
+136 Single Number.js
+137 Single Number II.js
+139 Word Break.js
+14 Longest Common Prefix.js
+141 Linked List Cycle.js
+144 Binary Tree Preorder Traversal My Submissions Question.js
+146 LRU Cache.js
+148 Sort List.js
+15 3Sum.js
+150 Evaluate Reverse Polish Notation.js
+151 Reverse Words in a String.js
+152 Maximum Product Subarray.js
+153 Find Minimum in Rotated Sorted Array.js
+155 Min Stack.js
+159 Longest Substring with At Most Two Disctinct Characters.js
+16 3Sum Closest.js
+160 Intersection Of Two Linked Lists.js
+162 Find Peak Element.js
+165 Compare Version Numbers.js
+166 Fraction to Recurring Decimal.js
+168 Excel Sheet Column Title.js
+169 Majority Element.js
+17 Letter Combinations of a Phone Number.js
+171 Excel Sheet Column Number.js
+172 Factorial Trailing Zeroes.js
+173 Binary Search Tree Iterator.js
+179 Largest Number.js
+189 Rotate Array.js
+19 Remove Nth Node From End of List.js
+190 Reverse Bits.js
+191 Number of 1 Bits.js
+198 House Robber.js
+199 Binary Tree Right Side View.js
+2 Add Two Numbers.js
+20 Valid Parentheses.js
+200 Number of Islands.js
+201 Bitwise AND of Numbers Range.js
+202 Happy Number.js
+203 Remove Linked List Elements.js
+204 Count Primes.js
+205 Isomorphic Strings.js
+206 Reverse Linked List.js
+207 Course Schedule.js
+208 Implement Trie (Prefix Tree).js
+209 Minimum Size Subarray Sum.js
+21 Merge Two Sorted Lists.js
+211 Add and Search Word - Data structure design.js
+215 Kth Largest Element in an Array.js
+217 Contain Duplicate.js
+219 Contains Duplicate II.js
+22 Generate Parentheses.js
+220 Contains Duplicate III.js
+222. Count Complete Tree Nodes.js
+223 Rectangle Area.js
+225 Implement Stack Using Queues.js
+226 Invert Binary Tree.js
+228 Summary Ranges.js
+229 Majority Element II.js
+231 Power of Two.js
+232 Implement Queue using Stacks.js
+233 Number of Digit One.js
+234 Palindrome Linked List.js
+235 Lowest Common Ancestor Of a Binary Search Tree.js
+236 Lowest Common Ancestor of a Binary Tree.js
+237 Delete Node in a Linked List.js
+24 Swap nodes in Pairs.js
+240 Search a 2D Matrix II.js
+241 Different Ways to Add Parentheses.js
+242 Valid Anagram.js
+257 Binary Tree Paths.js
+26 Remove Duplicates from Sorted Array.js
+263 Ugly Number.js
+264 Ugly Number II.js
+268 Missing Number.js
+27 Remove Element.js
+279. Perfect Squares.js
+28 Implement strStr().js
+286 Walls and Gates.js
+289. Game of Life.js
+297 Serialize and Deserialize Binary Tree My Submissions Question.js
+3 Longest Substring Without Repeating Characters.js
+300 Longest Increasing Subsequence.js
+31 Next Permutation.js
+314 Binary Tree Vertical Order Traversal.js
+318 Maximum Product of Word Lengths My Submissions Question.js
+322 Coin Change.js
+33 Search in Rotated Sorted Array.js
+335 Self Crossing.js
+34 Search for a Range.js
+340 Longest Substring With At Most K Distinct Characters.js
+35 Search Insert Position.js
+36 Valid Sudoku.js
+37 Sudoku Solver.js
+38 Count and Say.js
+39 Combination Sum.js
+4. Median of Two Sorted Arrays.js
+40 combination Sum II.js
+43 Multiply Strings.js
+46 Permutations.js
+48 Rotate Image.js
+49 Anagrams.js
+49 Group Anagrams.js
+5 Longest Palindromic Substring.js
+50 Pow(x, n).js
+51 N-Queens.js
+53 Maximum Subarray.js
+54 Spiral Matrix.js
+55 Jump Game.js
+56. Merge Intervals.js
+57. Insert Interval.js
+58 Length of Last Word.js
+59 Spiral Matrix II.js
+61 Rotate List.js
+62 Unique Paths.js
+63 Unique Paths II.js
+64 Minimum Path Sum.js
+66 Plus One.js
+67 Add Binary.js
+69 Sqrt(x).js
+70 Climbing Stairs.js
+71 Simplify Path.js
+72 Edit Distance.js
+74 Search a 2D Matrix.js
+75 Sort Colors.js
+77 Combinations.js
+8 String to Integer (atoi).js
+80 Remove Duplicates from Sorted Array II.js
+81 Search in Rotated Sorted Array II.js
+82 Remove Duplicates from Sorted List II.js
+83 Remove Duplicates from Sorted List.js
+86 Partition List.js
+88 Merge Sorted Array.js
+9 Palindrome Number.js
+90 Subsets II.js
+91 Decode Ways.js
+92 Reverse Linked List II.js
+93 Restore IP Addresses.js
+94 Binary Tree Inorder Traversal.js
+96 Unique Binary Search Trees.js
+98 Validate Binary Search Tree.js
+Hackrank.js
+Javascript Closure Questions.js
+Jump Game II.js
+Rate Limiter.js
+Reverse Integer.js
+String Encoding and Decoding.js
+find kth element in two arrays.js
+flatten nested array.js
\ No newline at end of file From aa76f9008bab121d7adbc2acb72cdc405fa83fbf Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sun, 3 Jul 2016 18:24:16 -0700 Subject: [PATCH 10/47] add more solutions --- 124 Binary Tree Maximum Path Sum.js | 34 ++ 139 Word Break.js | 34 +- 14 Longest Common Prefix.js | 37 +- 140 Word Break II.js | 53 +++ ...order Traversal My Submissions Question.js | 61 ++- 145 Binary Tree Post Order Traversal.js | 48 +++ 249 Group Shifted Strings.js | 45 +++ 295 Find Median From Data Stream.js | 216 +++++++++++ Jump Game II.js => 45 Jump Game II.js | 0 68 Text Justification.js | 96 +++++ 70 Climbing Stairs.js | 30 +- Data Structure Max Heap.js | 111 ++++++ Data Structure Min Heap.js | 118 ++++++ Hackrank.js => Disambiguos Actors.js | 0 ...matrix in Matrix Dynamic Programming:2D.js | 86 ++++ README.md | 366 +++++++++--------- test.py | 22 -- 17 files changed, 1093 insertions(+), 264 deletions(-) create mode 100644 124 Binary Tree Maximum Path Sum.js create mode 100644 140 Word Break II.js create mode 100644 145 Binary Tree Post Order Traversal.js create mode 100644 249 Group Shifted Strings.js create mode 100644 295 Find Median From Data Stream.js rename Jump Game II.js => 45 Jump Game II.js (100%) create mode 100644 68 Text Justification.js create mode 100644 Data Structure Max Heap.js create mode 100644 Data Structure Min Heap.js rename Hackrank.js => Disambiguos Actors.js (100%) create mode 100644 Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js delete mode 100644 test.py diff --git a/124 Binary Tree Maximum Path Sum.js b/124 Binary Tree Maximum Path Sum.js new file mode 100644 index 0000000..0622d86 --- /dev/null +++ b/124 Binary Tree Maximum Path Sum.js @@ -0,0 +1,34 @@ +// http://bangbingsyb.blogspot.com/2014/11/leetcode-binary-tree-maximum-path-sum.html +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var maxPathSum = function(root) { + var maxVal = -Infinity; + findMaxPath(root); + return maxVal; + + function findMaxPath(node) { + if(!node) { + return 0; + } + + var leftVal = Math.max(findMaxPath(node.left), 0); + var rightVal = Math.max(findMaxPath(node.right), 0); + + var ps1 = node.val + Math.max(leftVal, rightVal); + // ps2 means taking this current node as parent node and stop there + var ps2 = node.val + leftVal + rightVal; + + maxVal = Math.max(maxVal, Math.max(ps1, ps2)); + // return ps1 only since, ps2 cannot be combined with the parent node + return ps1; + } +}; diff --git a/139 Word Break.js b/139 Word Break.js index 3745fc2..d167ec9 100644 --- a/139 Word Break.js +++ b/139 Word Break.js @@ -1,32 +1,28 @@ -// Leetcode #139 -// Language: Javascript -// Problem: https://leetcode.com/problems/word-break/ -// Author: Chihung Yu /** * @param {string} s * @param {set} wordDict + * Note: wordDict is a Set object, see: + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set * @return {boolean} */ var wordBreak = function(s, wordDict) { - if(wordDict === null || wordDict.size === 0){ + if(wordDict === null || wordDict.size === 0) { return false; } - - var t = []; - t[0] = true; - for(var i = 0; i} wordDict + * Note: wordDict is a Set object, see: + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set + * @return {string[]} + */ +var wordBreak = function(s, wordDict) { + var result = []; + var solutions = []; + var len = s.length; + var possible = []; + + for(var i = 0; i <= s.length; i++) { + possible.push(true); + } + + getAllSolutions(0, s, wordDict, result, solutions, possible); + return solutions; +}; + +function getAllSolutions(start, s, wordDict, result, solutions, possible) { + if(start === s.length) { + solutions.push(result.join(' ')) // remove the last space + return; + } + + // loop through string from i to s.length + for(var i = start; i < s.length; i++) { + var piece = s.substring(start, i+1); + + // possible is to mark step whether i+1 to s.length have any possible words + if(wordDict.has(piece) && possible[i+1]) {// eliminate unnecessary search + result.push(piece); + var beforeChange = solutions.length; + getAllSolutions(i + 1, s, wordDict, result, solutions, possible); + if(solutions.length === beforeChange) { + possible[i+1] = false; + } + result.pop(); + } + } +} + + +var dict = new Set(); +dict.add('leet'); +dict.add('code'); +dict.add('cod'); +dict.add('de'); + +wordBreak('leetcode', dict) \ No newline at end of file diff --git a/144 Binary Tree Preorder Traversal My Submissions Question.js b/144 Binary Tree Preorder Traversal My Submissions Question.js index d13dbba..e2447e4 100644 --- a/144 Binary Tree Preorder Traversal My Submissions Question.js +++ b/144 Binary Tree Preorder Traversal My Submissions Question.js @@ -14,21 +14,60 @@ * @return {number[]} */ +// var preorderTraversal = function(root) { +// var result = []; + +// traverse(root, result); + +// return result; +// }; + +// function traverse(node, result) { +// if(!node) { +// return; +// } + +// result.push(node.val); + +// traverse(node.left, result); +// traverse(node.right, result); +// } + + + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[]} + */ var preorderTraversal = function(root) { var result = []; + + if(root === null) { + return result; + } + + var stack = []; + stack.push(root); - traverse(root, result); + while(stack.length) { + var node = stack.pop(); + result.push(node.val); + + if(node.right !== null) { + stack.push(node.right); + } + if(node.left !== null) { + stack.push(node.left); + } + } return result; }; -function traverse(node, result) { - if(!node) { - return; - } - - result.push(node.val); - - traverse(node.left, result); - traverse(node.right, result); -} \ No newline at end of file diff --git a/145 Binary Tree Post Order Traversal.js b/145 Binary Tree Post Order Traversal.js new file mode 100644 index 0000000..52c28f9 --- /dev/null +++ b/145 Binary Tree Post Order Traversal.js @@ -0,0 +1,48 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[]} + */ +var postorderTraversal = function(root) { + var result = []; + var stack = []; + var prev = null; + var curr = null; + + if(root === null) { + return result; + } + + stack.push(root); + + // use prev and curr to figure out the direction of tree traversal + while(stack.length !== 0) { + curr = stack[stack.length - 1]; + + if(prev === null || prev.left === curr || prev.right === curr) { // traverse down the tree + if(curr.left !== null) { + stack.push(curr.left); + } else if(curr.right !== null) { + stack.push(curr.right); + } + } else if(curr.left === prev) { //traverse up the tree from the left + if(curr.right !== null) { + stack.push(curr.right); + } + } else { + // it means that curr === prev + result.push(curr.val); + stack.pop(); + } + + prev = curr; + } + + return result; +}; \ No newline at end of file diff --git a/249 Group Shifted Strings.js b/249 Group Shifted Strings.js new file mode 100644 index 0000000..198a39d --- /dev/null +++ b/249 Group Shifted Strings.js @@ -0,0 +1,45 @@ +// Given a string, we can "shift" each of its letter to its successive letter, for example: "abc" -> "bcd". We can keep "shifting" which forms the sequence: + +// "abc" -> "bcd" -> ... -> "xyz" +// Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence. + +// For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"], +// A solution is: + +// [ +// ["abc","bcd","xyz"], +// ["az","ba"], +// ["acef"], +// ["a","z"] +// ] +// reference: http://blog.csdn.net/pointbreak1/article/details/48780345 + +/** + * @param {string[]} strings + * @return {string[][]} + */ +var groupStrings = function(strings) { + var result = []; + var map = new Map(); + + for(var i = 0; i < strings.length; i++) { + var shift = ''; + var string = strings[i] + for(var j = 0; j < string.length; j++) { + shift += (string.charCodeAt(j) - string.charCodeAt(0) + 26)%26; + shift += ' '; + } + if(map.has(shift)) { + map.get(shift).push(string); + } else { + map.set(shift, [string]); + } + } + + map.forEach((value, key)=> { + result.push(value); + }); + + + return result; +}; \ No newline at end of file diff --git a/295 Find Median From Data Stream.js b/295 Find Median From Data Stream.js new file mode 100644 index 0000000..e60177a --- /dev/null +++ b/295 Find Median From Data Stream.js @@ -0,0 +1,216 @@ +/** + * @constructor + */ +var MedianFinder = function() { + this.large = new MinHeap(); + this.small = new MaxHeap(); +}; + +/** + * @param {integer} word + * @return {void} + * Adds a num into the data structure. + */ +MedianFinder.prototype.addNum = function(num) { + var lg = this.large.peek(); // lg peek is the minimum of large set + var sm = this.small.peek(); // sm peek is the maximum of small set + + if(num <= sm) { + this.small.add(num); + } else { + this.large.add(num); + } + + var diff = this.small.size() - this.large.size(); + if(diff > 1) { + this.large.add(this.small.pop()); + } else if(diff < 0) { + this.small.add(this.large.pop()); + } +}; + + +/** + * @return {double} + * Return median of current data stream + */ +MedianFinder.prototype.findMedian = function() { + return this.small.size() > this.large.size() ? + this.small.peek() : (this.small.peek() + this.large.peek())/2; +}; + +/** + * Your MedianFinder object will be instantiated and called as such: + * var mf = new MedianFinder(); + * mf.addNum(1); + * mf.findMedian(); + */ + +class MaxHeap { + constructor() { + this.arr = []; + } + + peek() { + return this.arr[0] || null; + } + + size() { + return this.arr.length; + } + + pop() { + var arr = this.arr; + var len = arr.length; + + if(len === 0) { + return null; + } + + var max = arr[0]; + arr[0] = arr[len - 1] // swap the last value with max value + + arr.pop(); + + this.sinkDown(0); + + return max; + } + + add(val) { + var arr = this.arr; + arr.push(val); + this.bubbleUp(arr.length - 1); + } + + bubbleUp(n) { + var arr = this.arr; + + while(n > 0) { + var parentN = Math.floor((n + 1)/2) - 1; // [1,2,3] 1 as root 2 as left child and 3 as right child 2 has idx = 1 and 3 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + + if(arr[parentN] > arr[n]) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[parentN]; + arr[parentN] = tmp; + n = parentN; + } + } + + sinkDown(n) { + var arr = this.arr; + var len = arr.length; + var val = arr[n]; + + while(true) { + + var swap = null; + var child2N = (n+1)*2; // root = 0 right child idx is (0 + 1)*2 = 2 + var child1N = child2N - 1; // right child idx - 1 = 1 for root's left child + + if(child1N < len && arr[child1N] > val) { + swap = child1N; + } + + if(child2N < len && arr[child2N] > val && arr[child2N] >= arr[child1N]) { + swap = child2N; + } + + if(swap === null) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[swap]; + arr[swap] = tmp; + n = swap; + } + } +} + + +class MinHeap { + constructor() { + this.arr = []; + } + + peek() { + return this.arr[0] || null; + } + + size() { + return this.arr.length; + } + + pop() { + var arr = this.arr; + var len = arr.length; + + if(len === 0) { + return null; + } + + var min = arr[0]; + arr[0] = arr[len - 1] // swap the last value with min value + + arr.pop(); + + this.sinkDown(0); + + return min; + } + + add(val) { + var arr = this.arr; + arr.push(val); + this.bubbleUp(arr.length - 1); + } + + bubbleUp(n) { + var arr = this.arr; + + while(n > 0) { + var parentN = Math.floor((n + 1)/2) - 1; // [1,2,3] 1 as root 2 as left child and 3 as right child 2 has idx = 1 and 3 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + + if(arr[parentN] <= arr[n]) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[parentN]; + arr[parentN] = tmp; + n = parentN; + } + } + + sinkDown(n) { + var arr = this.arr; + var len = arr.length; + var val = arr[n] + + while(true) { + var swap = null; + var child2N = (n+1)*2; // root = 0 right child idx is (0 + 1)*2 = 2 + var child1N = child2N - 1; // right child idx - 1 = 1 for root's left child + if(child1N < len && arr[child1N] < val) { + swap = child1N; + } + + if(child2N < len && arr[child2N] < val && arr[child2N] <= arr[child1N]) { + swap = child2N; + } + + if(swap === null) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[swap]; + arr[swap] = tmp; + n = swap; + } + } +} \ No newline at end of file diff --git a/Jump Game II.js b/45 Jump Game II.js similarity index 100% rename from Jump Game II.js rename to 45 Jump Game II.js diff --git a/68 Text Justification.js b/68 Text Justification.js new file mode 100644 index 0000000..ff6446e --- /dev/null +++ b/68 Text Justification.js @@ -0,0 +1,96 @@ +// Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. + +// You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. + +// Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. + +// For the last line of text, it should be left justified and no extra space is inserted between words. + +// For example, +// words: ["This", "is", "an", "example", "of", "text", "justification."] +// L: 16. + +// Return the formatted lines as: +// [ +// "This is an", +// "example of text", +// "justification. " +// ] +// Note: Each word is guaranteed not to exceed L in length. +// http://bangbingsyb.blogspot.com/2014/11/leetcode-text-justification.html +/** + * @param {string[]} words + * @param {number} maxWidth + * @return {string[]} + */ +var fullJustify = function(words, maxWidth) { + var result = []; + var start = 0; + var end = -1; + var currentWordsLen = 0; + var i = 0; + + while(i < words.length) { + if(words[i].size > maxWidth) { + return result; + } + + var newLen = currentWordsLen + (end - start + 1) + words[i].length; // current words len + their spaces + new word + + if(newLen <= maxWidth) { // words[i] can fit in the current line + end = i; + currentWordsLen += words[i].length; + i++; + } else { + var line = createLine(words, maxWidth, start, end, currentWordsLen, false); + result.push(line); + start = i; + end = i - 1; + currentWordsLen = 0; + } + } + + var lastLine = createLine(words, maxWidth, start, end, currentWordsLen, true); + result.push(lastLine); + return result; +}; + + +function createLine(words, maxWidth, start, end, currentWordsLen, isLast) { + var result = ''; + if(start < 0 || end >= words.length) { + return result; + } + + result += words[start]; // consume the first word + var numberOfWords = end - start + 1; // number of words to insert in this line + + // special case: one word or last line - left justified + if(numberOfWords === 1 || isLast) { + for(var i = start + 1; i <= end; i++) { // start from start + 1 since we already append the first word + result += (" " + words[i]); + } + + var remainingSpaces = maxWidth - currentWordsLen - (numberOfWords - 1); + for(i = 0; i < remainingSpaces; i++) { + result += ' '; + } + + return result; + } + + var k = parseInt((maxWidth - currentWordsLen)/(numberOfWords - 1)); + var m = (maxWidth - currentWordsLen)%(numberOfWords - 1); + + for(i = start + 1; i <= end; i++) { // start from start + 1 since we already append the first word + var nspace = i - start <= m ? k + 1: k; + + for(var j = 0; j < nspace; j++) { + result += ' '; + } + + result += words[i]; + } + + return result; +} \ No newline at end of file diff --git a/70 Climbing Stairs.js b/70 Climbing Stairs.js index 3248c05..33803ac 100644 --- a/70 Climbing Stairs.js +++ b/70 Climbing Stairs.js @@ -1,22 +1,24 @@ +// You are climbing a stair case. It takes n steps to reach to the top. + +// Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + /** * @param {number} n * @return {number} */ var climbStairs = function(n) { - if(n <= 0){ - return 0; - } - if(n === 1){ - return 1; - } - - var uniqueways = []; - uniqueways[0] = 1; - uniqueways[1] = 1; + var n1 = 1; + var n2 = 1; - for(var i = 2; i <= n; i++){ - uniqueways[i] = uniqueways[i-1] + uniqueways[i-2]; + + // n1 and n2 stands for how many ways it can reach n taking one step or two steps, such as n - 1 and n - 2 + for(var i = 2; i <= n; i++) { + var ways = n1 + n2; + n1 = n2; + n2 = ways; } + + - return uniqueways[n] -}; + return n2; +}; \ No newline at end of file diff --git a/Data Structure Max Heap.js b/Data Structure Max Heap.js new file mode 100644 index 0000000..73fe60f --- /dev/null +++ b/Data Structure Max Heap.js @@ -0,0 +1,111 @@ +class MaxHeap { + constructor() { + this.arr = []; + } + + peek() { + return this.arr[0] || null; + } + + size() { + return this.arr.length; + } + + pop() { + var arr = this.arr; + var len = arr.length; + + if(len === 0) { + return null; + } + + var max = arr[0]; + arr[0] = arr[len - 1] // swap the last value with max value + + arr.pop(); + + this.sinkDown(0); + + return max; + } + + add(val) { + var arr = this.arr; + arr.push(val); + this.bubbleUp(arr.length - 1); + } + + bubbleUp(n) { + var arr = this.arr; + + while(n > 0) { + var parentN = Math.floor((n + 1)/2) - 1; // [1,2,3] 1 as root 2 as left child and 3 as right child 2 has idx = 1 and 3 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + + if(arr[parentN] > arr[n]) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[parentN]; + arr[parentN] = tmp; + n = parentN; + } + } + + sinkDown(n) { + var arr = this.arr; + var len = arr.length; + var val = arr[n]; + + while(true) { + + var swap = null; + var child2N = (n+1)*2; // root = 0 right child idx is (0 + 1)*2 = 2 + var child1N = child2N - 1; // right child idx - 1 = 1 for root's left child + + if(child1N < len && arr[child1N] > val) { + swap = child1N; + } + + if(child2N < len && arr[child2N] > val && arr[child2N] >= arr[child1N]) { + swap = child2N; + } + + if(swap === null) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[swap]; + arr[swap] = tmp; + n = swap; + } + } +} + +var m = new MaxHeap(); +// m.add(4); +m.add(1); +m.add(2); +m.add(3); +m.add(3); +m.add(3); +m.add(3); +m.add(3); + +m.add(-1); +m.add(4); +m.add(4); + +console.log(m.arr); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); + \ No newline at end of file diff --git a/Data Structure Min Heap.js b/Data Structure Min Heap.js new file mode 100644 index 0000000..6ad2f9d --- /dev/null +++ b/Data Structure Min Heap.js @@ -0,0 +1,118 @@ +class MinHeap { + constructor() { + this.arr = []; + } + + peek() { + return this.arr[0] || null; + } + + size() { + return this.arr.length; + } + + pop() { + var arr = this.arr; + var len = arr.length; + + if(len === 0) { + return null; + } + + var min = arr[0]; + arr[0] = arr[len - 1] // swap the last value with min value + + arr.pop(); + + this.sinkDown(0); + + return min; + } + + add(val) { + var arr = this.arr; + arr.push(val); + this.bubbleUp(arr.length - 1); + } + + bubbleUp(n) { + var arr = this.arr; + + while(n > 0) { + var parentN = Math.floor((n + 1)/2) - 1; // [1,2,3] 1 as root 2 as left child and 3 as right child 2 has idx = 1 and 3 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + + if(arr[parentN] <= arr[n]) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[parentN]; + arr[parentN] = tmp; + n = parentN; + } + } + + sinkDown(n) { + var arr = this.arr; + var len = arr.length; + var val = arr[n] + + while(true) { + var swap = null; + var child2N = (n+1)*2; // root = 0 right child idx is (0 + 1)*2 = 2 + var child1N = child2N - 1; // right child idx - 1 = 1 for root's left child + if(child1N < len && arr[child1N] < val) { + swap = child1N; + } + + if(child2N < len && arr[child2N] < val && arr[child2N] <= arr[child1N]) { + swap = child2N; + } + + if(swap === null) { + break; + } + + var tmp = arr[n]; + arr[n] = arr[swap]; + arr[swap] = tmp; + n = swap; + } + } +} + + +var m = new MinHeap(); + +// m.add(4); +m.add(1); +m.add(-1); +m.add(1); +m.add(-1); +m.add(1); +m.add(-1); +m.add(-1); +m.add(1); +m.add(1); +console.log('debug', m.arr) +m.add(1); +// m.add(1); +// m.add(-1); + +// console.log(m.arr); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); + + +console.log(m.arr); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); + +console.log(m.pop()); +console.log(m.pop()); +console.log(m.pop()); +// console.log(m.pop()); + diff --git a/Hackrank.js b/Disambiguos Actors.js similarity index 100% rename from Hackrank.js rename to Disambiguos Actors.js diff --git a/Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js b/Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js new file mode 100644 index 0000000..1df4f58 --- /dev/null +++ b/Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js @@ -0,0 +1,86 @@ +/** + * @param {number[]} nums + * @return {number} + */ + + // Kadane's algo +function maxSubArray(nums) { + var max = -Infinity; + var curMax = 0; + var beg = 0; + var end = 0; + + for(var i = 0; i < nums.length; i++) { + var val = nums[i]; + + curMax += val; + + if(curMax > max) { + end = i; + max = curMax; + } + + if(curMax < 0) { + beg = i + 1; + curMax = 0; + } + } + + return { + max: max, + beg: beg, + end: end + }; +}; + + +// https://www.youtube.com/watch?v=yCQN096CwWM + +var sampleData = [ + [ 2, 1,-3,-4, 5], + [ 0, 6, 3, 4, 1], + [ 2,-2,-1, 4,-5], + [-3, 3, 1, 0, 3] +] + +// move from left to right +function maximumRectangularSubmatrix(matrix) { + var row = matrix.length; + var col = matrix[0].length; + var max = -Infinity; + var maxTop = 0; + var maxLeft = 0; + var maxRight = 0; + var maxBottom = 0; + + for(var left = 0; left < col; left++){ + var subArray = []; + + for(var right = left; right < col; right++){ + for(var i = 0; i < row; i++) { + subArray[i] = subArray[i] || 0; + subArray[i] += matrix[i][right]; + } + + var info = maxSubArray(subArray); + + if(info.max > max) { + max = info.max; + maxLeft = left; + maxRight = right; + maxTop = info.beg; + maxBottom = info.end; + } + } + } + + return { + max: max, + left: maxLeft, + right: maxRight, + top: maxTop, + bottom: maxBottom + } +} + +console.log(maximumRectangularSubmatrix(sampleData)); \ No newline at end of file diff --git a/README.md b/README.md index 5896a47..b9e3353 100644 --- a/README.md +++ b/README.md @@ -1,178 +1,188 @@ -Leetcode Problems in Javascript - -1 Two Sum.js
-10 Regular Expresion Matching.js
-100 Same Tree.js
-101 Symmetric Tree.js
-102 Binary Tree Level Order Traversal.js
-103 Binary Tree Zigzag Level Order Traversal.js
-104 Maximum Depth of Binary Tree.js
-105 Construct Binary Tree from Preorder and Inorder Traversal.js
-106 Construct Binary Tree from Inorder and Postorder Traversal.js
-107 Binary Tree Level Order Traversal II.js
-108 Convert Sorted Array to Binary Search Tree.js
-11 Container With Most Water.js
-110 Balanced Binary Tree.js
-111 Minimum Depth of Binary Tree.js
-112 Path Sum.js
-114 Flatten Binary Tree to Linked List.js
-116 Populating Next Right Pointers in Each Node.js
-118 Pascal's Triangle.js
-119 Pascal's Triangle II.js
-12 Integer to Roman.js
-120 Triangle.js
-121 Best Time to Buy and Sell Stock.js
-122 Best Time to Buy and Sell Stock II.js
-127 Word Ladder.js
-129 Sum Root to Leaf Numbers.js
-13 Roman to Integer.js
-131 Palindrome Partitioning.js
-133 Clone Graph.js
-136 Single Number.js
-137 Single Number II.js
-139 Word Break.js
-14 Longest Common Prefix.js
-141 Linked List Cycle.js
-144 Binary Tree Preorder Traversal My Submissions Question.js
-146 LRU Cache.js
-148 Sort List.js
-15 3Sum.js
-150 Evaluate Reverse Polish Notation.js
-151 Reverse Words in a String.js
-152 Maximum Product Subarray.js
-153 Find Minimum in Rotated Sorted Array.js
-155 Min Stack.js
-159 Longest Substring with At Most Two Disctinct Characters.js
-16 3Sum Closest.js
-160 Intersection Of Two Linked Lists.js
-162 Find Peak Element.js
-165 Compare Version Numbers.js
-166 Fraction to Recurring Decimal.js
-168 Excel Sheet Column Title.js
-169 Majority Element.js
-17 Letter Combinations of a Phone Number.js
-171 Excel Sheet Column Number.js
-172 Factorial Trailing Zeroes.js
-173 Binary Search Tree Iterator.js
-179 Largest Number.js
-189 Rotate Array.js
-19 Remove Nth Node From End of List.js
-190 Reverse Bits.js
-191 Number of 1 Bits.js
-198 House Robber.js
-199 Binary Tree Right Side View.js
-2 Add Two Numbers.js
-20 Valid Parentheses.js
-200 Number of Islands.js
-201 Bitwise AND of Numbers Range.js
-202 Happy Number.js
-203 Remove Linked List Elements.js
-204 Count Primes.js
-205 Isomorphic Strings.js
-206 Reverse Linked List.js
-207 Course Schedule.js
-208 Implement Trie (Prefix Tree).js
-209 Minimum Size Subarray Sum.js
-21 Merge Two Sorted Lists.js
-211 Add and Search Word - Data structure design.js
-215 Kth Largest Element in an Array.js
-217 Contain Duplicate.js
-219 Contains Duplicate II.js
-22 Generate Parentheses.js
-220 Contains Duplicate III.js
-222. Count Complete Tree Nodes.js
-223 Rectangle Area.js
-225 Implement Stack Using Queues.js
-226 Invert Binary Tree.js
-228 Summary Ranges.js
-229 Majority Element II.js
-231 Power of Two.js
-232 Implement Queue using Stacks.js
-233 Number of Digit One.js
-234 Palindrome Linked List.js
-235 Lowest Common Ancestor Of a Binary Search Tree.js
-236 Lowest Common Ancestor of a Binary Tree.js
-237 Delete Node in a Linked List.js
-24 Swap nodes in Pairs.js
-240 Search a 2D Matrix II.js
-241 Different Ways to Add Parentheses.js
-242 Valid Anagram.js
-257 Binary Tree Paths.js
-26 Remove Duplicates from Sorted Array.js
-263 Ugly Number.js
-264 Ugly Number II.js
-268 Missing Number.js
-27 Remove Element.js
-279. Perfect Squares.js
-28 Implement strStr().js
-286 Walls and Gates.js
-289. Game of Life.js
-297 Serialize and Deserialize Binary Tree My Submissions Question.js
-3 Longest Substring Without Repeating Characters.js
-300 Longest Increasing Subsequence.js
-31 Next Permutation.js
-314 Binary Tree Vertical Order Traversal.js
-318 Maximum Product of Word Lengths My Submissions Question.js
-322 Coin Change.js
-33 Search in Rotated Sorted Array.js
-335 Self Crossing.js
-34 Search for a Range.js
-340 Longest Substring With At Most K Distinct Characters.js
-35 Search Insert Position.js
-36 Valid Sudoku.js
-37 Sudoku Solver.js
-38 Count and Say.js
-39 Combination Sum.js
-4. Median of Two Sorted Arrays.js
-40 combination Sum II.js
-43 Multiply Strings.js
-46 Permutations.js
-48 Rotate Image.js
-49 Anagrams.js
-49 Group Anagrams.js
-5 Longest Palindromic Substring.js
-50 Pow(x, n).js
-51 N-Queens.js
-53 Maximum Subarray.js
-54 Spiral Matrix.js
-55 Jump Game.js
-56. Merge Intervals.js
-57. Insert Interval.js
-58 Length of Last Word.js
-59 Spiral Matrix II.js
-61 Rotate List.js
-62 Unique Paths.js
-63 Unique Paths II.js
-64 Minimum Path Sum.js
-66 Plus One.js
-67 Add Binary.js
-69 Sqrt(x).js
-70 Climbing Stairs.js
-71 Simplify Path.js
-72 Edit Distance.js
-74 Search a 2D Matrix.js
-75 Sort Colors.js
-77 Combinations.js
-8 String to Integer (atoi).js
-80 Remove Duplicates from Sorted Array II.js
-81 Search in Rotated Sorted Array II.js
-82 Remove Duplicates from Sorted List II.js
-83 Remove Duplicates from Sorted List.js
-86 Partition List.js
-88 Merge Sorted Array.js
-9 Palindrome Number.js
-90 Subsets II.js
-91 Decode Ways.js
-92 Reverse Linked List II.js
-93 Restore IP Addresses.js
-94 Binary Tree Inorder Traversal.js
-96 Unique Binary Search Trees.js
-98 Validate Binary Search Tree.js
-Hackrank.js
-Javascript Closure Questions.js
-Jump Game II.js
-Rate Limiter.js
-Reverse Integer.js
-String Encoding and Decoding.js
-find kth element in two arrays.js
-flatten nested array.js
\ No newline at end of file +# Leetcode Problems and interview problems in Javascript +- 1 Two Sum.js +- 10 Regular Expresion Matching.js +- 100 Same Tree.js +- 101 Symmetric Tree.js +- 102 Binary Tree Level Order Traversal.js +- 103 Binary Tree Zigzag Level Order Traversal.js +- 104 Maximum Depth of Binary Tree.js +- 105 Construct Binary Tree from Preorder and Inorder Traversal.js +- 106 Construct Binary Tree from Inorder and Postorder Traversal.js +- 107 Binary Tree Level Order Traversal II.js +- 108 Convert Sorted Array to Binary Search Tree.js +- 11 Container With Most Water.js +- 110 Balanced Binary Tree.js +- 111 Minimum Depth of Binary Tree.js +- 112 Path Sum.js +- 114 Flatten Binary Tree to Linked List.js +- 116 Populating Next Right Pointers in Each Node.js +- 118 Pascal's Triangle.js +- 119 Pascal's Triangle II.js +- 12 Integer to Roman.js +- 120 Triangle.js +- 121 Best Time to Buy and Sell Stock.js +- 122 Best Time to Buy and Sell Stock II.js +- 124 Binary Tree Maximum Path Sum.js +- 127 Word Ladder.js +- 129 Sum Root to Leaf Numbers.js +- 13 Roman to Integer.js +- 131 Palindrome Partitioning.js +- 133 Clone Graph.js +- 136 Single Number.js +- 137 Single Number II.js +- 139 Word Break.js +- 14 Longest Common Prefix.js +- 140 Word Break II.js +- 141 Linked List Cycle.js +- 144 Binary Tree Preorder Traversal My Submissions Question.js +- 145 Binary Tree Post Order Traversal.js +- 146 LRU Cache.js +- 148 Sort List.js +- 15 3Sum.js +- 150 Evaluate Reverse Polish Notation.js +- 151 Reverse Words in a String.js +- 152 Maximum Product Subarray.js +- 153 Find Minimum in Rotated Sorted Array.js +- 155 Min Stack.js +- 159 Longest Substring with At Most Two Disctinct Characters.js +- 16 3Sum Closest.js +- 160 Intersection Of Two Linked Lists.js +- 162 Find Peak Element.js +- 165 Compare Version Numbers.js +- 166 Fraction to Recurring Decimal.js +- 168 Excel Sheet Column Title.js +- 169 Majority Element.js +- 17 Letter Combinations of a Phone Number.js +- 171 Excel Sheet Column Number.js +- 172 Factorial Trailing Zeroes.js +- 173 Binary Search Tree Iterator.js +- 179 Largest Number.js +- 189 Rotate Array.js +- 19 Remove Nth Node From End of List.js +- 190 Reverse Bits.js +- 191 Number of 1 Bits.js +- 198 House Robber.js +- 199 Binary Tree Right Side View.js +- 2 Add Two Numbers.js +- 20 Valid Parentheses.js +- 200 Number of Islands.js +- 201 Bitwise AND of Numbers Range.js +- 202 Happy Number.js +- 203 Remove Linked List Elements.js +- 204 Count Primes.js +- 205 Isomorphic Strings.js +- 206 Reverse Linked List.js +- 207 Course Schedule.js +- 208 Implement Trie (Prefix Tree).js +- 209 Minimum Size Subarray Sum.js +- 21 Merge Two Sorted Lists.js +- 211 Add and Search Word - Data structure design.js +- 215 Kth Largest Element in an Array.js +- 215 Kth Largest Element in an Array.py +- 217 Contain Duplicate.js +- 219 Contains Duplicate II.js +- 22 Generate Parentheses.js +- 220 Contains Duplicate III.js +- 222. Count Complete Tree Nodes.js +- 223 Rectangle Area.js +- 225 Implement Stack Using Queues.js +- 226 Invert Binary Tree.js +- 228 Summary Ranges.js +- 229 Majority Element II.js +- 231 Power of Two.js +- 232 Implement Queue using Stacks.js +- 233 Number of Digit One.js +- 234 Palindrome Linked List.js +- 235 Lowest Common Ancestor Of a Binary Search Tree.js +- 236 Lowest Common Ancestor of a Binary Tree.js +- 237 Delete Node in a Linked List.js +- 24 Swap nodes in Pairs.js +- 240 Search a 2D Matrix II.js +- 241 Different Ways to Add Parentheses.js +- 242 Valid Anagram.js +- 249 Group Shifted Strings.js +- 257 Binary Tree Paths.js +- 26 Remove Duplicates from Sorted Array.js +- 263 Ugly Number.js +- 264 Ugly Number II.js +- 268 Missing Number.js +- 27 Remove Element.js +- 279. Perfect Squares.js +- 28 Implement strStr().js +- 286 Walls and Gates.js +- 289. Game of Life.js +- 295 Find Median From Data Stream.js +- 297 Serialize and Deserialize Binary Tree My Submissions Question.js +- 3 Longest Substring Without Repeating Characters.js +- 300 Longest Increasing Subsequence.js +- 31 Next Permutation.js +- 314 Binary Tree Vertical Order Traversal.js +- 318 Maximum Product of Word Lengths My Submissions Question.js +- 322 Coin Change.js +- 33 Search in Rotated Sorted Array.js +- 335 Self Crossing.js +- 34 Search for a Range.js +- 340 Longest Substring With At Most K Distinct Characters.js +- 35 Search Insert Position.js +- 36 Valid Sudoku.js +- 37 Sudoku Solver.js +- 38 Count and Say.js +- 39 Combination Sum.js +- 4. Median of Two Sorted Arrays.js +- 40 combination Sum II.js +- 43 Multiply Strings.js +- 45 Jump Game II.js +- 46 Permutations.js +- 48 Rotate Image.js +- 49 Anagrams.js +- 49 Group Anagrams.js +- 5 Longest Palindromic Substring.js +- 50 Pow(x, n).js +- 51 N-Queens.js +- 53 Maximum Subarray.js +- 54 Spiral Matrix.js +- 55 Jump Game.js +- 56. Merge Intervals.js +- 57. Insert Interval.js +- 58 Length of Last Word.js +- 59 Spiral Matrix II.js +- 61 Rotate List.js +- 62 Unique Paths.js +- 63 Unique Paths II.js +- 64 Minimum Path Sum.js +- 66 Plus One.js +- 67 Add Binary.js +- 68 Text Justification.js +- 69 Sqrt(x).js +- 70 Climbing Stairs.js +- 71 Simplify Path.js +- 72 Edit Distance.js +- 74 Search a 2D Matrix.js +- 75 Sort Colors.js +- 77 Combinations.js +- 8 String to Integer (atoi).js +- 80 Remove Duplicates from Sorted Array II.js +- 81 Search in Rotated Sorted Array II.js +- 82 Remove Duplicates from Sorted List II.js +- 83 Remove Duplicates from Sorted List.js +- 86 Partition List.js +- 88 Merge Sorted Array.js +- 9 Palindrome Number.js +- 90 Subsets II.js +- 91 Decode Ways.js +- 92 Reverse Linked List II.js +- 93 Restore IP Addresses.js +- 94 Binary Tree Inorder Traversal.js +- 96 Unique Binary Search Trees.js +- 98 Validate Binary Search Tree.js +- Data Structure Max Heap.js +- Data Structure Min Heap.js +- Disambiguos Actors.js +- Javascript Closure Questions.js +- Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js +- README.md +- Rate Limiter.js +- Reverse Integer.js +- String Encoding and Decoding.js +- find kth element in two arrays.js +- flatten nested array.js \ No newline at end of file diff --git a/test.py b/test.py deleted file mode 100644 index f86a98e..0000000 --- a/test.py +++ /dev/null @@ -1,22 +0,0 @@ -class Solution(object): - def increasingTriplet(self, nums): - """ - :type nums: List[int] - :rtype: bool - """ - a = b = None - for n in nums: - if a is None or a >= n: - a = n - print "a: ", a - elif b is None or b >= n: - b = n - print "b: ", b - else: - return True - return False - -foo = Solution() -print foo.increasingTriplet([1,2,3]) -print foo.increasingTriplet([3,2,1]) -print foo.increasingTriplet([1,1,2]) \ No newline at end of file From e3c86bc8e793af6c7f6aefa2c94b8ed35213a443 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Tue, 5 Jul 2016 13:36:43 -0700 Subject: [PATCH 11/47] add more solutions --- 124 Binary Tree Maximum Path Sum.js | 19 +++- 224 Basic Calculator.js | 53 ++++++++++ 23 Merge k Sorted Lists.js | 60 ++++++++++++ 239 Sliding Window Maximum.js | 56 +++++++++++ 242 Valid Anagram.js | 58 ++++++----- 25 Reverse Nodes in k-Group.js | 64 ++++++++++++ 269 Alien Dictionary.js | 103 ++++++++++++++++++++ 296 Best Meeting Point.js | 56 +++++++++++ 317 Shortest Distance From All Buildings.js | 97 ++++++++++++++++++ 371 Sum of Two Integers.js | 26 +++++ 49 Group Anagrams.js | 35 ++++--- 69 Sqrt(x).js | 28 ++++++ 71 Simplify Path.js | 24 +++-- 91 Decode Ways.js | 13 +++ 92 Reverse Linked List II.js | 41 ++++---- Parse HTML.js | 70 +++++++++++++ Parse Log Top k Longest Running Job.js | 0 Ransom Note From Magazine.js | 40 ++++++++ Top k Longest Running Job.js | 17 ++++ 19 files changed, 787 insertions(+), 73 deletions(-) create mode 100644 224 Basic Calculator.js create mode 100644 23 Merge k Sorted Lists.js create mode 100644 239 Sliding Window Maximum.js create mode 100644 25 Reverse Nodes in k-Group.js create mode 100644 269 Alien Dictionary.js create mode 100644 296 Best Meeting Point.js create mode 100644 317 Shortest Distance From All Buildings.js create mode 100644 371 Sum of Two Integers.js create mode 100644 Parse HTML.js create mode 100644 Parse Log Top k Longest Running Job.js create mode 100644 Ransom Note From Magazine.js create mode 100644 Top k Longest Running Job.js diff --git a/124 Binary Tree Maximum Path Sum.js b/124 Binary Tree Maximum Path Sum.js index 0622d86..4d75cb6 100644 --- a/124 Binary Tree Maximum Path Sum.js +++ b/124 Binary Tree Maximum Path Sum.js @@ -1,3 +1,16 @@ +// Given a binary tree, find the maximum path sum. + +// For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root. + +// For example: +// Given the below binary tree, + +// 1 +// / \ +// 2 3 +// Return 6. + + // http://bangbingsyb.blogspot.com/2014/11/leetcode-binary-tree-maximum-path-sum.html /** * Definition for a binary tree node. @@ -22,13 +35,17 @@ var maxPathSum = function(root) { var leftVal = Math.max(findMaxPath(node.left), 0); var rightVal = Math.max(findMaxPath(node.right), 0); - + var ps1 = node.val + Math.max(leftVal, rightVal); // ps2 means taking this current node as parent node and stop there var ps2 = node.val + leftVal + rightVal; + // maxVal as if we end counting value here, what will be the maximum val + // leftVal and rightVal can be negative values maxVal = Math.max(maxVal, Math.max(ps1, ps2)); + // return ps1 only since, ps2 cannot be combined with the parent node + // leftVal and rightVal can be negative values, however, we can to see if combining with values down below can give higher number return ps1; } }; diff --git a/224 Basic Calculator.js b/224 Basic Calculator.js new file mode 100644 index 0000000..74ed6d2 --- /dev/null +++ b/224 Basic Calculator.js @@ -0,0 +1,53 @@ +/** +Implement a basic calculator to evaluate a simple expression string. + +The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces . + +You may assume that the given expression is always valid. + +Some examples: +"1 + 1" = 2 +" 2-1 + 2 " = 3 +"(1+(4+5+2)-3)+(6+8)" = 23 +Note: Do not use the eval built-in library function. +*/ +/** + * @param {string} s + * @return {number} + */ +var calculate = function(s) { + var stack = [], + len = s.length, + sum = 0, + num, + ch, + j, + i; + + stack.push(1); + stack.push(1); + + for (i = 0; i < len; i++) { + ch = s.charAt(i); + + if (!isNaN(parseInt(ch))) { + num = parseInt(ch); + + for (j = i + 1; j < len && !isNaN(parseInt(s.charAt(j))); j++) { + num = num * 10 + parseInt(s.charAt(j)); + } + + sum += stack.pop() * num; + + i = j - 1; + } else if (ch === '+' || ch === '(') { + stack.push(stack[stack.length - 1]); + } else if (ch === '-') { + stack.push(stack[stack.length - 1] * (-1)); + } else if (ch === ')') { + stack.pop(); + } + } + + return sum; +}; diff --git a/23 Merge k Sorted Lists.js b/23 Merge k Sorted Lists.js new file mode 100644 index 0000000..b49f111 --- /dev/null +++ b/23 Merge k Sorted Lists.js @@ -0,0 +1,60 @@ +// Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. +// http://www.cnblogs.com/springfor/p/3869217.html +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode[]} lists + * @return {ListNode} + */ +var mergeKLists = function(lists) { + return mergeHelper(lists, 0, lists.length - 1); +}; + +function mergeHelper(lists, l, r) { + if(l === r) { + return lists[l]; + } + + if(l > r) { + return null; + } + + var mid = Math.floor((l + r)/2); + var left = mergeHelper(lists, l, mid); + var right = mergeHelper(lists, mid + 1, r); + + return mergeTwoLists(left, right); +} + + +function mergeTwoLists(l1, l2) { + var dummy = new ListNode(0); + var cur = dummy; + + while(l1 && l2) { + if(l1.val < l2.val) { + cur.next = l1; + l1 = l1.next; + } else { + cur.next = l2; + l2 = l2.next; + } + + cur = cur.next; + } + + if(l1) { + cur.next = l1; + } + + if(l2) { + cur.next = l2; + } + + return dummy.next; +} \ No newline at end of file diff --git a/239 Sliding Window Maximum.js b/239 Sliding Window Maximum.js new file mode 100644 index 0000000..6458c91 --- /dev/null +++ b/239 Sliding Window Maximum.js @@ -0,0 +1,56 @@ +// Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. + +// For example, +// Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. + +// Window position Max +// --------------- ----- +// [1 3 -1] -3 5 3 6 7 3 +// 1 [3 -1 -3] 5 3 6 7 3 +// 1 3 [-1 -3 5] 3 6 7 5 +// 1 3 -1 [-3 5 3] 6 7 5 +// 1 3 -1 -3 [5 3 6] 7 6 +// 1 3 -1 -3 5 [3 6 7] 7 +// Therefore, return the max sliding window as [3,3,5,5,6,7]. + +/** + * @param {number[]} nums + * @param {number} k + * @return {number[]} + */ +var maxSlidingWindow = function(nums, k) { + var result = [], + linkedListWithTwoEndsOps = [], + len = nums.length, + i; + + if (k > len || k === 0) { + return result; + } + + for (i = 0; i < len; i++) { + // Remove anything that is less than the current value + // so linkedListWithTwoEndsOps maintains values greater than the curret value + while (linkedListWithTwoEndsOps.length > 0 && nums[linkedListWithTwoEndsOps[linkedListWithTwoEndsOps.length - 1]] < nums[i]) { + var val = linkedListWithTwoEndsOps.pop(); + } + + // In case that all elements in the linkedListWithTwoEndsOps are all greater than the current one (descending order) + // Shift out the + if (linkedListWithTwoEndsOps[0] < i - k + 1) { + linkedListWithTwoEndsOps.shift(); + } + + linkedListWithTwoEndsOps.push(i); + + // For each sliding window movement, we record the highest value in that sliding window + // i >= k - 1 to ensure that we don't prematurely record values before we get to the full range of the first sliding window + // e.g. [1 3 -1] -3 5 3 6 7 3 + // this ensure that i is at least at -1 (index 2) + if (i >= k - 1) { + result.push(nums[linkedListWithTwoEndsOps[0]]); + } + } + + return result; +}; \ No newline at end of file diff --git a/242 Valid Anagram.js b/242 Valid Anagram.js index 5b749e6..bccbafb 100644 --- a/242 Valid Anagram.js +++ b/242 Valid Anagram.js @@ -1,31 +1,41 @@ -// Leetcode #242 -// Language: Javascript -// Problem: https://leetcode.com/problems/valid-anagram/ -// Author: Chihung Yu +// Given two strings s and t, write a function to determine if t is an anagram of s. + +// For example, +// s = "anagram", t = "nagaram", return true. +// s = "rat", t = "car", return false. + + + /** * @param {string} s * @param {string} t * @return {boolean} */ var isAnagram = function(s, t) { - if((s === null || t === null) || (s.length !== t.length)){ - return false; - } - - var hash = {}; - - for(var i = 0; i < s.length; i++){ - hash[s[i]] = hash[s[i]] || 0; - hash[s[i]]++; - } - - for(var j = 0; j < t.length; j++){ - if(!hash[t[j]]){ - return false; - } - - hash[t[j]]--; - } - - return true; + var slen = s.length; + var tlen = t.length; + + if(slen !== tlen) { + return false; + } + + var hash = {}; + + for(var i = 0; i < slen; i++) { + var char = s[i]; + hash[char] = hash[char] || 0; + hash[char]++; + } + + for(i = 0; i < tlen; i++) { + char = t[i]; + + if(hash[char] === undefined || hash[char] === 0) { + return false; + } + + hash[char]--; + } + + return true; }; \ No newline at end of file diff --git a/25 Reverse Nodes in k-Group.js b/25 Reverse Nodes in k-Group.js new file mode 100644 index 0000000..bd0fabc --- /dev/null +++ b/25 Reverse Nodes in k-Group.js @@ -0,0 +1,64 @@ + +// Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. + +// If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. + +// You may not alter the values in the nodes, only nodes itself may be changed. + +// Only constant memory is allowed. + +// For example, +// Given this linked list: 1->2->3->4->5 + +// For k = 2, you should return: 2->1->4->3->5 + +// For k = 3, you should return: 3->2->1->4->5 + + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} k + * @return {ListNode} + */ + + // http://www.geeksforgeeks.org/reverse-a-list-in-groups-of-given-size/ +var reverseKGroup = function(head, k) { + var cur = head; + var pre = null; + var post = null; + var count = 0; + + while(cur !== null && count < k) { + cur = cur.next; + count++; + } + + if(count !== k) { + return head; + } + + cur = head; + + while(cur !== null && count > 0) { + post = cur.next; + cur.next = pre; + pre = cur; + cur = post; + count--; + } + + // post is now a pointer to (k+1)th node + // recursively call for the list starting from cur + if(post !== null) { + head.next = reverseKGroup(post, k); + } + + return pre; +}; \ No newline at end of file diff --git a/269 Alien Dictionary.js b/269 Alien Dictionary.js new file mode 100644 index 0000000..21c2f1c --- /dev/null +++ b/269 Alien Dictionary.js @@ -0,0 +1,103 @@ +var alienOrder = function(words) { + if (words.length === 0) { + return ''; + } + + const len = words.length; + let map = {}; // value is the prerequisite of key + let charPreReqCount = {}; + let i; + let queue = []; + let result = []; + let hasCycle = false; + + for (i = 0; i < len; i++) { + // wert vs woo + // map : { w: [], e: [ 'o' ], r: [], t: [], o: [] } + // charPreReqCount : { w: 0, e: 0, r: 0, t: 0, o: 1 } + const chars = words[i].split(''); + + let j = 0; + + for (j = 0; j < chars.length; j++) { + if (!map[chars[j]]) { + map[chars[j]] = []; + charPreReqCount[chars[j]] = 0; + } + } + + // skip the first one || the same word + if (i === 0 || words[i] === words[i - 1]) { + continue; + } + + const cur = words[i]; + const prev = words[i - 1]; + j = 0; + + + // skip same words such as wert and woo will skip w and compare only ert vs oo + while(j < cur.length && j < prev.length && cur.charAt(j) === prev.charAt(j)) { + j++; + } + + + // since words are in lexico order wert and woo -> ert vs oo, e will have higher order than oo + if (j < prev.length && map[prev.charAt(j)].indexOf(cur.charAt(j)) === -1) { + map[prev.charAt(j)].push(cur.charAt(j)); + // number of prerequisite for using that char in this case it will be o: 1 since o has prerequisite e + // { w: [], e: [ 'o' ], r: [], t: [], o: [] } + // { w: 0, e: 0, r: 0, t: 0, o: 1 } + charPreReqCount[cur.charAt(j)]++; + } + } + + + // these will be the roots since there are no prerequisite needed to use them + Object.keys(charPreReqCount).forEach(char => { + if (charPreReqCount[char] === 0) { + queue.push(char); + } + }); + + // for those that we know are root + while(queue.length > 0) { + const char = queue.shift(); + + result.push(char); + + for (i = 0; i < map[char].length; i++) { + charPreReqCount[map[char][i]]--; + + if (charPreReqCount[map[char][i]] === 0) { + queue.push(map[char][i]); + } + } + } + + Object.keys(charPreReqCount).forEach(function(char) { + if (charPreReqCount[char] !== 0) { + hasCycle = true; + } + }); + + return hasCycle ? '' : result.join(''); +} + + + +// var words = [ +// "wrt", +// "wrf", +// "er", +// "ett", +// "rftt" +// ]; + + +var words =[ + 'wert', + 'woo' +]; + +console.log('ans', alienOrder(words)); \ No newline at end of file diff --git a/296 Best Meeting Point.js b/296 Best Meeting Point.js new file mode 100644 index 0000000..4af79c2 --- /dev/null +++ b/296 Best Meeting Point.js @@ -0,0 +1,56 @@ +// A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|. + +// For example, given three people living at (0,0), (0,4), and (2,2): + +// 1 - 0 - 0 - 0 - 1 +// | | | | | +// 0 - 0 - 0 - 0 - 0 +// | | | | | +// 0 - 0 - 1 - 0 - 0 +// The point (0,2) is an ideal meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6. + +// Show Hint +// Show Company Tags +// Show Tags +// Show Similar Problems + + +/** + * @param {number[][]} grid + * @return {number} + */ +var minTotalDistance = function(grid) { + var xpos = []; + var ypos = []; + + // get all positions + for(var x = 0; x < grid.length; x++) { + for(var y = 0; y < grid[0].length; y++) { + if(grid[x][y] === 1) { + xpos.push(x); + ypos.push(y); + } + } + } + + // no need to sort x + return getMedianPoint(xpos) + getMedianPoint(ypos, true); +}; + +var getMedianPoint = function(arr, shouldSort) { + if(shouldSort) { + arr.sort((a,b)=> { + return a > b ? 1 : -1; + }); + } + + var beg = 0; + var end = arr.length - 1; + var res = 0; + + while(beg < end) { + res += arr[end--] - arr[beg++]; + } + + return res; +} \ No newline at end of file diff --git a/317 Shortest Distance From All Buildings.js b/317 Shortest Distance From All Buildings.js new file mode 100644 index 0000000..45e899e --- /dev/null +++ b/317 Shortest Distance From All Buildings.js @@ -0,0 +1,97 @@ +/** + * @param {number[][]} grid + * @return {number} + */ +var shortestDistance = function(grid) { + var rows = grid.length; + if(rows === 0) { + return -1; + } + + var cols = grid[0].length; + // 2D array that records sum distances to all buildings + var dist = []; + + // 2D array that records how many buildings can visit here + var nums = []; + + for(var row = 0; row < rows; row++) { + dist.push([]); + nums.push([]); + + for(var col = 0; col < cols; col++) { + dist[row][col] = 0; + nums[row][col] = 0; + } + } + + var buildingNum = 0; + + for(row = 0; row < rows; row++) { + for(col = 0; col < cols; col++) { + if(grid[row][col] === 1) { + buildingNum++; + bfs(grid, row, col, dist, nums); + } + } + } + + var min = Infinity; + + for(row = 0; row < rows; row++) { + for(col = 0; col < cols; col++) { + if(grid[row][col] === 0 && dist[row][col] !== 0 && nums[row][col] === buildingNum) { + min = Math.min(min, dist[row][col]); + } + } + } + + if(min < Infinity) { + return min; + } + + return -1; +}; + +function bfs(grid, begCol, begRow, dist, nums) { + var rows = grid.length; + var cols = grid[0].length; + var queue = []; + queue.push([begRow, begCol]); + var dirs = [[-1,0],[0,1],[1,0],[0,-1]]; + var level = 0; + + // record if location is visited + var visited = []; + // init visited to all false + for(var row = 0; row < rows; row++) { + visited.push([]); + for(var col = 0; col < cols; col++) { + visited[row][col] = false; + } + } + + while(queue.length !== 0) { + level++; + var len = queue.length; + + for(var i = 0; i < len; i++) { + var coords = queue.shift(); + for(var j =0; j < dirs.length; j++) { + var x = coords[0] + dirs[j][0]; + var y = coords[1] + dirs[j][1]; + + if(x >= 0 && x < rows && y >= 0 && y < cols && !visited[x][y] && grid[x][y] === 0) { + visited[x][y] = true; + + dist[x][y] += level; + nums[x][y]++; + queue.push([x,y]); + } + } + } + } +} + + +function init2D \ No newline at end of file diff --git a/371 Sum of Two Integers.js b/371 Sum of Two Integers.js new file mode 100644 index 0000000..2fe03aa --- /dev/null +++ b/371 Sum of Two Integers.js @@ -0,0 +1,26 @@ +// Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. + +// Example: +// Given a = 1 and b = 2, return 3. + +/** + * @param {number} a + * @param {number} b + * @return {number} + */ +var getSum = function(a, b) { + while(b !== 0) { + + // 100 + // 101 + + // carry = a&b and carry << 1 will give 1 in the front + // a^b will give 001 which is addition. + // b now will become 1000 and we just need to do this one more time then we get the answer. + var carry = a & b; + a ^= b; + b = carry << 1; + } + + return a; +}; \ No newline at end of file diff --git a/49 Group Anagrams.js b/49 Group Anagrams.js index e8738de..bc02cc6 100644 --- a/49 Group Anagrams.js +++ b/49 Group Anagrams.js @@ -1,37 +1,42 @@ +// Given an array of strings, group anagrams together. + +// For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], +// Return: + +// [ +// ["ate", "eat","tea"], +// ["nat","tan"], +// ["bat"] +// ] +// Note: All inputs will be in lower-case. /** * @param {string[]} strs * @return {string[][]} */ - - - var groupAnagrams = function(strs) { - var hash = {} + var hash = {}; for(var i = 0; i < strs.length; i++) { var str = strs[i]; - var sortedStr = sort(str); - hash[sortedStr] = hash[sortedStr] || []; - hash[sortedStr].push(str); + var key = sort(str); + + hash[key] = hash[key] || []; + hash[key].push(str); } var result = []; - for(i in hash) { - var arr = hash[i].sort(function (a,b) { - return a > b ? 1 : -1; - }); - result.push(arr); + result.push(hash[i]); } + return result; }; + var sort = function(s) { var arr = s.split(''); - arr.sort(function (a,b) { - return a > b ? 1 : -1; - }); + arr.sort((a,b)=> a > b ? 1 : -1); return arr.join(''); } \ No newline at end of file diff --git a/69 Sqrt(x).js b/69 Sqrt(x).js index 96387c7..57c1446 100644 --- a/69 Sqrt(x).js +++ b/69 Sqrt(x).js @@ -28,3 +28,31 @@ var mySqrt = function(x) { return start; }; + + + +// http://www.cs.wustl.edu/~kjg/CS101_SP97/Notes/SquareRoot/sqrt.html + +var mySqrtWithPrecision = function(digit, precision) { + // Set initial guess to 1 + var guess = 1; + var closeEnoughPrecision = Math.pow(0.1, precision + 1); + + while(true) { + // difference between guess and real value + // e.g. 5's sqrt = 2.236 + // val = x*x sqrt = val/x + // if we guess 3 as the sqrt of 5 -> 5/3 = 1.666 the difference between 3 and 1.6666 is 1.3333 and is way off + // as it should be x*x = 5 and x here is 2.236 + var diff = Math.abs(guess - digit/guess); + + if(diff > closeEnoughPrecision) { + // Better guess will be (3 + 1.66666)/2 => 2.3333 + guess = (guess + digit/guess)/2; + } else { + break; + } + } + + return guess; +} \ No newline at end of file diff --git a/71 Simplify Path.js b/71 Simplify Path.js index 69141e7..5e28f20 100644 --- a/71 Simplify Path.js +++ b/71 Simplify Path.js @@ -1,21 +1,25 @@ +// Given an absolute path for a file (Unix-style), simplify it. + +// For example, +// path = "/home/", => "/home" +// path = "/a/./b/../../c/", => "/c" + /** * @param {string} path * @return {string} */ var simplifyPath = function(path) { var arr = path.split('/'); - var stack = []; + var result = []; - for(var i = 0; i < arr.length; i++){ - var c = arr[i]; - - if(c === '..'){ - stack.pop(); - } else if(c !== '' && c !== '.' && c !== '/'){ - stack.push(c); + for(var i = 0; i < arr.length; i++) { + var p = arr[i]; + if(p === '..') { + result.pop(); + } else if(p !== '' && p !== '.') { + result.push(p); } } - var result = stack.join('/'); - return '/' + result; + return '/' + result.join('/'); }; \ No newline at end of file diff --git a/91 Decode Ways.js b/91 Decode Ways.js index 1a8f094..5a0cd16 100644 --- a/91 Decode Ways.js +++ b/91 Decode Ways.js @@ -1,3 +1,16 @@ +// A message containing letters from A-Z is being encoded to numbers using the following mapping: + +// 'A' -> 1 +// 'B' -> 2 +// ... +// 'Z' -> 26 +// Given an encoded message containing digits, determine the total number of ways to decode it. + +// For example, +// Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). + +// The number of ways decoding "12" is 2. + /** * @param {string} s * @return {number} diff --git a/92 Reverse Linked List II.js b/92 Reverse Linked List II.js index c0cc0b5..9b610bf 100644 --- a/92 Reverse Linked List II.js +++ b/92 Reverse Linked List II.js @@ -1,3 +1,5 @@ +// http://bangbingsyb.blogspot.com/2014/11/leetcode-reverse-linked-list-ii.html + /** * Definition for singly-linked list. * function ListNode(val) { @@ -12,39 +14,32 @@ * @return {ListNode} */ var reverseBetween = function(head, m, n) { - if(m === n){ + if(m >= n) { return head; } - var step = n - m; - var dummy = new ListNode(-1); + var dummy = new ListNode(0); dummy.next = head; - var pre = head = dummy; + head = dummy; - while(m > 1){ - pre = pre.next; - m--; + // move head to m - 1 node; + for(var i = 0; i < m - 1; i++) { + head = head.next; } + var pre = head.next; var cur = pre.next; - var post = cur.next; - if(step >= 1){ - while(step > 0 && post !== null){ - var temp = post.next; - post.next = cur; - cur = post; - post = temp; - step--; - } - - temp = pre.next; - pre.next = cur; - temp.next = post; + for(i = 0; i < n - m; i++) { + var tmp = cur.next; + cur.next = pre; + pre = cur; + cur = tmp; } - // safeG = head; - head = head.next; + // head.next still point to m + head.next.next = cur; + head.next = pre; - return head; + return dummy.next; }; \ No newline at end of file diff --git a/Parse HTML.js b/Parse HTML.js new file mode 100644 index 0000000..0dbc363 --- /dev/null +++ b/Parse HTML.js @@ -0,0 +1,70 @@ +// Hulu + + +function parseHtml(htmlArr) { + var context = []; + var stack = []; + + for(var i = 0; i < htmlArr.length; i++){ + var htmlTag = htmlArr[i]; + + if(htmlTag[0] === '/'){ + context = stack.pop(); + } else { + var map = {}; + map[htmlTag] = []; + stack.push(context); + context.push(map); + context = map[htmlTag]; + } + } + + return context; +} + + + + +var htmlArr = [ + 'html', + 'body', + 'div', + 'a', + '/a', + '/div', + 'div', + 'a', + '/a', + '/div', + 'div', + 'a', + '/a', + '/div', + '/body', + '/html' +]; + + +console.log(parseHtml(htmlArr)); +// will generate + +/* +[{ + html: [{ + body: [{ + div: { + a: {} + } + },{ + div: { + a: {} + } + },{ + div: { + a: {} + } + }] + }] +}] +*/ + diff --git a/Parse Log Top k Longest Running Job.js b/Parse Log Top k Longest Running Job.js new file mode 100644 index 0000000..e69de29 diff --git a/Ransom Note From Magazine.js b/Ransom Note From Magazine.js new file mode 100644 index 0000000..8f84a34 --- /dev/null +++ b/Ransom Note From Magazine.js @@ -0,0 +1,40 @@ +// Kidnapper kidnaps you and writes a ransom note. He does not write it with hand, as handwriting can put him in, so reaches to a magazine at table and creates ransom note. We need to find out given ransom string and magazine string, is it possible to create given ransom note. Kidnapper can use individual characters of words. + + + +function ransomNoteFromMagazine(magazine, ransom) { + var hash = {}; + var mLen = magazine.length; + var rLen = ransom.length; + var mIdx = 0; + var rIdx = 0; + + while(rIdx < rLen) { + var rc = ransom[rIdx]; + + if(hash[rc] === undefined || hash[rc] === 0) { + var found = false; + + while(mIdx < mLen) { + var mc = magazine[mIdx]; + hash[mc] = hash[mc] || 0; + hash[mc]++; + mIdx++; + + if(mc === rc) { + found = true; + break; + } + } + + if(!found) { + return false; + } + } + + hash[rc]--; + rIdx++; + } + + return true; +} diff --git a/Top k Longest Running Job.js b/Top k Longest Running Job.js new file mode 100644 index 0000000..b1fd1b1 --- /dev/null +++ b/Top k Longest Running Job.js @@ -0,0 +1,17 @@ +// parse log。 +// log是指进程运行的记录。一个进程有一个jobname。由于可以并行多次执行 +// 一个jobname下可以有多个jobid。每个jobid会有一个endtime。 +// 函数,print out 前k个运行时间最长的进程的jobname和对应的最长endtime。 + + +// jobname, jobid, endtime + +// hash1: jobname->endtime: +// store the longest endtime for that job +// hash2: jobid->jobname +// not sure what it's for + +// use min heap to store the top k longest running one + + + From df69de63b495276ac9a59255b75dcab7592d0630 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Tue, 5 Jul 2016 13:39:07 -0700 Subject: [PATCH 12/47] add readme --- README.md | 16 +++++++++++++--- memo.txt | 2 -- 2 files changed, 13 insertions(+), 5 deletions(-) delete mode 100644 memo.txt diff --git a/README.md b/README.md index b9e3353..eb460bc 100644 --- a/README.md +++ b/README.md @@ -78,17 +78,18 @@ - 21 Merge Two Sorted Lists.js - 211 Add and Search Word - Data structure design.js - 215 Kth Largest Element in an Array.js -- 215 Kth Largest Element in an Array.py - 217 Contain Duplicate.js - 219 Contains Duplicate II.js - 22 Generate Parentheses.js - 220 Contains Duplicate III.js - 222. Count Complete Tree Nodes.js - 223 Rectangle Area.js +- 224 Basic Calculator.js - 225 Implement Stack Using Queues.js - 226 Invert Binary Tree.js - 228 Summary Ranges.js - 229 Majority Element II.js +- 23 Merge k Sorted Lists.js - 231 Power of Two.js - 232 Implement Queue using Stacks.js - 233 Number of Digit One.js @@ -96,27 +97,32 @@ - 235 Lowest Common Ancestor Of a Binary Search Tree.js - 236 Lowest Common Ancestor of a Binary Tree.js - 237 Delete Node in a Linked List.js +- 239 Sliding Window Maximum.js - 24 Swap nodes in Pairs.js - 240 Search a 2D Matrix II.js - 241 Different Ways to Add Parentheses.js - 242 Valid Anagram.js - 249 Group Shifted Strings.js +- 25 Reverse Nodes in k-Group.js - 257 Binary Tree Paths.js - 26 Remove Duplicates from Sorted Array.js - 263 Ugly Number.js - 264 Ugly Number II.js - 268 Missing Number.js +- 269 Alien Dictionary.js - 27 Remove Element.js - 279. Perfect Squares.js - 28 Implement strStr().js - 286 Walls and Gates.js - 289. Game of Life.js - 295 Find Median From Data Stream.js +- 296 Best Meeting Point.js - 297 Serialize and Deserialize Binary Tree My Submissions Question.js - 3 Longest Substring Without Repeating Characters.js - 300 Longest Increasing Subsequence.js - 31 Next Permutation.js - 314 Binary Tree Vertical Order Traversal.js +- 317 Shortest Distance From All Buildings.js - 318 Maximum Product of Word Lengths My Submissions Question.js - 322 Coin Change.js - 33 Search in Rotated Sorted Array.js @@ -126,6 +132,7 @@ - 35 Search Insert Position.js - 36 Valid Sudoku.js - 37 Sudoku Solver.js +- 371 Sum of Two Integers.js - 38 Count and Say.js - 39 Combination Sum.js - 4. Median of Two Sorted Arrays.js @@ -179,10 +186,13 @@ - Data Structure Min Heap.js - Disambiguos Actors.js - Javascript Closure Questions.js -- Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js -- README.md +Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.- js +- Parse HTML.js +- Parse Log Top k Longest Running Job.js +- Ransom Note From Magazine.js - Rate Limiter.js - Reverse Integer.js - String Encoding and Decoding.js +- Top k Longest Running Job.js - find kth element in two arrays.js - flatten nested array.js \ No newline at end of file diff --git a/memo.txt b/memo.txt deleted file mode 100644 index 4fc3db6..0000000 --- a/memo.txt +++ /dev/null @@ -1,2 +0,0 @@ -Q: Find Kth smallest/largest in an on sort order -A: Use quick select! O(n) \ No newline at end of file From 9148989ce674a74e5f0139116c2bad5e1fb2173c Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Thu, 14 Jul 2016 22:44:30 -0700 Subject: [PATCH 13/47] add more solutions --- 123 Best Time to Buy and Sell Stock III.js | 41 ++++++ 126 Word Ladder II.js | 30 ++++ 127 Word Ladder.js | 89 +++++++----- 133 Clone Graph.js | 23 +++ 138 Copy List With Random Pointer.js | 46 ++++++ 146 LRU Cache.js | 19 +-- 148 Sort List.js | 11 +- 186 Reverse Words in a String II.js | 37 +++++ 188 Best Time to Buy and Sell Stock IV.js | 57 ++++++++ 198 House Robber.js | 33 ++++- 199 Binary Tree Right Side View.js | 65 +++++---- 2 Add Two Numbers.js | 1 + 200 Number of Islands.js | 71 +++++----- 204 Count Primes.js | 4 + 206 Reverse Linked List.js | 9 ++ 213 House Robber II.js | 39 +++++ 224 Basic Calculator.js | 3 + 234 Palindrome Linked List.js | 11 ++ ...Lowest Common Ancestor of a Binary Tree.js | 19 +++ 238 Product of Array Except Self.js | 30 ++++ 256 Paint House.js | 34 +++++ 265 Paint House II.js | 62 ++++++++ 266 Palindrome Permutation.js | 42 ++++++ 289. Game of Life.js | 35 ++--- ...ize Binary Tree My Submissions Question.js | 36 ++++- 300 Longest Increasing Subsequence.js | 20 ++- 307 Range Sum Query - Mutable.js | 1 + 320 Generalized Abbreviation.js | 30 ++++ 337 House Robber III.js | 53 +++++++ 42 Trapping Rain Water.js | 50 +++++++ 46 Permutations.js | 38 ++++- 47 Permutations II.js | 53 +++++++ 48 Rotate Image.js | 35 +++-- 5 Longest Palindromic Substring.js | 3 + 57. Insert Interval.js | 17 +++ 74 Search a 2D Matrix.js | 63 ++++----- 78 Subsets.js | 40 ++++++ 8 String to Integer (atoi).js | 44 ++++-- 88 Merge Sorted Array.js | 4 +- 89 Gray Code.js | 50 +++++++ 91 Decode Ways.js | 38 +++++ Bean Probability.js | 2 + Conjuct Names With Limit.js | 41 ++++++ ...inary Search Tree To Doubly Linked List.js | 133 ++++++++++++++++++ Custom Tree Problem.js | 119 ++++++++++++++++ Data Structure Max Heap.js | 8 +- Log Hits.js | 106 ++++++++++++++ Merge Two Lists Into Sorted List.js | 82 +++++++++++ Parse HTML.js | 20 +-- Parse String Into Array.js | 79 +++++++++++ README.md | 28 +++- Snake And Ladder.js | 67 +++++++++ ZigZag Conversion.js | 45 ++++++ 53 files changed, 1891 insertions(+), 225 deletions(-) create mode 100644 123 Best Time to Buy and Sell Stock III.js create mode 100644 126 Word Ladder II.js create mode 100644 138 Copy List With Random Pointer.js create mode 100644 186 Reverse Words in a String II.js create mode 100644 188 Best Time to Buy and Sell Stock IV.js create mode 100644 213 House Robber II.js create mode 100644 238 Product of Array Except Self.js create mode 100644 256 Paint House.js create mode 100644 265 Paint House II.js create mode 100644 266 Palindrome Permutation.js create mode 100644 307 Range Sum Query - Mutable.js create mode 100644 320 Generalized Abbreviation.js create mode 100644 337 House Robber III.js create mode 100644 42 Trapping Rain Water.js create mode 100644 47 Permutations II.js create mode 100644 78 Subsets.js create mode 100644 89 Gray Code.js create mode 100644 Bean Probability.js create mode 100644 Conjuct Names With Limit.js create mode 100644 Convert Binary Search Tree To Doubly Linked List.js create mode 100644 Custom Tree Problem.js create mode 100644 Log Hits.js create mode 100644 Merge Two Lists Into Sorted List.js create mode 100644 Parse String Into Array.js create mode 100644 Snake And Ladder.js create mode 100644 ZigZag Conversion.js diff --git a/123 Best Time to Buy and Sell Stock III.js b/123 Best Time to Buy and Sell Stock III.js new file mode 100644 index 0000000..d073487 --- /dev/null +++ b/123 Best Time to Buy and Sell Stock III.js @@ -0,0 +1,41 @@ +// 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 at most two transactions. + +// Note: +// You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). + +// http://www.cnblogs.com/springfor/p/3877068.html + +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function(prices) { + // Calculate MaxProfit from 0 to x and MaxProfit from x + 1 to len - 1; + var profitFromZeroToX = []; + var profitFromXToEnd = []; + var min = prices[0]; + + // get max profit from 0 to x + for(var x = 1; x < prices.length; x++) { + var price = prices[x]; + min = Math.min(price, min); + profitFromZeroToX[x] = Math.max(profitFromZeroToX[x - 1] || 0, price - min); + } + // get max profit from i + 1 to end + var max = prices[prices.length - 1]; + for(x = prices.length - 2; x >= 0; x--) { + price = prices[x]; + max = Math.max(price, max); + profitFromXToEnd[x] = Math.max(profitFromXToEnd[x + 1] || 0, max - price); + } + + var maxProfit = 0; + for(x = 0; x < prices.length; x++) { + var maxProfitSeperateAtX = (profitFromZeroToX[x] || 0) + (profitFromXToEnd[x] || 0); + maxProfit = Math.max(maxProfitSeperateAtX, maxProfit); + } + + return maxProfit; +}; diff --git a/126 Word Ladder II.js b/126 Word Ladder II.js new file mode 100644 index 0000000..1852354 --- /dev/null +++ b/126 Word Ladder II.js @@ -0,0 +1,30 @@ +// Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: + +// Only one letter can be changed at a time +// Each intermediate word must exist in the word list +// For example, + +// Given: +// beginWord = "hit" +// endWord = "cog" +// wordList = ["hot","dot","dog","lot","log"] +// Return +// [ +// ["hit","hot","dot","dog","cog"], +// ["hit","hot","lot","log","cog"] +// ] +// Note: +// All words have the same length. +// All words contain only lowercase alphabetic characters. + +/** + * @param {string} beginWord + * @param {string} endWord + * @param {Set} wordList + * Note: wordList is a Set object, see: + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set + * @return {string[][]} + */ +var findLadders = function(beginWord, endWord, wordList) { + +}; \ No newline at end of file diff --git a/127 Word Ladder.js b/127 Word Ladder.js index ae8bd3a..7d7f8f7 100644 --- a/127 Word Ladder.js +++ b/127 Word Ladder.js @@ -1,57 +1,68 @@ +// Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: + +// Only one letter can be changed at a time +// Each intermediate word must exist in the word list +// For example, + +// Given: +// beginWord = "hit" +// endWord = "cog" +// wordList = ["hot","dot","dog","lot","log"] +// As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", +// return its length 5. + +// Note: +// Return 0 if there is no such transformation sequence. +// All words have the same length. +// All words contain only lowercase alphabetic characters. +// Amazon LinkedIn Snapchat Facebook Yelp + + // Leetcode 127 // Language: Javascript // Problem: https://leetcode.com/problems/word-ladder/ // Author: Chihung Yu + /** * @param {string} beginWord * @param {string} endWord - * @param {set} wordDict + * @param {Set} wordList + * Note: wordList is a Set object, see: + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set * @return {number} */ - -String.prototype.replaceAt = function(i, c){ - return this.substring(0,i) + c + this.substring(i+1); -}; - -var ladderLength = function(beginWord, endWord, wordDict) { - if(beginWord === null || endWord === null || beginWord.length !== endWord.length || beginWord.length === 0 || endWord.length === 0){ - return 0; - } - - var queue = []; - queue.push(beginWord); +var ladderLength = function(beginWord, endWord, wordList) { var visited = new Set(); - visited.add(beginWord); - + var queue = []; var level = 1; - var curLvlCnt = 1; - var nextLvlCnt = 0; + var letters = 'abcdefghijklmnopqrstuvwxyz'; + queue.push(beginWord); + visited.add(beginWord); - while(queue.length !== 0){ - var cur = queue.shift(); - curLvlCnt--; + while(queue.length > 0) { - for(var i = 0; i < cur.length; i++){ - for(var j = 0; j < 26; j++){ - var char = String.fromCharCode('a'.charCodeAt(0) + j); - var word = cur.replaceAt(i,char); - - if(word === endWord){ - return level + 1; - } - if(wordDict.has(word) && !visited.has(word)){ - nextLvlCnt++; - queue.push(word); - visited.add(word); + var len = queue.length; + + for(var i = 0; i < len; i++) { + var word = queue.shift(); + + for(var j = 0; j < word.length; j++) { + for(var k = 0; k < letters.length; k++) { + var newWord = word.substring(0, j) + letters[k] + word.substring(j + 1); + + if(newWord === endWord) { + return level + 1; + } + if(wordList.has(newWord) && !visited.has(newWord)) { + queue.push(newWord); + visited.add(newWord); + } } } } - if(curLvlCnt === 0){ - curLvlCnt = nextLvlCnt; - nextLvlCnt = 0; - level++; - } + + level++; } + return 0; -}; - +}; \ No newline at end of file diff --git a/133 Clone Graph.js b/133 Clone Graph.js index d17f7f9..c4c3e03 100644 --- a/133 Clone Graph.js +++ b/133 Clone Graph.js @@ -1,3 +1,26 @@ +// Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. + + +// OJ's undirected graph serialization: +// 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 +// / \ +// \_/ + /** * Definition for undirected graph. * function UndirectedGraphNode(label) { diff --git a/138 Copy List With Random Pointer.js b/138 Copy List With Random Pointer.js new file mode 100644 index 0000000..61a90cb --- /dev/null +++ b/138 Copy List With Random Pointer.js @@ -0,0 +1,46 @@ +// A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. + +// Return a deep copy of the list. + +// Hide Company Tags Amazon Microsoft Bloomberg Uber +// Show Tags +// Show Similar Problems + + +/** + * Definition for singly-linked list with a random pointer. + * function RandomListNode(label) { + * this.label = label; + * this.next = this.random = null; + * } + */ + +/** + * @param {RandomListNode} head + * @return {RandomListNode} + */ +var copyRandomList = function(head) { + var hashMap = {}; + var newHead = new RandomListNode(0); + newHead.next = copyList(head); + + function copyList(node) { + if(node === null) { + return node; + } + + if(hashMap[node.label]) { + return hashMap[node.label]; + } + + var newNode = new RandomListNode(node.label); + hashMap[node.label] = newNode; + + newNode.next = copyList(node.next); + newNode.random = copyList(node.random); + + return newNode; + } + + return newHead.next; +}; \ No newline at end of file diff --git a/146 LRU Cache.js b/146 LRU Cache.js index 5a9a2f8..10ae3d6 100644 --- a/146 LRU Cache.js +++ b/146 LRU Cache.js @@ -1,7 +1,3 @@ -// Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. - -// get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. -// set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. class Node { constructor(key, val) { this.key = key; @@ -18,7 +14,7 @@ var LRUCache = function(capacity) { this.map = new Map(); this.head = null; this.tail = null; - this.size = capacity; + this.capacity = capacity; this.curSize = 0; }; @@ -27,12 +23,11 @@ var LRUCache = function(capacity) { * @returns {number} */ LRUCache.prototype.get = function(key) { - if (!this.map.get(key)) { + let node = this.map.get(key); + if (!node) { return -1; } - let node = this.map.get(key); - if (node === this.head) { return node.val; } @@ -70,7 +65,7 @@ LRUCache.prototype.set = function(key, value) { } this.head = newNode; - this.curSize++; + // this.curSize++; // update if (this.map.get(key)) { @@ -84,11 +79,9 @@ LRUCache.prototype.set = function(key, value) { oldNode.prev.next = oldNode.next; oldNode.next.prev = oldNode.prev; } - - this.curSize--; - } else { - if (this.curSize > this.size) { + this.curSize++ + if (this.curSize > this.capacity) { //delete tail this.map.delete(this.tail.key); this.tail = this.tail.prev; diff --git a/148 Sort List.js b/148 Sort List.js index 6aa1d40..86e8a69 100644 --- a/148 Sort List.js +++ b/148 Sort List.js @@ -1,3 +1,5 @@ +// Sort a linked list in O(n log n) time using constant space complexity. + /** * Definition for singly-linked list. * function ListNode(val) { @@ -28,13 +30,18 @@ var sortList = function(head) { return newHead; function sort(len) { + // there will be no case of len = 0 which is caused by 1/2 if(len === 1) { var temp = head; - head = head.next; + // !!! important: moving pointer to the next + // e.g. 1->2->3->4 + // head-> 1 + // now head will be point to 2 + head = head.next; temp.next = null; return temp; } - + // there will be no case of len = 0 which is caused by 1/2 var leftHead = sort(parseInt(len/2)); var rightHead = sort(len - parseInt(len/2)); var newHead = merge(leftHead, rightHead); diff --git a/186 Reverse Words in a String II.js b/186 Reverse Words in a String II.js new file mode 100644 index 0000000..2c0a405 --- /dev/null +++ b/186 Reverse Words in a String II.js @@ -0,0 +1,37 @@ +// Given an input string, reverse the string word by word. A word is defined as a sequence of non-space characters. + +// The input string does not contain leading or trailing spaces and the words are always separated by a single space. + +// For example, +// Given s = "the sky is blue", +// return "blue is sky the". + +// Could you do it in-place without allocating extra space? + +/** + * @param {character[]} str + * @return {void} Do not return anything, modify the string in-place instead. + */ +var reverseWords = function(str) { + var arr = str; + + reverse(arr, 0, arr.length - 1); + var last = 0; + + for(var i = 0; i <= arr.length; i++) { + if(arr[i] === ' ' || i === arr.length) { + reverse(arr, last, i - 1); + last = i + 1; + } + } + + function reverse(arr, beg, end) { + while(beg < end) { + var tmp = str[beg]; + str[beg] = str[end]; + str[end] = tmp; + beg++; + end--; + } + } +}; \ No newline at end of file diff --git a/188 Best Time to Buy and Sell Stock IV.js b/188 Best Time to Buy and Sell Stock IV.js new file mode 100644 index 0000000..5339baa --- /dev/null +++ b/188 Best Time to Buy and Sell Stock IV.js @@ -0,0 +1,57 @@ +// memory limit exceeded +// Time O(n*k) +// Space (n*k) +// ref: http://blog.csdn.net/fightforyourdream/article/details/14503469 + +/** + * @param {number} k + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function(k, prices) { + var len = prices.length; + + if(len === 0) { + return 0; + } + var globalBest = initMatrix(len, k + 1); + var localBest = initMatrix(len, k + 1); + + // matrix[row][col] + // row is ith day + // col is jth transaction + // localBest[i][j] is the max profit across i day, with j transaction where there is transaction happening on i day + // globalBest[i][j] is the max profit across i day, with j transaction + + for(var i = 1; i < len; i++) { + var diff = prices[i] - prices[i - 1]; + + for(var j = 1; j <= k; j++) { + + // globalBest[i - 1][j - 1] + Math.max(diff, 0) + // -> current global best before ith day and jth transaction, Math.max(diff, 0) means we can take this transaction into account or discard it. + // localBest[i - 1][j] + diff + // -> since localBest[i][j] means the last transaction has to happen on this day, regardless transaction lost money or not, we need to add it. + // In addition, localBest[i - 1][j] + diff -> does not add transaction count e.g. + // [buy, sell and buy, sell] is the same as [buy, nothing, sell] since it's all continuous actions + localBest[i][j] = Math.max(globalBest[i - 1][j - 1] + Math.max(diff, 0), localBest[i - 1][j] + diff); + globalBest[i][j] = Math.max(globalBest[i - 1][j], localBest[i][j]); + } + } + + return globalBest[len - 1][k]; +}; + + +function initMatrix(days, transactions) { + var matrix = []; + + for(var i = 0; i < days; i++) { + matrix.push([]); + for(var j = 0; j < transactions; j++) { + matrix[i][j] = 0; + } + } + + return matrix; +} \ No newline at end of file diff --git a/198 House Robber.js b/198 House Robber.js index 6d2be47..bc8bc12 100644 --- a/198 House Robber.js +++ b/198 House Robber.js @@ -1,3 +1,16 @@ +// You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. + +// Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + +// Credits: +// Special thanks to @ifanchu for adding this problem and creating all test cases. Also thanks to @ts for adding additional test cases. + +// Hide Company Tags LinkedIn Airbnb +// Show Tags +// Show Similar Problems + + + // Leetcode #198 // Language: Javascript // Problem: https://leetcode.com/problems/house-robber/ @@ -23,4 +36,22 @@ var rob = function(nums) { } return Math.max(even,odd); -}; \ No newline at end of file +}; + + +// var rob = function(nums) { +// var dp = []; + +// if(!nums || nums.length === 0) { +// return 0; +// } +// // dp[i] is the max amount can rob on ith house + +// for(var i = 0; i < nums.length; i++){ +// var num = nums[i]; +// dp[i] = Math.max((dp[i-2] || 0) + num, (dp[i-1] || 0)); +// } + +// return dp[nums.length - 1]; +// }; + diff --git a/199 Binary Tree Right Side View.js b/199 Binary Tree Right Side View.js index 6ecf0c8..4ca72c2 100644 --- a/199 Binary Tree Right Side View.js +++ b/199 Binary Tree Right Side View.js @@ -1,7 +1,13 @@ -// Leetcode #199 -// Language: Javascript -// Problem: https://leetcode.com/problems/binary-tree-right-side-view/ -// Author: Chihung Yu +// For example: +// Given the following binary tree, +// 1 <--- +// / \ +// 2 3 <--- +// \ \ +// 5 4 <--- +// You should return [1, 3, 4]. + + /** * Definition for a binary tree node. * function TreeNode(val) { @@ -14,37 +20,34 @@ * @return {number[]} */ var rightSideView = function(root) { - var answer = []; - - if(root === null){ - return answer; + var result = []; + + if(root === null) { + return result; } - - var queue = []; + + queue = []; queue.push(root); - var curLvlCnt = queue.length; - var nextLvlCnt = 0; - while(queue.length !== 0){ - var node = queue.shift(); - curLvlCnt--; + while(queue.length > 0) { + var len = queue.length; - if(node.left){ - queue.push(node.left); - nextLvlCnt++; - } - if(node.right){ - queue.push(node.right); - nextLvlCnt++; + for(var i = 0; i < len; i++) { + var node = queue.shift(); + + if(node.left) { + queue.push(node.left); + } + + if(node.right) { + queue.push(node.right); + } + + if(i === len - 1) { + result.push(node.val); + } } - - if(curLvlCnt <= 0){ - answer.push(node.val); - curLvlCnt = nextLvlCnt; - nextLvlCnt = 0; - } - } - return answer; -} \ No newline at end of file + return result; +}; \ No newline at end of file diff --git a/2 Add Two Numbers.js b/2 Add Two Numbers.js index 279acbc..b13270e 100644 --- a/2 Add Two Numbers.js +++ b/2 Add Two Numbers.js @@ -3,6 +3,7 @@ // Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) // Output: 7 -> 0 -> 8 +// Amazon Microsoft Bloomberg Airbnb Adobe /** * Definition for singly-linked list. diff --git a/200 Number of Islands.js b/200 Number of Islands.js index a755398..dd0d2aa 100644 --- a/200 Number of Islands.js +++ b/200 Number of Islands.js @@ -1,51 +1,54 @@ +// 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: + +// 11110 +// 11010 +// 11000 +// 00000 +// Answer: 1 + +// Example 2: + +// 11000 +// 11000 +// 00100 +// 00011 +// Answer: 3 /** * @param {character[][]} grid * @return {number} */ var numIslands = function(grid) { - var count = 0; + var visited = []; + var row = grid.length; - var rows = grid.length; - - if(rows === 0){ - return count; + if(!grid || row === 0) { + return 0; } - var cols = grid[0].length; - - if(cols === 0) { - return count; - } - - for(i = 0; i < rows; i++) { - for(var j = 0; j < cols; j++) { - if(grid[i][j] === "1") { + var col = grid[0].length; + var count = 0; + for(var i = 0; i < row; i++) { + for(var j = 0; j < col; j++) { + if(grid[i][j] === '1') { count++; - walk(grid, i, j, rows, cols); + traverse(i, j, grid, row, col); } } } + return count; }; -var walk = function(grid, x, y, rows, cols) { - if(grid[x][y] === "1") { - grid[x][y] = "0"; - } - - if((x + 1) < rows && grid[x+1][y] === "1") { - walk(grid, x + 1, y, rows, cols); - } - - if((x - 1) >= 0 && grid[x-1][y] === "1") { - walk(grid, x - 1, y, rows, cols); - } - - if((y + 1) < cols && grid[x][y+1] === "1") { - walk(grid, x, y + 1, rows, cols); - } - - if((y - 1) >= 0 && grid[x][y-1] === "1") { - walk(grid, x, y - 1, rows, cols); +var traverse = function(i, j, grid, row, col) { + if((0 <= i && i < row) && (0 <= j && j < col) && grid[i][j] === '1') { + grid[i][j] = '2'; + + + traverse(i + 1, j, grid, row, col); + traverse(i, j + 1, grid, row, col); + traverse(i - 1, j, grid, row, col); + traverse(i, j - 1, grid, row, col); } } \ No newline at end of file diff --git a/204 Count Primes.js b/204 Count Primes.js index 6fcb9c7..21c4d2d 100644 --- a/204 Count Primes.js +++ b/204 Count Primes.js @@ -1,3 +1,7 @@ +// Description: + +// Count the number of prime numbers less than a non-negative number, n. + // Leetcode #204 // Language: Javascript // Problem: https://leetcode.com/problems/count-primes/ diff --git a/206 Reverse Linked List.js b/206 Reverse Linked List.js index f3d4f14..5e0c0b2 100644 --- a/206 Reverse Linked List.js +++ b/206 Reverse Linked List.js @@ -2,6 +2,15 @@ // Language: Javascript // Problem: https://leetcode.com/problems/reverse-linked-list/ // Author: Chihung Yu + + +// Reverse a singly linked list. + +// Uber Facebook Twitter Zenefits Amazon Microsoft Snapchat Apple Yahoo Bloomberg Yelp Adobe +// Show Tags +// Show Similar Problems + + /** * Definition for singly-linked list. * function ListNode(val) { diff --git a/213 House Robber II.js b/213 House Robber II.js new file mode 100644 index 0000000..18e1038 --- /dev/null +++ b/213 House Robber II.js @@ -0,0 +1,39 @@ +// Note: This is an extension of House Robber. + +// After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street. + +// Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. +// Microsoft + + +/** + * @param {number[]} nums + * @return {number} + */ +var rob = function(nums) { + // same as house robber I, but we cannot rob first and last house at the same time. + + function robHouses(nums) { + var odd = 0; + var even = 0; + + for(var i = 0; i < nums.length; i++) { + var num = nums[i]; + if(i % 2 === 0) { + even = Math.max(even + num, odd); + } else { + odd = Math.max(odd + num, even); + } + } + + return Math.max(even, odd); + } + + if(nums.length <= 1) { + return robHouses(nums); + } + + var robHousesExceptLast = robHouses(nums.slice(0, -1)); + var robHousesExceptFirst = robHouses(nums.slice(1)); + return Math.max(robHousesExceptLast, robHousesExceptFirst); +}; \ No newline at end of file diff --git a/224 Basic Calculator.js b/224 Basic Calculator.js index 74ed6d2..b7cfcd4 100644 --- a/224 Basic Calculator.js +++ b/224 Basic Calculator.js @@ -1,3 +1,6 @@ +// http://yucoding.blogspot.com/2015/10/leetcode-question-basic-calculator.html +// http://blog.welkinlan.com/2015/09/06/basic-calculator-i-ii-leetcode-java/ + /** Implement a basic calculator to evaluate a simple expression string. diff --git a/234 Palindrome Linked List.js b/234 Palindrome Linked List.js index 00b2f1c..d20ef93 100644 --- a/234 Palindrome Linked List.js +++ b/234 Palindrome Linked List.js @@ -26,6 +26,17 @@ var isPalindrome = function(head) { fast = fast.next.next; } + // if fast.next === null it's odd + // else fast.next !== null it's even + // but wether it's odd or even, we want to reverse slow's next + // 1 2 3 3 2 1 + // slow is pointing at 3 (index 2) and we want to reverse 3 2 1 + // to 1 2 3 1 2 3 + // + // 1 2 3 4 3 2 1 + // slow is pointing at 4 (index 3) and we want to reverse 3 2 1 + // to 1 2 3 4 1 2 3 + var secondHead = slow.next; slow.next = null; diff --git a/236 Lowest Common Ancestor of a Binary Tree.js b/236 Lowest Common Ancestor of a Binary Tree.js index be7c6de..e6d3975 100644 --- a/236 Lowest Common Ancestor of a Binary Tree.js +++ b/236 Lowest Common Ancestor of a Binary Tree.js @@ -1,3 +1,22 @@ +// 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 v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” + +// _______3______ +// / \ +// ___5__ ___1__ +// / \ / \ +// 6 _2 0 8 +// / \ +// 7 4 +// For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition. + +// Hide Company Tags Amazon LinkedIn Apple Facebook Microsoft +// Show Tags +// Show Similar Problems + + + /** * Definition for a binary tree node. * function TreeNode(val) { diff --git a/238 Product of Array Except Self.js b/238 Product of Array Except Self.js new file mode 100644 index 0000000..ade4c27 --- /dev/null +++ b/238 Product of Array Except Self.js @@ -0,0 +1,30 @@ +// Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. + +// Solve it without division and in O(n). + +// For example, given [1,2,3,4], return [24,12,8,6]. + +// Follow up: +// Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) + +/** + * @param {number[]} nums + * @return {number[]} + */ + +// http://fisherlei.blogspot.com/2015/10/leetcode-product-of-array-except-self.html +var productExceptSelf = function(nums) { + var len = nums.length; + var output = Array(len).fill(1); + var left = 1; + var right = 1; + + for(var i = 0; i < len - 1; i++) { + left *= nums[i]; + right *= nums[len - i - 1]; + output[i + 1] *= left; + output[len - i - 2] *= right; + } + + return output; +}; \ No newline at end of file diff --git a/256 Paint House.js b/256 Paint House.js new file mode 100644 index 0000000..08e1140 --- /dev/null +++ b/256 Paint House.js @@ -0,0 +1,34 @@ +// There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color. + +// The cost of painting each house with a certain color is represented by a n x 3 cost matrix. For example, costs[0][0] is the cost of painting house 0 with color red; costs[1][2] is the cost of painting house 1 with color green, and so on... Find the minimum cost to paint all houses. + +// Note: +// All costs are positive integers. + +// Hide Company Tags LinkedIn +// Show Tags +// Show Similar Problems + +// reference: https://segmentfault.com/a/1190000003903965 +/** + * @param {number[][]} costs + * @return {number} + */ + + // space O(1) time O(n) +var minCost = function(costs) { + if(!costs || costs.length === 0) { + return 0; + } + + for(var i = 1; i < costs.length; i++) { + // The colors that can be painted depends on the color we used for the previous houses, + // pick the min cost from previous colors + costs[i][0] += Math.min(costs[i-1][1], costs[i-1][2]); + costs[i][1] += Math.min(costs[i-1][0], costs[i-1][2]); + costs[i][2] += Math.min(costs[i-1][0], costs[i-1][1]); + } + + i--; + return Math.min.apply(null, costs[i]); +}; \ No newline at end of file diff --git a/265 Paint House II.js b/265 Paint House II.js new file mode 100644 index 0000000..4583411 --- /dev/null +++ b/265 Paint House II.js @@ -0,0 +1,62 @@ +// There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color. + +// The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses. + +// Note: +// All costs are positive integers. + +// Follow up: +// Could you solve it in O(nk) runtime? + +// Hide Company Tags Facebook +// Show Tags +// Show Similar Problems + +/** + * @param {number[][]} costs + * @return {number} + */ + +// reference https://segmentfault.com/a/1190000003903965 +var minCostII = function(costs) { + if(costs === null || costs.length === 0) { + return 0; + } + + var min1Idx = -1; + var min1 = 0; + var min2 = 0; + + for(var i = 0; i < costs.length; i++) { + // min1 and min2 for recording the smallest and the second smallest + // The min cost of using the current paint k: + // is equal to: the min cost of previous paint j (k !== j) + // In order to find the min cost which k !== j, we can use 2 variable min1 and min2 + + var oldMin1Idx = min1Idx; + var oldMin1 = min1; + var oldMin2 = min2; + + min1Idx = -1; + min1 = Infinity; + min2 = Infinity; + + for(var j = 0; j < costs[i].length; j++) { + if(j === oldMin1Idx) { + costs[i][j] += oldMin2; + } else { + costs[i][j] += oldMin1; + } + + if(costs[i][j] < min1) { + min2 = min1; + min1 = costs[i][j]; + min1Idx = j; + } else if(costs[i][j] < min2) { + min2 = costs[i][j]; + } + } + } + + return min1; +}; \ No newline at end of file diff --git a/266 Palindrome Permutation.js b/266 Palindrome Permutation.js new file mode 100644 index 0000000..1a41d7c --- /dev/null +++ b/266 Palindrome Permutation.js @@ -0,0 +1,42 @@ +// Given a string, determine if a permutation of the string could form a palindrome. + +// For example, +// "code" -> False, "aab" -> True, "carerac" -> True. + + +/** + * @param {string} s + * @return {boolean} + */ +var canPermutePalindrome = function(s) { + var countMap = {}; + + for(var i = 0; i < s.length; i++) { + var c = s[i]; + + countMap[c] = countMap[c] || 0; + countMap[c]++; + } + var oddCount = 0; + + for(i in countMap) { + if(countMap[i]%2 === 1) { + oddCount++; + } + } + + return oddCount < 2; +}; + +// Solution (2) that assume it's ascii 256 chars only + +var canPermutePalindrome = function(s) { + // assume that s is only contact 256 english letters + var letters = Array(256).fill(0); + var odd = 0; + for(var i = 0; i < s.length; i++) { + var letterIndex = s[i].charCodeAt(0); + odd += (++letters[letterIndex] & 1) === 1 ? 1 : -1; + } + return odd < 2; +}; \ No newline at end of file diff --git a/289. Game of Life.js b/289. Game of Life.js index 4f9e89a..e8b2fd9 100644 --- a/289. Game of Life.js +++ b/289. Game of Life.js @@ -12,39 +12,26 @@ var gameOfLife = function(board) { var rows = board.length; var cols = board[0].length; + var dirX = [-1, 0, 1, 1, 1, 0,-1,-1]; + var dirY = [-1,-1,-1, 0, 1, 1, 1, 0]; for(var i = 0; i < rows; i++) { for(var j = 0; j < cols; j++) { var cur = board[i][j]; var count = 0; - - if(i - 1 >= 0 && j -1 >= 0 && (board[i - 1][j - 1])%2 === 1) { - count++; - } - if(i - 1 >= 0 && (board[i - 1][j])%2 === 1) { - count++; - } - if(i - 1 >= 0 && j + 1 < cols && (board[i - 1][j + 1])%2 === 1) { - count++; - } - if(j - 1 >= 0 && (board[i][j - 1])%2 === 1) { - count++; - } - if(j + 1 < cols && (board[i][j + 1])%2 === 1) { - count++; - } - if(i + 1 < rows && j - 1 >= 0 && (board[i + 1][j - 1])%2 === 1) { - count++; - } - if(i + 1 < rows && (board[i + 1][j])%2 === 1) { - count++; - } - if(i + 1 < rows && j + 1 < cols && (board[i + 1][j + 1])%2 === 1) { - count++; + + for(var k = 0; k < 8; k++) { + var x = i + dirX[k]; + var y = j + dirY[k]; + if(x >= 0 && x <= rows && y >= 0 && y <= cols && board[x][y]%2 === 1) { + count++; + } } if(board[i][j] === 1) { if(count > 3 || count < 2) { + + board[i][j] = 3; } } else { diff --git a/297 Serialize and Deserialize Binary Tree My Submissions Question.js b/297 Serialize and Deserialize Binary Tree My Submissions Question.js index d9d3da0..ce6dad5 100644 --- a/297 Serialize and Deserialize Binary Tree My Submissions Question.js +++ b/297 Serialize and Deserialize Binary Tree My Submissions Question.js @@ -1,4 +1,26 @@ -/** +// Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. + +// Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure. + +// For example, you may serialize the following tree + +// 1 +// / \ +// 2 3 +// / \ +// 4 5 +// as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself. +// Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless. + +// Credits: +// Special thanks to @Louis1992 for adding this problem and creating all test cases. + +// Hide Company Tags LinkedIn Google Uber Facebook Amazon Microsoft Yahoo Bloomberg +// Show Tags +// Show Similar Problems + + +/* * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; @@ -13,6 +35,9 @@ * @return {string} */ // http://fisherlei.blogspot.com/2013/03/interview-serialize-and-de-serialize.html + +// only pre order travesal can provide information about the root node +// the other technique that we can use is to use level order traversal var serialize = function(root) { var result = []; serializer(root, result); @@ -48,18 +73,15 @@ var deserialize = function(data) { var node = new TreeNode(parseInt(data[index])); index++; - node.left = deserializer(data, index); + node.left = deserializer(data); index++; - - node.right = deserializer(data, index); + node.right = deserializer(data); return node; } return deserializer(data); }; - - /** * Your functions will be called as such: * deserialize(serialize(root)); @@ -180,4 +202,4 @@ var deserialize = function(data) { /** * Your functions will be called as such: * deserialize(serialize(root)); - */ \ No newline at end of file + \ No newline at end of file diff --git a/300 Longest Increasing Subsequence.js b/300 Longest Increasing Subsequence.js index f09154e..f222615 100644 --- a/300 Longest Increasing Subsequence.js +++ b/300 Longest Increasing Subsequence.js @@ -1,3 +1,19 @@ +// Given an unsorted array of integers, find the length of longest increasing subsequence. + +// For example, +// Given [10, 9, 2, 5, 3, 7, 101, 18], +// The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length. + +// Your algorithm should run in O(n2) complexity. + +// Follow up: Could you improve it to O(n log n) time complexity? + +// Credits: +// Special thanks to @pbrother for adding this problem and creating all test cases. + +// Hide Company Tags Microsoft +// Show Tags +// Show Similar Problems /** * @param {number[]} nums * @return {number} @@ -9,9 +25,9 @@ var lengthOfLIS = function(nums) { return 0; } - var dp = Array.from({length: size}, () => 1); + dp = Array(size).fill(1); - for(var i = 0; i < size; i++) { + for(var i = 1; i < size; i++) { for(var j = 0; j < i; j++) { if(nums[i] > nums[j]) { dp[i] = Math.max(dp[i], dp[j] + 1); diff --git a/307 Range Sum Query - Mutable.js b/307 Range Sum Query - Mutable.js new file mode 100644 index 0000000..2bfda14 --- /dev/null +++ b/307 Range Sum Query - Mutable.js @@ -0,0 +1 @@ +// http://bookshadow.com/weblog/2015/08/13/segment-tree-set-1-sum-of-given-range/ \ No newline at end of file diff --git a/320 Generalized Abbreviation.js b/320 Generalized Abbreviation.js new file mode 100644 index 0000000..ed6ff12 --- /dev/null +++ b/320 Generalized Abbreviation.js @@ -0,0 +1,30 @@ +// Write a function to generate the generalized abbreviations of a word. + +// Example: +// Given word = "word", return the following list (order does not matter): +// ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"] +// Hide Company Tags Google +// Hide Tags + +/** + * @param {string} word + * @return {string[]} + */ +var generateAbbreviations = function(word) { + var result = []; + dfs(result, word, 0, '', 0); + return result; +}; + +var dfs = function(result, word, pos, cur, count) { + if(pos === word.length) { + if(count > 0) { + cur += count; + } + result.push(cur); + return; + } + + dfs(result, word, pos + 1, cur, count + 1); + dfs(result, word, pos + 1, cur + (count > 0 ? count : '') + word[pos], 0); +} diff --git a/337 House Robber III.js b/337 House Robber III.js new file mode 100644 index 0000000..c467c26 --- /dev/null +++ b/337 House Robber III.js @@ -0,0 +1,53 @@ +// The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night. + +// Determine the maximum amount of money the thief can rob tonight without alerting the police. + +// Example 1: +// 3 +// / \ +// 2 3 +// \ \ +// 3 1 +// Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. +// Example 2: +// 3 +// / \ +// 4 5 +// / \ \ +// 1 3 1 +// Maximum amount of money the thief can rob = 4 + 5 = 9. + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var rob = function(root) { + var result = robViaDfs(root); + return Math.max.apply(null, result); +}; + + +// Array[0] max money when root is selected +// Array[1] max money when root is Not selected +function robViaDfs(root) { + if (!root) { + return [0, 0]; + } + + var left = robViaDfs(root.left), + right = robViaDfs(root.right), + includeRoot, + notIncludeRoot; + + includeRoot = left[1] + right[1] + root.val; // array[1] is value from before of not including root + notIncludeRoot = Math.max.apply(null, left) + Math.max.apply(null, right); + + return [includeRoot, notIncludeRoot]; +} diff --git a/42 Trapping Rain Water.js b/42 Trapping Rain Water.js new file mode 100644 index 0000000..f1922b2 --- /dev/null +++ b/42 Trapping Rain Water.js @@ -0,0 +1,50 @@ +// Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. + +// For example, +// Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. + + +// The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image! + + +// http://bangbingsyb.blogspot.com/2014/11/leetcode-trapping-rain-water.html + +/** + * @param {number[]} height + * @return {number} + */ +var trap = function(height) { + // scan left max + // scan right max + // e.g. heights: 0 3 2 1 5 1 + // left max: 0 0 3 3 3 5 + // right max: 5 5 5 5 1 0 + // what that means is? + // for index 1 -> height 3 + // 0 is its left max, 5 is its right max -> that gives zero volumn as it cannot hold water + // for index 2 -> height 2 + // 3 is its left max and 5 is its right max -> min(3,5) = 3 and height 2 is the bottom of the water bed, so that gives (3-2) -> 1 volumn of water + + var leftMax = []; + var rightMax= []; + var water = 0; + + // to get the left of i so we do i - 1 + for(var i = 1; i < height.length; i++) { + leftMax[i] = leftMax[i] || 0; + leftMax[i] = Math.max(leftMax[i - 1] || 0, height[i - 1]); + } + + for(i = height.length - 2; i >= 0; i--) { + rightMax[i] = rightMax[i] || 0; + rightMax[i] = Math.max(rightMax[i + 1] || 0, height[i + 1]); + + var minHeight = Math.min(leftMax[i], rightMax[i]); + var waterBottom = height[i]; + if(minHeight > waterBottom) { + water += (minHeight - waterBottom); + } + } + + return water; +}; \ No newline at end of file diff --git a/46 Permutations.js b/46 Permutations.js index 14f1e8c..467e1ee 100644 --- a/46 Permutations.js +++ b/46 Permutations.js @@ -1,4 +1,4 @@ -// Leetcode 309 +// Leetcode 46 // Language: Javascript // Problem: https://leetcode.com/problems/permutations/ // Author: Chihung Yu @@ -6,6 +6,34 @@ * @param {number[]} nums * @return {number[][]} */ + +var permute = function(nums) { + var result = []; + generatePermute(nums, [], result); + + return result; +}; + +var generatePermute = function(nums, currentResult, finalResult) { + if(nums.length === 0) { + finalResult.push(currentResult.slice()); + return; + } + + for(var i = 0; i < nums.length; i++) { + var num = nums[i]; + + currentResult.push(num); + var newNums = nums.slice(0, i).concat(nums.slice(i + 1)); + generatePermute(newNums, currentResult, finalResult); + currentResult.pop(); + } +} + +// can be optimized by using an array to keep track of visited elements in the array which ultimately cut down the time slicing array +// consider array is of size n -> n^2 vs n! + + var permute = function(nums) { var result = []; var visited = []; @@ -18,6 +46,7 @@ var permute = function(nums) { var generate = function(nums, index, visited, output, result) { if(nums.length === output.length) { result.push(output.slice()); + return; } for(var i = 0; i < nums.length; i++) { @@ -30,4 +59,9 @@ var generate = function(nums, index, visited, output, result) { } } -} \ No newline at end of file +} + + + + + diff --git a/47 Permutations II.js b/47 Permutations II.js new file mode 100644 index 0000000..3bb9f3b --- /dev/null +++ b/47 Permutations II.js @@ -0,0 +1,53 @@ +// Given a collection of numbers that might contain duplicates, return all possible unique permutations. + +// For example, +// [1,1,2] have the following unique permutations: +// [ +// [1,1,2], +// [1,2,1], +// [2,1,1] +// ] +// Hide Company Tags LinkedIn Microsoft +// Show Tags +// Hide Similar Problems (M) Next Permutation (M) Permutations (M) Palindrome Permutation II + + +/** + * @param {number[]} nums + * @return {number[][]} + */ +var permuteUnique = function(nums) { + nums.sort((a,b)=> a > b ? 1 : -1); + + var result = []; + var visited = Array(nums.length).fill(false); + generatePermute(nums, 0, [], visited, result); + + return result; +}; + + +var generatePermute = function(nums, step, currentResult, visited, finalResult) { + // Since we might have duplicate and skipped some nums, so the currentResult.length might not equal to nums.length even when we are already done traversing + // if(nums.length === currentResult.length) { + if(step === nums.length) { + finalResult.push(currentResult.slice()); + return; + } + + for(var i = 0; i < nums.length; i++) { + if(!visited[i]) { + // !!! important: nums[i] === nums[i-1] && !visited[i-1] + if(i > 0 && nums[i] === nums[i-1] && !visited[i-1]) { + continue; + } + + visited[i] = true; + var num = nums[i]; + currentResult.push(num); + generatePermute(nums, step + 1, currentResult, visited, finalResult); + currentResult.pop(); + visited[i] = false; + } + } +} \ No newline at end of file diff --git a/48 Rotate Image.js b/48 Rotate Image.js index 47fe88f..68e2819 100644 --- a/48 Rotate Image.js +++ b/48 Rotate Image.js @@ -1,29 +1,40 @@ +// You are given an n x n 2D matrix representing an image. + +// Rotate the image by 90 degrees (clockwise). + +// Follow up: +// Could you do this in-place? + /** * @param {number[][]} matrix * @return {void} Do not return anything, modify matrix in-place instead. */ var rotate = function(matrix) { - if(matrix === null || matrix.length === 0){ + var row = matrix.length; + + if(row === 0) { return; } - - var len = matrix.length; - for(var i = 0; i < len - 1; i++){ - for(var j = 0; j < len - i; j++){ - swap(matrix,i,j,len-1-j,len-1-i); + var col = matrix[0].length; + + // swap them in diagonal + for(var i = 0; i < row; i++) { + for(var j = 0; j < col - i; j++) { + swap(matrix, i, j, row - 1 - j, col - 1 - i); } } - for(i = 0; i < parseInt(len/2); i++){ - for(j = 0; j < len; j++){ - swap(matrix,i,j,len-1-i,j); + // swap in middle + for(i = 0; i < Math.floor(row/2); i++) { + for(j = 0; j < col; j++) { + swap(matrix, i, j, row - 1 - i, j); } } }; -var swap = function(matrix,x1,y1,x2,y2){ - var temp = matrix[x1][y1]; +function swap(matrix, x1, y1, x2, y2) { + var tmp = matrix[x1][y1]; matrix[x1][y1] = matrix[x2][y2]; - matrix[x2][y2] = temp; + matrix[x2][y2] = tmp; } \ No newline at end of file diff --git a/5 Longest Palindromic Substring.js b/5 Longest Palindromic Substring.js index 74b60c3..deb0ab9 100644 --- a/5 Longest Palindromic Substring.js +++ b/5 Longest Palindromic Substring.js @@ -1,4 +1,7 @@ // Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. +// Amazon Microsoft Bloomberg +// Show Tags +// Show Similar Problems /** * @param {string} s diff --git a/57. Insert Interval.js b/57. Insert Interval.js index 891b984..e5a68a7 100644 --- a/57. Insert Interval.js +++ b/57. Insert Interval.js @@ -1,3 +1,20 @@ +// Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). + +// You may assume that the intervals were initially sorted according to their start times. + +// Example 1: +// Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. + +// Example 2: +// Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. + +// This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. + +// Hide Company Tags LinkedIn Google Facebook +// Show Tags +// Show Similar Problems + + /** * Definition for an interval. * function Interval(start, end) { diff --git a/74 Search a 2D Matrix.js b/74 Search a 2D Matrix.js index 28b7549..83adad9 100644 --- a/74 Search a 2D Matrix.js +++ b/74 Search a 2D Matrix.js @@ -1,3 +1,23 @@ +// 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. +// For 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. + + /** * @param {number[][]} matrix * @param {number} target @@ -5,48 +25,23 @@ */ var searchMatrix = function(matrix, target) { - if(matrix === null || matrix.length === 0 || matrix[0].length === 0){ - return false; - } - - if(target < matrix[0][0]){ // Key base condition + if(matrix === null || matrix.length === 0 || matrix[0].length === 0) { return false; } - var rows = matrix.length - 1; - var cols = matrix[0].length - 1; + var rows = matrix.length; + var cols = matrix[0].length; - if(target > matrix[rows][cols]){ // Key base condition - return false; - } + var y = cols - 1; - var start = 0; - var end = rows; - while(start <= end){ - var mid = start + parseInt((end - start)/2); - if(matrix[mid][0] === target){ - return true; - } else if(matrix[mid][0] < target){ - start = mid + 1; - } else { // Utilize else rather than define all conditions - end = mid - 1; + for(var x = 0; x < rows; x++) { + while(y && target < matrix[x][y]) { + y--; } - } - - var targetRow = end; - start = 0; - end = cols ; - - while(start <= end){ - mid = start + parseInt((end - start)/2); - - if(matrix[targetRow][mid] === target){ + if(matrix[x][y] === target) { return true; - } else if(matrix[targetRow][mid] < target){ - start = mid + 1; - } else { // Utilize else rather than define all conditions - end = mid - 1; } } + return false; }; \ No newline at end of file diff --git a/78 Subsets.js b/78 Subsets.js new file mode 100644 index 0000000..030c477 --- /dev/null +++ b/78 Subsets.js @@ -0,0 +1,40 @@ +// Given a set of distinct integers, nums, return all possible subsets. + +// Note: The solution set must not contain duplicate subsets. + +// For example, +// If nums = [1,2,3], a solution is: + +// [ +// [3], +// [1], +// [2], +// [1,2,3], +// [1,3], +// [2,3], +// [1,2], +// [] +// ] + + +/** + * @param {number[]} nums + * @return {number[][]} + */ +var subsets = function(nums) { + var result = []; + generate(nums, 0, [], result); + return result; +}; + +var generate = function(nums, index, cur, result) { + if(index === nums.length) { + result.push(cur.slice()); + return + } + + generate(nums, index + 1, cur, result); + cur.push(nums[index]); + generate(nums, index + 1, cur, result); + cur.pop(); +} \ No newline at end of file diff --git a/8 String to Integer (atoi).js b/8 String to Integer (atoi).js index d04dde8..f981829 100644 --- a/8 String to Integer (atoi).js +++ b/8 String to Integer (atoi).js @@ -1,24 +1,52 @@ +// Implement atoi to convert a string to an integer. + +// Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. + +// Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. /** * @param {string} str * @return {number} */ var myAtoi = function(str) { + var num = 0; + var baseCharCode = '0'.charCodeAt(0); + var sign = 1; - var val = parseInt(str) - if(str === null || str.length === 0 || isNaN(val)){ - return 0; + str = str.trim(); + + if(str[0] === '+' || str[0] === '-') { + + if(str[0] === '-') { + sign = -1; + } + + str = str.substring(1); + } + + for(var i = 0; i < str.length; i++) { + var c = str[i]; + var charCode = c.charCodeAt(0) - baseCharCode; + + if(0 <= charCode && charCode <= 9) { + num *= 10; + num += charCode; + } else { + break; + } } - var maxNegInt = -Math.pow(2,31); var maxInt = Math.pow(2,31) - 1; + var minNegInt = -Math.pow(2,31); + + num = sign*num; - if(val > 0 && val > maxInt){ + if(0 < num && maxInt < num) { return maxInt; } - if(val < 0 && val < maxNegInt){ - return maxNegInt; + if(num < 0 && num < minNegInt) { + return minNegInt; } - return val; + return num; }; \ No newline at end of file diff --git a/88 Merge Sorted Array.js b/88 Merge Sorted Array.js index 35a70b2..a8aaa4a 100644 --- a/88 Merge Sorted Array.js +++ b/88 Merge Sorted Array.js @@ -16,8 +16,8 @@ var merge = function(A, m, B, n) { } } - while(n > 0){ - A[m+n-1] = B[n-1]; + while(n > 0) { + nums1[n - 1] = nums2[n - 1]; n--; } }; \ No newline at end of file diff --git a/89 Gray Code.js b/89 Gray Code.js new file mode 100644 index 0000000..ff8ac22 --- /dev/null +++ b/89 Gray Code.js @@ -0,0 +1,50 @@ + + +// The gray code is a binary numeral system where two successive values differ in only one bit. + +// Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. + +// For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: + +// 00 - 0 +// 01 - 1 +// 11 - 3 +// 10 - 2 +// Note: +// For a given n, a gray code sequence is not uniquely defined. + +// For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. + +// For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. + + +// n = 0: 0 +// n = 1: 0, 1 +// n = 2: 00, 01, 11, 10 (0, 1, 3, 2) +// n = 3: 000, 001, 011, 010, 110, 111, 101, 100 (0, 1, 3, 2, 6, 7, 5, 4) +// 以n = 3为例,grey code中前4个包括了n = 2的所有gray code。后4个则是前4个逆序后加上2^2。 + +// 推广:n = i的grey code的前一半包括了n = i-1的所有grey code,而后一半则为前一半逆序后家上2^(i-1)。 + + +// Silly question... + +/** + * @param {number} n + * @return {number[]} + */ +var grayCode = function(n) { + if(n === 0) { + return [0]; + } + + var result = grayCode(n - 1); + var addNumber = 1 << (n - 1); + var len = result.length; + + for(var i = len; i--;) { + result.push(result[i] + addNumber); + } + + return result; +}; \ No newline at end of file diff --git a/91 Decode Ways.js b/91 Decode Ways.js index 5a0cd16..e8b9028 100644 --- a/91 Decode Ways.js +++ b/91 Decode Ways.js @@ -50,4 +50,42 @@ var numDecodings = function(s) { } return nums[s.length]; +}; + + + +// Using recusion +// It also store all the possible combination +var numDecodings = function(s) { + var result = []; + + function traverse(s, beg, end, cur) { + if(end > s.length) { + return + } + + + var str = s.substring(beg, end); + var num = parseInt(str); + + if(isNaN(num) || num === 0 || num > 26) { + return; + } + + cur.push(str); + + if(end === s.length){ + result.push(cur.slice()); + return; + } + + traverse(s, end, end + 1, cur); + traverse(s, end, end + 2, cur); + cur.pop(); + } + + traverse(s, 0, 1, []); + traverse(s, 0, 2, []); + + return result.length; }; \ No newline at end of file diff --git a/Bean Probability.js b/Bean Probability.js new file mode 100644 index 0000000..aa54d97 --- /dev/null +++ b/Bean Probability.js @@ -0,0 +1,2 @@ +// 你有一个罐子里面有红色和白色的豆子,你每一轮拿一个豆子出来,要是白色就吃了,要是红色就放回去再拿一次,这一次无论什么颜色你都吃。。问最后吃的一个是白色的概率是多少。。 +// r/(r+w)*(r/(r+w)*f(r - 1, w)+w/(r+w)*f(r, w - 1)) \ No newline at end of file diff --git a/Conjuct Names With Limit.js b/Conjuct Names With Limit.js new file mode 100644 index 0000000..2b96669 --- /dev/null +++ b/Conjuct Names With Limit.js @@ -0,0 +1,41 @@ +function conjuctNamesWithLimit(names, limit) { + var left, right; + + if(names.length === 0) { + return ''; + } + + if(limit === 0) { + return names.length + ' more'; + } + + if(limit >= names.length) { + left = names.slice(0, -1); + right = names.slice(-1)[0]; + return left.join(', ') + ' and ' + right; + } else { + left = names.slice(0, limit); + right = names.slice(limit); + return left.join(', ') + ' and ' + right.length + ' more'; + } +} + +var data = [ + [], + ['a','b'], + ['a','b','c'], + ['a','b','c','d'] +] + +for(var i = 0; i < 5; i++){ + data.forEach((d)=>{ + console.log(conjuctNamesWithLimit(d, i)); + }); +} + + + +console.log(conjuctNamesWithLimit(['alex', 'peter', 'jeremy'], 2) == 'alex, peter and 1 more'); +console.log(conjuctNamesWithLimit(['alex', 'peter', 'jeremy', 'joseph'], 2) == 'alex, peter and 2 more'); +console.log(conjuctNamesWithLimit(['alex', 'peter', 'jeremy', 'joseph'], 3) == 'alex, peter, jeremy and 1 more'); +console.log(conjuctNamesWithLimit(['alex', 'peter', 'jeremy', 'joseph'], 5) == 'alex, peter, jeremy and joseph'); diff --git a/Convert Binary Search Tree To Doubly Linked List.js b/Convert Binary Search Tree To Doubly Linked List.js new file mode 100644 index 0000000..0e94dad --- /dev/null +++ b/Convert Binary Search Tree To Doubly Linked List.js @@ -0,0 +1,133 @@ +// http://kubicode.me/2015/07/01/Algorithm/Binary-Search-Tree-2-Double-LinkedList/ + +// 二叉排序树的中序遍历可以得到它的排序元素,但是,但是“它不能创建任何新的节点,只能调整指针的指向”,所以,直接中序法就不可行了。 +// 大致思路是如下的: +// 如果当前根节点的左子树不为空,则 +// 递归左子树 +// 查找左子树最大的元素 +// 将该元素的right指针指向根节点,将根节点的left指针指向该元素 +// 如果当前根节点的右子树不为空,则 +// 递归右子树 +// 查找右子树最小的元素 +// 将该元素的left指针指向根节点,将根节点的right指针指向该元素 +// 注:tree的left和right结构正好对应list的pre和next结构 +// 8 +// / \ +// 3 10 +// / \ \ +// 1 6 14 +// / \ / +// 4 7 13 + +// 它依次调整的点为:1(l),4(l),7(r),4(r),7(l),13(l),13(r),10(r) +// 8 +// / \ +// 1-3 10 +// \ \ +// 6 14 +// / \ / +// 4 7 13 +// 1为3左子树的最大点,所以的右指针指向3,3的左指针指向1 + + +// 8 +// / \ +// 1-3 10 +// \ \ +// 4-6 14 +// \ / +// 7 13 + +// 4为6的左子树的最大值,所以4的右指针指向6,6左指针4 + +// 8 +// / \ +// 1-3 10 +// \ \ +// 4-6-7 14 +// / +// 13 + +// 7为6的右子树的最小值,所以7的左指针指向6,6右指针4 + +// 8 +// / \ +// 1-3 10 +// \ \ +// 4-6-7 14 +// / +// 13 + +// 4为3的右子树的最小值,所以4的左指针指向3,3右指针4 + +// 1-3-4-6-7-8 +// \ +// 10 +// \ +// 14 +// / +// 13 + +// 7为8左子树的最小值,所以7的右指针指向8,8的左指针指向7 +// 这样就完成了根节点左边的转换,右边的转换思路一致 + +/** + * 查找左子树中最大的节点 + * @param T + * @return + */ +private static TreeNode findMaxNodeInLeft(TreeNode T) +{ + TreeNode t=T.left; + if(t!=null) + while(t.right!=null) + { + t=t.right;//因为肯定右子树更加大 + } + + return t; + +} + +/** + * 查找右子树种的最小节点 + * @param T + * @return + */ +private static TreeNode findMinNodeInRight(TreeNode T) +{ + TreeNode t=T.right; + if(t!=null) + while(t.left!=null) + t=t.left; + + return t; +} + +/** + * 二叉排序树转双向链表 + * @param T + */ +public static void convertNode(TreeNode T) +{ + if(T==null) + return ; + + if(T.left!=null) + { + convertNode(T.left); + TreeNode t=findMaxNodeInLeft(T);//左子树中最大的点 它一定是在叶子上面 + t.right=T;//将左子树最小的点连在根节点的左侧 + T.left=t; + t.parent=null; + } + + if(T.right!=null) + { + convertNode(T.right); + TreeNode t=findMinNodeInRight(T); + t.left=T;//将右子树最小的点连点根节点的右侧 + T.right=t; + t.parent=null; + } +} \ No newline at end of file diff --git a/Custom Tree Problem.js b/Custom Tree Problem.js new file mode 100644 index 0000000..683116b --- /dev/null +++ b/Custom Tree Problem.js @@ -0,0 +1,119 @@ +// a ---> b +// b ---> c +// b ---> d +// a ---> e +// Print the tree that would form when each pair of these links that has the same character as start and end point is joined together. You have to maintain fidelity w.r.t. the height of nodes, i.e. nodes at height n from root should be printed at same row or column. For set of links given above, tree printed should be – + +// -->a +// |-->b +// | |-->c +// | |-->d +// |-->e +// Note that these links need not form a single tree; they could form, ahem, a forest. Consider the following links + +// a ---> b +// a ---> g +// b ---> c +// c ---> d +// d ---> e +// c ---> f +// z ---> y +// y ---> x +// x ---> w +// The output would be following forest. + +// -->a +// |-->b +// | |-->c +// | | |-->d +// | | | |-->e +// | | |-->f +// |-->g + +// -->z +// |-->y +// | |-->x +// | | |-->w + +// http://ideone.com/l0QiJx +function printTree(data) { + // 0 -> not seen, can possibly be root + // 1 -> not root + // 2 -> root + + var NOT_SEEN = 0; + var NOT_ROOT = 1; + var IS_ROOT = 2; + + var roots = Array(26).fill(NOT_SEEN); + // [[neightbors],[neighbors],...] -> idx = 0 -> 'a' + var graph = []; + for(var i = 0; i < 26; i++){ + graph.push([]); + } + + for(i = 0; i < data.length; i++) { + var pair = data[i]; + var rootChar = pair[0]; + var rootIdx = charToIdx(rootChar); + var depChar = pair[1]; + var depIdx = charToIdx(depChar); + + graph[rootIdx].push(depIdx); + + roots[depIdx] = NOT_ROOT; + + if(roots[rootIdx] === NOT_SEEN) { + roots[rootIdx] = IS_ROOT; + } + } + // console.log(roots); + for(i = 0; i < roots.length; i++) { + if(roots[i] === IS_ROOT) { + dfs(i, 0, graph); + } + } +} + +function charToIdx(char) { + var base = 'a'.charCodeAt(0); + return char.charCodeAt(0) - base; +} + +function idxToChar(idx) { + var base = 'a'.charCodeAt(0); + return String.fromCharCode(base + idx); +} + +function dfs(idx, level, graph) { + var str = ''; + + for(var i = 1; i <= level; i++) { + str += ' |'; + } + + var char = idxToChar(idx); + str += ('-->' + char); + console.log(str); + + for(i = 0; i < graph[idx].length; i++) { + var depIdx = graph[idx][i]; + dfs(depIdx, level + 1, graph); + } +} + + + +var data = [ + ['a', 'b'], + ['a', 'g'], + ['b', 'c'], + ['c', 'd'], + ['d', 'e'], + ['c', 'f'], + ['z', 'y'], + ['y', 'x'], + ['x', 'w'] +]; + +console.log(printTree(data)); \ No newline at end of file diff --git a/Data Structure Max Heap.js b/Data Structure Max Heap.js index 73fe60f..c910f2d 100644 --- a/Data Structure Max Heap.js +++ b/Data Structure Max Heap.js @@ -39,7 +39,7 @@ class MaxHeap { var arr = this.arr; while(n > 0) { - var parentN = Math.floor((n + 1)/2) - 1; // [1,2,3] 1 as root 2 as left child and 3 as right child 2 has idx = 1 and 3 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + var parentN = Math.floor(n/2); // [3,2,1] 3 as root, 2 as left child and 1 as right child 2 has idx = 1 and 1 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end if(arr[parentN] > arr[n]) { break; @@ -60,8 +60,8 @@ class MaxHeap { while(true) { var swap = null; - var child2N = (n+1)*2; // root = 0 right child idx is (0 + 1)*2 = 2 - var child1N = child2N - 1; // right child idx - 1 = 1 for root's left child + var child2N = n*2 + 2; // root = 0 right child idx is (0 + 1)*2 = 2 + var child1N = n*2 + 1; // right child idx - 1 = 1 for root's left child if(child1N < len && arr[child1N] > val) { swap = child1N; @@ -90,6 +90,7 @@ m.add(2); m.add(3); m.add(3); m.add(3); +m.add(4); m.add(3); m.add(3); @@ -108,4 +109,5 @@ console.log(m.pop()); console.log(m.pop()); console.log(m.pop()); console.log(m.pop()); +console.log(m.pop()); \ No newline at end of file diff --git a/Log Hits.js b/Log Hits.js new file mode 100644 index 0000000..0c5d20f --- /dev/null +++ b/Log Hits.js @@ -0,0 +1,106 @@ +// void log_hit() +// int get_hits() - Returns the number of hits in the last 6 minutes +// ........... +// [11,12,13,14,15,............] 6mins +// 6*60sec => 360 +// [0,...,359] +// { time: timestamp, count: integer} +// lastTime: 1, count +// 丟掉盒子 + +class Node { + constructor(time) { + this.time = time; + this.count = 0; + this.next = null; + } +} + +class Logger { + constructor(precision, seconds) { + this.lastTimeHit = null; + this.precision = precision; // 1 src + this.seconds = seconds; // 360 seconds + // this.count = []; // initialize later // linklist structure + + this.head = this.tail = new Node(this.getCurTimeInSec()); + this.count = 0; + this.totalCount = 0; + } + + logHit() { // assume this log hit got hits more + var curTimeInSec = this.getCurTimeInSec(); + + if(curTimeInSec === this.lastTimeHit) { + this.tail.count++; + } else { + var node = new Node(curTimeInSec); + node.count+=; + this.tail.next = node; + this.tail = node; + this.count++; + } + + // 361 > 360 + if(this.count > this.seconds) { + var next = this.head.next; + this.head.next = null; + this.head = next; + this.totalCount -= this.head.count; + } + + this.totalCount++; + + } + + getHits() { + var curTime = this.getCurTimeInSec(); + var startTime = curTime - this.seconds; // 360 seconds + var discount = 0; + + while(this.head && this.head.time < startTime) { + discount += this.head.count; + var next = this.head.next; + this.head.next = null; + this.head = next; + } + + if(this.head === null) { + this.head = this.tail = new Node(curTime); + } + + this.totalCount -= discount; + + return this.totalCount; + } + + getCurTimeInSec() { + var curTime = Date.now(); // assuming this is ms + var curTimeInSec = Math.floor(curTime / 1000); + return curTimeInSec; + } +} + + +new Logger(1, 6); +// starting 123 +// loghit 154 + +// head(123) -> node(154) +// tail at node(154) +//loghit 160 + +// head(123) -> node(154) -> node(160); +// tail at 160 +// getHits() // curTime 510 +// 510 - 360 = 150 + +// logHit at 100 +// totalCount -> 1 +// head(0) -> node(100) +// tail is at node(100) +// getHits at 500 +// 500 - 360 = 140 +// dicount += 0 +// dicount += 1 +// curHead === null diff --git a/Merge Two Lists Into Sorted List.js b/Merge Two Lists Into Sorted List.js new file mode 100644 index 0000000..f761047 --- /dev/null +++ b/Merge Two Lists Into Sorted List.js @@ -0,0 +1,82 @@ +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ + +// !!! we can concat two list together than use merge sort to sort the merged list + +var sortList = function(head) { + if(head === null) { + return null; + } + + var len = 0; + var p = head; + + while(p) { + len++; + p = p.next; + } + + var newHead = sort(len); + + return newHead; + + function sort(len) { + // there will be no case of len = 0 which is caused by 1/2 + if(len === 1) { + var temp = head; + // !!! important: moving pointer to the next + // e.g. 1->2->3->4 + // head-> 1 + // now head will be point to 2 + head = head.next; + temp.next = null; + return temp; + } + // there will be no case of len = 0 which is caused by 1/2 + var leftHead = sort(parseInt(len/2)); + var rightHead = sort(len - parseInt(len/2)); + var newHead = merge(leftHead, rightHead); + + return newHead; + } + + function merge(first, second) { + var h = new ListNode(-1); + var cur = h; + + while(first && second) { + + + if(first.val <= second.val) { + cur.next = first; + first = first.next; + } else { + cur.next = second; + second = second.next; + } + + cur = cur.next; + } + + if(first) { + cur.next = first; + } + + if(second) { + cur.next = second; + } + + cur = h.next; + h.next = null; + return cur; + } +}; \ No newline at end of file diff --git a/Parse HTML.js b/Parse HTML.js index 0dbc363..8c11db8 100644 --- a/Parse HTML.js +++ b/Parse HTML.js @@ -13,8 +13,8 @@ function parseHtml(htmlArr) { } else { var map = {}; map[htmlTag] = []; - stack.push(context); context.push(map); + stack.push(context); context = map[htmlTag]; } } @@ -52,17 +52,17 @@ console.log(parseHtml(htmlArr)); [{ html: [{ body: [{ - div: { - a: {} - } + div: [{ + a: [{}] + }] },{ - div: { - a: {} - } + div: [{ + a: [{}] + }] },{ - div: { - a: {} - } + div: [{ + a: [{}] + }] }] }] }] diff --git a/Parse String Into Array.js b/Parse String Into Array.js new file mode 100644 index 0000000..9af8761 --- /dev/null +++ b/Parse String Into Array.js @@ -0,0 +1,79 @@ +// Given a string, parse it and return a string array. +// It's like a tokenizer, but the rules are too... +// For exmple, string="abc(edf)hij{klmn}opq[rst]uvw" +// Rule 1: +// The delimitors are (), {}, []. They are in pair. +// So output array: ["abc", "edf", "hij", "klmn", "opq", "rst", "uvw"] +// Rule 2: +// if any two consecutive "(" means escaping, that is "((" is actually output char "(". +// It's not part of the delimitor. Similar to ")", "{", "}", "[", "]". abc(e))df) => ["abc", "e)df"], since the "))" outpus ")". +// Rule 3: if "{" is inside a delimitor pair (), then "{" isn't part of the delimitor. Output it as is. abc(e{df}}g) => ["abc", "e{df}}g"] +// So, parse the given string and assume the given string is always valid and parsable. + + + +function tokenizeString(str) { + var result = []; + var cur = ''; + var i = 0; + + while(i < str.length){ + var c = str[i]; + + // Need to take care of [ && [[ && [[[ + // [123] -> ['123'], [[123]] --> ['[123]'], [[[123]]] -> ['[[123]]'] + if(c === '[' || c === '(' || c === '{') { + if(cur !== '') { + result.push(cur); + cur = ''; + } + var eq = escapeQuote(str, i + 1, c); + result.push(eq[0]); + i = eq[1]; + + } else { + cur += c; + i++; + } + } + + if(cur !== '') { + result.push(cur); + } + + return result; + + function escapeQuote(str, i, quoteSym) { + var quoteCnt = 1; + var result = ''; + + while(i < str.length) { + var c = str[i] + if(quoteSym === c) { + quoteCnt++; + } else if((quoteSym === '[' && c === ']') + || (quoteSym === '{' && c === '}') + || (quoteSym === '(' && c === ')') + ) { + quoteCnt--; + } + + i++; + + if(quoteCnt === 0) { + break; + } + + result += c; + } + + return [result, i]; + } +} + + +var str = "abc(((edf)))hij{{klmn}}opq[rst]uvw"; +// answer should be ['abc', '((edf))', 'hij', '{klmn}', 'opq', 'rst', 'uvw'] + +console.log(tokenizeString(str)); +// [ 'abc', '((edf))', 'hij', '{klmn}', 'opq', 'rst', 'uvw' ] diff --git a/README.md b/README.md index eb460bc..f286ea3 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,9 @@ - 120 Triangle.js - 121 Best Time to Buy and Sell Stock.js - 122 Best Time to Buy and Sell Stock II.js +- 123 Best Time to Buy and Sell Stock III.js - 124 Binary Tree Maximum Path Sum.js +- 126 Word Ladder II.js - 127 Word Ladder.js - 129 Sum Root to Leaf Numbers.js - 13 Roman to Integer.js @@ -30,6 +32,7 @@ - 133 Clone Graph.js - 136 Single Number.js - 137 Single Number II.js +- 138 Copy List With Random Pointer.js - 139 Word Break.js - 14 Longest Common Prefix.js - 140 Word Break II.js @@ -57,6 +60,8 @@ - 172 Factorial Trailing Zeroes.js - 173 Binary Search Tree Iterator.js - 179 Largest Number.js +- 186 Reverse Words in a String II.js +- 188 Best Time to Buy and Sell Stock IV.js - 189 Rotate Array.js - 19 Remove Nth Node From End of List.js - 190 Reverse Bits.js @@ -77,6 +82,7 @@ - 209 Minimum Size Subarray Sum.js - 21 Merge Two Sorted Lists.js - 211 Add and Search Word - Data structure design.js +- 213 House Robber II.js - 215 Kth Largest Element in an Array.js - 217 Contain Duplicate.js - 219 Contains Duplicate II.js @@ -97,6 +103,7 @@ - 235 Lowest Common Ancestor Of a Binary Search Tree.js - 236 Lowest Common Ancestor of a Binary Tree.js - 237 Delete Node in a Linked List.js +- 238 Product of Array Except Self.js - 239 Sliding Window Maximum.js - 24 Swap nodes in Pairs.js - 240 Search a 2D Matrix II.js @@ -104,10 +111,13 @@ - 242 Valid Anagram.js - 249 Group Shifted Strings.js - 25 Reverse Nodes in k-Group.js +- 256 Paint House.js - 257 Binary Tree Paths.js - 26 Remove Duplicates from Sorted Array.js - 263 Ugly Number.js - 264 Ugly Number II.js +- 265 Paint House II.js +- 266 Palindrome Permutation.js - 268 Missing Number.js - 269 Alien Dictionary.js - 27 Remove Element.js @@ -120,13 +130,16 @@ - 297 Serialize and Deserialize Binary Tree My Submissions Question.js - 3 Longest Substring Without Repeating Characters.js - 300 Longest Increasing Subsequence.js +- 307 Range Sum Query - Mutable.js - 31 Next Permutation.js - 314 Binary Tree Vertical Order Traversal.js - 317 Shortest Distance From All Buildings.js - 318 Maximum Product of Word Lengths My Submissions Question.js +- 320 Generalized Abbreviation.js - 322 Coin Change.js - 33 Search in Rotated Sorted Array.js - 335 Self Crossing.js +- 337 House Robber III.js - 34 Search for a Range.js - 340 Longest Substring With At Most K Distinct Characters.js - 35 Search Insert Position.js @@ -137,9 +150,11 @@ - 39 Combination Sum.js - 4. Median of Two Sorted Arrays.js - 40 combination Sum II.js +- 42 Trapping Rain Water.js - 43 Multiply Strings.js - 45 Jump Game II.js - 46 Permutations.js +- 47 Permutations II.js - 48 Rotate Image.js - 49 Anagrams.js - 49 Group Anagrams.js @@ -167,6 +182,7 @@ - 74 Search a 2D Matrix.js - 75 Sort Colors.js - 77 Combinations.js +- 78 Subsets.js - 8 String to Integer (atoi).js - 80 Remove Duplicates from Sorted Array II.js - 81 Search in Rotated Sorted Array II.js @@ -174,6 +190,7 @@ - 83 Remove Duplicates from Sorted List.js - 86 Partition List.js - 88 Merge Sorted Array.js +- 89 Gray Code.js - 9 Palindrome Number.js - 90 Subsets II.js - 91 Decode Ways.js @@ -182,17 +199,26 @@ - 94 Binary Tree Inorder Traversal.js - 96 Unique Binary Search Trees.js - 98 Validate Binary Search Tree.js +- Bean Probability.js +- Conjuct Names With Limit.js +- Convert Binary Search Tree To Doubly Linked List.js +- Custom Tree Problem.js - Data Structure Max Heap.js - Data Structure Min Heap.js - Disambiguos Actors.js - Javascript Closure Questions.js -Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.- js +- Log Hits.js +- Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js +- Merge Two Lists Into Sorted List.js - Parse HTML.js - Parse Log Top k Longest Running Job.js +- Parse String Into Array.js - Ransom Note From Magazine.js - Rate Limiter.js - Reverse Integer.js +- Snake And Ladder.js - String Encoding and Decoding.js - Top k Longest Running Job.js +- ZigZag Conversion.js - find kth element in two arrays.js - flatten nested array.js \ No newline at end of file diff --git a/Snake And Ladder.js b/Snake And Ladder.js new file mode 100644 index 0000000..fb239ef --- /dev/null +++ b/Snake And Ladder.js @@ -0,0 +1,67 @@ +// Snake and Ladder Problem +// Given a snake and ladder board, find the minimum number of dice throws required to reach the destination or last cell from source or 1st cell. Basically, the player has total control over outcome of dice throw and wants to find out minimum number of throws required to reach last cell. + +// If the player reaches a cell which is base of a ladder, the player has to climb up that ladder and if reaches a cell is mouth of the snake, has to go down to the tail of snake without a dice throw. + +// snakesladders + +// For example consider the board shown on right side (taken from here), the minimum number of dice throws required to reach cell 30 from cell 1 is 3. Following are steps. + +// a) First throw two on dice to reach cell number 3 and then ladder to reach 22 +// b) Then throw 6 to reach 28. +// c) Finally through 2 to reach 30. + +// There can be other solutions as well like (2, 2, 6), (2, 4, 4), (2, 3, 5).. etc. + + + +function snakeAndLadder(moves, n){ + var visited = Array(n).fill(false); + visited[0] = true; + var queue = []; + queue.push({ + dist: 0, + vertex: 0 + }); + + while(queue.length > 0) { + var move = queue.shift(); + + if(move.vertex === n - 1) { + return move.dist; + } + + for(var i = move.vertex + 1; i <= move.vertex + 6; i++) { + + if(!visited[i]) { + var newMove = { + dist: move.dist + 1, + }; + visited[i] = true; + + if(moves[i] !== -1) { + newMove.vertex = moves[i]; + } else { + newMove.vertex = i; + } + + queue.push(newMove); + } + } + } + + return -1; +} + +var moves = []; +var n = 100; +for(var i = 0; i < n; i++){ + moves.push(-1); +} + +moves[2] = 53; +moves[41] = 99; +moves[54] = 40; + + +console.log(snakeAndLadder(moves, n)); \ No newline at end of file diff --git a/ZigZag Conversion.js b/ZigZag Conversion.js new file mode 100644 index 0000000..7088253 --- /dev/null +++ b/ZigZag Conversion.js @@ -0,0 +1,45 @@ +// Ref: http://www.cnblogs.com/springfor/p/3889414.html +// The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) + +// P A H N +// A P L S I I G +// Y I R +// And then read line by line: "PAHNAPLSIIGYIR" +// Write the code that will take a string and make this conversion given a number of rows: + +// string convert(string text, int nRows); +// convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". + + +/** + * @param {string} s + * @param {number} numRows + * @return {string} + */ +var convert = function(s, numRows) { + if(s === null || s.length === 0 || numRows <= 0) { + return ""; + } + + if(numRows === 1) { + return s; + } + + var res = ''; + var size = 2 * numRows - 2; + + for(var i = 0; i < numRows; i++) { + for(var j = i; j < s.length; j += size) { + res += s[j]; + + if(i !== 0 && i !== numRows - 1) { // except first and last row + var tmp = j + size - 2 * i; + if(tmp < s.length) { + res += s[tmp]; + } + } + } + } + + return res; +}; \ No newline at end of file From 6a85535b9686b5a3f0393301274a194eec25ac9d Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Fri, 15 Jul 2016 00:26:11 -0700 Subject: [PATCH 14/47] update some solutions --- 26 Remove Duplicates from Sorted Array.js | 40 +++++++--- 286 Walls and Gates.js | 89 ++++++++++------------- 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/26 Remove Duplicates from Sorted Array.js b/26 Remove Duplicates from Sorted Array.js index 33ee2cd..2999b1e 100644 --- a/26 Remove Duplicates from Sorted Array.js +++ b/26 Remove Duplicates from Sorted Array.js @@ -1,21 +1,41 @@ +// Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. + +// Do not allocate extra space for another array, you must do this in place with constant memory. + +// For example, +// Given input array nums = [1,1,2], + +// Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + + /** - * @param {number[]} A + * @param {number[]} nums * @return {number} */ -var removeDuplicates = function(A) { - if(A === null){ +var removeDuplicates = function(nums) { + if(!nums || nums.length === 0) { return 0; } + + var end = 0; - var index = 1; + // index: 012345678 + // vals: 111222333 + // first swap happen when end = 0; i points at index 3 with val 2 + // end++ becomes end points at index 1 and swap with index 3 + // after that vals become: + // vals: 121122333 + // i at at index 4 and end is at index 2 - while(index < A.length){ - if(A[index] === A[index - 1]){ - A.splice(index, 1); - } else{ - index++; + for(var i = 1; i < nums.length; i++) { + if(nums[i] !== nums[end]) { + end++; + + if(i !== end) { + nums[end] = nums[i]; + } } } - return A.length; + return end+1; }; \ No newline at end of file diff --git a/286 Walls and Gates.js b/286 Walls and Gates.js index 6f32212..f874a12 100644 --- a/286 Walls and Gates.js +++ b/286 Walls and Gates.js @@ -1,73 +1,60 @@ -// https://segmentfault.com/a/1190000003906674 - // You are given a m x n 2D grid initialized with these three possible values. // -1 - A wall or an obstacle. // 0 - A gate. -// INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647. Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF. -// For example, given the 2D grid: +// INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647. +// Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF. +// For example, given the 2D grid: // INF -1 0 INF // INF INF INF -1 // INF -1 INF -1 -// 0 -1 INF INF +// 0 -1 INF INF // After running your function, the 2D grid should be: - // 3 -1 0 1 // 2 2 1 -1 // 1 -1 2 -1 // 0 -1 3 4 +// Hide Company Tags Google Facebook +// Show Tags +// Show Similar Problems + -public class Solution { - public void wallsAndGates(int[][] rooms) { - if(rooms.length == 0) return; - for(int i = 0; i < rooms.length; i++){ - for(int j = 0; j < rooms[0].length; j++){ - // 如果遇到一个门,从门开始广度优先搜索,标记连通的节点到自己的距离 - if(rooms[i][j] == 0) bfs(rooms, i, j); +var wallsAndGates = function(rooms) { + var gates = []; + + if(!rooms || rooms.length === 0) { + return; + } + + var rows = rooms.length; + var cols = rooms[0].length; + + // find all gates + for(var i = 0; i < rows; i++) { + for(var j = 0; j < cols; j++) { + if(rooms[i][j] === 0) { + gates.push([i, j]); } } } - public void bfs(int[][] rooms, int i, int j){ - Queue queue = new LinkedList(); - queue.offer(i * rooms[0].length + j); - int dist = 0; - // 用一个集合记录已经访问过的点 - Set visited = new HashSet(); - visited.add(i * rooms[0].length + j); - while(!queue.isEmpty()){ - int size = queue.size(); - // 记录深度的搜索 - for(int k = 0; k < size; k++){ - Integer curr = queue.poll(); - int row = curr / rooms[0].length; - int col = curr % rooms[0].length; - // 选取之前标记的值和当前的距离的较小值 - rooms[row][col] = Math.min(rooms[row][col], dist); - int up = (row - 1) * rooms[0].length + col; - int down = (row + 1) * rooms[0].length + col; - int left = row * rooms[0].length + col - 1; - int right = row * rooms[0].length + col + 1; - if(row > 0 && rooms[row - 1][col] > 0 && !visited.contains(up)){ - queue.offer(up); - visited.add(up); - } - if(col > 0 && rooms[row][col - 1] > 0 && !visited.contains(left)){ - queue.offer(left); - visited.add(left); - } - if(row < rooms.length - 1 && rooms[row + 1][col] > 0 && !visited.contains(down)){ - queue.offer(down); - visited.add(down); - } - if(col < rooms[0].length - 1 && rooms[row][col + 1] > 0 && !visited.contains(right)){ - queue.offer(right); - visited.add(right); - } - } - dist++; + // starting from all gates and traverse + for(i = 0; i < gates.length; i++) { + var gate = gates[i]; + traverse(rooms, gate[0], gate[1], rows, cols, 0); + } +}; + +function traverse(rooms, i, j, rows, cols, dist) { + if(i >= 0 && i < rows && j >= 0 && j < cols) { + if(rooms[i][j] !== -1 && rooms[i][j] >= dist) { + rooms[i][j] = dist; + traverse(rooms, i + 1, j, rows, cols, dist + 1); + traverse(rooms, i, j + 1, rows, cols, dist + 1); + traverse(rooms, i - 1, j, rows, cols, dist + 1); + traverse(rooms, i, j - 1, rows, cols, dist + 1); } } } \ No newline at end of file From bbf5af32b2cd4617b00f46c347d206997b3e2726 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sat, 16 Jul 2016 16:48:52 -0700 Subject: [PATCH 15/47] add more solutions --- 243 Shortest Word Distance.js | 34 +++++++++++++ 244 Shortest Word Distance II.js | 67 +++++++++++++++++++++++++ 245 Shortest Word Distance III.js | 49 ++++++++++++++++++ 277 Find the Celebrity.js | 59 ++++++++++++++++++++++ 339 Nested List Weight Sum.js | 64 ++++++++++++++++++++++++ 364 Nested List Weight Sum II.js | 82 +++++++++++++++++++++++++++++++ 367 Valid Perfect Square.js | 41 ++++++++++++++++ 76 Minimum Window Substring.js | 81 ++++++++++++++++++++++++++++++ README.md | 9 ++++ 9 files changed, 486 insertions(+) create mode 100644 243 Shortest Word Distance.js create mode 100644 244 Shortest Word Distance II.js create mode 100644 245 Shortest Word Distance III.js create mode 100644 277 Find the Celebrity.js create mode 100644 339 Nested List Weight Sum.js create mode 100644 364 Nested List Weight Sum II.js create mode 100644 367 Valid Perfect Square.js create mode 100644 76 Minimum Window Substring.js diff --git a/243 Shortest Word Distance.js b/243 Shortest Word Distance.js new file mode 100644 index 0000000..98e3af8 --- /dev/null +++ b/243 Shortest Word Distance.js @@ -0,0 +1,34 @@ +// Given a list of words and two words word1 and word2, return the shortest distance between these two words in the list. + +// For example, +// Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + +// Given word1 = “coding”, word2 = “practice”, return 3. +// Given word1 = "makes", word2 = "coding", return 1. + +// Note: +// You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. + +// Hide Company Tags LinkedIn +// Hide Tags + + +var shortestDistance = function(words, word1, word2) { + var idx1 = -1; + var idx2 = -1; + var dist = words.length - 1; + + for(var i = 0; i < words.length; i++) { + if(words[i] === word1) { + idx1 = i; + } else if(words[i] === word2) { + idx2 = i; + } + + if(idx1 !== -1 && idx2 !== -1) { + dist = Math.min(dist, Math.abs(idx1 - idx2)) + } + } + + return dist; +}; \ No newline at end of file diff --git a/244 Shortest Word Distance II.js b/244 Shortest Word Distance II.js new file mode 100644 index 0000000..3c7eee7 --- /dev/null +++ b/244 Shortest Word Distance II.js @@ -0,0 +1,67 @@ +// This is a follow up of Shortest Word Distance. The only difference is now you are given the list of words and your method will be called repeatedly many times with different parameters. How would you optimize it? + +// Design a class which receives a list of words in the constructor, and implements a method that takes two words word1 and word2 and return the shortest distance between these two words in the list. + +// For example, +// Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + +// Given word1 = “coding”, word2 = “practice”, return 3. +// Given word1 = "makes", word2 = "coding", return 1. + +// Note: +// You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. + +// Hide Company Tags LinkedIn +// Hide Tags Hash Table Design +// Show Similar Problems + + +/** + * @constructor + * @param {string[]} words + */ +var WordDistance = function(words) { + this.positions = {}; + + for(var i = 0; i < words.length; i++) { + var word = words[i]; + + this.positions[word] = this.positions[word] || []; + this.positions[word].push(i); + } +}; + +/** + * @param {string} word1 + * @param {string} word2 + * @return {integer} + */ +WordDistance.prototype.shortest = function(word1, word2) { + var i = 0; + var j = 0; + var dist = Infinity; + var pos1 = this.positions[word1]; + var pos2 = this.positions[word2]; + + while(i < pos1.length && j < pos2.length) { + var i1 = pos1[i]; + var i2 = pos2[j]; + + dist = Math.min(dist, Math.abs(i1 - i2)); + + if(i1 < i2) { + i++; + } else { + j++; + } + } + + return dist; +}; + +/** + * Your WordDistance object will be instantiated and called as such: + * var wordDistance = new WordDistance(words); + * wordDistance.shortest("word1", "word2"); + * wordDistance.shortest("anotherWord1", "anotherWord2"); + */ \ No newline at end of file diff --git a/245 Shortest Word Distance III.js b/245 Shortest Word Distance III.js new file mode 100644 index 0000000..a5a2c20 --- /dev/null +++ b/245 Shortest Word Distance III.js @@ -0,0 +1,49 @@ +// This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as word2. + +// Given a list of words and two words word1 and word2, return the shortest distance between these two words in the list. + +// word1 and word2 may be the same and they represent two individual words in the list. + +// For example, +// Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + +// Given word1 = “makes”, word2 = “coding”, return 1. +// Given word1 = "makes", word2 = "makes", return 3. + +// Note: +// You may assume word1 and word2 are both in the list. + +// Hide Company Tags LinkedIn +// Hide Tags Array +// Hide Similar Problems + + +/** + * @param {string[]} words + * @param {string} word1 + * @param {string} word2 + * @return {number} + */ +var shortestWordDistance = function(words, word1, word2) { + var idx1 = -1; + var idx2 = -1; + var dist = words.length - 1; + + for(var i = 0; i < words.length; i++) { + if(words[i] === word1) { + if(words[idx1] === word1 && word1 === word2) { + idx2 = idx1; + } + + idx1 = i; + } else if(words[i] === word2) { + idx2 = i; + } + + if(idx1 !== -1 && idx2 !== -1) { + dist = Math.min(dist, Math.abs(idx1 - idx2)) + } + } + + return dist; +}; \ No newline at end of file diff --git a/277 Find the Celebrity.js b/277 Find the Celebrity.js new file mode 100644 index 0000000..fd5e23b --- /dev/null +++ b/277 Find the Celebrity.js @@ -0,0 +1,59 @@ +// Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them. + +// Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense). + +// You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int findCelebrity(n), your function should minimize the number of calls to knows. + +// Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's label if there is a celebrity in the party. If there is no celebrity, return -1. + +// Hide Company Tags LinkedIn Facebook +// Show Tags + + + +/** + * Definition for knows() + * + * @param {integer} person a + * @param {integer} person b + * @return {boolean} whether a knows b + * knows = function(a, b) { + * ... + * }; + */ + +/** + * @param {function} knows() + * @return {function} + */ +var solution = function(knows) { + /** + * @param {integer} n Total people + * @return {integer} The celebrity + */ + return function(n) { + var candidate = 0; + + // iterate through the list, + // if candidate is known by i -> continue + // if i doesnt know candidate, i becomes the candidate + for(var i = 1; i < n; i++) { + if(!knows(i, candidate)) { + candidate = i; + } + } + + for(i = 0; i < n; i++) { + if(i === candidate) { + continue; + } + + // if candidate is not known by i or candidate know i + if(!knows(i, candidate) || knows(candidate, i)) { + return -1; + } + } + + return candidate; + }; +}; \ No newline at end of file diff --git a/339 Nested List Weight Sum.js b/339 Nested List Weight Sum.js new file mode 100644 index 0000000..d1c8ab3 --- /dev/null +++ b/339 Nested List Weight Sum.js @@ -0,0 +1,64 @@ +// Given a nested list of integers, return the sum of all integers in the list weighted by their depth. + +// Each element is either an integer, or a list -- whose elements may also be integers or other lists. + +// Example 1: +// Given the list [[1,1],2,[1,1]], return 10. (four 1's at depth 2, one 2 at depth 1) + +// Example 2: +// Given the list [1,[4,[6]]], return 27. (one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 4*2 + 6*3 = 27) + +// Hide Company Tags LinkedIn +// Show Tags +// Show Similar Problems + + +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * function NestedInteger() { + * + * Return true if this NestedInteger holds a single integer, rather than a nested list. + * @return {boolean} + * this.isInteger = function() { + * ... + * }; + * + * Return the single integer that this NestedInteger holds, if it holds a single integer + * Return null if this NestedInteger holds a nested list + * @return {integer} + * this.getInteger = function() { + * ... + * }; + * + * Return the nested list that this NestedInteger holds, if it holds a nested list + * Return null if this NestedInteger holds a single integer + * @return {NestedInteger[]} + * this.getList = function() { + * ... + * }; + * }; + */ +/** + * @param {NestedInteger[]} nestedList + * @return {number} + */ + +var depthSum = function(nestedList) { + + function traverse(arr, lvl) { + var sum = 0; + + for(var i = 0; i < arr.length; i++) { + if(arr[i].isInteger()) { + sum += arr[i].getInteger()*lvl; + } else { + sum += traverse(arr[i].getList(), lvl + 1); + } + } + + return sum; + } + + return traverse(nestedList, 1); +}; \ No newline at end of file diff --git a/364 Nested List Weight Sum II.js b/364 Nested List Weight Sum II.js new file mode 100644 index 0000000..be128f6 --- /dev/null +++ b/364 Nested List Weight Sum II.js @@ -0,0 +1,82 @@ +// Given a nested list of integers, return the sum of all integers in the list weighted by their depth. + +// Each element is either an integer, or a list -- whose elements may also be integers or other lists. + +// Different from the previous question where weight is increasing from root to leaf, now the weight is defined from bottom up. i.e., the leaf level integers have weight 1, and the root level integers have the largest weight. + +// Example 1: +// Given the list [[1,1],2,[1,1]], return 8. (four 1's at depth 1, one 2 at depth 2) + +// Example 2: +// Given the list [1,[4,[6]]], return 17. (one 1 at depth 3, one 4 at depth 2, and one 6 at depth 1; 1*3 + 4*2 + 6*1 = 17) + +// Hide Company Tags LinkedIn +// Show Tags +// Show Similar Problems + +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * function NestedInteger() { + * + * Return true if this NestedInteger holds a single integer, rather than a nested list. + * @return {boolean} + * this.isInteger = function() { + * ... + * }; + * + * Return the single integer that this NestedInteger holds, if it holds a single integer + * Return null if this NestedInteger holds a nested list + * @return {integer} + * this.getInteger = function() { + * ... + * }; + * + * Return the nested list that this NestedInteger holds, if it holds a nested list + * Return null if this NestedInteger holds a single integer + * @return {NestedInteger[]} + * this.getList = function() { + * ... + * }; + * }; + */ +/** + * @param {NestedInteger[]} nestedList + * @return {number} + */ +var depthSumInverse = function(nestedList) { + + function getDepth(arr, lvl) { + var maxDepth = lvl; + + for(var i = 0; i < arr.length; i++) { + if(!arr[i].isInteger()) { + // maxDepth represents the max depth at that level, + // e.g. [[[[55]]],[[31]],[99],[],75] + // at lvl 1, we want to know which [[[55]]], [[31]], [99], [], 75 + // has the maxDepth + maxDepth = Math.max(maxDepth, getDepth(arr[i].getList(), lvl + 1)); + } + } + + return maxDepth; + } + + var depth = getDepth(nestedList, 1); + + function traverse(arr, lvl) { + var sum = 0; + + for(var i = 0; i < arr.length; i++) { + if(arr[i].isInteger()) { + sum += arr[i].getInteger()*lvl; + } else { + sum += traverse(arr[i].getList(), lvl - 1); + } + } + + return sum; + } + + return traverse(nestedList, depth); +}; \ No newline at end of file diff --git a/367 Valid Perfect Square.js b/367 Valid Perfect Square.js new file mode 100644 index 0000000..3692c70 --- /dev/null +++ b/367 Valid Perfect Square.js @@ -0,0 +1,41 @@ +// Given a positive integer num, write a function which returns True if num is a perfect square else False. + +// Note: Do not use any built-in library function such as sqrt. + +// Example 1: + +// Input: 16 +// Returns: True +// Example 2: + +// Input: 14 +// Returns: False +// Credits: +// Special thanks to @elmirap for adding this problem and creating all test cases. + +// Hide Company Tags LinkedIn +// Show Tags +// Show Similar Problems + + +/** + * @param {number} num + * @return {boolean} + */ +var isPerfectSquare = function(num) { + var left = 0; + var right = num; + + while(left <= right) { + var mid = left + parseInt((right - left)/2); + var pow = mid*mid; + if(pow === num) { + return true; + } else if(pow < num) { + left = mid + 1; + } else { + right = mid - 1; + } + } + return false; +}; \ No newline at end of file diff --git a/76 Minimum Window Substring.js b/76 Minimum Window Substring.js new file mode 100644 index 0000000..0c23dca --- /dev/null +++ b/76 Minimum Window Substring.js @@ -0,0 +1,81 @@ +// 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). + +// For example, +// S = "ADOBECODEBANC" +// T = "ABC" +// Minimum window is "BANC". + +// Note: +// If there is no such window in S that covers all characters in T, return the empty string "". + +// If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S. + +// Hide Company Tags LinkedIn Uber Facebook +// Hide Tags Hash Table Two Pointers String +// Hide Similar Problems + + +/** + * @param {string} s + * @param {string} t + * @return {string} + */ + +// reference: http://www.cnblogs.com/TenosDoIt/p/3461301.html +var minWindow = function(s, t) { + var lenS = s.length; + var lenT = t.length; + var queue = []; + var tRequireCount = {}; + var tFoundCount = {}; + var hasFound = 0; + var windowBeg = -1; + var windowEnd = lenS; + + for(var i = 0; i < lenT; i++) { + // init tFoundCount to all 0s + tFoundCount[t[i]] = 0; + // init tRequireCount to count of that character in t + tRequireCount[t[i]] = tRequireCount[t[i]] || 0; + tRequireCount[t[i]]++; + } + + for(i = 0; i < lenS; i++) { + if(tRequireCount[s[i]] > 0) { + // use queue to skip a lot of redudant character + // minWindow('aeeeeeebceeeeaeeedcb', 'abc'); + // queue will contain index + // 1st round: [ 0, 7, 8 ] and then get rid of character at 0 + // 2nd round: [ 7, 8, 13 ] and get rid of character at 7 + // 3rd round: [ 8, 13, 18, 19 ] + queue.push(i); + tFoundCount[s[i]]++; + + if(tFoundCount[s[i]] <= tRequireCount[s[i]]) { + hasFound++; + } + + // when the current location which is in queue + if(hasFound === lenT) { + var k; + + do { + k = queue.shift(); + tFoundCount[s[k]]--; + } while(tFoundCount[s[k]] >= tRequireCount[s[k]]); + + if(windowEnd - windowBeg > i - k) { + windowBeg = k; + windowEnd = i; + // window will be in + // 1st round 0 8 + // 2nd round 7 13 + } + + hasFound--; + } + } + } + + return windowBeg !== -1 ? s.substring(windowBeg, windowEnd + 1) : ''; +}; \ No newline at end of file diff --git a/README.md b/README.md index f286ea3..6ea1e14 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Leetcode Problems and interview problems in Javascript + - 1 Two Sum.js - 10 Regular Expresion Matching.js - 100 Same Tree.js @@ -109,6 +110,9 @@ - 240 Search a 2D Matrix II.js - 241 Different Ways to Add Parentheses.js - 242 Valid Anagram.js +- 243 Shortest Word Distance.js +- 244 Shortest Word Distance II.js +- 245 Shortest Word Distance III.js - 249 Group Shifted Strings.js - 25 Reverse Nodes in k-Group.js - 256 Paint House.js @@ -121,6 +125,7 @@ - 268 Missing Number.js - 269 Alien Dictionary.js - 27 Remove Element.js +- 277 Find the Celebrity.js - 279. Perfect Squares.js - 28 Implement strStr().js - 286 Walls and Gates.js @@ -140,10 +145,13 @@ - 33 Search in Rotated Sorted Array.js - 335 Self Crossing.js - 337 House Robber III.js +- 339 Nested List Weight Sum.js - 34 Search for a Range.js - 340 Longest Substring With At Most K Distinct Characters.js - 35 Search Insert Position.js - 36 Valid Sudoku.js +- 364 Nested List Weight Sum II.js +- 367 Valid Perfect Square.js - 37 Sudoku Solver.js - 371 Sum of Two Integers.js - 38 Count and Say.js @@ -181,6 +189,7 @@ - 72 Edit Distance.js - 74 Search a 2D Matrix.js - 75 Sort Colors.js +- 76 Minimum Window Substring.js - 77 Combinations.js - 78 Subsets.js - 8 String to Integer (atoi).js From ed0990f4f20579a2fdc26adf7774dde2d5226571 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sun, 17 Jul 2016 17:57:24 -0700 Subject: [PATCH 16/47] add more solution --- 101 Symmetric Tree.js | 76 +++++++------ 150 Evaluate Reverse Polish Notation.js | 57 +++++----- 152 Maximum Product Subarray.js | 14 ++- 156 Binary Tree Upside Down.js | 86 +++++++++++++++ 187 Repeated DNA Sequences.js | 34 ++++++ ...Lowest Common Ancestor of a Binary Tree.js | 6 +- 254 Factor Combinations.js | 68 ++++++++++++ 261 Graph Valid Tree.js | 81 ++++++++++++++ 283 Move Zeroes.js | 55 ++++++++++ 348. Design Tic-Tac-Toe.java | 103 ++++++++++++++++++ 54 Spiral Matrix.js | 16 +++ 59 Spiral Matrix II.js | 64 +++++++---- 65 Valid Number.js | 30 +++++ 13 files changed, 605 insertions(+), 85 deletions(-) create mode 100644 156 Binary Tree Upside Down.js create mode 100644 187 Repeated DNA Sequences.js create mode 100644 254 Factor Combinations.js create mode 100644 261 Graph Valid Tree.js create mode 100644 283 Move Zeroes.js create mode 100644 348. Design Tic-Tac-Toe.java create mode 100644 65 Valid Number.js diff --git a/101 Symmetric Tree.js b/101 Symmetric Tree.js index a2876c3..b4084f9 100644 --- a/101 Symmetric Tree.js +++ b/101 Symmetric Tree.js @@ -1,3 +1,26 @@ +// 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. + +// Hide Company Tags LinkedIn Bloomberg Microsoft +// Hide Tags Tree Depth-first Search Breadth-first Search + + + /** * Definition for a binary tree node. * function TreeNode(val) { @@ -10,31 +33,22 @@ * @return {boolean} */ var isSymmetric = function(root) { - if(root === null){ - return true; - } - var queue = []; queue.push(root); - var temp = []; - var curCnt = 1; - var nextCnt = 0; - - while(queue.length !== 0){ - var p = queue.shift(); + while(queue.length !== 0) { + var len = queue.length; - if(p !== null){ - temp.push(p.left); - temp.push(p.right); + if(!isLevelSymmetric(queue)) { + return false; } - if(queue.length === 0){ - if(isPalindrome(temp)){ - queue = temp; - temp = []; - } else { - return false; + for(var i = 0; i < len; i++) { + var node = queue.shift(); + + if(node !== null) { + queue.push(node.left); + queue.push(node.right); } } } @@ -42,23 +56,19 @@ var isSymmetric = function(root) { return true; }; - -var isPalindrome = function(arr){ - var head = 0; - var tail = arr.length - 1; +function isLevelSymmetric(nodes) { + var len = nodes.length; + var beg = 0; + var end = len - 1; - while(head < tail){ - if(arr[head] && arr[tail]){ - if(arr[head].val !== arr[tail].val){ - return false; - } - } else if(arr[head] || arr[tail]){ + while(beg < end) { + if(nodes[beg] === null && nodes[end] === null || (nodes[beg] && nodes[end] && nodes[beg].val === nodes[end].val)) { + beg++; + end--; + } else { return false; } - - head++; - tail--; } return true; -} \ No newline at end of file +} diff --git a/150 Evaluate Reverse Polish Notation.js b/150 Evaluate Reverse Polish Notation.js index 6fbae82..41761e4 100644 --- a/150 Evaluate Reverse Polish Notation.js +++ b/150 Evaluate Reverse Polish Notation.js @@ -1,7 +1,14 @@ -// Leetcode #150 -// Language: Javascript -// Problem: https://leetcode.com/problems/evaluate-reverse-polish-notation/ -// Author: Chihung Yu +// Evaluate the value of an arithmetic expression in Reverse Polish Notation. + +// Valid operators are +, -, *, /. Each operand may be an integer or another expression. + +// Some examples: +// ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 +// ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6 +// Hide Company Tags LinkedIn +// Hide Tags Stack +// Hide Similar Problems (H) Basic Calculator (H) Expression Add Operators + /** * @param {string[]} tokens * @return {number} @@ -9,29 +16,27 @@ var evalRPN = function(tokens) { var stack = []; - for(var i = 0; i < tokens.length; i++){ - var t = tokens[i]; - - if(t === '+'){ - var x = parseInt(stack.pop()); - var y = parseInt(stack.pop()); - stack.push(x + y); - } else if(t === '-'){ - x = parseInt(stack.pop()); - y = parseInt(stack.pop()); - stack.push(y - x); - } else if(t === '*'){ - x = parseInt(stack.pop()); - y = parseInt(stack.pop()); - stack.push(parseInt(y * x)); - } else if(t === '/'){ - x = parseInt(stack.pop()); - y = parseInt(stack.pop()); - stack.push(parseInt(y / x)); + for(var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + var val1,val2; + var val = parseInt(token); + if(!isNaN(val)) { + stack.push(val); } else { - stack.push(t); + val2 = stack.pop(); + val1 = stack.pop(); + + if(token === '*') { + stack.push(parseInt(val1 * val2)); + } else if(token === '/') { + stack.push(parseInt(val1 / val2)); + } else if(token === '-') { + stack.push(val1 - val2); + } else if(token === '+') { + stack.push(val1 + val2); + } } } - var num = stack.pop(); - return parseInt(num); + + return stack.pop(); }; \ No newline at end of file diff --git a/152 Maximum Product Subarray.js b/152 Maximum Product Subarray.js index b3aff51..8366765 100644 --- a/152 Maximum Product Subarray.js +++ b/152 Maximum Product Subarray.js @@ -1,12 +1,22 @@ +// Find the contiguous subarray within an array (containing at least one number) which has the largest product. + +// For example, given the array [2,3,-2,4], +// the contiguous subarray [2,3] has the largest product = 6. + +// Hide Company Tags LinkedIn +// Hide Tags Array Dynamic Programming +// Show Similar Problems + + + // Leetcode #152 // Language: Javascript // Problem: https://leetcode.com/problems/maximum-product-subarray/ -// Author: Chihung Yu /** * @param {number[]} nums * @return {number} */ -// http://www.programcreek.com/2014/03/leetcode-maximum-product-subarray-java/ +// reference: http://www.programcreek.com/2014/03/leetcode-maximum-product-subarray-java/ var maxProduct = function(nums) { if(nums === null || nums.length === 0){ return 0; diff --git a/156 Binary Tree Upside Down.js b/156 Binary Tree Upside Down.js new file mode 100644 index 0000000..f2eb627 --- /dev/null +++ b/156 Binary Tree Upside Down.js @@ -0,0 +1,86 @@ +// Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that shares the same parent node) or empty, flip it upside down and turn it into a tree where the original right nodes turned into left leaf nodes. Return the new root. + +// For example: +// Given a binary tree {1,2,3,4,5}, +// 1 +// / \ +// 2 3 +// / \ +// 4 5 +// return the root of the binary tree [4,5,2,#,#,3,1]. +// 4 +// / \ +// 5 2 +// / \ +// 3 1 +// confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + +// Hide Company Tags LinkedIn +// Hide Tags Tree +// Show Similar Problems + + + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var upsideDownBinaryTree = function(root) { + var newRoot = root; + + generateUpsideDownHelper(root); + + function generateUpsideDownHelper(root) { + if(!root) { + return root; + } + + if(!root.left && !root.right) { + newRoot = root; + return root; + } + + if(root.left) { + var ret = generateUpsideDownHelper(root.left); + ret.left = root.right; + ret.right = root; + root.left = null; + root.right = null; + } + + return root; + } + return newRoot; +}; + + +// simpler solution +var upsideDownBinaryTree = function(root) { + // second condition ensure the left most child will be the new root + if (!root || (!root.left && !root.right)) { + return root; + } + + let newRoot = upsideDownBinaryTree(root.left); + console.log(newRoot.val, root.left) + + root.left.left = root.right; + root.left.right = root; + + // cannot work if we sub root.left with newRoot + // since new root is always the left most child + // [doesn't work] newRoot.left = root.right; + // [doesn't work] newRoot.right = root; + + root.left = null; + root.right = null; + + return newRoot; +}; diff --git a/187 Repeated DNA Sequences.js b/187 Repeated DNA Sequences.js new file mode 100644 index 0000000..56dfb34 --- /dev/null +++ b/187 Repeated DNA Sequences.js @@ -0,0 +1,34 @@ +// All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA. + +// Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. + +// For example, + +// Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT", + +// Return: +// ["AAAAACCCCC", "CCCCCAAAAA"]. +// Hide Company Tags LinkedIn +// Hide Tags Hash Table Bit Manipulation + + +/** + * @param {string} s + * @return {string[]} + */ +var findRepeatedDnaSequences = function(s) { + var hash = {}; + var result = []; + + for(var i = 10; i <= s.length; i++) { + var substr = s.substring(i - 10, i); + if(hash[substr] === undefined) { + hash[substr] = 1; + } else if(hash[substr] === 1) { + hash[substr]++; + result.push(substr); + } + } + + return result; +}; \ No newline at end of file diff --git a/236 Lowest Common Ancestor of a Binary Tree.js b/236 Lowest Common Ancestor of a Binary Tree.js index e6d3975..e1f92cd 100644 --- a/236 Lowest Common Ancestor of a Binary Tree.js +++ b/236 Lowest Common Ancestor of a Binary Tree.js @@ -30,8 +30,12 @@ * @param {TreeNode} q * @return {TreeNode} */ + +// Amazon LinkedIn Apple Facebook Microsoft +// Hide Tags Tree +// Hide Similar Problems -// http://www.cnblogs.com/anne-vista/p/4815076.html +// reference: http://www.cnblogs.com/anne-vista/p/4815076.html var lowestCommonAncestor = function(root, p, q) { if(root === null || root === p || root === q) { return root; diff --git a/254 Factor Combinations.js b/254 Factor Combinations.js new file mode 100644 index 0000000..58ac238 --- /dev/null +++ b/254 Factor Combinations.js @@ -0,0 +1,68 @@ +// Numbers can be regarded as product of its factors. For example, + +// 8 = 2 x 2 x 2; +// = 2 x 4. +// Write a function that takes an integer n and return all possible combinations of its factors. + +// Note: +// You may assume that n is always positive. +// Factors should be greater than 1 and less than n. +// Examples: +// input: 1 +// output: +// [] +// input: 37 +// output: +// [] +// input: 12 +// output: +// [ +// [2, 6], +// [2, 2, 3], +// [3, 4] +// ] +// input: 32 +// output: +// [ +// [2, 16], +// [2, 2, 8], +// [2, 2, 2, 4], +// [2, 2, 2, 2, 2], +// [2, 4, 4], +// [4, 8] +// ] +// Hide Company Tags LinkedIn Uber +// Hide Tags Backtracking +// Show Similar Problems + + +/** + * @param {number} n + * @return {number[][]} + */ + +// reference: http://www.cnblogs.com/airwindow/p/4822572.html +var getFactors = function(n) { + var result = []; + gatherResult(n, 2, [], result); + return result; +}; + +function gatherResult(n, start, currentResult, finalResult) { + if(n === 1) { + if(currentResult.length > 1) { + finalResult.push(currentResult.slice()); + } + + return; + } + // i = start will ensure ascending order + for(var i = start; i <= n; i++) { + if(n%i === 0) { + currentResult.push(i); + gatherResult(n/i, i, currentResult, finalResult); + currentResult.pop(); + } + } +} + \ No newline at end of file diff --git a/261 Graph Valid Tree.js b/261 Graph Valid Tree.js new file mode 100644 index 0000000..75b6786 --- /dev/null +++ b/261 Graph Valid Tree.js @@ -0,0 +1,81 @@ +// Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree. + +// For example: + +// Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true. + +// Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false. + +// Show Hint +// Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges. + +// Hide Company Tags Google Facebook Zenefits +// Hide Tags Depth-first Search Breadth-first Search Graph Union Find +// Hide Similar Problems (M) Course Schedule (M) Number of Connected Components in an Undirected Graph + + +/** + * @param {number} n + * @param {number[][]} edges + * @return {boolean} + */ + + +// reference: https://segmentfault.com/a/1190000003791051 + +var validTree = function(n, edges) { + var unionFind = new UnionFind(n); + + for(var i = 0; i < edges.length; i++) { + if(!unionFind.union(edges[i][0], edges[i][1])) { + return false; + } + } + + return unionFind.unionCount() === 1; +}; + +// reference: http://blog.csdn.net/dm_vincent/article/details/7655764 +class UnionFind { + constructor(size) { + this.ids = []; + + for(var i = 0; i < size; i++) { + this.ids[i] = i; + } + + this.count = size; + } + + union(m, n) { + var src = this.find(m); + var dest = this.find(n); + + if(src === dest) { + return false; + } + + for(var i = 0; i < this.ids.length; i++) { + if(this.ids[i] === src) { + this.ids[i] = dest; + } + } + + // once union, count-- -> count === 1 means it's a tree with no circle + this.count--; + + return true; + } + + find(m) { + return this.ids[m]; + } + + areConnected(m, n) { + return this.find(m) === this.find(n); + } + + unionCount() { + return this.count; + } +} \ No newline at end of file diff --git a/283 Move Zeroes.js b/283 Move Zeroes.js new file mode 100644 index 0000000..7357f3e --- /dev/null +++ b/283 Move Zeroes.js @@ -0,0 +1,55 @@ +// Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. + +// For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. + +// Note: +// You must do this in-place without making a copy of the array. +// Minimize the total number of operations. +// Credits: +// Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + +// Hide Company Tags Bloomberg Facebook +// Hide Tags Array Two Pointers +// Hide Similar Problems (E) Remove Element + + + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ +var moveZeroes = function(nums) { + var x = 0; + var i = 0; + while(i < nums.length) { + if(nums[i] !== 0 && nums[x] === 0) { + nums[x] = nums[i]; + nums[i] = 0; + } + + while(nums[x] !== 0 && x < nums.length) { + x++; + } + + if(i <= x) { + i = x + 1; + } + + while(nums[i] === 0) { + i++; + } + } +}; + +// Simpler but slower algo +var moveZeroes = function(nums) { + y = 0; + for (var i = 0; i < nums.length; i++) { + if (nums[i]) { + var tmp = nums[i]; + nums[i] = nums[y]; + nums[y] = tmp; + y += 1; + } + } +}; diff --git a/348. Design Tic-Tac-Toe.java b/348. Design Tic-Tac-Toe.java new file mode 100644 index 0000000..f00d77b --- /dev/null +++ b/348. Design Tic-Tac-Toe.java @@ -0,0 +1,103 @@ +// Design a Tic-tac-toe game that is played between two players on a n x n grid. + +// You may assume the following rules: + +// A move is guaranteed to be valid and is placed on an empty block. +// Once a winning condition is reached, no more moves is allowed. +// A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal row wins the game. +// Example: +// Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. + +// TicTacToe toe = new TicTacToe(3); + +// toe.move(0, 0, 1); -> Returns 0 (no one wins) +// |X| | | +// | | | | // Player 1 makes a move at (0, 0). +// | | | | + +// toe.move(0, 2, 2); -> Returns 0 (no one wins) +// |X| |O| +// | | | | // Player 2 makes a move at (0, 2). +// | | | | + +// toe.move(2, 2, 1); -> Returns 0 (no one wins) +// |X| |O| +// | | | | // Player 1 makes a move at (2, 2). +// | | |X| + +// toe.move(1, 1, 2); -> Returns 0 (no one wins) +// |X| |O| +// | |O| | // Player 2 makes a move at (1, 1). +// | | |X| + +// toe.move(2, 0, 1); -> Returns 0 (no one wins) +// |X| |O| +// | |O| | // Player 1 makes a move at (2, 0). +// |X| |X| + +// toe.move(1, 0, 2); -> Returns 0 (no one wins) +// |X| |O| +// |O|O| | // Player 2 makes a move at (1, 0). +// |X| |X| + +// toe.move(2, 1, 1); -> Returns 1 (player 1 wins) +// |X| |O| +// |O|O| | // Player 1 makes a move at (2, 1). +// |X|X|X| +// Follow up: +// Could you do better than O(n2) per move() operation? + + + +public class TicTacToe { + private int[] rows; + private int[] cols; + private int diagonal; + private int antiDiagonal; + private int size; + + /** Initialize your data structure here. */ + public TicTacToe(int n) { + rows = new int[n]; + cols = new int[n]; + size = n; + } + + /** Player {player} makes a move at ({row}, {col}). + @param row The row of the board. + @param col The column of the board. + @param player The player, can be either 1 or 2. + @return The current winning condition, can be either: + 0: No one wins. + 1: Player 1 wins. + 2: Player 2 wins. */ + public int move(int row, int col, int player) { + int toAdd = player == 1 ? 1 : -1; + + rows[row] += toAdd; + cols[col] += toAdd; + + if(row == col) { + diagonal += toAdd; + } + + if(col == cols.length - row - 1) { + antiDiagonal += toAdd; + } + + if(Math.abs(cols[col]) == size || + Math.abs(rows[row]) == size || + Math.abs(diagonal) == size || + Math.abs(antiDiagonal) == size) { + return player; + } + + return 0; + } +} + +/** + * Your TicTacToe object will be instantiated and called as such: + * TicTacToe obj = new TicTacToe(n); + * int param_1 = obj.move(row,col,player); + */ \ No newline at end of file diff --git a/54 Spiral Matrix.js b/54 Spiral Matrix.js index c61f75e..76d20db 100644 --- a/54 Spiral Matrix.js +++ b/54 Spiral Matrix.js @@ -1,3 +1,19 @@ +// Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. + +// For example, +// Given the following matrix: + +// [ +// [ 1, 2, 3 ], +// [ 4, 5, 6 ], +// [ 7, 8, 9 ] +// ] +// You should return [1,2,3,6,9,8,7,4,5]. + +// Hide Company Tags Microsoft Google Uber +// Hide Tags Array +// Hide Similar Problems (M) Spiral Matrix II + /** * @param {number[][]} matrix * @return {number[]} diff --git a/59 Spiral Matrix II.js b/59 Spiral Matrix II.js index a0788d2..a1694d1 100644 --- a/59 Spiral Matrix II.js +++ b/59 Spiral Matrix II.js @@ -1,40 +1,58 @@ +// Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. + +// For example, +// Given n = 3, + +// You should return the following matrix: +// [ +// [ 1, 2, 3 ], +// [ 8, 9, 4 ], +// [ 7, 6, 5 ] +// ] +// Hide Tags Array +// Hide Similar Problems (M) Spiral Matrix + + + /** * @param {number} n * @return {number[][]} */ - var generateMatrix = function(n) { - var m = []; - for(var i = 0; i < n; i++){ - m.push([]); + var matrix = []; + for(var i = 0; i < n; i++) { + matrix.push([]); } - - var level = parseInt(n/2); + var x = 0; + var y = 0; var count = 1; - for(var l = 0; l < level; l++){ - var x = l; - var y = l; - for(x = l; x < n - 1 - l; x++){ - m[y][x] = count++; + while(0 < n) { + if(n === 1) { + matrix[x][y] = count; + break; } - for(y = l; y < n - 1 - l; y++){ - m[y][x] = count++; + for(i = 0; i < n - 1; i++) { + matrix[x][y++] = count++; } - for(; x > l; x--){ - m[y][x] = count++; + for(i = 0; i < n - 1; i++) { + matrix[x++][y] = count++; } - for(; y > l; y--){ - m[y][x] = count++; + for(i = 0; i < n - 1; i++) { + matrix[x][y--] = count++; } + + for(i = 0; i < n - 1; i++) { + matrix[x--][y] = count++; + } + + x++; + y++; + n -= 2; } - if(n%2 === 1){ - m[level][level] = count; - } - - return m; -} \ No newline at end of file + return matrix; +}; \ No newline at end of file diff --git a/65 Valid Number.js b/65 Valid Number.js new file mode 100644 index 0000000..f77f915 --- /dev/null +++ b/65 Valid Number.js @@ -0,0 +1,30 @@ +/** + * @param {string} s + * @return {boolean} + */ + + + +// valid cases +// 9 +// .9 +// 9. +// 0.9 +// 9e10 +// 9e-10 + +// invalid case +// . +// ab +// 9ea10 +// 9e +// e9 +// .e1 + + + +// cannot use (\d*\.?\d*)\d+ + +var isNumber = function(s) { + return !!s.match(/^\s*[+-]?(\d+\.\d+|\d+\.|\.\d+|\d+)(\e[+-]?\d+)?\s*$/); +}; \ No newline at end of file From f77e6fd9aea885855ad1a96205dcad4b0247916f Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sun, 17 Jul 2016 17:58:23 -0700 Subject: [PATCH 17/47] add readme --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 6ea1e14..2667532 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ - 152 Maximum Product Subarray.js - 153 Find Minimum in Rotated Sorted Array.js - 155 Min Stack.js +- 156 Binary Tree Upside Down.js - 159 Longest Substring with At Most Two Disctinct Characters.js - 16 3Sum Closest.js - 160 Intersection Of Two Linked Lists.js @@ -62,6 +63,7 @@ - 173 Binary Search Tree Iterator.js - 179 Largest Number.js - 186 Reverse Words in a String II.js +- 187 Repeated DNA Sequences.js - 188 Best Time to Buy and Sell Stock IV.js - 189 Rotate Array.js - 19 Remove Nth Node From End of List.js @@ -85,6 +87,7 @@ - 211 Add and Search Word - Data structure design.js - 213 House Robber II.js - 215 Kth Largest Element in an Array.js +- 215 Kth Largest Element in an Array.py - 217 Contain Duplicate.js - 219 Contains Duplicate II.js - 22 Generate Parentheses.js @@ -115,9 +118,11 @@ - 245 Shortest Word Distance III.js - 249 Group Shifted Strings.js - 25 Reverse Nodes in k-Group.js +- 254 Factor Combinations.js - 256 Paint House.js - 257 Binary Tree Paths.js - 26 Remove Duplicates from Sorted Array.js +- 261 Graph Valid Tree.js - 263 Ugly Number.js - 264 Ugly Number II.js - 265 Paint House II.js @@ -128,6 +133,7 @@ - 277 Find the Celebrity.js - 279. Perfect Squares.js - 28 Implement strStr().js +- 283 Move Zeroes.js - 286 Walls and Gates.js - 289. Game of Life.js - 295 Find Median From Data Stream.js @@ -148,6 +154,7 @@ - 339 Nested List Weight Sum.js - 34 Search for a Range.js - 340 Longest Substring With At Most K Distinct Characters.js +- 348. Design Tic-Tac-Toe.java - 35 Search Insert Position.js - 36 Valid Sudoku.js - 364 Nested List Weight Sum II.js @@ -180,6 +187,7 @@ - 62 Unique Paths.js - 63 Unique Paths II.js - 64 Minimum Path Sum.js +- 65 Valid Number.js - 66 Plus One.js - 67 Add Binary.js - 68 Text Justification.js @@ -222,6 +230,7 @@ - Parse HTML.js - Parse Log Top k Longest Running Job.js - Parse String Into Array.js +- README.md - Ransom Note From Magazine.js - Rate Limiter.js - Reverse Integer.js From 067b35b10aa24b68aeb26574c43ca0fd360cbd49 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sat, 23 Jul 2016 12:49:10 -0700 Subject: [PATCH 18/47] add more solutions --- 150 Evaluate Reverse Polish Notation.js | 5 +- 170 Two Sum III - Data structure design.js | 45 ++++++++ 205 Isomorphic Strings.js | 51 +++++---- 224 Basic Calculator.js | 119 +++++++++++++++----- 261 Graph Valid Tree.js | 4 +- 349 Intersection of Two Arrays.js | 43 +++++++ 350 Intersection of Two Arrays II.js | 52 +++++++++ Basic Calculator II.js | 83 ++++++++++++++ Basic Calculator III.js | 83 ++++++++++++++ Convert Infix to Reverse Polish Notation.js | 64 +++++++++++ 10 files changed, 499 insertions(+), 50 deletions(-) create mode 100644 170 Two Sum III - Data structure design.js create mode 100644 349 Intersection of Two Arrays.js create mode 100644 350 Intersection of Two Arrays II.js create mode 100644 Basic Calculator II.js create mode 100644 Basic Calculator III.js create mode 100644 Convert Infix to Reverse Polish Notation.js diff --git a/150 Evaluate Reverse Polish Notation.js b/150 Evaluate Reverse Polish Notation.js index 41761e4..5d6eb24 100644 --- a/150 Evaluate Reverse Polish Notation.js +++ b/150 Evaluate Reverse Polish Notation.js @@ -39,4 +39,7 @@ var evalRPN = function(tokens) { } return stack.pop(); -}; \ No newline at end of file +}; + + +console.log(evalRPN([ 12, 12, 12, '*', '+', 3, 4, '-', '+' ] )); diff --git a/170 Two Sum III - Data structure design.js b/170 Two Sum III - Data structure design.js new file mode 100644 index 0000000..d437be3 --- /dev/null +++ b/170 Two Sum III - Data structure design.js @@ -0,0 +1,45 @@ +/** + * initialize your data structure here + * @constructor + */ +var TwoSum = function() { + this.hashmap = new Map(); +}; + +/** + * Add the number to an internal data structure. + * @param {number} input + * @returns {void} + */ +TwoSum.prototype.add = function(input) { + this.hashmap[input] = this.hashmap[input] || 0; + this.hashmap[input]++; +}; + +/** + * Find if there exists any pair of numbers which sum is equal to the value. + * @param {number} val + * @returns {boolean} + */ +TwoSum.prototype.find = function(val) { + for(var key in this.hashmap) { + var diff = val - parseInt(key); + + if(diff === parseInt(key)){ + if(this.hashmap[diff] >= 2) { + return true; + } + } else if(this.hashmap[diff] >= 1) { + return true; + } + } + + return false; +}; + +/** + * Your TwoSum object will be instantiated and called as such: + * var twoSum = new TwoSum(); + * twoSum.add(number); + * twoSum.find(value); + */ \ No newline at end of file diff --git a/205 Isomorphic Strings.js b/205 Isomorphic Strings.js index 457370d..9e00acb 100644 --- a/205 Isomorphic Strings.js +++ b/205 Isomorphic Strings.js @@ -1,36 +1,49 @@ -// Leetcode #205 -// Language: Javascript -// Problem: https://leetcode.com/problems/isomorphic-strings/ -// Author: Chihung Yu +// Given two strings s and t, determine if they are isomorphic. + +// Two strings are isomorphic if the characters in s can be replaced to get t. + +// All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself. + +// For example, +// Given "egg", "add", return true. + +// Given "foo", "bar", return false. + +// Given "paper", "title", return true. + +// Note: +// You may assume both s and t have the same length. + +// Hide Company Tags LinkedIn +// Hide Tags Hash Table +// Hide Similar Problems (E) Word Pattern + + + /** * @param {string} s * @param {string} t * @return {boolean} */ var isIsomorphic = function(s, t) { - if(s === null || t === null){ - return true; + if(s.length !== t.length) { + return false; } var hash1 = {}; var hash2 = {}; - for(var i = 0; i < s.length; i++){ - var sc = s[i]; - var tc = t[i]; - - hash1[sc] = tc; - hash2[tc] = sc; + for(var i = 0; i < s.length; i++) { + hash1[s[i]] = t[i]; + hash2[t[i]] = s[i]; } - var result1 = ""; - var result2 = ""; + var result1 = ''; + var result2 = ''; - for(i = 0; i < s.length; i++){ - sc = s[i] - tc = t[i]; - result1 += hash1[sc]; - result2 += hash2[tc]; + for(i = 0; i < s.length; i++) { + result1 += hash1[s[i]]; + result2 += hash2[t[i]]; } return result1 === t && result2 === s; diff --git a/224 Basic Calculator.js b/224 Basic Calculator.js index b7cfcd4..d5c6a75 100644 --- a/224 Basic Calculator.js +++ b/224 Basic Calculator.js @@ -18,39 +18,102 @@ Note: Do not use the eval built-in library function. * @param {string} s * @return {number} */ -var calculate = function(s) { - var stack = [], - len = s.length, - sum = 0, - num, - ch, - j, - i; +// var calculate = function(s) { +// var stack = [], +// len = s.length, +// sum = 0, +// num, +// ch, +// j, +// i; - stack.push(1); - stack.push(1); +// stack.push(1); +// stack.push(1); - for (i = 0; i < len; i++) { - ch = s.charAt(i); +// for (i = 0; i < len; i++) { +// ch = s.charAt(i); - if (!isNaN(parseInt(ch))) { - num = parseInt(ch); +// if (!isNaN(parseInt(ch))) { +// num = parseInt(ch); - for (j = i + 1; j < len && !isNaN(parseInt(s.charAt(j))); j++) { - num = num * 10 + parseInt(s.charAt(j)); - } +// for (j = i + 1; j < len && !isNaN(parseInt(s.charAt(j))); j++) { +// num = num * 10 + parseInt(s.charAt(j)); +// } - sum += stack.pop() * num; +// sum += stack.pop() * num; - i = j - 1; - } else if (ch === '+' || ch === '(') { - stack.push(stack[stack.length - 1]); - } else if (ch === '-') { - stack.push(stack[stack.length - 1] * (-1)); - } else if (ch === ')') { - stack.pop(); +// i = j - 1; +// } else if (ch === '+' || ch === '(') { +// stack.push(stack[stack.length - 1]); +// } else if (ch === '-') { +// stack.push(stack[stack.length - 1] * (-1)); +// } else if (ch === ')') { +// stack.pop(); +// } +// } + +// return sum; +// }; + + + +/** +Implement a basic calculator to evaluate a simple expression string. + +The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces . + +You may assume that the given expression is always valid. + +Some examples: +"1 + 1" = 2 +" 2-1 + 2 " = 3 +"(1+(4+5+2)-3)+(6+8)" = 23 +Note: Do not use the eval built-in library function. +*/ +/** + * @param {string} s + * @return {number} + */ + + + +console.log(calculate("10+20-((2-4)*6-5)*6")); +var calculate = function(s) { + + + + + +} + +function helper(s, i, sign, finalSum, currentSum) { + while(i < s.length) { + if(s[i].match(/[0-9]/)) { + var num = 0; + + while(i < s.length) { + if(s[i].match(/[0-9]/)) { + num *= 10; + num += parseInt(s[i]); + i++ + } else { + break; + } + } + } else if(s[i] === '-') { + + } else if(s[i] === '+') { + return num + helper(s, i, sign, finalSum, currentSum); + } else if(s[i] === '*') { + + } else if(s[i] === '/') { + + } else if(s[i] === '(') { + + } else if(s[i] === ')') { + } + + i++; } - - return sum; -}; +} \ No newline at end of file diff --git a/261 Graph Valid Tree.js b/261 Graph Valid Tree.js index 75b6786..0e8fa03 100644 --- a/261 Graph Valid Tree.js +++ b/261 Graph Valid Tree.js @@ -32,7 +32,7 @@ var validTree = function(n, edges) { } } - return unionFind.unionCount() === 1; + return unionFind.count() === 1; }; // reference: http://blog.csdn.net/dm_vincent/article/details/7655764 @@ -75,7 +75,7 @@ class UnionFind { return this.find(m) === this.find(n); } - unionCount() { + count() { return this.count; } } \ No newline at end of file diff --git a/349 Intersection of Two Arrays.js b/349 Intersection of Two Arrays.js new file mode 100644 index 0000000..850b43e --- /dev/null +++ b/349 Intersection of Two Arrays.js @@ -0,0 +1,43 @@ +// Given two arrays, write a function to compute their intersection. + +// Example: +// Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2]. + +// Note: +// Each element in the result must be unique. +// The result can be in any order. +// Hide Tags Binary Search Hash Table Two Pointers Sort +// Hide Similar Problems (E) Intersection of Two Arrays II + + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number[]} + */ +var intersection = function(nums1, nums2) { + var hash = {}; + var result = []; + var i = 0; + while(i < nums1.length || i < nums2.length) { + if(i < nums1.length) { + hash[nums1[i]] = hash[nums1[i]] || []; + hash[nums1[i]][0] = true; + } + + if(i < nums2.length) { + hash[nums2[i]] = hash[nums2[i]] || []; + hash[nums2[i]][1] = true; + } + + i++ + } + + for(i in hash) { + if(hash[i][0] && hash[i][1]) { + result.push(parseInt(i)); + } + } + + return result; +}; \ No newline at end of file diff --git a/350 Intersection of Two Arrays II.js b/350 Intersection of Two Arrays II.js new file mode 100644 index 0000000..4d3a1af --- /dev/null +++ b/350 Intersection of Two Arrays II.js @@ -0,0 +1,52 @@ +// Given two arrays, write a function to compute their intersection. + +// Example: +// Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2]. + +// Note: +// Each element in the result should appear as many times as it shows in both arrays. +// The result can be in any order. +// Follow up: +// What if the given array is already sorted? How would you optimize your algorithm? +// What if nums1's size is small compared to nums2's size? Which algorithm is better? +// What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once? +// Hide Tags Binary Search Hash Table Two Pointers Sort +// Hide Similar Problems (E) Intersection of Two Arrays + + + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number[]} + */ +var intersect = function(nums1, nums2) { + var hash = {}; + var arr1, arr2; + + if(nums1.length > nums2.length) { + arr1 = nums2; + arr2 = nums1; + } else { + arr1 = nums1; + arr2 = nums2; + } + + var count = arr1.length; + var result = []; + + for(var i = 0; i < arr1.length; i++) { + hash[arr1[i]] = hash[arr1[i]] || 0; + hash[arr1[i]]++; + } + + for(i = 0; i < arr2.length && count !== 0; i++) { + if(hash[arr2[i]] > 0) { + hash[arr2[i]]--; + count--; + result.push(arr2[i]); + } + } + + return result; +}; \ No newline at end of file diff --git a/Basic Calculator II.js b/Basic Calculator II.js new file mode 100644 index 0000000..d6fa1dd --- /dev/null +++ b/Basic Calculator II.js @@ -0,0 +1,83 @@ +// Implement a basic calculator to evaluate a simple expression string. + +// The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero. + +// You may assume that the given expression is always valid. + +// Some examples: +// "3+2*2" = 7 +// " 3/2 " = 1 +// " 3+5 / 2 " = 5 +// Note: Do not use the eval built-in library function. + +// Credits: +// Special thanks to @ts for adding this problem and creating all test cases. + +// Hide Company Tags Airbnb +// Hide Tags String +// Hide Similar Problems (H) Basic Calculator (H) Expression Add Operators + + + +/** + * @param {string} s + * @return {number} + */ +var calculate = function(s) { + var values = []; + var ops = []; + + for(var i = 0; i < s.length; i++) { + var ch = s[i]; + if(ch === ' ') { + continue; + } + + if(ch.match(/\d/)) { + var num = ''; + while(i < s.length && s[i].match(/\d/)) { + num += s[i++]; + } + values.push(parseInt(num)); + i--; + } else if(ch === '-' || ch === '+' || ch === '*' || ch === '/') { + if(!hasPrecedence(ch, ops[ops.length - 1])) { + while(ops.length > 0 && !hasPrecedence(ch, ops[ops.length - 1])) { + values.push(applyOp(values.pop(), values.pop(), ops.pop())); + } + } + ops.push(ch); + } + } + + while(ops.length > 0) { + values.push(applyOp(values.pop(), values.pop(), ops.pop())); + } + + return values.pop(); +}; + +var hasPrecedence = function(op1, op2) { + var map = { + '-': 1, + '+': 1, + '/': 2, + '*': 2 + } + + return map[op1] > map[op2]; +} + +var applyOp = function(v1, v2, op) { + if(op === '*') { + return v2*v1; + } else if(op === '-') { + return v2-v1; + } else if(op === '+') { + return v2+v1; + } else if(op === '/') { + return parseInt(v2/v1); + } +} + +console.log(calculate("1+1+1*3*4/2+2*3"), eval("1+1+1*3*4/2+2*3")); \ No newline at end of file diff --git a/Basic Calculator III.js b/Basic Calculator III.js new file mode 100644 index 0000000..f145df0 --- /dev/null +++ b/Basic Calculator III.js @@ -0,0 +1,83 @@ +function evaluateStr(expression) { + var values = []; + var ops = []; + + for(var i = 0; i < expression.length; i++) { + var ch = expression[i]; + + if(ch === ' ') { + continue; + } + + if(ch.match(/\d/)) { + var numStr = ''; + + while(i < expression.length && expression[i].match(/\d/)) { + numStr += expression[i++]; + } + i--; + values.push(parseInt(numStr)); + } else if(ch === '(') { + ops.push(ch); + } else if(ch === ')') { + while(ops[ops.length - 1] !== '(') { + values.push(applyOp(values.pop(), values.pop(), ops.pop())); + } + ops.pop(); + } else if(ch === '+' || ch === '-' || ch === '*' || ch === '/') { + while(ops.length > 0 && hasPrecedence(ch, ops[ops.length - 1])) { + values.push(applyOp(values.pop(), values.pop(), ops.pop())); + } + ops.push(ch); + } + } + + while(ops.length > 0) { + values.push(applyOp(values.pop(), values.pop(), ops.pop())); + } + + return values.pop(); +} + +function hasPrecedence(op1, op2) { + var precedenceMap = { + '=': 1, + '(': 2, + '+': 3, + '-': 3, + '*': 4, + '/': 4, + '~': 4, + '^': 5 + }; + + var precendence1 = precedenceMap[op1]; + var precendence2 = precedenceMap[op2]; + + return precendence2 >= precendence1; +} + +function applyOp(val1, val2, op) { + if(op === '*') { + return val2*val1; + } else if(op === '+') { + return val2+val1; + } else if(op === '/') { + return parseInt(val2/val1); + } else if(op === '-') { + return val2-val1; + } +} + + +var data = [ + '(11+(22*3-4)*5-(3+1))', + '11+22*3+(1*3+1)', + '11+22*3-(1*3+1)', +]; + +// '11+22*3*(1*3+1)' => doesn't work + +data.forEach((d)=> { + console.log(evaluateStr(d), eval(d)); +}); diff --git a/Convert Infix to Reverse Polish Notation.js b/Convert Infix to Reverse Polish Notation.js new file mode 100644 index 0000000..c4ab367 --- /dev/null +++ b/Convert Infix to Reverse Polish Notation.js @@ -0,0 +1,64 @@ +// https://www.youtube.com/watch?v=LQ-iW8jm6Mk + +function convertInfixToReversePolishNotation(strExpression) { + var precedenceMap = { + '=': 1, + '(': 2, + '+': 3, + '-': 3, + '*': 4, + '/': 4, + '~': 4, + '^': 5 + }; + + var stack = []; + var rpn = []; + + for(var i = 0; i < strExpression.length; i++) { + var ch = strExpression[i]; + if(!isNaN(parseInt(ch))) { + var num = 0; + + while(i < strExpression.length && !isNaN(parseInt(strExpression[i]))) { + num *= 10; + num += parseInt(strExpression[i]); + i++; + } + + i--; + rpn.push(num); + } else if(ch === '(') { + stack.push('('); + } else if(ch === '*' || ch === '-' || ch === '+') { + var precedence = precedenceMap[ch]; + + if(precedence > precedenceMap[stack[stack.length - 1]]) { + stack.push(ch); + } else { + while(precedenceMap[stack[stack.length - 1]] >= precedence) { + rpn.push(stack.pop()); + } + + stack.push(ch); + } + } else if(ch === ')') { + while(stack[stack.length - 1] !== '(') { + rpn.push(stack.pop()); + } + + stack.pop(); + } + } + + while(stack.length > 0) { + rpn.push(stack.pop()); + } + + return rpn; +} + + +// console.log(convertInfixToReversePolishNotation('(12*-36+(3+4-2)-(4*4+12))')); +console.log(convertInfixToReversePolishNotation('12+12*12+(3-4)')) + From 10e8ef1d83735fcbfc961e522f4bde8a579ca781 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sun, 24 Jul 2016 15:20:07 -0700 Subject: [PATCH 19/47] add more solutions --- 10 Regular Expresion Matching.js | 2 +- 124 Binary Tree Maximum Path Sum.js | 2 +- 133 Clone Graph.js | 23 +++---- 207 Course Schedule.js | 64 ++++++++++++++++++- 210 Course Schedule II.js | 98 +++++++++++++++++++++++++++++ 252 Meeting Rooms.js | 39 ++++++++++++ 253 Meeting Rooms II.js | 50 +++++++++++++++ 269 Alien Dictionary.js | 57 ++++++++++++----- 91 Decode Ways.js | 1 - Can Win.js | 33 ++++++++++ Data Structure Max Heap.js | 71 +++++++++++++++------ Data Structure Min Heap.js | 28 +++++---- Find Duplicate Files.js | 24 +++++++ Min CPU Count.js | 23 +++++++ Snake And Ladder.js | 46 +++++++------- 15 files changed, 475 insertions(+), 86 deletions(-) create mode 100644 210 Course Schedule II.js create mode 100644 252 Meeting Rooms.js create mode 100644 253 Meeting Rooms II.js create mode 100644 Can Win.js create mode 100644 Find Duplicate Files.js create mode 100644 Min CPU Count.js diff --git a/10 Regular Expresion Matching.js b/10 Regular Expresion Matching.js index 5cbe618..bf3f54e 100644 --- a/10 Regular Expresion Matching.js +++ b/10 Regular Expresion Matching.js @@ -53,7 +53,7 @@ var isMatch = function(s, p) { dp[i][j] = true; } } else if(j > 1) { // '*' cannot be the first element - if(dp[i][j-1] || dp[i][j-2]) { + if(dp[i][j-2]) { // 0 Occurance dp[i][j] = true; } else if(i > 0 && (p[j-2] == s[i-1] || p[j-2] == '.') && dp[i-1][j]) { diff --git a/124 Binary Tree Maximum Path Sum.js b/124 Binary Tree Maximum Path Sum.js index 4d75cb6..85ecde5 100644 --- a/124 Binary Tree Maximum Path Sum.js +++ b/124 Binary Tree Maximum Path Sum.js @@ -42,7 +42,7 @@ var maxPathSum = function(root) { // maxVal as if we end counting value here, what will be the maximum val // leftVal and rightVal can be negative values - maxVal = Math.max(maxVal, Math.max(ps1, ps2)); + maxVal = Math.max.apply(null, [maxVal, ps1, ps2]); // return ps1 only since, ps2 cannot be combined with the parent node // leftVal and rightVal can be negative values, however, we can to see if combining with values down below can give higher number diff --git a/133 Clone Graph.js b/133 Clone Graph.js index c4c3e03..8e87de4 100644 --- a/133 Clone Graph.js +++ b/133 Clone Graph.js @@ -21,6 +21,12 @@ // / \ // \_/ +// Pocket Gems Google Uber Facebook +// Hide Tags Depth-first Search Breadth-first Search Graph +// Hide Similar Problems (H) Copy List with Random Pointer + + + /** * Definition for undirected graph. * function UndirectedGraphNode(label) { @@ -42,21 +48,12 @@ var cloneGraph = function(graph) { } function dfs(node){ - var newNode = null; - - if(visited[node.label]){ - newNode = visited[node.label]; - }else{ - newNode = new UndirectedGraphNode(node.label); - visited[node.label] = newNode; - } + var newNode = visited[node.label] ? visited[node.label] : new UndirectedGraphNode(node.label); + visited[node.label] = newNode; for(var i = 0; i < node.neighbors.length; i++){ - if(!visited[node.neighbors[i].label]){ - newNode.neighbors.push(dfs(node.neighbors[i])); - }else{ - newNode.neighbors.push(visited[node.neighbors[i].label]); - } + var newNeighbor = visited[node.neighbors[i].label] ? visited[node.neighbors[i].label] : dfs(node.neighbors[i]); + newNode.neighbors.push(newNeighbor); } return newNode; } diff --git a/207 Course Schedule.js b/207 Course Schedule.js index 63d3216..8919e63 100644 --- a/207 Course Schedule.js +++ b/207 Course Schedule.js @@ -2,6 +2,67 @@ // Language: Javascript // Problem: https://leetcode.com/problems/course-schedule/ // Author: Chihung Yu + +// Non-recursion version 144ms +// more generic solution to problem that doesn't need information of numCourses and can deal with duplicated prerequisites + +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {boolean} + */ +var canFinish = function(numCourses, prerequisites) { + var courseWithOtherCoursesDependOn = {}; + var courseDependsOnOtherCourses = {}; + + prerequisites.forEach((prerequisite)=> { + var prereqCourse = prerequisite[1]; + var courseToTake = prerequisite[0] + + + courseWithOtherCoursesDependOn[prereqCourse] = courseWithOtherCoursesDependOn[prereqCourse] || new Set(); + courseWithOtherCoursesDependOn[prereqCourse].add(courseToTake); + + courseDependsOnOtherCourses[prereqCourse] = courseDependsOnOtherCourses[prereqCourse] || new Set(); + courseDependsOnOtherCourses[courseToTake] = courseDependsOnOtherCourses[courseToTake] || new Set(); + courseDependsOnOtherCourses[courseToTake].add(prereqCourse); + }); + + var courseWithNoDependencies = []; + + for(var i in courseDependsOnOtherCourses) { + if(courseDependsOnOtherCourses[i].size === 0) { + courseWithNoDependencies.push(i); + } + } + + while(courseWithNoDependencies.length > 0) { + var rootCourse = courseWithNoDependencies.shift(); + + if(courseWithOtherCoursesDependOn[rootCourse]) { + courseWithOtherCoursesDependOn[rootCourse].forEach((childCourse)=> { + courseDependsOnOtherCourses[childCourse].delete(parseInt(rootCourse)); + + if(courseDependsOnOtherCourses[childCourse].size === 0) { + courseWithNoDependencies.push(childCourse + ''); + } + }); + } + } + + for(i in courseDependsOnOtherCourses) { + if(courseDependsOnOtherCourses[i].size !== 0) { + return false; + } + } + + return true; +}; + + + +// recursion 132ms + /** * @param {number} numCourses * @param {number[][]} prerequisites @@ -53,10 +114,9 @@ var canFinish = function(numCourses, prerequisites) { var parent = []; var hasCycle = dfs(nodes[i], parent); - console.log(hasCycle, i, nodes[i], parent) if (hasCycle) return false; } return true; }; -canFinish(5, [[0,1],[1,2],[1,3],[1,4],[2,3]]) \ No newline at end of file + diff --git a/210 Course Schedule II.js b/210 Course Schedule II.js new file mode 100644 index 0000000..fb3c78c --- /dev/null +++ b/210 Course Schedule II.js @@ -0,0 +1,98 @@ +// There are a total of n courses you have to take, labeled from 0 to n - 1. + +// Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] + +// Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. + +// There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. + +// For example: + +// 2, [[1,0]] +// There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] + +// 4, [[1,0],[2,0],[3,1],[3,2]] +// There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3]. + +// Note: +// The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented. + +// click to show more hints. + +// Hide Company Tags Facebook Zenefits +// Hide Tags Depth-first Search Breadth-first Search Graph Topological Sort +// Hide Similar Problems (M) Course Schedule (H) Alien Dictionary (M) Minimum Height Trees + + +// 160ms + +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {number[]} + */ +var findOrder = function(numCourses, prerequisites) { + var courseWithOtherCoursesDependOn = {}; + var courseDependsOnOtherCourses = {}; + + prerequisites.forEach((prerequisite)=> { + var prereqCourse = prerequisite[1]; + var courseToTake = prerequisite[0] + + + courseWithOtherCoursesDependOn[prereqCourse] = courseWithOtherCoursesDependOn[prereqCourse] || new Set(); + courseWithOtherCoursesDependOn[prereqCourse].add(courseToTake); + + courseDependsOnOtherCourses[prereqCourse] = courseDependsOnOtherCourses[prereqCourse] || new Set(); + courseDependsOnOtherCourses[courseToTake] = courseDependsOnOtherCourses[courseToTake] || new Set(); + courseDependsOnOtherCourses[courseToTake].add(prereqCourse); + }); + + var courseWithNoDependencies = []; + + for(var i in courseDependsOnOtherCourses) { + if(courseDependsOnOtherCourses[i].size === 0) { + courseWithNoDependencies.push(i); + } + } + + + // pretty much the same as Course Schedule I. Just need to add those non root + var courseOrders = []; + var hasCourseOrders = {}; + + while(courseWithNoDependencies.length > 0) { + var rootCourse = courseWithNoDependencies.shift(); + + courseOrders.push(parseInt(rootCourse)); + hasCourseOrders[parseInt(rootCourse)] = true; + + if(courseWithOtherCoursesDependOn[rootCourse]) { + courseWithOtherCoursesDependOn[rootCourse].forEach((childCourse)=> { + courseDependsOnOtherCourses[childCourse].delete(parseInt(rootCourse)); + + if(courseDependsOnOtherCourses[childCourse].size === 0) { + courseWithNoDependencies.push(childCourse + ''); + } + }); + } + } + + for(i in courseDependsOnOtherCourses) { + if(courseDependsOnOtherCourses[i].size !== 0) { + return []; + } + } + + if(courseOrders.length < numCourses) { + for(i = 0; i < numCourses; i++) { + if(!hasCourseOrders[i]) { + courseOrders.push(i); + } + } + } + + return courseOrders; +}; + +console.log(findOrder(3, [[1,0]])); \ No newline at end of file diff --git a/252 Meeting Rooms.js b/252 Meeting Rooms.js new file mode 100644 index 0000000..8aa4b57 --- /dev/null +++ b/252 Meeting Rooms.js @@ -0,0 +1,39 @@ +// Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings. + +// For example, +// Given [[0, 30],[5, 10],[15, 20]], +// return false. + +// Hide Company Tags Facebook +// Hide Tags Sort +// Hide Similar Problems (H) Merge Intervals (M) Meeting Rooms II + + +/** + * Definition for an interval. + * function Interval(start, end) { + * this.start = start; + * this.end = end; + * } + */ +/** + * @param {Interval[]} intervals + * @return {boolean} + */ + +// 132 ms +var canAttendMeetings = function(intervals) { + // sort by starting time + intervals.sort((interval1, interval2)=> interval1.start > interval2.start ? 1 : -1); + + for(var i = 1; i < intervals.length; i++) { + var pre = intervals[i-1]; + var cur = intervals[i]; + + if(pre.end > cur.start) { + return false; + } + } + + return true; +}; \ No newline at end of file diff --git a/253 Meeting Rooms II.js b/253 Meeting Rooms II.js new file mode 100644 index 0000000..47ea1d1 --- /dev/null +++ b/253 Meeting Rooms II.js @@ -0,0 +1,50 @@ +// Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required. + +// For example, +// Given [[0, 30],[5, 10],[15, 20]], +// return 2. + +// Hide Company Tags Google Facebook +// Hide Tags Heap Greedy Sort +// Hide Similar Problems (H) Merge Intervals (E) Meeting Rooms + + +/** + * Definition for an interval. + * function Interval(start, end) { + * this.start = start; + * this.end = end; + * } + */ +/** + * @param {Interval[]} intervals + * @return {number} + */ + +var minMeetingRooms = function(intervals) { + var schedule = {}; + + intervals.forEach((interval)=>{ + schedule[interval.start] = schedule[interval.start] || 0; + schedule[interval.start]++; + + schedule[interval.end] = schedule[interval.end] || 0; + schedule[interval.end]--; + }); + + var maxRooms = 0; + var rooms = 0; + + for(var i in schedule) { + rooms += schedule[i]; + maxRooms = Math.max(maxRooms, rooms); + } + + return maxRooms; +}; + +var data = [ + {start: 2, end: 7}, +] + +console.log(minMeetingRooms(data)); \ No newline at end of file diff --git a/269 Alien Dictionary.js b/269 Alien Dictionary.js index 21c2f1c..6081235 100644 --- a/269 Alien Dictionary.js +++ b/269 Alien Dictionary.js @@ -1,10 +1,36 @@ +// There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language. + +// For example, +// Given the following words in dictionary, + +// [ +// "wrt", +// "wrf", +// "er", +// "ett", +// "rftt" +// ] +// The correct order is: "wertf". + +// Note: +// You may assume all letters are in lowercase. +// If the order is invalid, return an empty string. +// There may be multiple valid order of letters, return any one of them is fine. +// Hide Company Tags Google Airbnb Facebook Twitter Snapchat Pocket Gems +// Hide Tags Graph Topological Sort +// Hide Similar Problems (M) Course Schedule II + +/** + * @param {string[]} words + * @return {string} + */ var alienOrder = function(words) { if (words.length === 0) { return ''; } const len = words.length; - let map = {}; // value is the prerequisite of key + let requiredCharMap = {}; // value is the prerequisite of key let charPreReqCount = {}; let i; let queue = []; @@ -12,16 +38,16 @@ var alienOrder = function(words) { let hasCycle = false; for (i = 0; i < len; i++) { - // wert vs woo - // map : { w: [], e: [ 'o' ], r: [], t: [], o: [] } + // wert and woo + // requiredCharMap : { w: [], e: [ 'o' ], r: [], t: [], o: [] } // charPreReqCount : { w: 0, e: 0, r: 0, t: 0, o: 1 } const chars = words[i].split(''); let j = 0; for (j = 0; j < chars.length; j++) { - if (!map[chars[j]]) { - map[chars[j]] = []; + if (!requiredCharMap[chars[j]]) { + requiredCharMap[chars[j]] = []; charPreReqCount[chars[j]] = 0; } } @@ -42,9 +68,9 @@ var alienOrder = function(words) { } - // since words are in lexico order wert and woo -> ert vs oo, e will have higher order than oo - if (j < prev.length && map[prev.charAt(j)].indexOf(cur.charAt(j)) === -1) { - map[prev.charAt(j)].push(cur.charAt(j)); + // since words are in lexico order. wert and woo after skipping w, they becomes ert and oo, e will have higher order than oo + if (j < prev.length && requiredCharMap[prev.charAt(j)].indexOf(cur.charAt(j)) === -1) { + requiredCharMap[prev.charAt(j)].push(cur.charAt(j)); // number of prerequisite for using that char in this case it will be o: 1 since o has prerequisite e // { w: [], e: [ 'o' ], r: [], t: [], o: [] } // { w: 0, e: 0, r: 0, t: 0, o: 1 } @@ -62,20 +88,21 @@ var alienOrder = function(words) { // for those that we know are root while(queue.length > 0) { - const char = queue.shift(); + const rootChar = queue.shift(); - result.push(char); + result.push(rootChar); - for (i = 0; i < map[char].length; i++) { - charPreReqCount[map[char][i]]--; + for (i = 0; i < requiredCharMap[rootChar].length; i++) { + var charRequiresRoot = requiredCharMap[rootChar][i]; + charPreReqCount[charRequiresRoot]--; - if (charPreReqCount[map[char][i]] === 0) { - queue.push(map[char][i]); + if (charPreReqCount[charRequiresRoot] === 0) { + queue.push(charRequiresRoot); } } } - Object.keys(charPreReqCount).forEach(function(char) { + Object.keys(charPreReqCount).forEach((char) => { if (charPreReqCount[char] !== 0) { hasCycle = true; } diff --git a/91 Decode Ways.js b/91 Decode Ways.js index e8b9028..5623b0d 100644 --- a/91 Decode Ways.js +++ b/91 Decode Ways.js @@ -64,7 +64,6 @@ var numDecodings = function(s) { return } - var str = s.substring(beg, end); var num = parseInt(str); diff --git a/Can Win.js b/Can Win.js new file mode 100644 index 0000000..74e4046 --- /dev/null +++ b/Can Win.js @@ -0,0 +1,33 @@ +// CanWin. 给一个数组比如 和一个index比如4,从这个index每次可以向左或者向右跳ary的距离, 如果能跳到值为0的index则返回true。 + + +function canWin(arr) { + if(!arr || arr.length === 0) { + return false; + } + + var visitedIdx = {}; + var unvisited = []; + unvisited.push(0); + + while(unvisited.length > 0) { + var curVisitIdx = unvisited.shift(); + + if(visitedIdx[curVisitIdx] === undefined) { + visitedIdx[curVisitIdx] = true; + + if(arr[curVisitIdx] === 0) { + return true; + } + + unvisited.push(curVisitIdx + arr[curVisitIdx]); + unvisited.push(curVisitIdx - arr[curVisitIdx]); + } + } + + return false; +} + +var arr = [3,3,6,2,0,2]; +// win path 0 3 1 4 +console.log(canWin(arr)); diff --git a/Data Structure Max Heap.js b/Data Structure Max Heap.js index c910f2d..c8079c3 100644 --- a/Data Structure Max Heap.js +++ b/Data Structure Max Heap.js @@ -1,3 +1,5 @@ +'use strict' + class MaxHeap { constructor() { this.arr = []; @@ -11,7 +13,7 @@ class MaxHeap { return this.arr.length; } - pop() { + pollMax() { var arr = this.arr; var len = arr.length; @@ -20,7 +22,7 @@ class MaxHeap { } var max = arr[0]; - arr[0] = arr[len - 1] // swap the last value with max value + arr[0] = arr[len - 1] // replace max value with the last value arr.pop(); @@ -39,7 +41,11 @@ class MaxHeap { var arr = this.arr; while(n > 0) { - var parentN = Math.floor(n/2); // [3,2,1] 3 as root, 2 as left child and 1 as right child 2 has idx = 1 and 1 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + // [3,2,1] 3 as root, 2 as left child and 1 as right child + // 2 has idx = 1 and 1 has idx = 2 + // 1/2 will result in parent idx = 0 + // and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + var parentN = Math.floor((n + 1)/2) - 1; if(arr[parentN] > arr[n]) { break; @@ -84,30 +90,59 @@ class MaxHeap { } var m = new MaxHeap(); -// m.add(4); +m.add(4); m.add(1); m.add(2); -m.add(3); -m.add(3); +m.add(1); +m.add(15); m.add(3); m.add(4); m.add(3); m.add(3); +m.add(3); +m.add(4); +m.add(-1); + +m.add(-1); +m.add(1); +m.add(10); + m.add(-1); m.add(4); +m.add(8); +m.add(9); +m.add(100); +m.add(3); +m.add(7); +m.add(9); m.add(4); console.log(m.arr); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); - \ No newline at end of file +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); +console.log(m.pollMax()); \ No newline at end of file diff --git a/Data Structure Min Heap.js b/Data Structure Min Heap.js index 6ad2f9d..95808c8 100644 --- a/Data Structure Min Heap.js +++ b/Data Structure Min Heap.js @@ -11,7 +11,7 @@ class MinHeap { return this.arr.length; } - pop() { + pollMin() { var arr = this.arr; var len = arr.length; @@ -39,7 +39,9 @@ class MinHeap { var arr = this.arr; while(n > 0) { - var parentN = Math.floor((n + 1)/2) - 1; // [1,2,3] 1 as root 2 as left child and 3 as right child 2 has idx = 1 and 3 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + // [1,2,3] 1 as root 2 as left child and 3 as right child + // 2 has idx = 1 and 3 has idx = 2 1/2 will result in parent idx = 0 and 2/2 will result in parent idx = 1. So we need to add one to them and -1 at the end + var parentN = Math.floor((n + 1)/2) - 1; if(arr[parentN] <= arr[n]) { break; @@ -100,19 +102,19 @@ m.add(1); // m.add(-1); // console.log(m.arr); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); +console.log(m.pollMin()); +console.log(m.pollMin()); +console.log(m.pollMin()); console.log(m.arr); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); +console.log(m.pollMin()); +console.log(m.pollMin()); +console.log(m.pollMin()); +console.log(m.pollMin()); -console.log(m.pop()); -console.log(m.pop()); -console.log(m.pop()); -// console.log(m.pop()); +console.log(m.pollMin()); +console.log(m.pollMin()); +console.log(m.pollMin()); +// console.log(m.pollMin()); diff --git a/Find Duplicate Files.js b/Find Duplicate Files.js new file mode 100644 index 0000000..e6736cc --- /dev/null +++ b/Find Duplicate Files.js @@ -0,0 +1,24 @@ +// 题目是给定两个函数, get_files(dir), get_dir(dir) 返回所有内容相同的file, +// 问怎么定义内容相同, 然后用hashing把文件的内容hash成key放在dictionary,最后返回这个dictionary。很快写完code,test case。 小哥follow up说, 如果hashing非常expensive怎么办, 答曰hashing前先check file size,如果文件大小一样,再用hashing判断是不是一样。 小哥点头,又来一个follow up说get_files, get_dir如果expensive怎么办,答曰用parrallel programming (gpu or multi core) 可以优化,小哥点头。迎来第五轮system design的面试官。 + +// getDir(dir) +// getFiles(dir) + + +function findDuplicateFiles(dir) { + var files = []; + var queue = []; + + queue.push(dir); + + // get all files + while(queue.length > 0) { + var curDir = queue.shift(); + + var curFiles = getFiles(curDir); + var curDirs = getDir(curDir); + + queue.concat(curDirs); + files.concat(curFiles); + } +} \ No newline at end of file diff --git a/Min CPU Count.js b/Min CPU Count.js new file mode 100644 index 0000000..9869342 --- /dev/null +++ b/Min CPU Count.js @@ -0,0 +1,23 @@ +// 一个list of task, task纪录了开始时间,结束时间,需要的cpu 数量。 求最小的cpu数量可以满足complete all task without cpu deficit + +var minCPU = function(intervals) { + var schedule = {}; + + intervals.forEach((interval)=>{ + schedule[interval.start] = schedule[interval.start] || 0; + schedule[interval.start] += interval.cpu; + + schedule[interval.end] = schedule[interval.end] || 0; + schedule[interval.start] -= interval.cpu; + }); + + var maxCpu = 0; + var curCpu = 0; + + for(var i in schedule) { + curCpu += schedule[i]; + maxCpu = Math.max(maxCpu, curCpu); + } + + return maxCpu; +}; \ No newline at end of file diff --git a/Snake And Ladder.js b/Snake And Ladder.js index fb239ef..437356e 100644 --- a/Snake And Ladder.js +++ b/Snake And Ladder.js @@ -19,35 +19,37 @@ function snakeAndLadder(moves, n){ var visited = Array(n).fill(false); visited[0] = true; var queue = []; - queue.push({ - dist: 0, - vertex: 0 - }); + queue.push(0); + + var dist = 0; while(queue.length > 0) { - var move = queue.shift(); - - if(move.vertex === n - 1) { - return move.dist; - } - - for(var i = move.vertex + 1; i <= move.vertex + 6; i++) { + var len = queue.length; + + for(var j = 0; j < len; j++) { + var move = queue.shift(); - if(!visited[i]) { - var newMove = { - dist: move.dist + 1, - }; - visited[i] = true; + if(move === n - 1) { + return dist; + } - if(moves[i] !== -1) { - newMove.vertex = moves[i]; - } else { - newMove.vertex = i; - } + for(var i = move + 1; i <= move + 6; i++) { + + if(!visited[i]) { + visited[i] = true; - queue.push(newMove); + if(moves[i] !== -1) { + newMove = moves[i]; + } else { + newMove = i; + } + + queue.push(newMove); + } } } + + dist++; } return -1; From d02932fe7a688c4b1a18286a81f0bfd2407354b2 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sun, 24 Jul 2016 15:22:19 -0700 Subject: [PATCH 20/47] add readme --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2667532..f130219 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ - 168 Excel Sheet Column Title.js - 169 Majority Element.js - 17 Letter Combinations of a Phone Number.js +- 170 Two Sum III - Data structure design.js - 171 Excel Sheet Column Number.js - 172 Factorial Trailing Zeroes.js - 173 Binary Search Tree Iterator.js @@ -84,10 +85,10 @@ - 208 Implement Trie (Prefix Tree).js - 209 Minimum Size Subarray Sum.js - 21 Merge Two Sorted Lists.js +- 210 Course Schedule II.js - 211 Add and Search Word - Data structure design.js - 213 House Robber II.js - 215 Kth Largest Element in an Array.js -- 215 Kth Largest Element in an Array.py - 217 Contain Duplicate.js - 219 Contains Duplicate II.js - 22 Generate Parentheses.js @@ -118,6 +119,8 @@ - 245 Shortest Word Distance III.js - 249 Group Shifted Strings.js - 25 Reverse Nodes in k-Group.js +- 252 Meeting Rooms.js +- 253 Meeting Rooms II.js - 254 Factor Combinations.js - 256 Paint House.js - 257 Binary Tree Paths.js @@ -154,8 +157,9 @@ - 339 Nested List Weight Sum.js - 34 Search for a Range.js - 340 Longest Substring With At Most K Distinct Characters.js -- 348. Design Tic-Tac-Toe.java +- 349 Intersection of Two Arrays.js - 35 Search Insert Position.js +- 350 Intersection of Two Arrays II.js - 36 Valid Sudoku.js - 364 Nested List Weight Sum II.js - 367 Valid Perfect Square.js @@ -216,21 +220,26 @@ - 94 Binary Tree Inorder Traversal.js - 96 Unique Binary Search Trees.js - 98 Validate Binary Search Tree.js +- Basic Calculator II.js +- Basic Calculator III.js - Bean Probability.js +- Can Win.js - Conjuct Names With Limit.js - Convert Binary Search Tree To Doubly Linked List.js +- Convert Infix to Reverse Polish Notation.js - Custom Tree Problem.js - Data Structure Max Heap.js - Data Structure Min Heap.js - Disambiguos Actors.js +- Find Duplicate Files.js - Javascript Closure Questions.js - Log Hits.js - Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js - Merge Two Lists Into Sorted List.js +- Min CPU Count.js - Parse HTML.js - Parse Log Top k Longest Running Job.js - Parse String Into Array.js -- README.md - Ransom Note From Magazine.js - Rate Limiter.js - Reverse Integer.js From 893650b9cac0705262ba2fe81bc1f8fd44f4ae42 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sat, 6 Aug 2016 23:15:55 -0700 Subject: [PATCH 21/47] add more solution --- ...inary Tree Zigzag Level Order Traversal.js | 88 ++++++---- 117 Populating Next Right Pointer.js | 69 ++++++++ ...ing Next Right Pointers in Each Node II.js | 0 125 Valid Palindrome.js | 40 +++++ 149 Max Points on a Line.js | 69 ++++++++ 161 One Edit Distance.js | 45 +++++ 191 Number of 1 Bits.js | 14 ++ 212 Word Search II.js | 95 +++++++++++ 221 Maximal Square.js | 56 +++++++ 226 Invert Binary Tree.js | 45 +++-- 231 Power of Two.js | 10 ++ 253 Meeting Rooms II.js | 3 + 278 First Bad Version.js | 52 ++++++ 285 Inorder Successor in BST.js | 42 +++++ 286 Walls and Gates.js | 13 +- 293 Flip Game.js | 38 +++++ 294 Flip Game II.js | 49 ++++++ 300 Longest Increasing Subsequence.js | 6 +- 301 Remove Invalid Parentheses.js | 79 +++++++++ 322 Coin Change.js | 13 +- 334 Increasing Triplet Subsequence.js | 41 +++++ 338 Count Bits.js | 36 ++++ 341 Flatten Nested List Iterator.js | 95 +++++++++++ 353 Design Snake Game.js | 157 ++++++++++++++++++ 366 Find Leaves of Binary Tree.js | 71 ++++++++ 39 Combination Sum.js | 19 +++ 40 combination Sum II.js | 36 ++-- 57. Insert Interval.js | 8 +- 67 Add Binary.js | 37 +++-- 72 Edit Distance.js | 14 ++ 75 Sort Colors.js | 42 +++-- 79 Word Search.js | 60 +++++++ 80 Remove Duplicates from Sorted Array II.js | 26 ++- 84 Largest Rectangle in Histogram.js | 64 +++++++ 85 Maximal Rectangle.js | 89 ++++++++++ 95 Unique Binary Search Trees II.js | 84 ++++++++++ Longest Common Subsequence.js | 27 +++ Matrix Diagonal Traversal.js | 82 +++++++++ README.md | 33 +++- URL shortening.js | 30 ++++ Weighted Job Scheduling.js | 88 ++++++++++ 41 files changed, 1854 insertions(+), 111 deletions(-) create mode 100644 117 Populating Next Right Pointer.js create mode 100644 117 Populating Next Right Pointers in Each Node II.js create mode 100644 125 Valid Palindrome.js create mode 100644 149 Max Points on a Line.js create mode 100644 161 One Edit Distance.js create mode 100644 212 Word Search II.js create mode 100644 221 Maximal Square.js create mode 100644 278 First Bad Version.js create mode 100644 285 Inorder Successor in BST.js create mode 100644 293 Flip Game.js create mode 100644 294 Flip Game II.js create mode 100644 301 Remove Invalid Parentheses.js create mode 100644 334 Increasing Triplet Subsequence.js create mode 100644 338 Count Bits.js create mode 100644 341 Flatten Nested List Iterator.js create mode 100644 353 Design Snake Game.js create mode 100644 366 Find Leaves of Binary Tree.js create mode 100644 79 Word Search.js create mode 100644 84 Largest Rectangle in Histogram.js create mode 100644 85 Maximal Rectangle.js create mode 100644 95 Unique Binary Search Trees II.js create mode 100644 Longest Common Subsequence.js create mode 100644 Matrix Diagonal Traversal.js create mode 100644 URL shortening.js create mode 100644 Weighted Job Scheduling.js diff --git a/103 Binary Tree Zigzag Level Order Traversal.js b/103 Binary Tree Zigzag Level Order Traversal.js index f0edc9c..ee258a0 100644 --- a/103 Binary Tree Zigzag Level Order Traversal.js +++ b/103 Binary Tree Zigzag Level Order Traversal.js @@ -1,3 +1,22 @@ +// Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). + +// For example: +// Given binary tree [3,9,20,null,null,15,7], +// 3 +// / \ +// 9 20 +// / \ +// 15 7 +// return its zigzag level order traversal as: +// [ +// [3], +// [20,9], +// [15,7] +// ] +// Hide Company Tags LinkedIn Bloomberg Microsoft +// Hide Tags Tree Breadth-first Search Stack +// Hide Similar Problems (E) Binary Tree Level Order Traversal + /** * Definition for a binary tree node. * function TreeNode(val) { @@ -10,47 +29,50 @@ * @return {number[][]} */ var zigzagLevelOrder = function(root) { - var result = [] + // bfs if(!root) { - return result; + return []; } - var fromLeft = false; - var curLvl = []; - curLvl.push(root); - - var nextLvl = []; - var temp = []; - - while(curLvl.length !== 0) { - var p = curLvl.pop(); - temp.push(p.val); + var curLevel = []; + curLevel.push(root); + + var fromLeft = true; + var result = []; + var tmpResult = []; + var nextLevel = []; + + while(curLevel.length > 0) { + var len = curLevel.length; - if(fromLeft) { - if(p.left) { - nextLvl.push(p.left); - } - if(p.right) { - nextLvl.push(p.right); - } - } else { - if(p.right) { - nextLvl.push(p.right); - } - if(p.left) { - nextLvl.push(p.left); + for(var i = 0; i < len; i++) { + var node = curLevel.pop(); + tmpResult.push(node.val); + + if(fromLeft) { + if(node.left) { + nextLevel.push(node.left); + } + if(node.right) { + nextLevel.push(node.right); + } + } else { + if(node.right) { + nextLevel.push(node.right); + } + if(node.left) { + nextLevel.push(node.left); + } } } - if(curLvl.length === 0) { - fromLeft = !fromLeft; - result.push(temp); - temp = []; - curLvl = nextLvl; - nextLvl = []; - } + fromLeft = !fromLeft; + curLevel = nextLevel; + nextLevel = []; + result.push(tmpResult); + tmpResult = []; } - return result + return result; }; \ No newline at end of file diff --git a/117 Populating Next Right Pointer.js b/117 Populating Next Right Pointer.js new file mode 100644 index 0000000..b357d44 --- /dev/null +++ b/117 Populating Next Right Pointer.js @@ -0,0 +1,69 @@ +// Follow up for problem "Populating Next Right Pointers in Each Node". + +// What if the given tree could be any binary tree? Would your previous solution still work? + +// Note: + +// You may only use constant extra space. +// For example, +// Given the following binary tree, +// 1 +// / \ +// 2 3 +// / \ \ +// 4 5 7 +// After calling your function, the tree should look like: +// 1 -> NULL +// / \ +// 2 -> 3 -> NULL +// / \ \ +// 4-> 5 -> 7 -> NULL +// Hide Company Tags Microsoft Bloomberg Facebook +// Hide Tags Tree Depth-first Search +// Hide Similar Problems (M) Populating Next Right Pointers in Each Node + + + +/** + * Definition for binary tree with next pointer. + * function TreeLinkNode(val) { + * this.val = val; + * this.left = this.right = this.next = null; + * } + */ + +/** + * @param {TreeLinkNode} root + * @return {void} Do not return anything, modify tree in-place instead. + */ +var connect = function(root) { + if(!root) { + return; + } + + // leftEnd is used to track the current left most node + var leftEnd = root; + + while(leftEnd !== null) { + var cur = leftEnd; + // dummy is used to point to the next level's leftEnd + var dummy = new TreeLinkNode(0); + var pre = dummy; + // for each level we use leftEnd and leftEnd next to achieve level traversal + while(cur !== null) { + if(cur.left !== null) { + pre.next = cur.left; + pre = cur.left; + } + + if(cur.right !== null) { + pre.next = cur.right; + pre = cur.right; + } + + cur = cur.next; + } + + leftEnd = dummy.next; + } +}; \ No newline at end of file diff --git a/117 Populating Next Right Pointers in Each Node II.js b/117 Populating Next Right Pointers in Each Node II.js new file mode 100644 index 0000000..e69de29 diff --git a/125 Valid Palindrome.js b/125 Valid Palindrome.js new file mode 100644 index 0000000..1278fac --- /dev/null +++ b/125 Valid Palindrome.js @@ -0,0 +1,40 @@ +// Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. + +// For example, +// "A man, a plan, a canal: Panama" is a palindrome. +// "race a car" is not a palindrome. + +// Note: +// Have you consider that the string might be empty? This is a good question to ask during an interview. + +// For the purpose of this problem, we define empty string as valid palindrome. + +// Hide Company Tags Microsoft Uber Facebook Zenefits +// Hide Tags Two Pointers String +// Hide Similar Problems (E) Palindrome Linked List + + +/** + * @param {string} s + * @return {boolean} + */ +var isPalindrome = function(s) { + s = s.toLowerCase(); + var beg = 0; + var end = s.length - 1; + + while(beg < end) { + if(!s[beg].match(/[a-z0-9]/)) { + beg++; + } else if(!s[end].match(/[a-z0-9]/)) { + end--; + } else if(s[beg] !== s[end]) { + return false; + } else { + end--; + beg++; + } + } + + return true; +}; \ No newline at end of file diff --git a/149 Max Points on a Line.js b/149 Max Points on a Line.js new file mode 100644 index 0000000..9615ee9 --- /dev/null +++ b/149 Max Points on a Line.js @@ -0,0 +1,69 @@ +解这个平面几何题有3个要点: + +1. 如何判断共线? +两点成一直线,所以两点没有共线不共线之说。对于点p1(x1, y1),p2(x2, y2),p3(x3, y3)来说,共线的条件是p1-p2连线的斜率与p1-p3连线的斜率相同,即 +(y2-y1)/(x2-x1) = (y3-y1)/(x3-x1) +所以对共线的n点,其中任意两点连线的斜率相同。 + +2. 如何判断最多的共线点? +对于每个点p出发,计算该点到所有其他点qi的斜率,对每个斜率统计有多少个点符合。其中最多的个数加1(出发点本身)即为最多的共线点。 + +3. 特殊情况 +当x1 = x2,y1!=y2时,为垂直连线。计算斜率时分母为0会出错。 +当x1 = x2,y1 = y2时,两点重合。则(x2, y2)和所有(x1, y1)的连线共线。 + + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +class Solution { +public: + int maxPoints(vector &points) { + int maxPts = 0; + for(int i=0; i comSlopes; + + for(int j=i+1; j t.length) { + var tmp = s; + s = t; + t = tmp; + } + + if((t.length - s.length) > 1) { + return false; + } + + var found = false; + + for(var i = 0, j = 0; i < s.length; i++, j++) { + if(s[i] !== t[j]) { + + if(found) { + return false; + } + + found = true; + + if(s.length < t.length) { + i--; + } + } + } + + return found || s.length < t.length; +}; \ No newline at end of file diff --git a/191 Number of 1 Bits.js b/191 Number of 1 Bits.js index fc84d8a..a26280e 100644 --- a/191 Number of 1 Bits.js +++ b/191 Number of 1 Bits.js @@ -2,6 +2,20 @@ // Language: Javascript // Problem: https://leetcode.com/problems/number-of-1-bits/ // Author: Chihung Yu + +// Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight). + +// For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3. + +// Credits: +// Special thanks to @ts for adding this problem and creating all test cases. + +// Hide Company Tags Microsoft Apple +// Hide Tags Bit Manipulation +// Hide Similar Problems (E) Reverse Bits (E) Power of Two (M) Counting Bits + + + /** * @param {number} n - a positive integer * @return {number} diff --git a/212 Word Search II.js b/212 Word Search II.js new file mode 100644 index 0000000..929f597 --- /dev/null +++ b/212 Word Search II.js @@ -0,0 +1,95 @@ +// Given a 2D board and a list of words from the dictionary, find all words in the board. + +// Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. + +// For example, +// Given words = ["oath","pea","eat","rain"] and board = + +// [ +// ['o','a','a','n'], +// ['e','t','a','e'], +// ['i','h','k','r'], +// ['i','f','l','v'] +// ] +// Return ["eat","oath"]. +// Note: +// You may assume that all inputs are consist of lowercase letters a-z. + +// click to show hint. + +// Hide Company Tags Microsoft Google Airbnb +// Hide Tags Backtracking Trie +// Hide Similar Problems (M) Word Search + + + +/** + * @param {character[][]} board + * @param {string[]} words + * @return {string[]} + */ +var findWords = function(board, words) { + var root = buildTrie(words); + var result = []; + + for(var i = 0; i < board.length; i++) { + for(var j = 0; j < board[0].length; j++) { + searchWord(result, root, board, i, j); + } + } + + return result; +}; + +function searchWord(result, root, board, i, j) { + if(root.word) { + result.push(root.word); + root.word = null; + } + + if(i < 0 || i >= board.length || j < 0 || j >= board[0].length) { + return; + } + + if(board[i][j] === '#' || !root.children[board[i][j]]) { + return; + } + + var ch = board[i][j]; + board[i][j] = '#'; + + searchWord(result, root.children[ch], board, i+1, j); + searchWord(result, root.children[ch], board, i-1, j); + searchWord(result, root.children[ch], board, i, j+1); + searchWord(result, root.children[ch], board, i, j-1) + + board[i][j] = ch; +} + + +function buildTrie(words) { + var root = new TrieNode(); + + for(var i = 0; i < words.length; i++) { + var word = words[i]; + var node = root; + + for(var j = 0; j < word.length; j++) { + var ch = word[j]; + + node.children[ch] = node.children[ch] || new TrieNode(); + node = node.children[ch]; + } + + node.word = word; + } + + return root; +} + +class TrieNode { + constructor() { + this.word = null; + this.children = {}; + } +} \ No newline at end of file diff --git a/221 Maximal Square.js b/221 Maximal Square.js new file mode 100644 index 0000000..7fba62b --- /dev/null +++ b/221 Maximal Square.js @@ -0,0 +1,56 @@ +// Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. + +// For example, given the following matrix: + +// 1 0 1 0 0 +// 1 0 1 1 1 +// 1 1 1 1 1 +// 1 0 0 1 0 +// Return 4. +// Credits: +// Special thanks to @Freezen for adding this problem and creating all test cases. + +// Hide Company Tags Apple Airbnb Facebook +// Hide Tags Dynamic Programming +// Hide Similar Problems (H) Maximal Rectangle + + +/** + * @param {character[][]} matrix + * @return {number} + */ +var maximalSquare = function(matrix) { + var dp = []; + var ans = 0; + + for(var i = 0; i < matrix.length; i++) { + var arr = Array(matrix[i].length).fill(0); + dp.push(arr); + } + + for(var x = 0; x < matrix.length; x++) { + for(var y = 0; y < matrix[x].length; y++) { + dp[x][y] = parseInt(matrix[x][y]); + + // conditions to make sure that x !== 0 && y !== 0 && dp[x][y] !== 0 + // dp[x][y] is the current position + // if the current position is not 1 then it cannot form square from previous values + // and if matrix[x][y] is 0, then it will next dp[x+1][y+1] becomes zero plus one, since x+1 and y+1 will become the new start of the square. + if(x && y && dp[x][y]) { + dp[x][y] = Math.min(dp[x - 1][y - 1], dp[x - 1][y], dp[x][y - 1]) + 1; + } + + ans = Math.max(ans, dp[x][y]); + } + } + + return Math.pow(ans, 2); +}; + +var matrix = ["1111","1111","1111"]; +// dp becomes +// 1111 +// 1222 +// 1233 + +console.log(maximalSquare(matrix)); \ No newline at end of file diff --git a/226 Invert Binary Tree.js b/226 Invert Binary Tree.js index 5f66cd3..14ca813 100644 --- a/226 Invert Binary Tree.js +++ b/226 Invert Binary Tree.js @@ -1,3 +1,23 @@ +// Invert a binary tree. + +// 4 +// / \ +// 2 7 +// / \ / \ +// 1 3 6 9 +// to +// 4 +// / \ +// 7 2 +// / \ / \ +// 9 6 3 1 +// Trivia: +// This problem was inspired by this original tweet by Max Howell: +// Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off. +// Hide Tags Tree + + + // Leetcode #226 // Language: Javascript // Problem: https://leetcode.com/problems/invert-binary-tree/ @@ -14,27 +34,16 @@ * @return {TreeNode} */ var invertTree = function(root) { - var cur = root; - - generate(root); - - return cur; -}; - - -var generate = function(root){ - if(!root){ - return null; - } - - if(root.left === null && root.right === null){ + if(root === null) { return root; } - var temp = root.left; + var tmp = root.left; root.left = root.right; - root.right = temp; - + root.right = tmp; + invertTree(root.left); invertTree(root.right); -} + + return root; +}; \ No newline at end of file diff --git a/231 Power of Two.js b/231 Power of Two.js index 7b908b6..8426ff4 100644 --- a/231 Power of Two.js +++ b/231 Power of Two.js @@ -2,6 +2,16 @@ // Language: Javascript // Problem: https://leetcode.com/problems/power-of-two/ // Author: Chihung Yu +// Given an integer, write a function to determine if it is a power of two. + +// Credits: +// Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + +// Hide Company Tags Google +// Hide Tags Math Bit Manipulation +// Hide Similar Problems (E) Number of 1 Bits (E) Power of Three (E) Power of Four + + /** * @param {number} n * @return {boolean} diff --git a/253 Meeting Rooms II.js b/253 Meeting Rooms II.js index 47ea1d1..9355b30 100644 --- a/253 Meeting Rooms II.js +++ b/253 Meeting Rooms II.js @@ -44,7 +44,10 @@ var minMeetingRooms = function(intervals) { }; var data = [ + {start: 9, end: 12}, {start: 2, end: 7}, + {start: 5, end: 17}, + {start: 12, end: 17}, ] console.log(minMeetingRooms(data)); \ No newline at end of file diff --git a/278 First Bad Version.js b/278 First Bad Version.js new file mode 100644 index 0000000..7013caa --- /dev/null +++ b/278 First Bad Version.js @@ -0,0 +1,52 @@ +// You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad. + +// Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad. + +// You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API. + +// Credits: +// Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + +// Hide Company Tags Facebook +// Hide Tags Binary Search +// Hide Similar Problems (M) Search for a Range (M) Search Insert Position (E) Guess Number Higher or Lower + + +/** + * Definition for isBadVersion() + * + * @param {integer} version number + * @return {boolean} whether the version is bad + * isBadVersion = function(version) { + * ... + * }; + */ + +/** + * @param {function} isBadVersion() + * @return {function} + */ +var solution = function(isBadVersion) { + /** + * @param {integer} n Total versions + * @return {integer} The first bad version + */ + return function(n) { + var beg = 0; + var end = n; + var lastBad; + + while(beg <= end) { + var mid = beg + Math.floor((end - beg)/2); + if(isBadVersion(mid)) { + // everything including and after are bad version + lastBad = mid; + end = mid - 1; + } else { + beg = mid + 1; + } + } + + return lastBad; + }; +}; \ No newline at end of file diff --git a/285 Inorder Successor in BST.js b/285 Inorder Successor in BST.js new file mode 100644 index 0000000..e9f3430 --- /dev/null +++ b/285 Inorder Successor in BST.js @@ -0,0 +1,42 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @return {TreeNode} + */ +var inorderSuccessor = function(root, p) { + if(p.right) { // handle p = 14 or p = 27 + p = p.right; + while(p.left) { + p = p.left; + } + return p; + } + + // if p has no right child + + // 20 + // 10 25 + // 6 14 22 27 + // 1 9 + // 8 + + var succ = null; + while(root !== p) { + if(root.val > p.val) { // root is on the right hand side of p, handle case p = 1 + succ = root; + root = root.left; + } else if(root.val < p.val && root.right) { // handle case p = 8 + root = root.right; + } else { + break; + } + } + return succ; +}; \ No newline at end of file diff --git a/286 Walls and Gates.js b/286 Walls and Gates.js index f874a12..443aeed 100644 --- a/286 Walls and Gates.js +++ b/286 Walls and Gates.js @@ -19,8 +19,6 @@ // Show Tags // Show Similar Problems - - var wallsAndGates = function(rooms) { var gates = []; @@ -31,20 +29,15 @@ var wallsAndGates = function(rooms) { var rows = rooms.length; var cols = rooms[0].length; - // find all gates + for(var i = 0; i < rows; i++) { for(var j = 0; j < cols; j++) { + // find all gates if(rooms[i][j] === 0) { - gates.push([i, j]); + traverse(rooms, i, j, rows, cols, 0); } } } - - // starting from all gates and traverse - for(i = 0; i < gates.length; i++) { - var gate = gates[i]; - traverse(rooms, gate[0], gate[1], rows, cols, 0); - } }; function traverse(rooms, i, j, rows, cols, dist) { diff --git a/293 Flip Game.js b/293 Flip Game.js new file mode 100644 index 0000000..3521531 --- /dev/null +++ b/293 Flip Game.js @@ -0,0 +1,38 @@ +// You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive "++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner. + +// Write a function to compute all possible states of the string after one valid move. + +// For example, given s = "++++", after one move, it may become one of the following states: + +// [ +// "--++", +// "+--+", +// "++--" +// ] +// If there is no valid move, return an empty list []. + +// Hide Company Tags Google +// Hide Tags String +// Hide Similar Problems (M) Flip Game II + + +/** + * @param {string} s + * @return {string[]} + */ +var generatePossibleNextMoves = function(s) { + var result = []; + var arr = s.split(''); + + for(var i = 0; i < s.length - 1; i++) { + if(arr[i] === '+' && arr[i+1] === '+') { + arr[i] = '-'; + arr[i+1] = '-'; + result.push(arr.join('')); + arr[i] = '+'; + arr[i+1] = '+'; + } + } + + return result; +}; \ No newline at end of file diff --git a/294 Flip Game II.js b/294 Flip Game II.js new file mode 100644 index 0000000..7490041 --- /dev/null +++ b/294 Flip Game II.js @@ -0,0 +1,49 @@ +// You are playing the following Flip Game with your friend: Given a string that contains only these two characters: + and -, you and your friend take turns to flip two consecutive "++" into "--". The game ends when a person can no longer make a move and therefore the other person will be the winner. + +// Write a function to determine if the starting player can guarantee a win. + +// For example, given s = "++++", return true. The starting player can guarantee a win by flipping the middle "++" to become "+--+". + +// Follow up: +// Derive your algorithm's runtime complexity. + +// Hide Company Tags Google +// Hide Tags Backtracking +// Hide Similar Problems (E) Nim Game (E) Flip Game (M) Guess Number Higher or Lower II + + + +/** + * @param {string} s + * @return {boolean} + */ +var canWin = function(s) { + if(s === null || s.length === 0) { + return false; + } + + var arr = s.split(''); + + + // player 1 can guarantee win if the move player 1 made can lead to player 2 no win of winning + function checkCanWin(arr) { + for(var i = 0; i < arr.length - 1; i++) { + if(arr[i] === '+' && arr[i+1] === '+') { + arr[i] = arr[i+1] = '-'; + + var win = !checkCanWin(arr); + + arr[i] = arr[i+1] = '+'; + + if(win) { + return true; + } + } + } + + return false; + } + + + return checkCanWin(arr); +}; \ No newline at end of file diff --git a/300 Longest Increasing Subsequence.js b/300 Longest Increasing Subsequence.js index f222615..c3cfc89 100644 --- a/300 Longest Increasing Subsequence.js +++ b/300 Longest Increasing Subsequence.js @@ -36,4 +36,8 @@ var lengthOfLIS = function(nums) { } return Math.max.apply(null, dp); -}; \ No newline at end of file +}; + + + +console.log(Infinity < Infinity) \ No newline at end of file diff --git a/301 Remove Invalid Parentheses.js b/301 Remove Invalid Parentheses.js new file mode 100644 index 0000000..a2642e7 --- /dev/null +++ b/301 Remove Invalid Parentheses.js @@ -0,0 +1,79 @@ +// 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 ). + +// Examples: +// "()())()" -> ["()()()", "(())()"] +// "(a)())()" -> ["(a)()()", "(a())()"] +// ")(" -> [""] +// Credits: +// Special thanks to @hpplayer for adding this problem and creating all test cases. + +// Hide Company Tags Facebook +// Hide Tags Depth-first Search Breadth-first Search +// Hide Similar Problems (E) Valid Parentheses + + +/** + * @param {string} s + * @return {string[]} + */ + +function isValid(s) { + var count = 0; + + for(var i = 0; i < s.length; i++) { + if(s[i] === '(') { + count++; + } else if(s[i] === ')') { + count--; + } + + if(count < 0) { + return false; + } + } + + return count === 0; +} + +var removeInvalidParentheses = function(s) { + var queue = []; + queue.push(s); + var visited = {}; + var res = []; + var found = false; + + + // breadth first search since we are looking for the minimum changes + while(queue.length > 0) { + s = queue.shift(); + + // things stored in the queue represent the same level (same number of changes) + // once we found a valid one, we should not look further into the next level (by setting found to true) + if(isValid(s)) { + res.push(s); + found = true; + } + + if(found) { + continue; + } + + // if nothing found, then loop through the entire string and remove one of the parenthesis. + for(var i = 0; i < s.length; i++) { + if(s[i] !== '(' && s[i] !== ')') { + continue; + } + + var newS = s.substring(0,i) + s.substring(i + 1); + + if(!visited[newS]) { + visited[newS] = true; + queue.push(newS); + } + } + } + + return res; +}; \ No newline at end of file diff --git a/322 Coin Change.js b/322 Coin Change.js index 6626e84..33da65e 100644 --- a/322 Coin Change.js +++ b/322 Coin Change.js @@ -9,6 +9,7 @@ var coinChange = function(coins, amount) { dp.push(-1); } + for(var a = 0; a < amount; a++) { if(dp[a] < 0) { continue; @@ -21,11 +22,15 @@ var coinChange = function(coins, amount) { continue; } - if(dp[a + coin] < 0 || dp[a + coin] > dp[a] + 1) { - dp[a+coin] = dp[a] + 1; + // if(dp[a + coin] < 0 || dp[a + coin] > dp[a] + 1) { + if(dp[a + coin] < 0) { + dp[a + coin] = dp[a] + 1; } } } - + console.log(dp) + console.log(dp[amount]) return dp[amount]; -}; \ No newline at end of file +}; + +coinChange([1,2,5,10,25], 25); \ No newline at end of file diff --git a/334 Increasing Triplet Subsequence.js b/334 Increasing Triplet Subsequence.js new file mode 100644 index 0000000..ca96da9 --- /dev/null +++ b/334 Increasing Triplet Subsequence.js @@ -0,0 +1,41 @@ +// Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array. + +// Formally the function should: +// Return true if there exists i, j, k +// such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. +// Your algorithm should run in O(n) time complexity and O(1) space complexity. + +// Examples: +// Given [1, 2, 3, 4, 5], +// return true. + +// Given [5, 4, 3, 2, 1], +// return false. + +// Credits: +// Special thanks to @DjangoUnchained for adding this problem and creating all test cases. + +// Hide Company Tags Facebook +// Hide Similar Problems (M) Longest Increasing Subsequence + + +/** + * @param {number[]} nums + * @return {boolean} + */ +var increasingTriplet = function(nums) { + var min1 = Infinity; + var min2 = Infinity; + + for(var i = 0; i < nums.length; i++) { + if(nums[i] <= min1) { + min1 = nums[i]; + } else if(nums[i] <= min2) { + min2 = nums[i]; + } else { + return true; + } + } + + return false; +}; \ No newline at end of file diff --git a/338 Count Bits.js b/338 Count Bits.js new file mode 100644 index 0000000..ffea316 --- /dev/null +++ b/338 Count Bits.js @@ -0,0 +1,36 @@ +// Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. + +// Example: +// For num = 5 you should return [0,1,1,2,1,2]. + +// Follow up: + +// It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass? +// Space complexity should be O(n). +// Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language. +// Show Hint +// Credits: +// Special thanks to @ syedee for adding this problem and creating all test cases. + +// Hide Tags Dynamic Programming Bit Manipulation +// Hide Similar Problems (E) Number of 1 Bits + + + +var countBits = function(num) { + var ans = [0]; + + for(var i = 1; i <= num; i++) { + ans[i] = (ans[i] || 0) + ans[i&(i-1)] + 1; + } + + return ans; +}; + +// 0 0 0 1 +// 0 0 1 0 +// 0 0 1 1 +// 0 1 0 0 + + +console.log(countBits(3)); \ No newline at end of file diff --git a/341 Flatten Nested List Iterator.js b/341 Flatten Nested List Iterator.js new file mode 100644 index 0000000..c82b569 --- /dev/null +++ b/341 Flatten Nested List Iterator.js @@ -0,0 +1,95 @@ +// Given a nested list of integers, implement an iterator to flatten it. + +// Each element is either an integer, or a list -- whose elements may also be integers or other lists. + +// Example 1: +// Given the list [[1,1],2,[1,1]], + +// By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1]. + +// Example 2: +// Given the list [1,[4,[6]]], + +// By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6]. + +// Hide Company Tags Google Facebook Twitter +// Hide Tags Stack Design +// Hide Similar Problems (M) Flatten 2D Vector (M) Zigzag Iterator + + + +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * function NestedInteger() { + * + * Return true if this NestedInteger holds a single integer, rather than a nested list. + * @return {boolean} + * this.isInteger = function() { + * ... + * }; + * + * Return the single integer that this NestedInteger holds, if it holds a single integer + * Return null if this NestedInteger holds a nested list + * @return {integer} + * this.getInteger = function() { + * ... + * }; + * + * Return the nested list that this NestedInteger holds, if it holds a nested list + * Return null if this NestedInteger holds a single integer + * @return {NestedInteger[]} + * this.getList = function() { + * ... + * }; + * }; + */ +/** + * @constructor + * @param {NestedInteger[]} nestedList + */ +var NestedIterator = function(nestedList) { + this.stack = []; + + for(var i = nestedList.length; i--;) { + this.stack.push(nestedList[i]); + } +}; + + +/** + * @this NestedIterator + * @returns {boolean} + */ +NestedIterator.prototype.hasNext = function() { + // keep looping until we found insert an integer in the stack + while(this.stack.length > 0) { + var next = this.stack[this.stack.length - 1]; + + if(next.isInteger()) { + return true; + } + + this.stack.pop(); + var list = next.getList(); + for(var i = list.length; i--;) { + this.stack.push(list[i]); + } + } + + return false; +}; + +/** + * @this NestedIterator + * @returns {integer} + */ +NestedIterator.prototype.next = function() { + return this.stack.pop(); +}; + +/** + * Your NestedIterator will be called like this: + * var i = new NestedIterator(nestedList), a = []; + * while (i.hasNext()) a.push(i.next()); +*/ \ No newline at end of file diff --git a/353 Design Snake Game.js b/353 Design Snake Game.js new file mode 100644 index 0000000..cb16940 --- /dev/null +++ b/353 Design Snake Game.js @@ -0,0 +1,157 @@ +// Design a Snake game that is played on a device with screen size = width x height. Play the game online if you are not familiar with the game. + +// The snake is initially positioned at the top left corner (0,0) with length = 1 unit. + +// You are given a list of food's positions in row-column order. When a snake eats the food, its length and the game's score both increase by 1. + +// Each food appears one by one on the screen. For example, the second food will not appear until the first food was eaten by the snake. + +// When a food does appear on the screen, it is guaranteed that it will not appear on a block occupied by the snake. + +// Example: +// Given width = 3, height = 2, and food = [[1,2],[0,1]]. + +// Snake snake = new Snake(width, height, food); + +// Initially the snake appears at position (0,0) and the food at (1,2). + +// |S| | | +// | | |F| + +// snake.move("R"); -> Returns 0 + +// | |S| | +// | | |F| + +// snake.move("D"); -> Returns 0 + +// | | | | +// | |S|F| + +// snake.move("R"); -> Returns 1 (Snake eats the first food and right after that, the second food appears at (0,1) ) + +// | |F| | +// | |S|S| + +// snake.move("U"); -> Returns 1 + +// | |F|S| +// | | |S| + +// snake.move("L"); -> Returns 2 (Snake eats the second food) + +// | |S|S| +// | | |S| + +// snake.move("U"); -> Returns -1 (Game over because snake collides with border) + +// Credits: +// Special thanks to @elmirap for adding this problem and creating all test cases. + +// Hide Company Tags Google +// Hide Tags Design Queue + + + +public class SnakeGame { + + /** Initialize your data structure here. + @param width - screen width + @param height - screen height + @param food - A list of food positions + E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. */ + + private Set board = new HashSet<>(); + private int[][] food; + private int eat = 0; + private LinkedList snake = new LinkedList<>(); + private int width, height; + + + private boolean eat(int y, int x) { + if(eat >= food.length) { + return false; + } + if(food[eat][0] < 0 || food[eat][0] >= height || food[eat][1] <0 || food[eat][1] >= width) { + return false; + } + if(y == food[eat][0] && x == food[eat][1]) { + return true; + } + + return false; + } + + + public SnakeGame(int width, int height, int[][] food) { + this.food = food; + Position head = new Position(0,0); + this.snake.add(head); + board.add(head.toString()); + this.height = height; + this.width = width; + } + + /** Moves the snake. + @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down + @return The game's score after the move. Return -1 if game over. + Game over when snake crosses the screen boundary or bites its body. */ + public int move(String direction) { + Position head = snake.getFirst(); + Position next = new Position(head.y, head.x); + + if("U".equals(direction)) { + next.y--; + } else if("D".equals(direction)) { + next.y++; + } else if("L".equals(direction)) { + next.x--; + } else if("R".equals(direction)) { + next.x++; + } else { + return -1; + } + + if(next.y < 0 || next.y >= height || next.x < 0 || next.x >= width) { + return -1; + } + + String ns = next.toString(); + if(eat(next.y, next.x)) { + snake.addFirst(next); + board.add(ns); + return ++eat; + } + + Position tail = snake.getLast(); + board.remove(tail.toString()); + snake.removeLast(); + + if(board.contains(ns)) { + return -1; + } + + snake.addFirst(next); + board.add(ns); + return eat; + } +} + +class Position { + int x, y; + + Position(int y, int x) { + this.y = y; + this.x = x; + } + + public String toString() { + return y + "," + x; + } +} + +/** + * Your SnakeGame object will be instantiated and called as such: + * SnakeGame obj = new SnakeGame(width, height, food); + * int param_1 = obj.move(direction); + */ \ No newline at end of file diff --git a/366 Find Leaves of Binary Tree.js b/366 Find Leaves of Binary Tree.js new file mode 100644 index 0000000..21f1ed8 --- /dev/null +++ b/366 Find Leaves of Binary Tree.js @@ -0,0 +1,71 @@ +// Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves, repeat until the tree is empty. + +// Example: +// Given binary tree +// 1 +// / \ +// 2 3 +// / \ +// 4 5 +// Returns [4, 5, 3], [2], [1]. + +// Explanation: +// 1. Removing the leaves [4, 5, 3] would result in this tree: + +// 1 +// / +// 2 +// 2. Now removing the leaf [2] would result in this tree: + +// 1 +// 3. Now removing the leaf [1] would result in the empty tree: + +// [] +// Returns [4, 5, 3], [2], [1]. + +// Credits: +// Special thanks to @elmirap for adding this problem and creating all test cases. + +// Hide Company Tags LinkedIn +// Hide Tags Tree Depth-first Search + + + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ +var findLeaves = function(root) { + var result = []; + + while(root) { + var leaves = [] + root = removeLeaves(root, leaves); + result.push(leaves); + } + + return result; +}; + +function removeLeaves(node, leaves) { + if(!node) { + return null; + } + + if(!node.left && !node.right) { + leaves.push(node.val); + return null; + } + + node.left = removeLeaves(node.left, leaves); + node.right = removeLeaves(node.right, leaves); + + return node; +} \ No newline at end of file diff --git a/39 Combination Sum.js b/39 Combination Sum.js index c7e0fa2..e8214d3 100644 --- a/39 Combination Sum.js +++ b/39 Combination Sum.js @@ -1,3 +1,22 @@ +// Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. + +// The same repeated number may be chosen from C unlimited number of times. + +// Note: +// All numbers (including target) will be positive integers. +// The solution set must not contain duplicate combinations. +// For example, given candidate set [2, 3, 6, 7] and target 7, +// A solution set is: +// [ +// [7], +// [2, 2, 3] +// ] +// Hide Company Tags Snapchat Uber +// Hide Tags Array Backtracking +// Hide Similar Problems (M) Letter Combinations of a Phone Number (M) Combination Sum II (M) Combinations (M) Combination Sum III (M) Factor Combinations (M) Combination Sum IV + + + /** * @param {number[]} candidates * @param {number} target diff --git a/40 combination Sum II.js b/40 combination Sum II.js index 2e79154..00a4439 100644 --- a/40 combination Sum II.js +++ b/40 combination Sum II.js @@ -1,3 +1,23 @@ +// Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. + +// Each number in C may only be used once in the combination. + +// Note: +// All numbers (including target) will be positive integers. +// The solution set must not contain duplicate combinations. +// For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, +// A solution set is: +// [ +// [1, 7], +// [1, 2, 5], +// [2, 6], +// [1, 1, 6] +// ] +// Hide Tags Array Backtracking +// Hide Similar Problems (M) Combination Sum + + + /** * @param {number[]} candidates * @param {number} target @@ -12,8 +32,6 @@ var combinationSum2 = function(candidates, target) { var output = []; candidates.sort(function(a,b){return a > b ? 1 : -1;}); - - console.log('c',candidates); generate(candidates, target, 0, result, output); return result; @@ -25,19 +43,17 @@ var generate = function(c, t, index, result, output){ } if(t === 0){ result.push(output.slice()); - console.log(output) return } - for(var i = index; i index && c[i] === c[i-1]) { + continue; + } var val = c[i]; - + output.push(val); - generate(c, t - val, i+1, result, output); + generate(c, t - val, i + 1, result, output); output.pop(); - - while(i < (c.length - 1) && c[i] === c[i+1]){ - i++; - } } } \ No newline at end of file diff --git a/57. Insert Interval.js b/57. Insert Interval.js index e5a68a7..7f23e5e 100644 --- a/57. Insert Interval.js +++ b/57. Insert Interval.js @@ -46,13 +46,11 @@ var insert = function(intervals, newInterval) { result.push(newInterval); result.push(interval); isInsert = true; - } else if(newInterval.start <= interval.end && interval.start <= newInterval.end){ - + } else if(interval.end < newInterval.start) { + result.push(interval); + } else { newInterval.start = Math.min(newInterval.start, interval.start); newInterval.end = Math.max(newInterval.end, interval.end); - continue; - } else { - result.push(interval); } } diff --git a/67 Add Binary.js b/67 Add Binary.js index 3685410..9a30aa6 100644 --- a/67 Add Binary.js +++ b/67 Add Binary.js @@ -1,3 +1,15 @@ +// Given two binary strings, return their sum (also a binary string). + +// For example, +// a = "11" +// b = "1" +// Return "100". + +// Hide Company Tags Facebook +// Hide Tags Math String +// Hide Similar Problems (M) Add Two Numbers (M) Multiply Strings (E) Plus One + + /** * @param {string} a * @param {string} b @@ -6,19 +18,20 @@ var addBinary = function(a, b) { var lenA = a.length; var lenB = b.length; + var ai = 0; + var bi = 0; + var sum = ''; var carry = 0; - var result = ''; - var maxLen = Math.max(lenA, lenB); - - for(var i = 0; i < maxLen; i++){ - - var p = parseInt(a[lenA - i - 1] || '0'); - var q = parseInt(b[lenB - i - 1] || '0'); - - var tmp = p + q + carry; - result = tmp%2 + result; - carry = parseInt(tmp/2); + while(ai < lenA || bi < lenB) { + var valA = ai < lenA ? parseInt(parseInt(a[lenA - 1 - ai])) : 0; + var valB = bi < lenB ? parseInt(parseInt(b[lenB - 1 - bi])) : 0; + var val = valA + valB + carry; + var rem = val%2; + carry = val > 1 ? 1 : 0; + sum = rem + sum; + ai++; + bi++; } - return (carry === 0) ? result : '1' + result; + return carry > 0 ? carry + sum : sum; }; \ No newline at end of file diff --git a/72 Edit Distance.js b/72 Edit Distance.js index ffc2dd4..f6099c7 100644 --- a/72 Edit Distance.js +++ b/72 Edit Distance.js @@ -1,3 +1,17 @@ +// reference: https://www.youtube.com/watch?v=We3YDTzNXEk + +// Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) + +// You have the following 3 operations permitted on a word: + +// a) Insert a character +// b) Delete a character +// c) Replace a character +// Hide Tags Dynamic Programming String +// Hide Similar Problems (M) One Edit Distance + + + /** * @param {string} word1 * @param {string} word2 diff --git a/75 Sort Colors.js b/75 Sort Colors.js index 7a26698..09b3db1 100644 --- a/75 Sort Colors.js +++ b/75 Sort Colors.js @@ -1,29 +1,43 @@ +// Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. + +// Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. + +// Note: +// You are not suppose to use the library's sort function for this problem. + +// click to show follow up. + +// Hide Company Tags Pocket Gems Microsoft Facebook +// Hide Tags Array Two Pointers Sort +// Hide Similar Problems (M) Sort List (M) Wiggle Sort (M) Wiggle Sort II + /** * @param {number[]} nums * @return {void} Do not return anything, modify nums in-place instead. */ - var sortColors = function(nums) { var redIndex = 0; var blueIndex = nums.length - 1; - var i = 0 - - while(i <= blueIndex){ - if(nums[i] === 0){ - swap(nums, i, redIndex); - i++; // [!!!] if swap with latter colors do not i++ + var red = 0; + var blue = 2; + + for(var i = 0; i <= blueIndex; i++) { + if(nums[i] === red) { + swap(nums, redIndex, i); redIndex++; - } else if(nums[i] === 2){ - swap(nums, i, blueIndex); + } else if(nums[i] === blue) { + swap(nums, blueIndex, i); blueIndex--; - } else { - i++; + i--; } } }; -var swap = function(arr, i, j){ - var temp = arr[i]; +function swap(arr, i, j) { + if(i === j) { + return; + } + var tmp = arr[i]; arr[i] = arr[j]; - arr[j] = temp; + arr[j] = tmp; } \ No newline at end of file diff --git a/79 Word Search.js b/79 Word Search.js new file mode 100644 index 0000000..589eabd --- /dev/null +++ b/79 Word Search.js @@ -0,0 +1,60 @@ +// Given a 2D board and a word, find if the word exists in the grid. + +// The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. + +// For example, +// Given board = + +// [ +// ['A','B','C','E'], +// ['S','F','C','S'], +// ['A','D','E','E'] +// ] +// word = "ABCCED", -> returns true, +// word = "SEE", -> returns true, +// word = "ABCB", -> returns false. +// Hide Company Tags Microsoft Bloomberg Facebook +// Hide Tags Array Backtracking +// Hide Similar Problems (H) Word Search II + + +var exist = function(board, word) { + var hash = {}; + + for(var i = 0; i < board.length; i++) { + for(var j = 0; j < board[0].length; j++) { + if(dfs(board, word, 0, i, j)) { + return true; + } + } + } + + function dfs(board, word, w, i, j) { + var key = i + ',' + j; + if(hash[key]) { + return false; + } + + if(w === word.length) { + return true; + } + + if(i < 0 || i >= board.length || j < 0 || j >= board[0].length) { + return false; + } + + var result = false; + + if(word[w] === board[i][j]) { + hash[key] = true; + + result = dfs(board, word, w + 1, i+1, j) || dfs(board, word, w + 1, i-1, j) || dfs(board, word, w + 1, i, j+1) || dfs(board, word, w + 1, i, j-1); + + hash[key] = false; + } + + return result + } + + return false; +}; \ No newline at end of file diff --git a/80 Remove Duplicates from Sorted Array II.js b/80 Remove Duplicates from Sorted Array II.js index 731b272..dd04593 100644 --- a/80 Remove Duplicates from Sorted Array II.js +++ b/80 Remove Duplicates from Sorted Array II.js @@ -1,3 +1,18 @@ +// Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. + +// Do not allocate extra space for another array, you must do this in place with constant memory. + +// For example, +// Given input array nums = [1,1,2], + +// Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + +// Hide Company Tags Microsoft Bloomberg Facebook +// Hide Tags Array Two Pointers +// Hide Similar Problems (E) Remove Element + + + /** * @param {number[]} nums * @return {number} @@ -22,4 +37,13 @@ var removeDuplicates = function(nums) { } return index + 1; -}; \ No newline at end of file +}; + + + +161700 + +70000 rsu => $538,000 4yrs 1 yr cliff 25% every quarter + +benefit + diff --git a/84 Largest Rectangle in Histogram.js b/84 Largest Rectangle in Histogram.js new file mode 100644 index 0000000..710a9c0 --- /dev/null +++ b/84 Largest Rectangle in Histogram.js @@ -0,0 +1,64 @@ +// Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. + + +// Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. + + +// The largest rectangle is shown in the shaded area, which has area = 10 unit. + +// For example, +// Given heights = [2,1,5,6,2,3], +// return 10. + +// Hide Tags Array Stack +// Hide Similar Problems (H) Maximal Rectangle + + + +// reference: http://www.cnblogs.com/lichen782/p/leetcode_Largest_Rectangle_in_Histogram.html + +/** + * @param {number[]} heights + * @return {number} + */ +var largestRectangleArea = function(heights) { + var maxArea = 0; + + if(heights === null || heights.length === 0) { + return maxArea; + } + + var stack = []; + var i = 0; + + while(i <= heights.length) { + // Keep stack height in increasing order + // stack store the height index not the height + // everytime we encounter height smaller than the max height in the stack, we calculate area and pop + // height index in the stack until stack is empty or we found height smaller than the current height in the stack. + // taking [2,1,5,6,2,3] for example + // 2, then we encounter 1, it means anything after 1 will not yield rectangle with height greater than 1 since they all got throttle by 1 + // stack will look like + // 1. [2] + // 2. we calculate area 2*1, i is at index 0 and i is at 1 (1-0)*height(2) = 2 + // 3. [1] + // 4. [1,5] + // 5. [1,5,6] + // we calculate area 6*1, i is at index 4 and height 6 is at index 1 (4-3)*height(6) = 6 + // 6. [1,5] + // we calculate area 5*2, i is at index 4 and height 5 is at index 2 (4-2)*height(5) = 10 + // 7. [1,2] + // 8. [1,2,3] + // etc... + + if(stack.length === 0 || heights[stack[stack.length - 1]] <= heights[i]) { + stack.push(i++); + } else { + var height = heights[stack.pop()]; + var width = stack.length === 0 ? i : i - stack[stack.length - 1] - 1; + maxArea = Math.max(height*width, maxArea); + } + } + + return maxArea; +}; \ No newline at end of file diff --git a/85 Maximal Rectangle.js b/85 Maximal Rectangle.js new file mode 100644 index 0000000..f30bce3 --- /dev/null +++ b/85 Maximal Rectangle.js @@ -0,0 +1,89 @@ +// Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area. + +// For example, given the following matrix: + +// 1 0 1 0 0 +// 1 0 1 1 1 +// 1 1 1 1 1 +// 1 0 0 1 0 +// Return 6. +// Hide Company Tags Facebook +// Hide Tags Array Hash Table Stack Dynamic Programming +// Hide Similar Problems (H) Largest Rectangle in Histogram (M) Maximal Square + + +/** + * @param {character[][]} matrix + * @return {number} + */ +var maximalRectangle = function(matrix) { + if(matrix === null || matrix.length === 0 || matrix[0].length === 0) { + return 0; + } + var heights = []; + + var maxArea = 0; + for(var x = 0; x < matrix.length; x++) { + var height = Array(matrix[0].length).fill(0); + heights.push(height); + for(var y = 0; y < matrix[0].length; y++) { + if(matrix[x][y] === '1') { + if(x === 0) { + heights[x][y] = 1; + } else { + heights[x][y] = heights[x-1][y] + 1; + } + } + } + + maxArea = Math.max(maxArea, largestRectangleArea(heights[x])); + } + + return maxArea; +}; + + +var largestRectangleArea = function(heights) { + var maxArea = 0; + + if(heights === null || heights.length === 0) { + return maxArea; + } + + var stack = []; + var i = 0; + + while(i <= heights.length) { + // Keep stack height in increasing order + // stack store the height index not the height + // everytime we encounter height smaller than the max height in the stack, we calculate area and pop + // height index in the stack until stack is empty or we found height smaller than the current height in the stack. + // taking [2,1,5,6,2,3] for example + // 2, then we encounter 1, it means anything after 1 will not yield rectangle with height greater than 1 since they all got throttle by 1 + // stack will look like + // 1. [2] + // 2. we calculate area 2*1, i is at index 0 and i is at 1 (1-0)*height(2) = 2 + // 3. [1] + // 4. [1,5] + // 5. [1,5,6] + // we calculate area 6*1, i is at index 4 and height 6 is at index 1 (4-3)*height(6) = 6 + // 6. [1,5] + // we calculate area 5*2, i is at index 4 and height 5 is at index 2 (4-2)*height(5) = 10 + // 7. [1,2] + // 8. [1,2,3] + // etc... + + if(stack.length === 0 || heights[stack[stack.length - 1]] <= heights[i]) { + stack.push(i++); + } else { + var height = heights[stack.pop()]; + var width = stack.length === 0 ? i : i - stack[stack.length - 1] - 1; + maxArea = Math.max(height*width, maxArea); + } + } + + return maxArea; +}; + +var matrix = ["10100","10111","11111","10010"] +maximalRectangle(matrix); \ No newline at end of file diff --git a/95 Unique Binary Search Trees II.js b/95 Unique Binary Search Trees II.js new file mode 100644 index 0000000..4699a9f --- /dev/null +++ b/95 Unique Binary Search Trees II.js @@ -0,0 +1,84 @@ +// Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. + +// For example, +// Given n = 3, your program should return all 5 unique BST's shown below. + +// 1 3 3 2 1 +// \ / / / \ \ +// 3 2 1 1 3 2 +// / / \ \ +// 2 1 2 3 +// Hide Tags Tree Dynamic Programming +// Hide Similar Problems (M) Unique Binary Search Trees (M) Different Ways to Add Parentheses + + + + + +/** +Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. + +For example, +Given n = 3, your program should return all 5 unique BST's shown below. + + 1 3 3 2 1 + \ / / / \ \ + 3 2 1 1 3 2 + / / \ \ + 2 1 2 3 +confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. +*/ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {number} n + * @return {TreeNode[]} + */ +var generateTrees = function(n) { + if (n === 0) { + return []; + } + + return genTreeHelper(1, n); +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +function genTreeHelper(start, end) { + var result = []; + + if (start > end) { + return [null]; + } + + + + for (var i = start; i <= end; i++) { + // let node i becomes the center node and generate it's left and right nodes + var left = genTreeHelper(start, i - 1); + var right = genTreeHelper(i + 1, end); + for (var k = 0; k < left.length; k++) { + for (var j = 0; j < right.length; j++) { + var node = new TreeNode(i); + node.left = left[k]; + node.right = right[j]; + result.push(node); + } + } + } + + return result; +} + + + + +console.log(generateTrees(2)); \ No newline at end of file diff --git a/Longest Common Subsequence.js b/Longest Common Subsequence.js new file mode 100644 index 0000000..0717f81 --- /dev/null +++ b/Longest Common Subsequence.js @@ -0,0 +1,27 @@ +// https://www.youtube.com/watch?v=NnD96abizww + + +function longestCommonSubsequence(str1, str2) { + var dp = []; + + for(var i = 0 ; i <= str1.length; i++) { + dp.push([]); + for(var j = 0; j <= str2.length; j++) { + dp[i].push(0); + } + } + + var result = []; + + for(i = 1 ; i <= str1.length; i++) { + for(j = 1; j <= str2.length; j++) { + if(str1[i-1] === str2[j-1]) { + dp[i][j] = dp[i-1][j-1] + 1; + } else { + dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]); + } + } + } + + return dp[str1.length][str2.length]; +} \ No newline at end of file diff --git a/Matrix Diagonal Traversal.js b/Matrix Diagonal Traversal.js new file mode 100644 index 0000000..ee55f6e --- /dev/null +++ b/Matrix Diagonal Traversal.js @@ -0,0 +1,82 @@ +// Print a N x M matrix in diagonal from the upper left to lower right. +// However, with the following caveat. +// It's easy to just show the input and expect output. +// matrix: [ +// 'abc', +// 'defg', +// 'hijk' +// ] +// output: aej bfk cg di h + + +// matrix: [ +// 'abc', +// 'defgsb', +// 'hijk' +// ] +// output: aej bfk cg s b di h + +function matrixDiagonalTraversal(matrix) { + var maxLen = 0; + for(var i = 0; i < matrix.length; i++) { + maxLen = Math.max(matrix[i].length, maxLen); + } + + for(i = 0; i < matrix.length; i++) { + var row = matrix[i]; + var cnt = maxLen - row.length; + + while(cnt > 0) { + matrix[i] += ' '; + cnt--; + } + + var leftStr = matrix[i].substring(i); + + var reversedRightStr = ''; + cnt = i; + + while(cnt > 0) { + reversedRightStr += matrix[i][--cnt]; + } + + matrix[i] = leftStr + reversedRightStr; + } + + var result = ''; + + for(i = 0; i < maxLen; i++) { + for(var j = 0; j < matrix.length; j++) { + if(matrix[j][i] !== ' ') { + result += matrix[j][i]; + } + } + } + + return result; +} + + + + +console.log(matrixDiagonalTraversal([ + 'abc', + 'defgsb', + 'hijk', + 'lm', + 'nopq' +])); + + +'abc___' +'deggsb' +'hijk__' +'lm____' +'nopq__' + + +'abc___' +'efgsbd' +'jk__ih' +'____ml' +'__qpon' \ No newline at end of file diff --git a/README.md b/README.md index f130219..a7347ec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Leetcode Problems and interview problems in Javascript - -- 1 Two Sum.js +- - 10 Regular Expresion Matching.js - 100 Same Tree.js - 101 Symmetric Tree.js @@ -17,6 +16,8 @@ - 112 Path Sum.js - 114 Flatten Binary Tree to Linked List.js - 116 Populating Next Right Pointers in Each Node.js +- 117 Populating Next Right Pointer.js +- 117 Populating Next Right Pointers in Each Node II.js - 118 Pascal's Triangle.js - 119 Pascal's Triangle II.js - 12 Integer to Roman.js @@ -25,6 +26,7 @@ - 122 Best Time to Buy and Sell Stock II.js - 123 Best Time to Buy and Sell Stock III.js - 124 Binary Tree Maximum Path Sum.js +- 125 Valid Palindrome.js - 126 Word Ladder II.js - 127 Word Ladder.js - 129 Sum Root to Leaf Numbers.js @@ -42,6 +44,7 @@ - 145 Binary Tree Post Order Traversal.js - 146 LRU Cache.js - 148 Sort List.js +- 149 Max Points on a Line.js - 15 3Sum.js - 150 Evaluate Reverse Polish Notation.js - 151 Reverse Words in a String.js @@ -52,6 +55,7 @@ - 159 Longest Substring with At Most Two Disctinct Characters.js - 16 3Sum Closest.js - 160 Intersection Of Two Linked Lists.js +- 161 One Edit Distance.js - 162 Find Peak Element.js - 165 Compare Version Numbers.js - 166 Fraction to Recurring Decimal.js @@ -87,12 +91,15 @@ - 21 Merge Two Sorted Lists.js - 210 Course Schedule II.js - 211 Add and Search Word - Data structure design.js +- 212 Word Search II.js - 213 House Robber II.js - 215 Kth Largest Element in an Array.js +- 215 Kth Largest Element in an Array.py - 217 Contain Duplicate.js - 219 Contains Duplicate II.js - 22 Generate Parentheses.js - 220 Contains Duplicate III.js +- 221 Maximal Square.js - 222. Count Complete Tree Nodes.js - 223 Rectangle Area.js - 224 Basic Calculator.js @@ -134,16 +141,21 @@ - 269 Alien Dictionary.js - 27 Remove Element.js - 277 Find the Celebrity.js +- 278 First Bad Version.js - 279. Perfect Squares.js - 28 Implement strStr().js - 283 Move Zeroes.js +- 285 Inorder Successor in BST.js - 286 Walls and Gates.js - 289. Game of Life.js +- 293 Flip Game.js +- 294 Flip Game II.js - 295 Find Median From Data Stream.js - 296 Best Meeting Point.js - 297 Serialize and Deserialize Binary Tree My Submissions Question.js - 3 Longest Substring Without Repeating Characters.js - 300 Longest Increasing Subsequence.js +- 301 Remove Invalid Parentheses.js - 307 Range Sum Query - Mutable.js - 31 Next Permutation.js - 314 Binary Tree Vertical Order Traversal.js @@ -152,16 +164,22 @@ - 320 Generalized Abbreviation.js - 322 Coin Change.js - 33 Search in Rotated Sorted Array.js +- 334 Increasing Triplet Subsequence.js - 335 Self Crossing.js - 337 House Robber III.js +- 338 Count Bits.js - 339 Nested List Weight Sum.js - 34 Search for a Range.js - 340 Longest Substring With At Most K Distinct Characters.js +- 341 Flatten Nested List Iterator.js +- 348. Design Tic-Tac-Toe.java - 349 Intersection of Two Arrays.js - 35 Search Insert Position.js - 350 Intersection of Two Arrays II.js +- 353 Design Snake Game.js - 36 Valid Sudoku.js - 364 Nested List Weight Sum II.js +- 366 Find Leaves of Binary Tree.js - 367 Valid Perfect Square.js - 37 Sudoku Solver.js - 371 Sum of Two Integers.js @@ -204,11 +222,14 @@ - 76 Minimum Window Substring.js - 77 Combinations.js - 78 Subsets.js +- 79 Word Search.js - 8 String to Integer (atoi).js - 80 Remove Duplicates from Sorted Array II.js - 81 Search in Rotated Sorted Array II.js - 82 Remove Duplicates from Sorted List II.js - 83 Remove Duplicates from Sorted List.js +- 84 Largest Rectangle in Histogram.js +- 85 Maximal Rectangle.js - 86 Partition List.js - 88 Merge Sorted Array.js - 89 Gray Code.js @@ -218,6 +239,7 @@ - 92 Reverse Linked List II.js - 93 Restore IP Addresses.js - 94 Binary Tree Inorder Traversal.js +- 95 Unique Binary Search Trees II.js - 96 Unique Binary Search Trees.js - 98 Validate Binary Search Tree.js - Basic Calculator II.js @@ -234,18 +256,23 @@ - Find Duplicate Files.js - Javascript Closure Questions.js - Log Hits.js +- Longest Common Subsequence.js +- Matrix Diagonal Traversal.js - Maximum Sum Rectangular Submatrix in Matrix Dynamic Programming:2D.js - Merge Two Lists Into Sorted List.js - Min CPU Count.js - Parse HTML.js - Parse Log Top k Longest Running Job.js - Parse String Into Array.js +- README.md - Ransom Note From Magazine.js - Rate Limiter.js - Reverse Integer.js - Snake And Ladder.js - String Encoding and Decoding.js - Top k Longest Running Job.js +- URL shortening.js +- Weighted Job Scheduling.js - ZigZag Conversion.js - find kth element in two arrays.js -- flatten nested array.js \ No newline at end of file +- flatten nested array.js diff --git a/URL shortening.js b/URL shortening.js new file mode 100644 index 0000000..078fe71 --- /dev/null +++ b/URL shortening.js @@ -0,0 +1,30 @@ +// http://www.hiredintech.com/system-design/the-system-design-process/ + + + + + +Use Cases: + +1. shortening: take url => return a shorter url +2. redirection: take a short url => redirect to the original url + +high availability of the system + +traffic? + +how many request per sec? +how many new url per sec? + +10% shortening 90% from redirection + +data? + + + +out of scope +3. custom url +4. analytics +5. automatic link expriation +6. manual link removal +7. UI vs API \ No newline at end of file diff --git a/Weighted Job Scheduling.js b/Weighted Job Scheduling.js new file mode 100644 index 0000000..3fe5a14 --- /dev/null +++ b/Weighted Job Scheduling.js @@ -0,0 +1,88 @@ +// C++ program for weighted job scheduling using Dynamic +// Programming and Binary Search +#include +#include +using namespace std; + +// A job has start time, finish time and profit. +struct Job +{ + int start, finish, profit; +}; + +// A utility function that is used for sorting events +// according to finish time +bool myfunction(Job s1, Job s2) +{ + return (s1.finish < s2.finish); +} + +// A Binary Search based function to find the latest job +// (before current job) that doesn't conflict with current +// job. "index" is index of the current job. This function +// returns -1 if all jobs before index conflict with it. +// The array jobs[] is sorted in increasing order of finish +// time. +int binarySearch(Job jobs[], int index) +{ + // Initialize 'lo' and 'hi' for Binary Search + int lo = 0, hi = index - 1; + + // Perform binary Search iteratively + while (lo <= hi) + { + int mid = (lo + hi) / 2; + if (jobs[mid].finish <= jobs[index].start) + { + if (jobs[mid + 1].finish <= jobs[index].start) + lo = mid + 1; + else + return mid; + } + else + hi = mid - 1; + } + + return -1; +} + +// The main function that returns the maximum possible +// profit from given array of jobs +int findMaxProfit(Job arr[], int n) +{ + // Sort jobs according to finish time + sort(arr, arr+n, myfunction); + + // Create an array to store solutions of subproblems. table[i] + // stores the profit for jobs till arr[i] (including arr[i]) + int *table = new int[n]; + table[0] = arr[0].profit; + + // Fill entries in table[] using recursive property + for (int i=1; i Date: Sun, 7 Aug 2016 21:21:41 -0700 Subject: [PATCH 22/47] add more solutions --- 173 Binary Search Tree Iterator.js | 15 ++++ 209 Minimum Size Subarray Sum.js | 56 +++++++++---- 282 Expression Add Operators.js | 52 ++++++++++++ 311 Sparse Matrix Multiplication.js | 97 +++++++++++++++++++++++ 325 Maximum Size Subarray Sum Equals k.js | 44 ++++++++++ 43 Multiply Strings.js | 54 +++++++------ 6 files changed, 281 insertions(+), 37 deletions(-) create mode 100644 282 Expression Add Operators.js create mode 100644 311 Sparse Matrix Multiplication.js create mode 100644 325 Maximum Size Subarray Sum Equals k.js diff --git a/173 Binary Search Tree Iterator.js b/173 Binary Search Tree Iterator.js index 26535de..08de1f2 100644 --- a/173 Binary Search Tree Iterator.js +++ b/173 Binary Search Tree Iterator.js @@ -1,3 +1,18 @@ +// Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. + +// Calling next() will return the next smallest number in the BST. + +// Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. + +// Credits: +// Special thanks to @ts for adding this problem and creating all test cases. + +// Hide Company Tags LinkedIn Google Facebook Microsoft +// Hide Tags Tree Stack Design +// Hide Similar Problems (M) Binary Tree Inorder Traversal (M) Flatten 2D Vector (M) Zigzag Iterator (M) Peeking Iterator (M) Inorder Successor in BST + + + /** * Definition for binary tree * function TreeNode(val) { diff --git a/209 Minimum Size Subarray Sum.js b/209 Minimum Size Subarray Sum.js index 7fc3302..ae6b33e 100644 --- a/209 Minimum Size Subarray Sum.js +++ b/209 Minimum Size Subarray Sum.js @@ -1,30 +1,58 @@ // http://blog.csdn.net/lisonglisonglisong/article/details/45666975 +// http://www.cnblogs.com/grandyang/p/4501934.html + +// Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn't one, return 0 instead. + +// For example, given the array [2,3,1,2,4,3] and s = 7, +// the subarray [4,3] has the minimal length under the problem constraint. + +// click to show more practice. + +// Credits: +// Special thanks to @Freezen for adding this problem and creating all test cases. + +// Hide Company Tags Facebook +// Hide Tags Array Two Pointers Binary Search +// Hide Similar Problems (H) Minimum Window Substring (M) Maximum Size Subarray Sum Equals k + /** * @param {number} s * @param {number[]} nums * @return {number} */ + +// O(n) solution var minSubArrayLen = function(s, nums) { var sum = 0; var left = 0; - var right = -1; - var len = nums.length; + var right = 0; var minLen = Infinity; - while(right < len) { - while(right < len && sum < s) { - sum += nums[++right]; - } - if(sum >= s) { - minLen = Math.min(right - left + 1, minLen); - sum -= nums[left]; - left++; + while(right < nums.length) { + while(right < nums.length && sum < s) { + sum += nums[right++]; } + while(sum >= s) { + minLen = Math.min(minLen, right - left); + sum -= nums[left++]; + } } - - - return minLen > len ? 0 : minLen; -}; \ No newline at end of file + return minLen > nums.length ? 0 : minLen; +}; + +// The O(NlogN) solution is to sum up the array +// [1,2,3,4,5] becomes [1,3,6,10,15] +// then iterate through array from index 0 to nums.length - 1 +// for each value in the summed array +// binary search values after that index so the difference becomes greater than s +// example +// s = 8 +// at index 0 with value 1 look between [3,6,10,15] using binary search. +// we can find that at value 10 the difference is 10 - 1 = 9 the minLen is index 3 - 1 + 1 = 3 +// then we check index 1 with value 3 and binary search [6,10,15] we can find that at value 15 we have difference 15 - 3 = 12 +// the distance is index 4 - 1 + 1 = 4 + +// console.log(minSubArrayLen(11, [1,2,3,4,5])); \ No newline at end of file diff --git a/282 Expression Add Operators.js b/282 Expression Add Operators.js new file mode 100644 index 0000000..d425219 --- /dev/null +++ b/282 Expression Add Operators.js @@ -0,0 +1,52 @@ +// Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators (not unary) +, -, or * between the digits so they evaluate to the target value. + +// Examples: +// "123", 6 -> ["1+2+3", "1*2*3"] +// "232", 8 -> ["2*3+2", "2+3*2"] +// "105", 5 -> ["1*0+5","10-5"] +// "00", 0 -> ["0+0", "0-0", "0*0"] +// "3456237490", 9191 -> [] +// Credits: +// Special thanks to @davidtan1890 for adding this problem and creating all test cases. + +// Hide Company Tags Google Facebook +// Hide Tags Divide and Conquer +// Hide Similar Problems (M) Evaluate Reverse Polish Notation (H) Basic Calculator (M) Basic Calculator II (M) Different Ways to Add Parentheses + + +// reference: http://blog.csdn.net/pointbreak1/article/details/48596115 + +var addOperators = function(num, target) { + function opRecur(num, target, lastOp, result, expression, results) { + if(num.length === 0) { + if(target === result) { + results.push(expression); + } + return; + } + + for(var i = 1; i <= num.length; i++) { + var curr = num.substring(0, i); + if(curr.length > 1 && curr[0] === '0') { + continue; + } + + var rest = num.substring(i); + var currVal = parseInt(curr); + + if(expression.length === 0) { + opRecur(rest, target, currVal, currVal, expression + curr, results); + } else { + opRecur(rest, target, currVal, result + currVal, expression + "+" + curr, results); + opRecur(rest, target,-currVal, result - currVal, expression + "-" + curr, results); + opRecur(rest, target, currVal * lastOp, result - lastOp + lastOp * currVal, expression + "*" + curr, results); + } + } + } + + var results = []; + opRecur(num, target, 0, 0, '', results); + return results; +}; + +console.log(addOperators('01023', 3)); \ No newline at end of file diff --git a/311 Sparse Matrix Multiplication.js b/311 Sparse Matrix Multiplication.js new file mode 100644 index 0000000..aef291c --- /dev/null +++ b/311 Sparse Matrix Multiplication.js @@ -0,0 +1,97 @@ +// Given two sparse matrices A and B, return the result of AB. + +// You may assume that A's column number is equal to B's row number. + +// Example: + +// A = [ +// [ 1, 0, 0], +// [-1, 0, 3] +// ] + +// B = [ +// [ 7, 0, 0 ], +// [ 0, 0, 0 ], +// [ 0, 0, 1 ] +// ] + + +// | 1 0 0 | | 7 0 0 | | 7 0 0 | +// AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | +// | 0 0 1 | +// Hide Company Tags LinkedIn Facebook +// Hide Tags Hash Table + + +/** + * @param {number[][]} A + * @param {number[][]} B + * @return {number[][]} + */ + +// normal matrix mulitplication +// slower version +var multiply = function(A, B) { + var result = []; + + var rowA = A.length; + var colA = A[0].length; + var rowB = B.length; + var colB = B[0].length + + for(var i = 0; i < rowA; i++) { + result.push(Array(colB).fill(0)); + + for(var j = 0; j < colB; j++) { + + for(var k = 0; k < colA; k++) { + result[i][j] += A[i][k]*B[k][j] + } + + } + } + + return result; +}; + +// faster +// skip +multiply = function(A, B) { + var result = []; + var i,j,k; + + var rowA = A.length; + var colA = A[0].length; + var colB = B[0].length + + for(var i = 0; i < rowA; i++) { + result.push(Array(colB).fill(0)); + } + + for(i = 0; i < rowA; i++) { + for(k = 0; k < colA; k++) { + if(A[i][k] !== 0) { + for(j = 0; j < colB; j++) { + if(B[k][j] !== 0) { + result[i][j] += A[i][k]*B[k][j]; + } + } + } + } + } + + return result; +}; + + + +// var data1 = [[0,1],[0,0],[0,1]]; +// var data2 = [[1,0],[1,0]]; + +// var data1 = [[1,0,0],[-1,0,3]]; +// var data2 = [[7,0,0],[0,0,0],[0,0,1]]; + +var data1 = [[1,-5]]; +var data2 = [[12],[-1]]; + +console.log(multiply(data1,data2)); \ No newline at end of file diff --git a/325 Maximum Size Subarray Sum Equals k.js b/325 Maximum Size Subarray Sum Equals k.js new file mode 100644 index 0000000..a49ec87 --- /dev/null +++ b/325 Maximum Size Subarray Sum Equals k.js @@ -0,0 +1,44 @@ +// Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead. + +// Example 1: +// Given nums = [1, -1, 5, -2, 3], k = 3, +// return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest) + +// Example 2: +// Given nums = [-2, -1, 2, 1], k = 1, +// return 2. (because the subarray [-1, 2] sums to 1 and is the longest) + +// Follow Up: +// Can you do it in O(n) time? + +// Hide Company Tags Palantir Facebook +// Hide Tags Hash Table +// Hide Similar Problems (M) Minimum Size Subarray Sum (E) Range Sum Query - Immutable + + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var maxSubArrayLen = function(nums, k) { + var maxLen = 0; + var currSum = 0; + var dict = { 0: -1 }; + + for(var i = 0; i < nums.length; i++) { + currSum += nums[i]; + + // since we are looking for the maxlen, dict is used to store the very first + // location where currSum occurred + if(dict[currSum] === undefined) { + dict[currSum] = i; + } + + if(dict[currSum - k] !== undefined) { + maxLen = Math.max(maxLen, i - dict[currSum - k]); + } + } + + return maxLen; +}; \ No newline at end of file diff --git a/43 Multiply Strings.js b/43 Multiply Strings.js index eddba66..7f17f83 100644 --- a/43 Multiply Strings.js +++ b/43 Multiply Strings.js @@ -1,44 +1,52 @@ +// Given two numbers represented as strings, return multiplication of the numbers as a string. + +// Note: +// The numbers can be arbitrarily large and are non-negative. +// Converting the input string to integer is NOT allowed. +// You should NOT use internal library such as BigInteger. +// Hide Company Tags Facebook Twitter +// Hide Tags Math String +// Hide Similar Problems (M) Add Two Numbers (E) Plus One (E) Add Binary + /** * @param {string} num1 * @param {string} num2 * @return {string} */ var multiply = function(num1, num2) { - if(num1 === null || num2 === null || num1.length === 0 || num2.length === 0){ - return 0; + if(num1 === null || num2 === null || num1.length === 0 || num2.length === 0 || num1 === '0' || num2 === '0') { + return '0'; } var arr1 = num1.split('').reverse(); var arr2 = num2.split('').reverse(); - var result = []; - for(var i = 0; i < arr1.length; i++){ + for(var i = 0; i < arr1.length; i++) { var carry = 0; + var val1 = parseInt(arr1[i]); - for(var j = 0; j < arr2.length; j++){ - var n1 = parseInt(arr1[i]); - var n2 = parseInt(arr2[j]); - var exist = parseInt(result[i+j] || 0); - var total = n1*n2+carry+exist; - - var remain = total%10 + ''; - carry = parseInt(total/10); - result[i+j] = remain; + for(var j = 0; j < arr2.length; j++) { + var val2 = parseInt(arr2[j]); + var product = val1*val2 + carry; + var exist = result[i+j] || 0; + var sum = product + exist; + var digit = sum%10; + carry = Math.floor(sum/10); + result[i+j] = digit; } - if(carry > 0){ - result[i + j] = carry + ''; + if(carry > 0) { + result[i+j] = carry; } } - result = result.reverse(); + result.reverse(); result = result.join(''); - result = result.replace(/^0+/g,''); + result = result.replace(/^0+/, ''); - if(result.length === 0){ - return "0"; - } else { - return result; - } -}; \ No newline at end of file + + return result; +}; + +multiply('123', '456') \ No newline at end of file From dbf7b50298fce082439a92016de9a2216f83633d Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Sun, 21 Aug 2016 21:09:32 -0700 Subject: [PATCH 23/47] add more solution --- .gitignore | 2 + 1 Two Sum.js | 35 +++-- 10 Regular Expresion Matching.js | 37 +++-- 121 Best Time to Buy and Sell Stock.js | 22 ++- 125 Valid Palindrome.js | 28 ++++ 133 Clone Graph.js | 21 +++ 15 3Sum.js | 17 ++ 157 Read N Characters Given Read4.js | 57 +++++++ 161 One Edit Distance.js | 36 +++++ 17 Letter Combinations of a Phone Number.js | 102 ++++++------ 200 Number of Islands.js | 42 ++++- 206 Reverse Linked List.js | 21 +-- 21 Merge Two Sorted Lists.js | 6 + ...and Search Word - Data structure design.js | 91 ++++++----- 215 Kth Largest Element in an Array.js | 17 ++ 23 Merge k Sorted Lists.js | 86 +++++----- 257 Binary Tree Paths.js | 78 +++++----- 283 Move Zeroes.js | 57 ++++--- 314 Binary Tree Vertical Order Traversal.js | 53 +++---- 33 Search in Rotated Sorted Array.js | 10 +- 38 Count and Say.js | 27 +++- 43 Multiply Strings.js | 2 - 56. Merge Intervals.js | 87 ++++++----- 75 Sort Colors.js | 67 +++++--- 76 Minimum Window Substring.js | 2 + 81 Search in Rotated Sorted Array II.js | 16 +- 91 Decode Ways.js | 87 +++++------ Find Median in K Sorted Arrays.js | 147 ++++++++++++++++++ Job Sequencing Problem.js | 103 ++++++++++++ 29 files changed, 966 insertions(+), 390 deletions(-) create mode 100644 .gitignore create mode 100644 157 Read N Characters Given Read4.js create mode 100644 Find Median in K Sorted Arrays.js create mode 100644 Job Sequencing Problem.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c16356 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +facebook +test.js \ No newline at end of file diff --git a/1 Two Sum.js b/1 Two Sum.js index bbb0794..ed67bd0 100644 --- a/1 Two Sum.js +++ b/1 Two Sum.js @@ -1,3 +1,21 @@ +// Given an array of integers, return indices of the two numbers such that they add up to a specific target. + +// You may assume that each input would have exactly one solution. + +// Example: +// Given nums = [2, 7, 11, 15], target = 9, + +// Because nums[0] + nums[1] = 2 + 7 = 9, +// return [0, 1]. +// UPDATE (2016/2/13): +// The return format had been changed to zero-based indices. Please read the above updated description carefully. + +// Hide Company Tags LinkedIn Uber Airbnb Facebook Amazon Microsoft Apple Yahoo Dropbox Bloomberg Yelp Adobe +// Hide Tags Array Hash Table +// Hide Similar Problems (M) 3Sum (M) 4Sum (M) Two Sum II - Input array is sorted (E) Two Sum III - Data structure design + + + /** * @param {number[]} nums * @param {number} target @@ -6,19 +24,12 @@ var twoSum = function(nums, target) { var hash = {}; - for(var i = 0; i < nums.length; i++){ - hash[nums[i]] = i; - } - - for(i = 0; i < nums.length; i++){ + for(var i = 0; i < nums.length; i++) { var num = nums[i]; - var diff = target - num; - if(hash[diff] !== undefined && hash[diff] !== i){ - if(hash[diff] > i){ - return [i+1, hash[diff]+1]; - } else { - return [hash[diff]+1, i+1] - } + if(hash[num] !== undefined) { + return [hash[num], i] + } else { + hash[target - num] = i; } } diff --git a/10 Regular Expresion Matching.js b/10 Regular Expresion Matching.js index bf3f54e..ca77413 100644 --- a/10 Regular Expresion Matching.js +++ b/10 Regular Expresion Matching.js @@ -19,21 +19,20 @@ // isMatch("ab", ".*") → true // isMatch("aab", "c*a*b") → true - /** * @param {string} s * @param {string} p * @return {boolean} */ var isMatch = function(s, p) { - var m = s.length; - var n = p.length; + var sLen = s.length; + var pLen = p.length; var dp = []; - for(var i = 0; i <= m; i++) { + for(var i = 0; i <= sLen; i++) { var tmp = []; - for(var j = 0; j <= n; j++) { + for(var j = 0; j <= pLen; j++) { tmp.push(false); } @@ -42,21 +41,21 @@ var isMatch = function(s, p) { dp[0][0] = true; - for(i = 0; i <= m; i++) { - for(j = 0; j <= n; j++) { - if(p[j-1] !== '.' && p[j-1] !== '*') { - if(i > 0 && s[i-1] === p[j-1] && dp[i-1][j-1]) { + for(i = 0; i <= sLen; i++) { + for(j = 0; j <= pLen; j++) { + if(p[j - 1] !== '.' && p[j - 1] !== '*') { + if(i > 0 && p[j - 1] === s[i - 1] && dp[i - 1][j - 1]) { dp[i][j] = true; } - } else if(p[j-1] === '.') { - if(i > 0 && dp[i-1][j-1]) { - dp[i][j] = true; + } else if(p[j - 1] === '.') { + if(i > 0 && dp[i - 1][j - 1]) { + dp[i][j] = true; } - } else if(j > 1) { // '*' cannot be the first element - if(dp[i][j-2]) { // 0 Occurance - dp[i][j] = true; - } else if(i > 0 && (p[j-2] == s[i-1] || p[j-2] == '.') && dp[i-1][j]) { - + } else if(j > 1) { // '*' cannot be the first element + if(dp[i][j - 2]) { // 0 occurance + dp[i][j] = true; + } else if(i > 0 && (p[j - 2] === s[i - 1] || p[j - 2] === '.') && dp[i - 1][j]) { + // example // xa and xa* // s[i-1] === a @@ -64,11 +63,11 @@ var isMatch = function(s, p) { // a === a // so we can now compare x, xa* // and x here is dp[i-1][j] - dp[i][j] = true; + dp[i][j] = true; } } } } - return dp[m][n]; + return dp[sLen][pLen]; }; \ No newline at end of file diff --git a/121 Best Time to Buy and Sell Stock.js b/121 Best Time to Buy and Sell Stock.js index 00ecd01..245e43c 100644 --- a/121 Best Time to Buy and Sell Stock.js +++ b/121 Best Time to Buy and Sell Stock.js @@ -1,7 +1,21 @@ -// Leetcode 121 -// Language: Javascript -// Problem: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ -// Author: Chihung Yu +// Say you have an array for which the ith element is the price of a given stock on day i. + +// If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. + +// Example 1: +// Input: [7, 1, 5, 3, 6, 4] +// Output: 5 + +// max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) +// Example 2: +// Input: [7, 6, 4, 3, 1] +// Output: 0 + +// In this case, no transaction is done, i.e. max profit = 0. +// Hide Company Tags Amazon Microsoft Bloomberg Uber Facebook +// Hide Tags Array Dynamic Programming +// Hide Similar Problems (M) Maximum Subarray (M) Best Time to Buy and Sell Stock II (H) Best Time to Buy and Sell Stock III (H) Best Time to Buy and Sell Stock IV (M) Best Time to Buy and Sell Stock with Cooldown + /** * @param {number[]} prices * @return {number} diff --git a/125 Valid Palindrome.js b/125 Valid Palindrome.js index 1278fac..287e4cc 100644 --- a/125 Valid Palindrome.js +++ b/125 Valid Palindrome.js @@ -36,5 +36,33 @@ var isPalindrome = function(s) { } } + return true; +}; + + +/** + * @param {string} s + * @return {boolean} + */ +var isPalindrome = function(s) { + var head = 0; + var tail = s.length - 1; + + s = s.toLowerCase(); + + while(head < tail) { + while(s[head] && !s[head].match(/[a-z0-9]/)) { + head++; + } + while(s[tail] && !s[tail].match(/[a-z0-9]/)) { + tail--; + } + if(head < tail && s[head] !== s[tail]) { + return false; + } + head++; + tail--; + } + return true; }; \ No newline at end of file diff --git a/133 Clone Graph.js b/133 Clone Graph.js index 8e87de4..9d46c78 100644 --- a/133 Clone Graph.js +++ b/133 Clone Graph.js @@ -57,4 +57,25 @@ var cloneGraph = function(graph) { } return newNode; } +}; + + +var cloneGraph = function(graph) { + if(!graph) { + return graph; + } else { + return dfs(graph, {}); + } + + function dfs(node, visited) { + var newNode = visited[node.label] = visited[node.label] || new UndirectedGraphNode(node.label); + + for(var i = 0; i < node.neighbors.length; i++) { + var neighbor = node.neighbors[i]; + newNode.neighbors[i] = visited[neighbor.label] = visited[neighbor.label] || dfs(neighbor, visited); + } + + return newNode; + } + }; \ No newline at end of file diff --git a/15 3Sum.js b/15 3Sum.js index 53e215b..a2f21ec 100644 --- a/15 3Sum.js +++ b/15 3Sum.js @@ -1,3 +1,20 @@ +// Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. + +// Note: The solution set must not contain duplicate triplets. + +// For example, given array S = [-1, 0, 1, 2, -1, -4], + +// A solution set is: +// [ +// [-1, 0, 1], +// [-1, -1, 2] +// ] +// Hide Company Tags Amazon Microsoft Bloomberg Facebook Adobe +// Hide Tags Array Two Pointers +// Hide Similar Problems (E) Two Sum (M) 3Sum Closest (M) 4Sum (M) 3Sum Smaller + + + /** * @param {number[]} nums * @return {number[][]} diff --git a/157 Read N Characters Given Read4.js b/157 Read N Characters Given Read4.js new file mode 100644 index 0000000..8245c6b --- /dev/null +++ b/157 Read N Characters Given Read4.js @@ -0,0 +1,57 @@ +// The API: int read4(char *buf) reads 4 characters at a time from a file. + +// The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file. + +// By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file. + +// Note: +// The read function will only be called once for each test case. + +// Hide Company Tags Facebook +// Hide Tags String +// Hide Similar Problems (H) Read N Characters Given Read4 II - Call multiple times + + +/** + * Definition for read4() + * + * @param {character[]} buf Destination buffer + * @return {number} The number of characters read + * read4 = function(buf) { + * ... + * }; + */ + +/** + * @param {function} read4() + * @return {function} + */ +var solution = function(read4) { + /** + * @param {character[]} buf Destination buffer + * @param {number} n Maximum number of characters to read + * @return {number} The number of characters read + */ + return function(buf, n) { + var eof = false; + var total = 0; + var temp = Array(4); + + while(!eof && total < n) { + // read4 will populate temp with read characters, and return count ... + var count = read4(temp); + + if(count < 4) { + eof = true; + } + + count = Math.min(count, n - total); + + for(var i = 0; i < count; i++) { + buf[total++] = temp[i]; + } + } + + return total; + }; +}; \ No newline at end of file diff --git a/161 One Edit Distance.js b/161 One Edit Distance.js index feeac4a..f53ae22 100644 --- a/161 One Edit Distance.js +++ b/161 One Edit Distance.js @@ -42,4 +42,40 @@ var isOneEditDistance = function(s, t) { } return found || s.length < t.length; +}; + + +var isOneEditDistance = function(s, t) { + if(s.length > t.length) { + var tmp = s; + s = t; + t = tmp; + } + + if(t.length - s.length > 1) { + return false; + } + + + var i = 0; + var j = 0; + var diff = 0; + + while(i < s.length && j < t.length) { + if(s[i] !== t[j]) { + if(diff !== 0) { + return false; + } + diff++; + + if(t.length !== s.length) { + i--; + } + } + + i++; + j++; + } + + return diff === 1 || (t.length !== s.length && (t.length - j) === 1); }; \ No newline at end of file diff --git a/17 Letter Combinations of a Phone Number.js b/17 Letter Combinations of a Phone Number.js index a5843a0..f61b313 100644 --- a/17 Letter Combinations of a Phone Number.js +++ b/17 Letter Combinations of a Phone Number.js @@ -1,65 +1,57 @@ +// Given a digit string, return all possible letter combinations that the number could represent. + +// A mapping of digit to letters (just like on the telephone buttons) is given below. + + + +// Input:Digit string "23" +// Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. +// Note: +// Although the above answer is in lexicographical order, your answer could be in any order you want. + +// Hide Company Tags Amazon Dropbox Google Uber Facebook +// Hide Tags Backtracking String +// Hide Similar Problems (M) Generate Parentheses (M) Combination Sum + + /** * @param {string} digits * @return {string[]} */ + +var numToLetters = { + '0': ' ', + '1': '', + '2': 'abc', + '3': 'def', + '4': 'ghi', + '5': 'jkl', + '6': 'mno', + '7': 'pqrs', + '8': 'tuv', + '9': 'wxyz' +}; + var letterCombinations = function(digits) { - var result = []; + var res = []; - if(digits === null || digits.length === 0){ - return result; + if(digits.length === 0) { + return res; } - var str = []; - - generate(digits, 0, str, result); - return result; -}; - -var generate = function(digits, depth, str, result){ - if(digits.length === depth){ - result.push(str.join('')); - return; + function dfs(digits, idx, curr) { + if(idx === digits.length) { + res.push(curr); + return; + } + + var letters = numToLetters[digits[idx]]; + + for(var i = 0; i < letters.length; i++) { + dfs(digits, idx + 1, curr + letters[i]); + } } - - var letters = convertDigitToLetters(digits[depth]); - for(var i = 0; i < letters.length; i++){ - var letter = letters[i]; - str.push(letter); - generate(digits, depth + 1, str, result); - str.pop(); - } -} - -var convertDigitToLetters = function(c){ - if(c === '1'){ - return ''; - } - if(c === '2'){ - return 'abc'; - } - if(c === '3'){ - return 'def'; - } - if(c === '4'){ - return 'ghi'; - } - if(c === '5'){ - return 'jkl'; - } - if(c === '6'){ - return 'mno'; - } - if(c === '7'){ - return 'pqrs'; - } - if(c === '8'){ - return 'tuv'; - } - if(c === '9'){ - return 'wxyz'; - } - if(c === '0'){ - return ' '; - } -} \ No newline at end of file + dfs(digits, 0, ''); + return res; +}; \ No newline at end of file diff --git a/200 Number of Islands.js b/200 Number of Islands.js index dd0d2aa..ba829ec 100644 --- a/200 Number of Islands.js +++ b/200 Number of Islands.js @@ -51,4 +51,44 @@ var traverse = function(i, j, grid, row, col) { traverse(i - 1, j, grid, row, col); traverse(i, j - 1, grid, row, col); } -} \ No newline at end of file +} + +// non recusion +/** + * @param {character[][]} grid + * @return {number} + */ +var numIslands = function(grid) { + var count = 0; + + function traverseIsland(i, j, grid) { + var stack = []; + + stack.push([i, j]); + + while(stack.length) { + var pair = stack.pop(); + i = pair[0]; + j = pair[1]; + + if(i >= 0 && i < grid.length && j >= 0 && j < grid[0].length && grid[i][j] === '1') { + grid[i][j] = '2'; + stack.push([i + 1, j]); + stack.push([i - 1, j]); + stack.push([i, j + 1]); + stack.push([i, j - 1]); + } + } + } + + for(var i = 0; i < grid.length; i++) { + for(var j = 0; j < grid[0].length; j++) { + if(grid[i][j] === '1') { + traverseIsland(i, j, grid); + count++; + } + } + } + + return count; +}; \ No newline at end of file diff --git a/206 Reverse Linked List.js b/206 Reverse Linked List.js index 5e0c0b2..9b95909 100644 --- a/206 Reverse Linked List.js +++ b/206 Reverse Linked List.js @@ -10,7 +10,6 @@ // Show Tags // Show Similar Problems - /** * Definition for singly-linked list. * function ListNode(val) { @@ -23,19 +22,15 @@ * @return {ListNode} */ var reverseList = function(head) { - if(head === null){ - return head; - } + var curr = head; + var prev = null; - var cur = head; - var pre = null; - - while(cur){ - var post = cur.next; - cur.next = pre; - pre = cur; - cur = post; + while(curr) { + var next = curr.next; + curr.next = prev; + prev = curr; + curr = next; } - return pre; + return prev; }; \ No newline at end of file diff --git a/21 Merge Two Sorted Lists.js b/21 Merge Two Sorted Lists.js index f72bacf..b126758 100644 --- a/21 Merge Two Sorted Lists.js +++ b/21 Merge Two Sorted Lists.js @@ -1,3 +1,9 @@ +// Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. + +// Hide Company Tags Amazon LinkedIn Apple Microsoft +// Hide Tags Linked List +// Hide Similar Problems (H) Merge k Sorted Lists (E) Merge Sorted Array (M) Sort List (M) Shortest Word Distance II + /** * Definition for singly-linked list. * function ListNode(val) { diff --git a/211 Add and Search Word - Data structure design.js b/211 Add and Search Word - Data structure design.js index 3f9697f..9d28903 100644 --- a/211 Add and Search Word - Data structure design.js +++ b/211 Add and Search Word - Data structure design.js @@ -1,20 +1,39 @@ -// Leetcode #211 -// Language: Javascript -// Problem: https://leetcode.com/problems/add-and-search-word-data-structure-design/ -// Author: Chihung Yu +// Design a data structure that supports the following two operations: -var TrieNode = function(){ - this.iskey = false; - this.children = []; -} +// void addWord(word) +// bool search(word) +// search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter. + +// For example: + +// addWord("bad") +// addWord("dad") +// addWord("mad") +// search("pad") -> false +// search("bad") -> true +// search(".ad") -> true +// search("b..") -> true +// Note: +// You may assume that all words are consist of lowercase letters a-z. +// click to show hint. +// Hide Company Tags Facebook +// Hide Tags Backtracking Trie Design +// Hide Similar Problems (M) Implement Trie (Prefix Tree) /** * @constructor */ + +function TrieNode(letter) { + this.isWord = null; + this.letter = letter; + this.children = {}; +} + var WordDictionary = function() { - this.root = new TrieNode(); + this.root = new TrieNode(); }; /** @@ -25,21 +44,13 @@ var WordDictionary = function() { WordDictionary.prototype.addWord = function(word) { var node = this.root; - for(var i = 0; i < word.length; i++){ - var key = charKeyFromA(word[i]); - if(!node.children[key]){ - node.children[key] = new TrieNode(); - } - - node = node.children[key]; + for(var i = 0; i < word.length; i++) { + var ch = word[i]; + node.children[ch] = node.children[ch] || new TrieNode(ch); + node = node.children[ch]; } - node.iskey = true; -}; - -charKeyFromA = function(c){ - var a = 'a'.charCodeAt(0); - return c.charCodeAt(0) - a; + node.isWord = true; }; /** @@ -49,28 +60,28 @@ charKeyFromA = function(c){ * contain the dot character '.' to represent any one letter. */ WordDictionary.prototype.search = function(word) { - return searchWord(this.root, word, 0); -}; - -var searchWord = function(node, word, index){ - if(word.length === index){ - return node.iskey; - } - - var c = word[index]; + var node = this.root; - if(c === "."){ - for(var i = 0; i < 26; i++){ - if(node.children[i] && searchWord(node.children[i], word, index+1)){ - return true; + function searchWord(i, word, node) { + if(i === word.length) { + return node.isWord === true; + } + + if(word[i] === '.') { + for(var child in node.children) { + if(searchWord(i + 1, word, node.children[child])) { + return true; + } } + + return false; + } else { + return node.children[word[i]] !== undefined && searchWord(i + 1, word, node.children[word[i]]); } - return false; - } else { - var key = charKeyFromA(c); - return !!(node.children[key] && searchWord(node.children[key], word, index+1)); } -} + + return searchWord(0, word, node); +}; /** * Your WordDictionary object will be instantiated and called as such: diff --git a/215 Kth Largest Element in an Array.js b/215 Kth Largest Element in an Array.js index 153ecb5..c4253a6 100644 --- a/215 Kth Largest Element in an Array.js +++ b/215 Kth Largest Element in an Array.js @@ -1,3 +1,20 @@ +// 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. + +// For example, +// Given [3,2,1,5,6,4] and k = 2, return 5. + +// Note: +// You may assume k is always valid, 1 ≤ k ≤ array's length. + +// Credits: +// Special thanks to @mithmatt for adding this problem and creating all test cases. + +// Hide Company Tags Facebook Amazon Microsoft Apple Bloomberg Pocket Gems +// Hide Tags Heap Divide and Conquer +// Hide Similar Problems (M) Wiggle Sort II (M) Top K Frequent Elements + + + /** * @param {number[]} nums * @param {number} k diff --git a/23 Merge k Sorted Lists.js b/23 Merge k Sorted Lists.js index b49f111..8ee44d1 100644 --- a/23 Merge k Sorted Lists.js +++ b/23 Merge k Sorted Lists.js @@ -1,5 +1,12 @@ // Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. // http://www.cnblogs.com/springfor/p/3869217.html + +// Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + +// Hide Company Tags LinkedIn Google Uber Airbnb Facebook Twitter Amazon Microsoft +// Hide Tags Divide and Conquer Linked List Heap +// Hide Similar Problems (E) Merge Two Sorted Lists (M) Ugly Number II + /** * Definition for singly-linked list. * function ListNode(val) { @@ -12,49 +19,50 @@ * @return {ListNode} */ var mergeKLists = function(lists) { - return mergeHelper(lists, 0, lists.length - 1); -}; - -function mergeHelper(lists, l, r) { - if(l === r) { - return lists[l]; - } - - if(l > r) { - return null; - } - - var mid = Math.floor((l + r)/2); - var left = mergeHelper(lists, l, mid); - var right = mergeHelper(lists, mid + 1, r); - - return mergeTwoLists(left, right); -} - - -function mergeTwoLists(l1, l2) { - var dummy = new ListNode(0); - var cur = dummy; - while(l1 && l2) { - if(l1.val < l2.val) { - cur.next = l1; - l1 = l1.next; - } else { - cur.next = l2; - l2 = l2.next; + function merge(beg, end, lists) { + if(beg > end) { + return []; } - cur = cur.next; - } - - if(l1) { - cur.next = l1; + if(beg === end) { + return lists[beg]; + } + + var mid = beg + Math.floor((end - beg)/2); + var left = merge(beg, mid, lists); + var right = merge(mid + 1, end, lists); + + return mergeTwoLists(left, right); } - if(l2) { - cur.next = l2; + function mergeTwoLists(list1, list2) { + var head = new ListNode(0); + var tmp = head; + + while(list1 && list2) { + if(list1.val < list2.val) { + tmp.next = list1; + list1 = list1.next; + } else { + tmp.next = list2; + list2 = list2.next; + } + + tmp = tmp.next; + } + + if(list1) { + tmp.next = list1; + } else if(list2) { + tmp.next = list2; + } + + tmp = head.next; + head.next = null; + + return tmp; } - return dummy.next; -} \ No newline at end of file + return merge(0, lists.length - 1, lists); +}; \ No newline at end of file diff --git a/257 Binary Tree Paths.js b/257 Binary Tree Paths.js index 2d656fb..7f7dce5 100644 --- a/257 Binary Tree Paths.js +++ b/257 Binary Tree Paths.js @@ -10,44 +10,46 @@ // All root-to-leaf paths are: // ["1->2->5", "1->3"] +// Credits: +// Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. +// Hide Company Tags Google Apple Facebook +// Hide Tags Tree Depth-first Search +// Hide Similar Problems (M) Path Sum II -/** - * Definition for a binary tree node. - * function TreeNode(val) { - * this.val = val; - * this.left = this.right = null; - * } - */ -/** - * @param {TreeNode} root - * @return {string[]} - */ -var binaryTreePaths = function(root) { - var result = []; - - if(root !== null) { - traverse(root, [], result); - } - - return result; -}; + /** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + /** + * @param {TreeNode} root + * @return {string[]} + */ -var traverse = function(node, path, result) { - path.push(node.val); - - if(node.left || node.right) { - if(node.left) { - traverse(node.left, path, result); - path.pop(); - } - - if(node.right) { - traverse(node.right, path, result); - path.pop(); - } - // path.pop() - } else { - result.push(path.join("->")); - } -} \ No newline at end of file + var binaryTreePaths = function(root) { + var res = []; + + function dfs(node, curr, res) { + if(node === null) { + return; + } + + curr.push(node.val); + + if(node.left === null && node.right === null) { + res.push(curr.join('->')); + } else { + dfs(node.left, curr, res); + dfs(node.right, curr, res); + } + + curr.pop(); + } + + dfs(root, [], res); + + return res; + }; \ No newline at end of file diff --git a/283 Move Zeroes.js b/283 Move Zeroes.js index 7357f3e..48696ef 100644 --- a/283 Move Zeroes.js +++ b/283 Move Zeroes.js @@ -18,38 +18,47 @@ * @param {number[]} nums * @return {void} Do not return anything, modify nums in-place instead. */ -var moveZeroes = function(nums) { - var x = 0; - var i = 0; - while(i < nums.length) { - if(nums[i] !== 0 && nums[x] === 0) { - nums[x] = nums[i]; - nums[i] = 0; - } - - while(nums[x] !== 0 && x < nums.length) { - x++; - } +// var moveZeroes = function(nums) { +// var x = 0; +// var i = 0; +// while(i < nums.length) { +// if(nums[i] !== 0 && nums[x] === 0) { +// nums[x++] = nums[i]; +// nums[i++] = 0; +// } + +// while(nums[x] !== 0 && x < nums.length) { +// x++; +// } - if(i <= x) { - i = x + 1; - } +// if(i <= x) { +// i = x + 1; +// } - while(nums[i] === 0) { - i++; - } - } -}; +// while(nums[i] === 0) { +// i++; +// } +// } +// }; + + -// Simpler but slower algo + +// // Simpler but slower algo var moveZeroes = function(nums) { - y = 0; + y = 0; // y is none zero pointer + + // y only increase when i found a none zero number + // i only swap if i found a none zero number for (var i = 0; i < nums.length; i++) { - if (nums[i]) { + if (nums[i] !== 0) { var tmp = nums[i]; nums[i] = nums[y]; nums[y] = tmp; - y += 1; + y++; } } + + return nums; }; +console.log(moveZeroes([0,1,0,3,12])); \ No newline at end of file diff --git a/314 Binary Tree Vertical Order Traversal.js b/314 Binary Tree Vertical Order Traversal.js index a744f5e..633552a 100644 --- a/314 Binary Tree Vertical Order Traversal.js +++ b/314 Binary Tree Vertical Order Traversal.js @@ -11,52 +11,47 @@ */ var verticalOrder = function(root) { - var map = {}; - var queue = []; var res = []; - // since iterating over map cannot ensure order - // we store min and max index for enforcing that - var minIdx = Infinity; - var maxIdx = -Infinity; if(root === null) { return res; } - queue.push([0, root]); - while(queue.length > 0) { + var hash = {}; + var queue = []; + queue.push([root, 0]); + var min = Infinity; + var max = -Infinity; + + while(queue.length) { var len = queue.length; for(var i = 0; i < len; i++) { - var data = queue.shift(); - var cur = data[1]; - var idx = data[0]; + var pair = queue.shift(); + var node = pair[0]; + var order = pair[1]; - if(idx < minIdx) { - minIdx = idx; - } - if(idx > maxIdx) { - maxIdx = idx; - } + hash[order] = hash[order] || []; + hash[order].push(node.val); - map[idx] = map[idx] || []; - map[idx].push(cur.val); + min = Math.min(order, min); + max = Math.max(order, max); - if(cur.left) { - queue.push([idx - 1, cur.left]); + if(node.left) { + queue.push([node.left, order - 1]); } - if(cur.right) { - queue.push([idx + 1, cur.right]); + + if(node.right) { + queue.push([node.right, order + 1]); } } } - // since iterating over map cannot ensure order - for(i = minIdx; i <= maxIdx; i++) { - var key = i.toString(); - - if(map[key]) { - res.push(map[key]); + + while(min <= max) { + if(hash[min].length) { + res.push(hash[min]); } + min++; } return res; diff --git a/33 Search in Rotated Sorted Array.js b/33 Search in Rotated Sorted Array.js index 2fd6ce8..97cb72f 100644 --- a/33 Search in Rotated Sorted Array.js +++ b/33 Search in Rotated Sorted Array.js @@ -22,19 +22,21 @@ var search = function(nums, target) { return mid; } - if(nums[mid] >= nums[left]) { + if(nums[mid] >= nums[left]) { // correct order if(nums[left] <= target && target < nums[mid]) { - // in correct order + // target is within the correct order part right = mid - 1; } else { + // target is not within the correct order part left = mid + 1; } - } else { + } else { // incorrect order if(nums[mid] < target && target <= nums[right]) { - // in correct order + // target is within the correct order part left = mid + 1; } else { + // target is not within the correct order part right = mid - 1; } } diff --git a/38 Count and Say.js b/38 Count and Say.js index 13ea348..7bc589d 100644 --- a/38 Count and Say.js +++ b/38 Count and Say.js @@ -26,4 +26,29 @@ var countAndSay = function(n) { n--; } return cur; -}; \ No newline at end of file +}; + + +// var countAndSay = function(n) { +// var str = '1'; + +// for(var i = 1; i < n; i++) { +// var newStr = ''; +// var count = 1; + +// for(var j = 1; j < str.length; j++) { +// if(str[j] === str[j - 1]) { +// count++; +// } else { +// newStr += count + str[j - 1]; +// count = 1; +// } +// } + +// newStr += count + str[j - 1]; +// str = newStr; +// } + +// return str; +// }; + diff --git a/43 Multiply Strings.js b/43 Multiply Strings.js index 7f17f83..259a76e 100644 --- a/43 Multiply Strings.js +++ b/43 Multiply Strings.js @@ -43,8 +43,6 @@ var multiply = function(num1, num2) { result.reverse(); result = result.join(''); - result = result.replace(/^0+/, ''); - return result; }; diff --git a/56. Merge Intervals.js b/56. Merge Intervals.js index 993b6b9..86b5d0c 100644 --- a/56. Merge Intervals.js +++ b/56. Merge Intervals.js @@ -1,40 +1,47 @@ -/** - * Definition for an interval. - * function Interval(start, end) { - * this.start = start; - * this.end = end; - * } - */ -/** - * @param {Interval[]} intervals - * @return {Interval[]} - */ -var merge = function(intervals) { - - // http://yucoding.blogspot.com/2013/01/leetcode-question-51-merge-intervals.html - - var result = []; - - if(!intervals || intervals.length === 0) { - return result; - } - - intervals.sort((a, b)=> { - return a.start > b.start ? 1 : -1; - }); - - result.push(intervals[0]); - - for(var i = 1; i < intervals.length; i++) { - var topOfResult = result[result.length - 1]; - var interval = intervals[i]; - - if(topOfResult.end >= interval.start) { - topOfResult.end = Math.max(topOfResult.end, interval.end); - } else { - result.push(interval); - } - } - - return result; -}; \ No newline at end of file +// Given a collection of intervals, merge all overlapping intervals. + +// For example, +// Given [1,3],[2,6],[8,10],[15,18], +// return [1,6],[8,10],[15,18]. + +// Hide Company Tags LinkedIn Google Facebook Twitter Microsoft Bloomberg Yelp +// Hide Tags Array Sort +// Hide Similar Problems (H) Insert Interval (E) Meeting Rooms (M) Meeting Rooms II + + /** + * Definition for an interval. + * function Interval(start, end) { + * this.start = start; + * this.end = end; + * } + */ + /** + * @param {Interval[]} intervals + * @return {Interval[]} + */ + + + var merge = function(intervals) { + var res = []; + + intervals.sort((i1, i2) => i1.start > i2.start ? 1 : -1 ); + + if(intervals.length) { + res.push(intervals[0]); + } + + for(var i = 1; i < intervals.length; i++) { + var interval = intervals[i]; + var last = res.pop(); + + if(interval.start > last.end) { + res.push(last); + res.push(interval); + } else { + last.end = Math.max(last.end, interval.end); + res.push(last); + } + } + + return res; + }; \ No newline at end of file diff --git a/75 Sort Colors.js b/75 Sort Colors.js index 09b3db1..1bd8b54 100644 --- a/75 Sort Colors.js +++ b/75 Sort Colors.js @@ -15,29 +15,52 @@ * @param {number[]} nums * @return {void} Do not return anything, modify nums in-place instead. */ +// var sortColors = function(nums) { +// var redIndex = 0; +// var blueIndex = nums.length - 1; +// var red = 0; +// var blue = 2; + +// for(var i = 0; i <= blueIndex; i++) { +// if(nums[i] === red) { +// swap(nums, redIndex, i); +// redIndex++; +// } else if(nums[i] === blue) { +// swap(nums, blueIndex, i); +// blueIndex--; +// i--; +// } +// } +// }; + +// function swap(arr, i, j) { +// if(i === j) { +// return; +// } +// var tmp = arr[i]; +// arr[i] = arr[j]; +// arr[j] = tmp; +// } + + var sortColors = function(nums) { - var redIndex = 0; - var blueIndex = nums.length - 1; - var red = 0; - var blue = 2; - - for(var i = 0; i <= blueIndex; i++) { - if(nums[i] === red) { - swap(nums, redIndex, i); - redIndex++; - } else if(nums[i] === blue) { - swap(nums, blueIndex, i); - blueIndex--; - i--; + var redIdx = 0; + var blueIdx = nums.length - 1; + var i = 0; + + while(i <= blueIdx) { + if(nums[i] === 0) { + swap(nums, i++, redIdx++); + } else if(nums[i] === 2) { + swap(nums, i, blueIdx--); + } else { + i++; } } -}; - -function swap(arr, i, j) { - if(i === j) { - return; + + function swap(nums, i, j) { + var tmp = nums[i]; + nums[i] = nums[j]; + nums[j] = tmp; } - var tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/76 Minimum Window Substring.js b/76 Minimum Window Substring.js index 0c23dca..c5e1262 100644 --- a/76 Minimum Window Substring.js +++ b/76 Minimum Window Substring.js @@ -51,6 +51,7 @@ var minWindow = function(s, t) { queue.push(i); tFoundCount[s[i]]++; + // if found count is over require count, we don't need those extra, so don't record it to hasFound if(tFoundCount[s[i]] <= tRequireCount[s[i]]) { hasFound++; } @@ -63,6 +64,7 @@ var minWindow = function(s, t) { k = queue.shift(); tFoundCount[s[k]]--; } while(tFoundCount[s[k]] >= tRequireCount[s[k]]); + // moving to the minimum window location if(windowEnd - windowBeg > i - k) { windowBeg = k; diff --git a/81 Search in Rotated Sorted Array II.js b/81 Search in Rotated Sorted Array II.js index 361c6f2..5f666d5 100644 --- a/81 Search in Rotated Sorted Array II.js +++ b/81 Search in Rotated Sorted Array II.js @@ -1,3 +1,15 @@ +// Follow up for "Search in Rotated Sorted Array": +// What if duplicates are allowed? + +// Would this affect the run-time complexity? How and why? + +// Write a function to determine if a given target is in the array. + +// Hide Tags Array Binary Search +// Hide Similar Problems (H) Search in Rotated Sorted Array + + + /** * @param {number[]} nums * @param {number} target @@ -14,13 +26,13 @@ var search = function(nums, target) { return true; } - if(nums[start] < nums[mid]){ + if(nums[start] < nums[mid]){ // in correct order if(target >= nums[start] && target < nums[mid]){ // normal order part end = mid - 1; } else { start = mid + 1; } - } else if(nums[mid] < nums[start]) { + } else if(nums[mid] < nums[start]) { // incorrect order if(target <= nums[end] && target > nums[mid]){ // normal order part start = mid + 1; } else { diff --git a/91 Decode Ways.js b/91 Decode Ways.js index 5623b0d..95af0a1 100644 --- a/91 Decode Ways.js +++ b/91 Decode Ways.js @@ -17,74 +17,71 @@ */ var numDecodings = function(s) { - if(s === null || s.length === 0){ + if(!s || s[0] === '0') { return 0; } + + var nums = [1, 1]; - if(s[0] === '0'){ - return 0; - } - - var nums = []; - nums[0] = 1; - nums[1] = 1; - - for(var i = 2; i <= s.length; i++){ - var tmp = parseInt(s.substring(i-1, i)); + for(var i = 2; i <= s.length; i++) { + var tmp; - if(tmp !== 0){ - nums[i] = nums[i-1]; - } else { + tmp = parseInt(s.substring(i - 1, i)); + + if(tmp === 0) { nums[i] = 0; + } else { + nums[i] = nums[i-1]; } - if(s[i - 2] !== '0'){ - tmp = parseInt(s.substring(i-2, i)); + if(s[i - 2] !== '0') { + tmp = parseInt(s.substring(i - 2, i)); - if(tmp > 0 && tmp < 27){ - nums[i] += nums[i-2]; + if(0 < tmp && tmp <= 26) { + + nums[i] += nums[i - 2]; } - } else { - nums[i] = nums[i] || 0; } } return nums[s.length]; }; - +console.log(numDecodings('10')); // Using recusion // It also store all the possible combination -var numDecodings = function(s) { - var result = []; +// var numDecodings = function(s) { +// var result = []; - function traverse(s, beg, end, cur) { - if(end > s.length) { - return - } +// function traverse(s, beg, end, cur) { +// if(end > s.length) { +// return +// } - var str = s.substring(beg, end); - var num = parseInt(str); +// var str = s.substring(beg, end); +// var num = parseInt(str); - if(isNaN(num) || num === 0 || num > 26) { - return; - } +// if(isNaN(num) || num === 0 || num > 26) { +// return; +// } - cur.push(str); +// cur.push(str); - if(end === s.length){ - result.push(cur.slice()); - return; - } +// if(end === s.length){ +// result.push(cur.slice()); +// return; +// } - traverse(s, end, end + 1, cur); - traverse(s, end, end + 2, cur); - cur.pop(); - } +// traverse(s, end, end + 1, cur); +// traverse(s, end, end + 2, cur); +// cur.pop(); +// } - traverse(s, 0, 1, []); - traverse(s, 0, 2, []); +// traverse(s, 0, 1, []); +// traverse(s, 0, 2, []); - return result.length; -}; \ No newline at end of file +// return result.length; +// }; + + diff --git a/Find Median in K Sorted Arrays.js b/Find Median in K Sorted Arrays.js new file mode 100644 index 0000000..3f6973d --- /dev/null +++ b/Find Median in K Sorted Arrays.js @@ -0,0 +1,147 @@ +var data = [ + [1,2,3,4,5,6,7,19], + [2,3,5,7,8,10,11], + [2,3,5,7,8,9], + [10,13,15,17,18,100], + [5,8,100,1002,1033,1044] +]; + +findMedianInKSortedArrays(data); + +function findMedianInKSortedArrays(arrs) { + var len = 0; + + for(var i = 0; i < arrs.length; i++) { + len += arrs[i].length; + } + + var kth = Math.floor(len/arrs.length); + var list = []; + + +} + + +function findMedianInKArrs(arrs) { + var len = 0; + for(var i = 0; i < arrs.length; i++) { + len = arrs[i].length; + } + + findKthInKArrs(arrs, len); +} + + +function findKthInKArrs(arrs, n) { + var min = Infinity; + var max = -Infinity; + + for(var i = 0; i < arrs.length; i++) { + min = Math.min(arrs[i][0], min); + max = Math.max(arrs[i][arrs[i].length - 1], max); + } + + var removed = 0; + var dividers = []; + + for(var i = 0; i < arrs.length; i++) { + + } +} + + + + + +function findKth(a, m, b, n, k) { + // always assume that m is equal or smaller than n + if(m > n) { + return findKth(b, n, a, m, k); + } + + if(m === 0) { + return b[k-1]; + } + + if(k === 1) { + return Math.min(a[0],b[0]); + } + + // divide k into two parts + var pa = Math.min(parseInt(k/2), m); + var pb = k - pa; + + if(a[pa - 1] < b[pb - 1]) { + return findKth(a.slice(pa), m - pa, b, n, k - pa); + } else if(a[pa - 1] > b[pb - 1]) { + return findKth(a, m, b.slice(pb), n - pb, k - pb); + } else { + return a[pa - 1]; + } +} + + + + + + + + + + + + + +// function findMedian(arrs) { +// var n = 0; +// var min, max; + +// for(var i = 0; i < arrs.length; i++) { +// n += arrs[i].length; +// } + +// var res = mergeKLists(arrs, 0, arrs.length - 1); + +// function mergeKLists(arrs, left, right) { +// if(left === right) { +// return arrs[left]; +// } + +// if(left > right) { +// return []; +// } + +// var mid = Math.floor((left + right)/2); + +// var arr1 = mergeKLists(arrs, left, mid); +// var arr2 = mergeKLists(arrs, mid + 1, right); + +// return merge2Lists(arr1, arr2); +// } + +// function merge2Lists(arr1, arr2) { +// var res = []; +// var i = 0; +// var j = 0; +// while(i < arr1.length && j < arr2.length) { +// if(arr1[i] < arr2[j]) { +// res.push(arr1[i++]); +// } else { +// res.push(arr2[j++]); +// } +// } + +// while(i < arr1.length) { +// res.push(arr1[i++]); +// } +// while(j < arr2.length) { +// res.push(arr2[j++]); +// } + +// return res; +// } + +// return res; +// } + +// console.log(findMedian(data)); \ No newline at end of file diff --git a/Job Sequencing Problem.js b/Job Sequencing Problem.js new file mode 100644 index 0000000..8dd9f71 --- /dev/null +++ b/Job Sequencing Problem.js @@ -0,0 +1,103 @@ +// Given an array of jobs where every job has a deadline and associated profit if the job is finished before the deadline. It is also given that every job takes single unit of time, so the minimum possible deadline for any job is 1. How to maximize total profit if only one job can be scheduled at a time. + +// Examples: + +// Input: Four Jobs with following deadlines and profits +// JobID Deadline Profit +// a 4 20 +// b 1 10 +// c 1 40 +// d 1 30 +// Output: Following is maximum profit sequence of jobs +// c, a + + +// Input: Five Jobs with following deadlines and profits +// JobID Deadline Profit +// a 2 100 +// b 1 19 +// c 2 27 +// d 1 25 +// e 3 15 +// Output: Following is maximum profit sequence of jobs +// c, a, e +// We strongly recommend to minimize your browser and try this yourself first. + +// A Simple Solution is to generate all subsets of given set of jobs and check individual subset for feasibility of jobs in that subset. Keep track of maximum profit among all feasible subsets. The time complexity of this solution is exponential. + +// This is a standard Greedy Algorithm problem. Following is algorithm. + +// 1) Sort all jobs in decreasing order of profit. // 4, 2, 1, 6, 2 becomes 6, 4, 2, 2, 1 +// 2) Initialize the result sequence as first job in sorted jobs. +// 3) Do following for remaining n-1 jobs +// .......a) If the current job can fit in the current result sequence +// without missing the deadline, add current job to the result. +// Else ignore the current job. +// The Following is C++ implementation of above algorithm. + +// Program to find the maximum profit job sequence from a given array +// of jobs with deadlines and profits +#include +#include +using namespace std; + +// A structure to represent a job +struct Job +{ + char id; // Job Id + int dead; // Deadline of job + int profit; // Profit if job is over before or on deadline +}; + +// This function is used for sorting all jobs according to profit +bool comparison(Job a, Job b) +{ + return (a.profit > b.profit); +} + +// Returns minimum number of platforms reqquired +void printJobScheduling(Job arr[], int n) +{ + // Sort all jobs according to decreasing order of prfit + sort(arr, arr+n, comparison); + + int result[n]; // To store result (Sequence of jobs) + bool slot[n]; // To keep track of free time slots + + // Initialize all slots to be free + for (int i=0; i=0; j--) + { + // Free slot found + if (slot[j]==false) + { + result[j] = i; // Add this job to result + slot[j] = true; // Make this slot occupied + break; + } + } + } + + // Print the result + for (int i=0; i Date: Sun, 28 Aug 2016 00:22:01 -0700 Subject: [PATCH 24/47] add and modifed some solutions --- 127 Word Ladder.js | 75 +++++++++++- 128 Longest Consecutive Sequence.js | 52 ++++++++ 146 LRU Cache.js | 114 +++++++++++++++++- 157 Read N Characters Given Read4.js | 5 +- ...ers Give Read4 II - Call Multiple Times.js | 65 ++++++++++ 20 Valid Parentheses.js | 21 ++++ ...and Search Word - Data structure design.js | 44 +++---- ...Lowest Common Ancestor of a Binary Tree.js | 18 +++ 252 Meeting Rooms.js | 18 +++ 253 Meeting Rooms II.js | 3 +- 26 Remove Duplicates from Sorted Array.js | 22 +++- 261 Graph Valid Tree.js | 55 ++++++++- 265 Paint House II.js | 8 +- 282 Expression Add Operators.js | 4 + 286 Walls and Gates.js | 39 +++++- 44 Wildcard Matching.js | 87 +++++++++++++ 49 Group Anagrams.js | 35 +++++- 57. Insert Interval.js | 8 +- 77 Combinations.js | 17 +++ 78 Subsets.js | 23 +++- 80 Remove Duplicates from Sorted Array II.js | 24 ++-- 90 Subsets II.js | 4 + 22 files changed, 687 insertions(+), 54 deletions(-) create mode 100644 128 Longest Consecutive Sequence.js create mode 100644 158 Read N Characters Give Read4 II - Call Multiple Times.js create mode 100644 44 Wildcard Matching.js diff --git a/127 Word Ladder.js b/127 Word Ladder.js index 7d7f8f7..ddc0395 100644 --- a/127 Word Ladder.js +++ b/127 Word Ladder.js @@ -65,4 +65,77 @@ var ladderLength = function(beginWord, endWord, wordList) { } return 0; -}; \ No newline at end of file +}; + +// will time exceeded. javascript hash is slower than set +var ladderLength = function(beginWord, endWord, wordList) { + if(beginWord === endWord) { + return 0; + } + + var queue = []; + var visited = {}; + var count = 1; + var baseCharCode = 'a'.charCodeAt(0); + + queue.push(beginWord); + + while(queue.length) { + var len = queue.length; + + for(var i = 0; i < len; i++) { + var word = queue.shift(); + + for(var j = 0; j < word.length; j++) { + for(var k = 0; k < 26; k++) { + var newChar = String.fromCharCode(baseCharCode + k); + var newWord = word.substring(0, j) + newChar + word.substring(j + 1); + + if(newWord === endWord) { + return count + 1; + } + + if(!visited[newWord] && wordList.has(newWord)) { + visited[newWord] = true; + queue.push(newWord); + } + } + } + } + + count++; + } + + return 0; +}; + + + + +Hi Thiago + +I very much appreciate that you took the time writing this warm welcoming letter and provided me the opportunity to come onsite visiting the team at Periscope. +After much thought, I've decided to accept offer at another company. It was really a tough call for me since I really like the product, role and people I met during my visit. +Again, I cannot thank you enough for your time, and support. It's been a great pleasure to know you and the team. I hope that we cross paths in the near future. + +Wish you, teams, and Periscope all the success. + +Regards, +Jerry + + + + +Hi Cynthia + +Thank your for patience and support along the way. +I very much appreciate that you took the time answering many of my questions about the Periscope, and role. + +After much thought, I've decided to accept offer at another company. It was really a tough call for me since I really like the product and people I met during my visit. + +Again, I cannot thank you enough for your time, and support. It's been a great pleasure to know you and the team. I hope that we cross paths in the near future. + +Wish you, teams, and Periscope all the success. + +Regards, +Jerry \ No newline at end of file diff --git a/128 Longest Consecutive Sequence.js b/128 Longest Consecutive Sequence.js new file mode 100644 index 0000000..8c18bcc --- /dev/null +++ b/128 Longest Consecutive Sequence.js @@ -0,0 +1,52 @@ +// Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + +// For example, +// Given [100, 4, 200, 1, 3, 2], +// The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. + +// Your algorithm should run in O(n) complexity. + +// Hide Company Tags Google Facebook +// Hide Tags Array Union Find +// Hide Similar Problems (M) Binary Tree Longest Consecutive Sequence + + +/** + * @param {number[]} nums + * @return {number} + */ +var longestConsecutive = function(nums) { + var maxLen = -Infinity; + var hash = {}; + + for(var i = 0; i < nums.length; i++) { + hash[nums[i]] = 1; + } + + var visited = {}; + + for(i = 0; i < nums.length; i++) { + var val = nums[i]; + if(visited[val]) { + continue; + } + visited[val] = true; + var len = 1; + var preVal = val - 1; + while(hash[preVal]) { + len++ + visited[preVal--] = true; + } + var nxtVal = val + 1; + while(hash[nxtVal]) { + len++ + visited[nxtVal++] = true; + } + + if(len > maxLen) { + maxLen = len; + } + } + + return maxLen; +}; \ No newline at end of file diff --git a/146 LRU Cache.js b/146 LRU Cache.js index 10ae3d6..0fdfda3 100644 --- a/146 LRU Cache.js +++ b/146 LRU Cache.js @@ -91,4 +91,116 @@ LRUCache.prototype.set = function(key, value) { } this.map.set(key, newNode); -}; \ No newline at end of file +}; + + + + + + + + + + +// Second Implementation + + +function DoublyLinkListNode(key, value) { + this.key = key; + this.value = value; + this.prev = this.next = null; +} + +/** + * @constructor + */ +var LRUCache = function(capacity) { + this.head = this.tail = null; + this.maxCapacity = capacity; + this.currSize = 0; + this.hash = {}; +}; + +/** + * @param {number} key + * @returns {number} + */ +LRUCache.prototype.get = function(key) { + if(!this.hash[key]) { + return -1; + } + + this.moveToHead(key); + return this.hash[key].value; +}; + +/** + * @param {number} key + * @param {number} value + * @returns {void} + */ +LRUCache.prototype.set = function(key, value) { + if(this.maxCapacity <= 0) { + return; + } + + if(!this.hash[key]) { + + if(this.currSize === this.maxCapacity) { + this.removeLast(); + this.currSize--; + } + + this.hash[key] = new DoublyLinkListNode(key, value); + this.currSize++; + } + + this.hash[key].value = value; + this.moveToHead(key); +}; + +LRUCache.prototype.removeLast = function() { + if(this.tail === null) { + return; + } + + delete this.hash[this.tail.key]; + var newTail = this.tail.prev; + + if(newTail === null) { + this.head = this.tail = null; + return; + } + + this.tail.prev = null; + newTail.next = null; + this.tail = newTail; +} + +LRUCache.prototype.moveToHead = function(key) { + var newHead = this.hash[key]; + + if(this.head === null && this.tail === null) { + this.head = this.tail = newHead; + } + + if(newHead === this.head) { + return; + } + + if(newHead === this.tail) { + this.tail = newHead.prev; + } + + if(newHead.prev) { + newHead.prev.next = newHead.next; + } + if(newHead.next) { + newHead.next.prev = newHead.prev; + } + + newHead.prev = null; + newHead.next = this.head; + this.head.prev = newHead; + this.head = newHead; +} \ No newline at end of file diff --git a/157 Read N Characters Given Read4.js b/157 Read N Characters Given Read4.js index 8245c6b..5ea66de 100644 --- a/157 Read N Characters Given Read4.js +++ b/157 Read N Characters Given Read4.js @@ -54,4 +54,7 @@ var solution = function(read4) { return total; }; -}; \ No newline at end of file +}; + + +// [tricky] [important] \ No newline at end of file diff --git a/158 Read N Characters Give Read4 II - Call Multiple Times.js b/158 Read N Characters Give Read4 II - Call Multiple Times.js new file mode 100644 index 0000000..27efed5 --- /dev/null +++ b/158 Read N Characters Give Read4 II - Call Multiple Times.js @@ -0,0 +1,65 @@ +// The API: int read4(char *buf) reads 4 characters at a time from a file. + +// The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file. + +// By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file. + +// Note: +// The read function may be called multiple times. + +// Hide Company Tags Bloomberg Google Facebook +// Hide Tags String +// Hide Similar Problems (E) Read N Characters Given Read4 + + + +/** + * Definition for read4() + * + * @param {character[]} buf Destination buffer + * @return {number} The number of characters read + * read4 = function(buf) { + * ... + * }; + */ + +/** + * @param {function} read4() + * @return {function} + */ +var solution = function(read4) { + let bufRead = []; + let count = 0; // how many characters read with read4 + let i = 0; + + /** + * @param {character[]} buf Destination buffer + * @param {number} n Maximum number of characters to read + * @return {number} The number of characters read + */ + return function(buf, n) { + let numChrRead = 0; + + while (numChrRead < n) { + if (i === 0) { + count = read4(bufRead); + } + + while (i < count && numChrRead < n) { + buf[numChrRead++] = bufRead[i++]; + } + + // read4 buffer used up, start over + if (i === count) { + i = 0; + } + + // end of file + if (count < 4) { + break; + } + } + + return numChrRead; + }; +}; diff --git a/20 Valid Parentheses.js b/20 Valid Parentheses.js index 746b67e..748fa9a 100644 --- a/20 Valid Parentheses.js +++ b/20 Valid Parentheses.js @@ -27,5 +27,26 @@ var isValid = function(s) { index++; } + return stack.length === 0; +}; + +// second attempt + +var isValid = function(s) { + var stack = []; + + for(var i = 0; i < s.length; i++) { + var chr = s[i]; + + if(chr === '(' || chr === '{' || chr === '[') { + stack.push(chr); + } else if(chr === ')' || chr === '}' || chr === ']') { + var top = stack.pop(); + if(!top || (top === '(' && chr !== ')') || (top === '{' && chr !== '}') || (top === '[' && chr !== ']')) { + return false; + } + } + } + return stack.length === 0; }; \ No newline at end of file diff --git a/211 Add and Search Word - Data structure design.js b/211 Add and Search Word - Data structure design.js index 9d28903..8994bc6 100644 --- a/211 Add and Search Word - Data structure design.js +++ b/211 Add and Search Word - Data structure design.js @@ -22,18 +22,17 @@ // Hide Tags Backtracking Trie Design // Hide Similar Problems (M) Implement Trie (Prefix Tree) +function TrieNode(chr) { + this.val = chr; + this.isWord = false; + this.children = []; +} + /** * @constructor */ - -function TrieNode(letter) { - this.isWord = null; - this.letter = letter; - this.children = {}; -} - var WordDictionary = function() { - this.root = new TrieNode(); + this.root = new TrieNode(null, false); }; /** @@ -43,11 +42,10 @@ var WordDictionary = function() { */ WordDictionary.prototype.addWord = function(word) { var node = this.root; - for(var i = 0; i < word.length; i++) { - var ch = word[i]; - node.children[ch] = node.children[ch] || new TrieNode(ch); - node = node.children[ch]; + var chr = word[i]; + node.children[chr] = node.children[chr] || new TrieNode(chr); + node = node.children[chr]; } node.isWord = true; @@ -62,25 +60,27 @@ WordDictionary.prototype.addWord = function(word) { WordDictionary.prototype.search = function(word) { var node = this.root; - function searchWord(i, word, node) { + function dfs(node, word, i) { if(i === word.length) { - return node.isWord === true; + return node.isWord; } - if(word[i] === '.') { - for(var child in node.children) { - if(searchWord(i + 1, word, node.children[child])) { + var chr = word[i]; + + if(chr === '.') { + for(var key in node.children) { + if(dfs(node.children[key], word, i + 1)) { return true; } } - - return false; - } else { - return node.children[word[i]] !== undefined && searchWord(i + 1, word, node.children[word[i]]); + } else if(node.children[chr]) { + return dfs(node.children[chr], word, i + 1); } + + return false; } - return searchWord(0, word, node); + return dfs(node, word, 0); }; /** diff --git a/236 Lowest Common Ancestor of a Binary Tree.js b/236 Lowest Common Ancestor of a Binary Tree.js index e1f92cd..1bd5b77 100644 --- a/236 Lowest Common Ancestor of a Binary Tree.js +++ b/236 Lowest Common Ancestor of a Binary Tree.js @@ -51,3 +51,21 @@ var lowestCommonAncestor = function(root, p, q) { return (l !== null) ? l : r; // either one of p, q is on one side OR p, q is not in l&r subtrees }; + + +// second attempt + +var lowestCommonAncestor = function(root, p, q) { + if(root === null || root === p || root === q) { + return root; + } + + var left = lowestCommonAncestor(root.left, p, q); + var right = lowestCommonAncestor(root.right, p, q); + + if(left !== null && right !== null) { + return root; + } + + return left || right; +}; \ No newline at end of file diff --git a/252 Meeting Rooms.js b/252 Meeting Rooms.js index 8aa4b57..4740965 100644 --- a/252 Meeting Rooms.js +++ b/252 Meeting Rooms.js @@ -35,5 +35,23 @@ var canAttendMeetings = function(intervals) { } } + return true; +}; + + + +// second attempt + +var canAttendMeetings = function(intervals) { + intervals.sort((a,b) => { + return a.start > b.start ? 1 : -1; + }); + + for(var i = 1; i < intervals.length; i++) { + if(intervals[i - 1].end > intervals[i].start) { + return false; + } + } + return true; }; \ No newline at end of file diff --git a/253 Meeting Rooms II.js b/253 Meeting Rooms II.js index 9355b30..8cddac0 100644 --- a/253 Meeting Rooms II.js +++ b/253 Meeting Rooms II.js @@ -1,4 +1,5 @@ -// Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required. +// Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), +// find the minimum number of conference rooms required. // For example, // Given [[0, 30],[5, 10],[15, 20]], diff --git a/26 Remove Duplicates from Sorted Array.js b/26 Remove Duplicates from Sorted Array.js index 2999b1e..80f8f6a 100644 --- a/26 Remove Duplicates from Sorted Array.js +++ b/26 Remove Duplicates from Sorted Array.js @@ -38,4 +38,24 @@ var removeDuplicates = function(nums) { } return end+1; -}; \ No newline at end of file +}; + + + +// second attempt + +var removeDuplicates = function(nums) { + var sorted = 0; + + for(var i = 1; i < nums.length; i++) { + if(nums[i] !== nums[sorted]) { + sorted++; + nums[sorted] = nums[i]; + } + } + + return sorted + 1; +}; + + +// [tricky] \ No newline at end of file diff --git a/261 Graph Valid Tree.js b/261 Graph Valid Tree.js index 0e8fa03..6b920e0 100644 --- a/261 Graph Valid Tree.js +++ b/261 Graph Valid Tree.js @@ -78,4 +78,57 @@ class UnionFind { count() { return this.count; } -} \ No newline at end of file +} + + + + + + +// second attempt + +var validTree = function(n, edges) { + var unions = []; + for(var i = 0; i < n; i++) { + unions.push(i); + } + + for(i = 0; i < edges.length; i++) { + var edge = edges[i]; + if(isConnected(unions, edge[1], edge[0])) { + return false; + } + } + + var visited = {}; + var diff = 0; + + for(i = 0; i < unions.length; i++) { + var union = unions[i]; + if(visited[union]) { + continue; + } + + visited[union] = true; + diff++; + } + + return diff === 1; +}; + +function isConnected(unions, i, j) { + var group1 = unions[i]; + var group2 = unions[j]; + + if(group1 === group2) { + return true + } + + for(var k = 0; k < unions.length; k++) { + if(unions[k] === group2) { + unions[k] = group1; + } + } + + return false; +} diff --git a/265 Paint House II.js b/265 Paint House II.js index 4583411..fcb4a96 100644 --- a/265 Paint House II.js +++ b/265 Paint House II.js @@ -1,6 +1,10 @@ -// There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color. +// There are a row of n houses, each house can be painted with one of the k colors. +// The cost of painting each house with a certain color is different. +// You have to paint all the houses such that no two adjacent houses have the same color. -// The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses. +// The cost of painting each house with a certain color is represented by a n x k cost matrix. +// For example, costs[0][0] is the cost of painting house 0 with color 0; +// costs[1][2] is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses. // Note: // All costs are positive integers. diff --git a/282 Expression Add Operators.js b/282 Expression Add Operators.js index d425219..5c8572d 100644 --- a/282 Expression Add Operators.js +++ b/282 Expression Add Operators.js @@ -40,6 +40,10 @@ var addOperators = function(num, target) { opRecur(rest, target, currVal, result + currVal, expression + "+" + curr, results); opRecur(rest, target,-currVal, result - currVal, expression + "-" + curr, results); opRecur(rest, target, currVal * lastOp, result - lastOp + lastOp * currVal, expression + "*" + curr, results); + // need to record the last oprand for handling mulitiplication. + // result - lastOP + lastOP * curVaule + // e.g 4+3*2 when dealing with *2, we have 4+3 then -3 then do 3*2 + // The operation for the function will look like 4 + 3 - 3 + 3 * 2 } } } diff --git a/286 Walls and Gates.js b/286 Walls and Gates.js index 443aeed..d6429eb 100644 --- a/286 Walls and Gates.js +++ b/286 Walls and Gates.js @@ -50,4 +50,41 @@ function traverse(rooms, i, j, rows, cols, dist) { traverse(rooms, i, j - 1, rows, cols, dist + 1); } } -} \ No newline at end of file +} + + + + +// second attempt + +/** + * @param {number[][]} rooms + * @return {void} Do not return anything, modify rooms in-place instead. + */ +var wallsAndGates = function(rooms) { + for(var i = 0; i < rooms.length; i++) { + for(var j = 0; j < rooms[i].length; j++) { + if(rooms[i][j] === 0) { + dfs(rooms, i, j, 0); + } + } + } + + function dfs(rooms, i, j, dist) { + if(i >= 0 && i < rooms.length && j >= 0 && j < rooms[i].length) { + + if(rooms[i][j] === -1 || rooms[i][j] < dist) { + return; + } + + if(rooms[i][j] > dist) { + rooms[i][j] = dist; + } + + dfs(rooms, i + 1, j, dist + 1); + dfs(rooms, i - 1, j, dist + 1); + dfs(rooms, i, j + 1, dist + 1); + dfs(rooms, i, j - 1, dist + 1); + } + } +}; \ No newline at end of file diff --git a/44 Wildcard Matching.js b/44 Wildcard Matching.js new file mode 100644 index 0000000..9abccbc --- /dev/null +++ b/44 Wildcard Matching.js @@ -0,0 +1,87 @@ +// Implement wildcard pattern matching with support for '?' and '*'. + +// '?' Matches any single character. +// '*' Matches any sequence of characters (including the empty sequence). + +// The matching should cover the entire input string (not partial). + +// The function prototype should be: +// bool isMatch(const char *s, const char *p) + +// Some examples: +// isMatch("aa","a") → false +// isMatch("aa","aa") → true +// isMatch("aaa","aa") → false +// isMatch("aa", "*") → true +// isMatch("aa", "a*") → true +// isMatch("ab", "?*") → true +// isMatch("aab", "c*a*b") → false +// Hide Company Tags Google Snapchat Facebook +// Hide Tags Dynamic Programming Backtracking Greedy String +// Hide Similar Problems (H) Regular Expression Matching + + + +/** + * @param {string} s + * @param {string} p + * @return {boolean} + */ + +var matchChar = function(c, p){ + return (p === '?' || p === c); +} +var isMatch = function(s, p) { + if(s === null || p === null) { + return false; + } + + var idxS = 0; + var idxP = 0; + + var lenS = s.length; + var lenP = p.length; + + var back = false; + var preS = 0; + var preP = 0; + + while(idxS < lenS) { + var charS = s[idxS]; + var charP = p[idxP]; + + if(idxP < lenP && matchChar(s[idxS], p[idxP])) { + idxP++; + idxS++; + } else if(idxP < lenP && p[idxP] === '*') { + while(idxP < lenP && p[idxP] === '*') { + idxP++; + } + + back = true; + preS = idxS; + preP = idxP; + } else if(back) { + // since * means any sequence including ''. We can use greedy approach + // str = "abefcdgiescdfimde" pattern = "ab*cd?i*de" + // first * is "ef" first ? is "g" second * is escdfim + idxS = ++preS; + idxP = preP; + // preP is the pattern index after * + // even idxP got advanced by first the condition idxP < lenP && matchChar(s[idxS], p[idxP]) + // when the first and second condition don't work out, we backtrack of using the last wild card position. + } else { + return false; + } + } + + while(idxP < lenP && p[idxP] === '*') { + idxP++; + } + + if(idxS === lenS && idxP === lenP) { + return true; + } + + return false; +}; \ No newline at end of file diff --git a/49 Group Anagrams.js b/49 Group Anagrams.js index bc02cc6..65e684c 100644 --- a/49 Group Anagrams.js +++ b/49 Group Anagrams.js @@ -39,4 +39,37 @@ var sort = function(s) { arr.sort((a,b)=> a > b ? 1 : -1); return arr.join(''); -} \ No newline at end of file +} + + + +// Use bucket sort, much faster + +/** + * @param {string[]} strs + * @return {string[][]} + */ +var groupAnagrams = function(strs) { + var hash = {}; + var base = 'a'.charCodeAt(0); + + for(var i = 0; i < strs.length; i++) { + var arr = Array(26).fill(0); + for(var j = 0; j < str.length; j++) { + var code = str[j].charCodeAt(0) - base; + arr[code]++; + } + + var key = arr.join(''); + hash[key] = hash[key] || []; + hash[key].push(strs[i]); + } + + var res = []; + + for(i in hash) { + res.push(hash[i]); + } + + return res; +}; diff --git a/57. Insert Interval.js b/57. Insert Interval.js index 7f23e5e..58d8469 100644 --- a/57. Insert Interval.js +++ b/57. Insert Interval.js @@ -42,19 +42,19 @@ var insert = function(intervals, newInterval) { if(isInsert) { result.push(interval); - } else if(newInterval.end < interval.start) { + } else if(newInterval.end < interval.start) { // insertion before the sorted interval result.push(newInterval); result.push(interval); isInsert = true; - } else if(interval.end < newInterval.start) { + } else if(interval.end < newInterval.start) { // no overlap at all result.push(interval); } else { newInterval.start = Math.min(newInterval.start, interval.start); newInterval.end = Math.max(newInterval.end, interval.end); } } - - if(!isInsert) { + + if(!isInsert) { // insertion at the very end; result.push(newInterval); } diff --git a/77 Combinations.js b/77 Combinations.js index a3a951b..b69d858 100644 --- a/77 Combinations.js +++ b/77 Combinations.js @@ -1,3 +1,20 @@ +// Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. + +// For example, +// If n = 4 and k = 2, a solution is: + +// [ +// [2,4], +// [3,4], +// [2,3], +// [1,2], +// [1,3], +// [1,4], +// ] +// Hide Tags Backtracking +// Hide Similar Problems (M) Combination Sum (M) Permutations + + /** * @param {number} n * @param {number} k diff --git a/78 Subsets.js b/78 Subsets.js index 030c477..9e35ac8 100644 --- a/78 Subsets.js +++ b/78 Subsets.js @@ -37,4 +37,25 @@ var generate = function(nums, index, cur, result) { cur.push(nums[index]); generate(nums, index + 1, cur, result); cur.pop(); -} \ No newline at end of file +} + + + +// second try + + +var subsets = function(nums) { + var res = [[]]; + + function generate(nums, i, cur, res) { + for(; i < nums.length; i++) { + cur.push(nums[i]); + res.push(cur.slice()); + generate(nums, i + 1, cur, res); + cur.pop(); + } + } + + generate(nums, 0, [], res); + return res; +}; \ No newline at end of file diff --git a/80 Remove Duplicates from Sorted Array II.js b/80 Remove Duplicates from Sorted Array II.js index dd04593..1de97ca 100644 --- a/80 Remove Duplicates from Sorted Array II.js +++ b/80 Remove Duplicates from Sorted Array II.js @@ -12,38 +12,28 @@ // Hide Similar Problems (E) Remove Element - /** * @param {number[]} nums * @return {number} */ var removeDuplicates = function(nums) { - var n = nums.length; - var index = 0; var oc = 1; + var sorted = 0; for(var i = 1; i < nums.length; i++) { - if(nums[index] === nums[i]) { + if(nums[i] === nums[sorted]) { if(oc === 2) { continue; } + oc++; } else { oc = 1; } - index++; - nums[index] = nums[i]; + sorted++; + nums[sorted] = nums[i]; } - return index + 1; -}; - - - -161700 - -70000 rsu => $538,000 4yrs 1 yr cliff 25% every quarter - -benefit - + return sorted + 1; +}; \ No newline at end of file diff --git a/90 Subsets II.js b/90 Subsets II.js index 8ed90a7..cea5958 100644 --- a/90 Subsets II.js +++ b/90 Subsets II.js @@ -1,3 +1,7 @@ +// provide many different solutions +// reference: http://bangbingsyb.blogspot.com/2014/11/leetcode-subsets-i-ii.html + + /** * @param {number[]} nums * @return {number[][]} From 0e13e2dda120a424614393f0e9bf06c7ffa82366 Mon Sep 17 00:00:00 2001 From: ignacio chiazzo cardarello Date: Fri, 17 Feb 2017 19:17:26 -0300 Subject: [PATCH 25/47] Permutation Solution --- 46 Permutations.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/46 Permutations.js b/46 Permutations.js index 467e1ee..47a6069 100644 --- a/46 Permutations.js +++ b/46 Permutations.js @@ -62,6 +62,28 @@ var generate = function(nums, index, visited, output, result) { } +// Another clear solution +var permute = function(nums) { + return permuteAux(nums, []); +}; + +var permuteAux = function(nums, partialNums) { + if(nums === null || nums.length === 0) { + return [partialNums]; + } + var listArrays = []; + for(var i = 0; i < nums.length; i++) { + var withoutI = nums.slice(0,i).concat(nums.slice(i + 1, nums.length)); + var partial = partialNums.concat([nums[i]]); + var sol = permuteAux(withoutI, partial); + if(sol.legnth !== 0) { + listArrays = listArrays.concat(sol); + } + } + return listArrays; +}; + + From efdff0e2fa4c05a0302196ed3dd9e05490dc0cfe Mon Sep 17 00:00:00 2001 From: ignacio chiazzo cardarello Date: Sat, 18 Feb 2017 10:14:55 -0300 Subject: [PATCH 26/47] Added another solution to Permutation || Similar approach that permutation.js --- 47 Permutations II.js | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/47 Permutations II.js b/47 Permutations II.js index 3bb9f3b..5bb29fa 100644 --- a/47 Permutations II.js +++ b/47 Permutations II.js @@ -50,4 +50,32 @@ var generatePermute = function(nums, step, currentResult, visited, finalResult) visited[i] = false; } } -} \ No newline at end of file +} + +//Another Solution, similar approach that Permutation.js +var permuteUnique = function(nums) { + return permut(nums.sort(), []); +}; + +var permut = function(nums, partial) { + if(nums.length === 0) { + return [partial]; + } + var listSol = []; + for(var i = 0; i < nums.length; i++) { + var endRepeated = i; + while(endRepeated < nums.length && nums[i] === nums[endRepeated]) { + endRepeated++; + } + + var arrayWithoutI = nums.slice(0,i).concat(nums.slice(i + 1, nums.length)); + var partialSol = partial.concat([nums[i]]); + var sol = permut(arrayWithoutI, partialSol); + if(sol.length > 0){ + listSol = listSol.concat(sol); + } + i = endRepeated - 1; + } + return listSol; +}; + From 47a816e07b863f42bfbbd12793799af423a01c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Tue, 21 Feb 2017 21:18:04 -0300 Subject: [PATCH 27/47] third solution subset --- 78 Subsets.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/78 Subsets.js b/78 Subsets.js index 9e35ac8..7540086 100644 --- a/78 Subsets.js +++ b/78 Subsets.js @@ -32,7 +32,7 @@ var generate = function(nums, index, cur, result) { result.push(cur.slice()); return } - + generate(nums, index + 1, cur, result); cur.push(nums[index]); generate(nums, index + 1, cur, result); @@ -42,11 +42,9 @@ var generate = function(nums, index, cur, result) { // second try - - var subsets = function(nums) { var res = [[]]; - + function generate(nums, i, cur, res) { for(; i < nums.length; i++) { cur.push(nums[i]); @@ -55,7 +53,24 @@ var subsets = function(nums) { cur.pop(); } } - + generate(nums, 0, [], res); return res; -}; \ No newline at end of file +}; + +// Third solution +var subsets = function(nums) { + var results = []; + combine(nums, 0, [], results); + return results; +} + +var combine = function(nums, index, partial, results) { + if(index === nums.length) { + results.push(partial); + return; + } + + combine(nums, index + 1, partial, results); + combine(nums, index + 1, partial.concat([nums[index]]), results); +} From a05d4ecc9c8c451f231f8b41562a9557d46ac5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Wed, 22 Feb 2017 11:21:18 -0300 Subject: [PATCH 28/47] combination Sum DFS Solution --- 39 Combination Sum.js | 46 ++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/39 Combination Sum.js b/39 Combination Sum.js index e8214d3..27e2607 100644 --- a/39 Combination Sum.js +++ b/39 Combination Sum.js @@ -5,8 +5,8 @@ // Note: // All numbers (including target) will be positive integers. // The solution set must not contain duplicate combinations. -// For example, given candidate set [2, 3, 6, 7] and target 7, -// A solution set is: +// For example, given candidate set [2, 3, 6, 7] and target 7, +// A solution set is: // [ // [7], // [2, 2, 3] @@ -24,37 +24,61 @@ */ var combinationSum = function(candidates, target) { var result = []; - + if(candidates === null || candidates.length === 0){ return result; } - + candidates.sort(function(a,b){return a > b ? 1 : -1}); - + var output = []; - + generate(candidates, result, output, target, 0); - + return result; }; var generate = function(candidates, result, output, sum, index){ if(sum === 0){ - result.push(output.slice()); + result.push(output.slice()); } if(sum < 0){ return; } - + for(var i = index; i < candidates.length; i++){ if(i > index && candidates[i] === candidates[i - 1]){ continue; } - + if(candidates[i] <= sum){ output.push(candidates[i]); generate(candidates, result, output, sum - candidates[i], i); output.pop(); } } -} \ No newline at end of file +} + + +// Another solution +var combinationSum = function(candidates, target) { + var results = []; + comb(candidates.sort(), 0, [], 0, target, results); + return results; +}; + +var comb = function(cand, index, partial, partialSum, target, results) { + if(target === partialSum) { + results.push(partial); + return; + } + if(cand.length === index || partialSum > target) { + return; + } + + comb(cand, index + 1, partial, partialSum, target, results); + comb(cand, index, partial.concat([cand[index]].concat([cand[index]])), + partialSum + 2* cand[index], target, results); + comb(cand, index + 1, partial.concat([cand[index]]), + partialSum + cand[index], target, results); +}; From 265a17ff9fba7c551a01c82694a8119dfc9e585d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Thu, 23 Feb 2017 14:45:38 -0300 Subject: [PATCH 29/47] another shorter solution to ind minimun in rotated array problem --- 153 Find Minimum in Rotated Sorted Array.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/153 Find Minimum in Rotated Sorted Array.js b/153 Find Minimum in Rotated Sorted Array.js index 7e98c2f..a01c797 100644 --- a/153 Find Minimum in Rotated Sorted Array.js +++ b/153 Find Minimum in Rotated Sorted Array.js @@ -10,10 +10,10 @@ var findMin = function(nums) { var s = 0; var e = nums.length - 1; var min; - + while(s nums[e]) { @@ -21,8 +21,17 @@ var findMin = function(nums) { } else { return nums[s]; } - + } - + return Math.min(nums[e], nums[s]); -}; \ No newline at end of file +}; + +// Another shorter solution; +var findMin = function(nums) { + var i = 0; + while(i < nums.length - 1 && nums[i] < nums[i + 1]) { + i++; + } + return (i === nums.length - 1)? nums[0] : nums[i + 1] +}; From f0235ccf88c0d58b00a70bead0da161647b980de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Fri, 24 Feb 2017 10:51:50 -0300 Subject: [PATCH 30/47] clearer solution rotate image --- 48 Rotate Image.js | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/48 Rotate Image.js b/48 Rotate Image.js index 68e2819..546ab53 100644 --- a/48 Rotate Image.js +++ b/48 Rotate Image.js @@ -11,20 +11,20 @@ */ var rotate = function(matrix) { var row = matrix.length; - + if(row === 0) { return; } - + var col = matrix[0].length; - + // swap them in diagonal for(var i = 0; i < row; i++) { for(var j = 0; j < col - i; j++) { swap(matrix, i, j, row - 1 - j, col - 1 - i); } } - + // swap in middle for(i = 0; i < Math.floor(row/2); i++) { for(j = 0; j < col; j++) { @@ -37,4 +37,37 @@ function swap(matrix, x1, y1, x2, y2) { var tmp = matrix[x1][y1]; matrix[x1][y1] = matrix[x2][y2]; matrix[x2][y2] = tmp; -} \ No newline at end of file +} + +//Clearer Solution +var rotate = function(matrix) { + rotateColumns(matrix); + rotateEachDiagonal(matrix); +}; + +var rotateColumns = function(matrix) { + for(var j = 0; j < matrix.length; j++) { + var low = 0; + var ceil = matrix.length -1; + while(low < ceil) { + swap(matrix, low, j, ceil, j); + low++; + ceil--; + } + } +}; + +var rotateEachDiagonal = function(matrix){ + for(var i = 0; i < matrix.length; i++) { + for(var j = i; j < matrix.length; j++) { + swap(matrix, i, j, j, i); + } + } +}; + +var swap = function(matrix, i1, j1, i2, j2) { + var aux = matrix[i1][j1]; + matrix[i1][j1] = matrix[i2][j2]; + matrix[i2][j2] = aux; +}; + From 9bc6945257b9b58ca5335525a514a093304cd220 Mon Sep 17 00:00:00 2001 From: ignacio chiazzo cardarello Date: Sat, 25 Feb 2017 09:08:44 -0300 Subject: [PATCH 31/47] Update 39 Combination Sum.js --- 39 Combination Sum.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/39 Combination Sum.js b/39 Combination Sum.js index 27e2607..d1878c5 100644 --- a/39 Combination Sum.js +++ b/39 Combination Sum.js @@ -75,10 +75,7 @@ var comb = function(cand, index, partial, partialSum, target, results) { if(cand.length === index || partialSum > target) { return; } - - comb(cand, index + 1, partial, partialSum, target, results); - comb(cand, index, partial.concat([cand[index]].concat([cand[index]])), - partialSum + 2* cand[index], target, results); - comb(cand, index + 1, partial.concat([cand[index]]), + comb(cand, index, partial.concat([cand[index]]), partialSum + cand[index], target, results); + comb(cand, index + 1, partial, partialSum, target, results); }; From ff610c9e0cf481305cac574bd89c015559c953e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Sun, 26 Feb 2017 22:55:24 -0300 Subject: [PATCH 32/47] another recursive solution --- 114 Flatten Binary Tree to Linked List.js | 29 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/114 Flatten Binary Tree to Linked List.js b/114 Flatten Binary Tree to Linked List.js index 2f68381..1b20145 100644 --- a/114 Flatten Binary Tree to Linked List.js +++ b/114 Flatten Binary Tree to Linked List.js @@ -16,12 +16,12 @@ var flatten = function(root) { var stack = []; var p = root; - + while(p !== null || stack.length !== 0){ if(p.right !== null){ stack.push(p.right); } - + if(p.left !== null){ // [!!!]point of confusing, if null then pop stack p.right = p.left; p.left = null; @@ -29,8 +29,31 @@ var flatten = function(root) { var node = stack.pop(); p.right = node; } - + p = p.right; } }; +// Recursive solution + +var flatten = function(root) { + if(root === null || (root.left === null && root.right === null)) { + return; + } + + var rootLeft = root.left; + var rootRight = root.right; + root.left = null; + root.right = null; + + flatten(rootLeft); + flatten(rootRight); + + root.right = rootLeft; + + var aux = root; + while(aux !== null && aux.right !== null) { + aux = aux.right; + } + aux.right = rootRight; +}; From f478dea49cb9e0e1059b7742ba871867c4047459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Sat, 4 Mar 2017 18:27:20 -0300 Subject: [PATCH 33/47] 3 Sum closest --- 16 3Sum Closest.js | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/16 3Sum Closest.js b/16 3Sum Closest.js index 2308633..66c0350 100644 --- a/16 3Sum Closest.js +++ b/16 3Sum Closest.js @@ -7,7 +7,7 @@ var threeSumClosest = function(nums, target) { if(nums === null || nums.length < 2){ return null; } - + if(nums.length === 3){ return nums.reduce(function(prev,cur){return prev + cur;}); } @@ -16,18 +16,18 @@ var threeSumClosest = function(nums, target) { var closest = Infinity; nums.sort(function(a,b){return a > b ? 1 : -1;}); - + for(var i = 0; i < nums.length; i++){ var j = i + 1; var k = nums.length - 1; while(j < k){ var sum = nums[j] + nums[k] + nums[i]; var diff = sum - target; - + if(diff === 0){ return sum; } - + if(sum < target){ diff = target - sum; j++; @@ -35,15 +35,45 @@ var threeSumClosest = function(nums, target) { diff = sum - target; k-- } - + if(diff < closest){ closest = diff; result = sum; } } - + while(i < (nums.length-1) && nums[i] === nums[i+1]) i++; } - + return result; -}; \ No newline at end of file +}; + +//Shorter solution +var threeSumClosest = function(nums, target) { + var closest = Number.Infinity; + var gap = -1; + + nums.sort(function(a, b) { return a - b }); + for(var i = 0; i < nums.length - 2; i++) { + var low = i + 1; + var high = nums.length - 1; + + while(low < high) { + var sum = nums[i] + nums[low] + nums[high]; + partialGap = Math.abs(target - sum); + if(partialGap < gap || gap === -1) { + gap = partialGap; + closest = sum; + } + + if(sum === target) { + return target; + } else if (sum < target) { + low++; + } else { + high--; + } + } + } + return closest; +}; From 39bb2baeba530b95fb2e2b0d649f9199dea9bdb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Sat, 4 Mar 2017 19:17:36 -0300 Subject: [PATCH 34/47] added 4 sum same approach as 3 sum --- 18. 4Sum.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 18. 4Sum.js diff --git a/18. 4Sum.js b/18. 4Sum.js new file mode 100644 index 0000000..7ba27ae --- /dev/null +++ b/18. 4Sum.js @@ -0,0 +1,41 @@ +/** + * @param {number[]} nums + * @param {number} target + * @return {number[][]} + */ +var fourSum = function(nums, target) { + var results = []; + nums.sort(function(a,b) { return a - b }); + for(var i = 0; i < nums.length - 3; i++) { + while(i > 0 && i < nums.length - 3 && nums[i] === nums[i - 1]) { + i++; + } + for(var j = i + 1; j < nums.length - 2; j++) { + while(j > i + 1 && j < nums.length - 2 && nums[j] === nums[j - 1]) { + j++; + } + var low = j + 1; + var high = nums.length - 1; + var newTarget = target - (nums[i] + nums[j]); + while(low < high) { + partialSum = nums[low] + nums[high]; + if(partialSum === newTarget) { + results.push([nums[i], nums[j], nums[low], nums[high]]); + high--; + low++; + while(low < high && nums[low] === nums[low - 1]) { + low++; + } + while(low < high && nums[high] === nums[high + 1]) { + high--; + } + } else if (partialSum > newTarget) { + high--; + } else { + low++; + } + } + } + } + return results; +}; From 0ab64594165a0403f586696a0b42ba0abbc1fd55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Sun, 5 Mar 2017 20:09:56 -0300 Subject: [PATCH 35/47] Added solution to 532. K-diff Pairs in an Array --- 532. K-diff Pairs in an Array.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 532. K-diff Pairs in an Array.js diff --git a/532. K-diff Pairs in an Array.js b/532. K-diff Pairs in an Array.js new file mode 100644 index 0000000..03e75bc --- /dev/null +++ b/532. K-diff Pairs in an Array.js @@ -0,0 +1,24 @@ +var findPairs = function(nums, k) { + if(nums.length === 0 || k < 0) { + return 0; + } + var dict = {}; + var count = 0; + + nums.sort(function(a,b){ return a - b }); + for(var i = 0; i < nums.length; i++) { + var number = nums[i]; + dict[number] = (dict[number] === undefined)? 1 : dict[number] += dict[number]; + } + for(var numb in dict) { + numb = parseInt(numb); + if(k === 0) { + if(dict[numb] > 1) { + count++; + } + } else if(dict[numb + k] !== undefined){ + count++; + } + } + return count; +}; From 28256c4f8c20cf2de31f08fa501a5cfb6ed4cc13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Wed, 8 Mar 2017 09:42:08 -0300 Subject: [PATCH 36/47] added single number III solution --- 260. Single Number III.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 260. Single Number III.js diff --git a/260. Single Number III.js b/260. Single Number III.js new file mode 100644 index 0000000..14a4a8c --- /dev/null +++ b/260. Single Number III.js @@ -0,0 +1,34 @@ +/** + * @param {number[]} nums + * @return {number[]} + */ +var singleNumber = function(nums) { + if(nums === null || nums.length <= 2) { + return nums; + } + + var xor = nums[0]; + for(var i = 1; i < nums.length; i++) { + xor ^= nums[i]; + } + + var exp = 1; + while(!(exp & xor)) { + exp = exp * 2; + } + console.log(exp); + var xorBit0 = 0; + var xorBit1 = 0; + + for(var j = 0; j < nums.length; j++) { + if(exp & nums[j]){ + xorBit1 ^= nums[j]; + console.log("with 1: " + nums[j]); + } else { + console.log("with 0: " + nums[j]); + xorBit0 ^= nums[j]; + } + } + + return [xorBit0, xorBit1]; +}; From cc229c45be6f9b390e6e05e0ae891757e63b0bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Fgnacio?= Date: Fri, 10 Mar 2017 16:21:23 -0300 Subject: [PATCH 37/47] simplified solutino search in rotated array --- 81 Search in Rotated Sorted Array II.js | 27 +++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/81 Search in Rotated Sorted Array II.js b/81 Search in Rotated Sorted Array II.js index 5f666d5..433e5dd 100644 --- a/81 Search in Rotated Sorted Array II.js +++ b/81 Search in Rotated Sorted Array II.js @@ -18,30 +18,31 @@ var search = function(nums, target) { var start = 0; var end = nums.length -1; - + while(start <= end){ - var mid = start + parseInt((end - start)/2); - - if(nums[mid] === target){ + var mid = parseInt((end + start)/2); + + if(nums[mid] === target ){ return true; } - - if(nums[start] < nums[mid]){ // in correct order - if(target >= nums[start] && target < nums[mid]){ // normal order part + + if(nums[start] === nums[mid]) { + start++; + } else if(nums[start] < nums[mid]){ // left part sorted + if(target >= nums[start] && target < nums[mid]){ end = mid - 1; } else { start = mid + 1; } - } else if(nums[mid] < nums[start]) { // incorrect order - if(target <= nums[end] && target > nums[mid]){ // normal order part + } else { //right part sorted + if(target <= nums[end] && target > nums[mid]){ // normal order part start = mid + 1; } else { end = mid -1; } - } else { - start++; } } - + return false; -}; \ No newline at end of file +}; + From 77db876455ffbea67d5321a5dc33e8cbc29e8520 Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Tue, 2 Jan 2018 23:12:11 -0800 Subject: [PATCH 38/47] improved num 4 --- 4. Median of Two Sorted Arrays.js | 98 +++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 25 deletions(-) diff --git a/4. Median of Two Sorted Arrays.js b/4. Median of Two Sorted Arrays.js index c740e91..0b85a80 100644 --- a/4. Median of Two Sorted Arrays.js +++ b/4. Median of Two Sorted Arrays.js @@ -1,46 +1,94 @@ +// /** +// * @param {number[]} nums1 +// * @param {number[]} nums2 +// * @return {number} +// */ + +// // http://blog.csdn.net/yutianzuijin/article/details/11499917 +// var findMedianSortedArrays = function(nums1, nums2) { +// var m = nums1.length; +// var n = nums2.length; +// var total = m + n; + +// if(total%2 === 1) { +// return findKth(nums1, m, nums2, n, parseInt(total/2) + 1); +// } else { +// return (findKth(nums1, m, nums2, n, parseInt(total/2)) + findKth(nums1, m, nums2, n, parseInt(total/2) + 1))/2; +// } +// }; + + +// function findKth(a, m, b, n, k) { +// // always assume that m is equal or smaller than n +// if(m > n) { +// return findKth(b, n, a, m, k); +// } + +// if(m === 0) { +// return b[k-1]; +// } + +// if(k === 1) { +// return Math.min(a[0],b[0]); +// } + +// // divide k into two parts +// var pa = Math.min(parseInt(k/2), m); +// var pb = k - pa; + +// if(a[pa - 1] < b[pb - 1]) { +// return findKth(a.slice(pa), m - pa, b, n, k - pa); +// } else if(a[pa - 1] > b[pb - 1]) { +// return findKth(a, m, b.slice(pb), n - pb, k - pb); +// } else { +// return a[pa - 1]; +// } +// } + + /** * @param {number[]} nums1 * @param {number[]} nums2 * @return {number} */ - -// http://blog.csdn.net/yutianzuijin/article/details/11499917 var findMedianSortedArrays = function(nums1, nums2) { - var m = nums1.length; - var n = nums2.length; - var total = m + n; + var total = nums1.length + nums2.length; - if(total%2 === 1) { - return findKth(nums1, m, nums2, n, parseInt(total/2) + 1); + if (total % 2 === 1) { + return findKth(nums1, 0, nums2, 0, parseInt(total/2) + 1); } else { - return (findKth(nums1, m, nums2, n, parseInt(total/2)) + findKth(nums1, m, nums2, n, parseInt(total/2) + 1))/2; + return ( + findKth(nums1, 0, nums2, 0, parseInt(total/2)) + + findKth(nums1, 0, nums2, 0, parseInt(total/2) + 1) + )/2; } }; - -function findKth(a, m, b, n, k) { - // always assume that m is equal or smaller than n - if(m > n) { - return findKth(b, n, a, m, k); +function findKth(nums1, start1, nums2, start2, kth) { + var len1 = nums1.length - start1; + var len2 = nums2.length - start2; + + if (len1 > len2) { + return findKth(nums2, start2, nums1, start1, kth); } - if(m === 0) { - return b[k-1]; + if (len1 === 0) { + return nums2[kth - 1]; } - if(k === 1) { - return Math.min(a[0],b[0]); + if (kth === 1) { + return Math.min(nums1[start1], nums2[start2]); } - // divide k into two parts - var pa = Math.min(parseInt(k/2), m); - var pb = k - pa; + // divide kth into 2 parts + var part1 = Math.min(parseInt(kth/2), len1); + var part2 = kth - part1; - if(a[pa - 1] < b[pb - 1]) { - return findKth(a.slice(pa), m - pa, b, n, k - pa); - } else if(a[pa - 1] > b[pb - 1]) { - return findKth(a, m, b.slice(pb), n - pb, k - pb); + if (nums1[start1 + part1 - 1] < nums2[start2 + part2 - 1]) { + return findKth(nums1, start1 + part1, nums2, start2, kth - part1); + } else if (nums1[start1 + part1 - 1] > nums2[start2 + part2 - 1]) { + return findKth(nums1, start1, nums2, start2 + part2, kth - part2); } else { - return a[pa - 1]; + return nums1[start1 + part1 - 1]; } } \ No newline at end of file From 4151859e2403cd3893d57d110219db72186a7e2b Mon Sep 17 00:00:00 2001 From: chihungyu1116 Date: Mon, 15 Jan 2018 17:23:32 -0800 Subject: [PATCH 39/47] add more --- 112 Path Sum.js | 27 ++++++++++ 141 Linked List Cycle.js | 63 ++++++++++++++++++----- 190 Reverse Bits.js | 10 ++-- 242 Valid Anagram.js | 39 ++++++++++++++ 26 Remove Duplicates from Sorted Array.js | 23 ++++++++- 278 First Bad Version.js | 49 ++++++++++++++++-- 35 Search Insert Position.js | 51 ++++++++++++++---- 9 Palindrome Number.js | 46 ----------------- 8 files changed, 230 insertions(+), 78 deletions(-) delete mode 100644 9 Palindrome Number.js diff --git a/112 Path Sum.js b/112 Path Sum.js index b9e0d9e..3ecd17f 100644 --- a/112 Path Sum.js +++ b/112 Path Sum.js @@ -24,4 +24,31 @@ var hasPathSum = function(root, sum) { } return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); +}; + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {number} sum + * @return {boolean} + */ +var hasPathSum = function(root, sum) { + if (root === null) { + return false; + } + + var left = root.left; + var right = root.right; + + if (left === null && right === null) { + return root.val === sum; + } + + return hasPathSum(left, sum - root.val) || hasPathSum(right, sum - root.val); }; \ No newline at end of file diff --git a/141 Linked List Cycle.js b/141 Linked List Cycle.js index a4d76ad..ea7e272 100644 --- a/141 Linked List Cycle.js +++ b/141 Linked List Cycle.js @@ -2,6 +2,44 @@ // Language: Javascript // Problem: https://leetcode.com/problems/linked-list-cycle/ // Author: Chihung Yu +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {boolean} + */ +// var hasCycle = function(head) { +// if(head === null || head.next === null){ +// return false; +// } + +// var faster = head.next; +// var slower = head; + +// while(faster && slower){ +// if(faster.val === slower.val){ +// return true; +// } +// faster = faster.next; + +// if(faster === null){ +// return false; +// } else { +// faster = faster.next; +// } + +// slower = slower.next; +// } + +// return false; +// }; + /** * Definition for singly-linked list. * function ListNode(val) { @@ -15,26 +53,27 @@ * @return {boolean} */ var hasCycle = function(head) { - if(head === null || head.next === null){ + if (head === null) { return false; } + + var node1 = head; + var node2 = head; + node2 = node2.next; - var faster = head.next; - var slower = head; - - while(faster && slower){ - if(faster.val === slower.val){ + while(node1 !== null && node2 !== null) { + if (node1.val === node2.val) { return true; } - faster = faster.next; + + node1 = node1.next; + node2 = node2.next; - if(faster === null){ - return false; - } else { - faster = faster.next; + if (node2 !== null) { + node2 = node2.next; } - slower = slower.next; + } return false; diff --git a/190 Reverse Bits.js b/190 Reverse Bits.js index 76911a0..04d3eb1 100644 --- a/190 Reverse Bits.js +++ b/190 Reverse Bits.js @@ -9,11 +9,15 @@ var reverseBits = function(n) { var result = 0; - for(var i = 0; i < 32; i++){ + for(var i = 0; i < 31; i++){ result <<= 1; result |= n & 1; - n >>= 1; + + n >>>= 1; + console.log(result, n); } return Math.abs(result); -}; \ No newline at end of file +}; + +console.log(reverseBits(4294967295)); \ No newline at end of file diff --git a/242 Valid Anagram.js b/242 Valid Anagram.js index bccbafb..151c4c0 100644 --- a/242 Valid Anagram.js +++ b/242 Valid Anagram.js @@ -38,4 +38,43 @@ var isAnagram = function(s, t) { } return true; +}; + + + + +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ +var isAnagram = function(s, t) { + if (s === null || t === null || s.length !== t.length) { + return false; + } + + var hash = {}; + var i; + for(i = 0; i < s.length; i++) { + var sval = s[i]; + var tval = t[i]; + + if (hash[sval] === undefined) { + hash[sval] = 0; + } + + if (hash[tval] === undefined) { + hash[tval] = 0; + } + hash[sval]++; + hash[tval]--; + } + + for(var j in hash) { + if (hash[j] !== 0) { + return false; + } + } + + return true; }; \ No newline at end of file diff --git a/26 Remove Duplicates from Sorted Array.js b/26 Remove Duplicates from Sorted Array.js index 80f8f6a..04f251e 100644 --- a/26 Remove Duplicates from Sorted Array.js +++ b/26 Remove Duplicates from Sorted Array.js @@ -58,4 +58,25 @@ var removeDuplicates = function(nums) { }; -// [tricky] \ No newline at end of file +// [tricky] + +/** + * @param {number[]} nums + * @return {number} + */ +var removeDuplicates = function(nums) { + var hash = {}; + var cur = 0; + + for(var i = 0; i < nums.length; i++) { + var num = nums[i]; + + if (hash[num] === undefined) { + hash[num] = true; + nums[cur] = num; + cur++; + } + } + + return cur; +}; \ No newline at end of file diff --git a/278 First Bad Version.js b/278 First Bad Version.js index 7013caa..bdccb14 100644 --- a/278 First Bad Version.js +++ b/278 First Bad Version.js @@ -14,7 +14,7 @@ /** * Definition for isBadVersion() - * + * * @param {integer} version number * @return {boolean} whether the version is bad * isBadVersion = function(version) { @@ -35,7 +35,7 @@ var solution = function(isBadVersion) { var beg = 0; var end = n; var lastBad; - + while(beg <= end) { var mid = beg + Math.floor((end - beg)/2); if(isBadVersion(mid)) { @@ -43,10 +43,49 @@ var solution = function(isBadVersion) { lastBad = mid; end = mid - 1; } else { - beg = mid + 1; + beg = mid + 1; } } - + return lastBad; }; -}; \ No newline at end of file +}; + + + +/** + * Definition for isBadVersion() + * + * @param {integer} version number + * @return {boolean} whether the version is bad + * isBadVersion = function(version) { + * ... + * }; + */ + +/** + * @param {function} isBadVersion() + * @return {function} + */ +var solution = function(isBadVersion) { + /** + * @param {integer} n Total versions + * @return {integer} The first bad version + */ + return function(n) { + var left = 1; + var right = n; + + while (left < right) { + var mid = left + Math.floor((right - left)/2); + + if (isBadVersion(mid)) { + right = mid; + } else { + left = mid + 1; + } + } + + return left; + }; +}; diff --git a/35 Search Insert Position.js b/35 Search Insert Position.js index 40cc05c..bba8074 100644 --- a/35 Search Insert Position.js +++ b/35 Search Insert Position.js @@ -2,6 +2,37 @@ // Language: Javascript // Problem: https://leetcode.com/problems/search-insert-position/ // Author: Chihung Yu +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +// var searchInsert = function(nums, target) { +// var left = 0; +// var right = nums.length - 1; +// +// while(left <= right){ +// var mid = parseInt((left + right)/2); +// +// var val = nums[mid]; +// +// if(val === target){ +// return mid; +// } else if(val > target){ +// right = mid - 1; +// } else { +// left = mid + 1; +// } +// } +// +// if(nums[left] < target){ +// return left + 1; +// } else { +// return left; +// } +// }; + + /** * @param {number[]} nums * @param {number} target @@ -10,24 +41,22 @@ var searchInsert = function(nums, target) { var left = 0; var right = nums.length - 1; - - while(left <= right){ - var mid = parseInt((left + right)/2); - - var val = nums[mid]; - - if(val === target){ + + while (left < right) { + var mid = left + Math.ceil((right - left)/2); + + if (nums[mid] === target) { return mid; - } else if(val > target){ + } else if (nums[mid] > target) { right = mid - 1; } else { left = mid + 1; } } - - if(nums[left] < target){ + + if (nums[left] < target) { return left + 1; } else { return left; } -}; \ No newline at end of file +} diff --git a/9 Palindrome Number.js b/9 Palindrome Number.js deleted file mode 100644 index 2fc423b..0000000 --- a/9 Palindrome Number.js +++ /dev/null @@ -1,46 +0,0 @@ -// Leetcode #9: -// Language: Javascript -// Problem: https://leetcode.com/problems/palindrome-number/ -// Author: Chihung Yu - -// Determine whether an integer is a palindrome. Do this without extra space. - - /** - * @param {number} x - * @return {boolean} - */ -var isPalindrome = function(x) { - if(x < 0) { - return false; - } - - var div = 1; - - // it means that the div is still a valid divider - // e.g 600 the divider should be 100 at maximum - // e.g. 90 the divider should be 10 at maximum - // e.g. 1 the divider should be a 1 at maximum - while(parseInt(x/div) >= 10) { - div *= 10; - } - - var left, right; - - // when div === 1 it means the digit only has one value to examine - // e.g. 121 -> only 2 is left for examine which can be ignore - // e.g. 1 -> 1 - // e.g. 43234 -> 2 - while(div > 1) { - left = parseInt(x/div); - right = x%10; - if(left !== right) { - return false; - } - - x = x%div; // remove the left most digit - x = parseInt(x/10); // remove the right most digit - div /= 100; - } - - return true; -}; \ No newline at end of file From e40613996c62271facf00778c4802f8ae0878903 Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Sat, 22 Jun 2019 12:29:03 -0700 Subject: [PATCH 40/47] update --- 1 Two Sum.js | 37 ---------------- 10 Regular Expresion Matching.js | 73 -------------------------------- 2 Add Two Numbers.js | 73 -------------------------------- 3 files changed, 183 deletions(-) delete mode 100644 1 Two Sum.js delete mode 100644 10 Regular Expresion Matching.js delete mode 100644 2 Add Two Numbers.js diff --git a/1 Two Sum.js b/1 Two Sum.js deleted file mode 100644 index ed67bd0..0000000 --- a/1 Two Sum.js +++ /dev/null @@ -1,37 +0,0 @@ -// Given an array of integers, return indices of the two numbers such that they add up to a specific target. - -// You may assume that each input would have exactly one solution. - -// Example: -// Given nums = [2, 7, 11, 15], target = 9, - -// Because nums[0] + nums[1] = 2 + 7 = 9, -// return [0, 1]. -// UPDATE (2016/2/13): -// The return format had been changed to zero-based indices. Please read the above updated description carefully. - -// Hide Company Tags LinkedIn Uber Airbnb Facebook Amazon Microsoft Apple Yahoo Dropbox Bloomberg Yelp Adobe -// Hide Tags Array Hash Table -// Hide Similar Problems (M) 3Sum (M) 4Sum (M) Two Sum II - Input array is sorted (E) Two Sum III - Data structure design - - - -/** - * @param {number[]} nums - * @param {number} target - * @return {number[]} - */ -var twoSum = function(nums, target) { - var hash = {}; - - for(var i = 0; i < nums.length; i++) { - var num = nums[i]; - if(hash[num] !== undefined) { - return [hash[num], i] - } else { - hash[target - num] = i; - } - } - - return []; -}; \ No newline at end of file diff --git a/10 Regular Expresion Matching.js b/10 Regular Expresion Matching.js deleted file mode 100644 index ca77413..0000000 --- a/10 Regular Expresion Matching.js +++ /dev/null @@ -1,73 +0,0 @@ -// https://www.youtube.com/watch?v=l3hda49XcDE#t=211.113333 - -// 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). - -// The function prototype should be: -// bool isMatch(const char *s, const char *p) - -// Some examples: -// isMatch("aa","a") → false -// isMatch("aa","aa") → true -// isMatch("aaa","aa") → false -// isMatch("aa", "a*") → true -// isMatch("aa", ".*") → true -// isMatch("ab", ".*") → true -// isMatch("aab", "c*a*b") → true - -/** - * @param {string} s - * @param {string} p - * @return {boolean} - */ -var isMatch = function(s, p) { - var sLen = s.length; - var pLen = p.length; - var dp = []; - - for(var i = 0; i <= sLen; i++) { - var tmp = []; - - for(var j = 0; j <= pLen; j++) { - tmp.push(false); - } - - dp.push(tmp); - } - - dp[0][0] = true; - - for(i = 0; i <= sLen; i++) { - for(j = 0; j <= pLen; j++) { - if(p[j - 1] !== '.' && p[j - 1] !== '*') { - if(i > 0 && p[j - 1] === s[i - 1] && dp[i - 1][j - 1]) { - dp[i][j] = true; - } - } else if(p[j - 1] === '.') { - if(i > 0 && dp[i - 1][j - 1]) { - dp[i][j] = true; - } - } else if(j > 1) { // '*' cannot be the first element - if(dp[i][j - 2]) { // 0 occurance - dp[i][j] = true; - } else if(i > 0 && (p[j - 2] === s[i - 1] || p[j - 2] === '.') && dp[i - 1][j]) { - - // example - // xa and xa* - // s[i-1] === a - // p[j-2] === a - // a === a - // so we can now compare x, xa* - // and x here is dp[i-1][j] - dp[i][j] = true; - } - } - } - } - - return dp[sLen][pLen]; -}; \ No newline at end of file diff --git a/2 Add Two Numbers.js b/2 Add Two Numbers.js deleted file mode 100644 index b13270e..0000000 --- a/2 Add Two Numbers.js +++ /dev/null @@ -1,73 +0,0 @@ -// You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. - -// Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) -// Output: 7 -> 0 -> 8 - -// Amazon Microsoft Bloomberg Airbnb Adobe - -/** - * Definition for singly-linked list. - * function ListNode(val) { - * this.val = val; - * this.next = null; - * } - */ -/** - * @param {ListNode} l1 - * @param {ListNode} l2 - * @return {ListNode} - */ - - - -// value reverse helps to asslign the first digit or both linklist - -var addTwoNumbers = function(l1, l2) { - if(l1 === null || l2 === null){ - return l1 || l2; - } - - var result = new ListNode(0); - var cur = result; - var p = l1; - var q = l2; - var carry = 0; - - while(p || q){ - var qval; - var pval; - - if(q){ - qval = q.val; - q = q.next; - } else { - qval = 0; - } - - if(p){ - pval = p.val; - p = p.next; - } else { - pval = 0; - } - - var val = qval + pval + carry; - - if(val > 9){ - carry = 1; - val %= 10; - } else { - carry = 0; - } - - cur.next = new ListNode(val); - cur = cur.next; - } - - if(carry !== 0){ - cur.next = new ListNode(1); - } - - return result.next; - -}; \ No newline at end of file From 9fa76794755eb1a0470b85087387333e1cb5cb1c Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Sat, 22 Jun 2019 12:29:35 -0700 Subject: [PATCH 41/47] update --- [0001] Two Sum.js | 37 ++++++++++++++ [0002] Add Two Numbers.js | 55 +++++++++++++++++++++ [0010] Regular Expresion Matching.js | 73 ++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 [0001] Two Sum.js create mode 100644 [0002] Add Two Numbers.js create mode 100644 [0010] Regular Expresion Matching.js diff --git a/[0001] Two Sum.js b/[0001] Two Sum.js new file mode 100644 index 0000000..ed67bd0 --- /dev/null +++ b/[0001] Two Sum.js @@ -0,0 +1,37 @@ +// Given an array of integers, return indices of the two numbers such that they add up to a specific target. + +// You may assume that each input would have exactly one solution. + +// Example: +// Given nums = [2, 7, 11, 15], target = 9, + +// Because nums[0] + nums[1] = 2 + 7 = 9, +// return [0, 1]. +// UPDATE (2016/2/13): +// The return format had been changed to zero-based indices. Please read the above updated description carefully. + +// Hide Company Tags LinkedIn Uber Airbnb Facebook Amazon Microsoft Apple Yahoo Dropbox Bloomberg Yelp Adobe +// Hide Tags Array Hash Table +// Hide Similar Problems (M) 3Sum (M) 4Sum (M) Two Sum II - Input array is sorted (E) Two Sum III - Data structure design + + + +/** + * @param {number[]} nums + * @param {number} target + * @return {number[]} + */ +var twoSum = function(nums, target) { + var hash = {}; + + for(var i = 0; i < nums.length; i++) { + var num = nums[i]; + if(hash[num] !== undefined) { + return [hash[num], i] + } else { + hash[target - num] = i; + } + } + + return []; +}; \ No newline at end of file diff --git a/[0002] Add Two Numbers.js b/[0002] Add Two Numbers.js new file mode 100644 index 0000000..8142f50 --- /dev/null +++ b/[0002] Add Two Numbers.js @@ -0,0 +1,55 @@ +// You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + +// Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) +// Output: 7 -> 0 -> 8 + +// Amazon Microsoft Bloomberg Airbnb Adobe + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} l1 + * @param {ListNode} l2 + * @return {ListNode} + */ + + + +// value reverse helps to asslign the first digit or both linklist +var addTwoNumbers = function(l1, l2) { + const answer = new ListNode(0); + var node = answer; + var carry = 0; + while(l1 !== null || l2 !== null || carry !== 0) { + var val = 0; + if (carry !== 0) { + val += carry; + } + carry = 0; + if (l1 !== null) { + val += l1.val; + } + if (l2 !== null) { + val += l2.val; + } + if (val > 9) { + val -= 10; + carry = 1; + } + node.next = new ListNode(val); + node = node.next; + if (l1 !== null) { + l1 = l1.next; + } + if (l2 !== null) { + l2 = l2.next; + } + } + + return answer.next; +}; diff --git a/[0010] Regular Expresion Matching.js b/[0010] Regular Expresion Matching.js new file mode 100644 index 0000000..ca77413 --- /dev/null +++ b/[0010] Regular Expresion Matching.js @@ -0,0 +1,73 @@ +// https://www.youtube.com/watch?v=l3hda49XcDE#t=211.113333 + +// 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). + +// The function prototype should be: +// bool isMatch(const char *s, const char *p) + +// Some examples: +// isMatch("aa","a") → false +// isMatch("aa","aa") → true +// isMatch("aaa","aa") → false +// isMatch("aa", "a*") → true +// isMatch("aa", ".*") → true +// isMatch("ab", ".*") → true +// isMatch("aab", "c*a*b") → true + +/** + * @param {string} s + * @param {string} p + * @return {boolean} + */ +var isMatch = function(s, p) { + var sLen = s.length; + var pLen = p.length; + var dp = []; + + for(var i = 0; i <= sLen; i++) { + var tmp = []; + + for(var j = 0; j <= pLen; j++) { + tmp.push(false); + } + + dp.push(tmp); + } + + dp[0][0] = true; + + for(i = 0; i <= sLen; i++) { + for(j = 0; j <= pLen; j++) { + if(p[j - 1] !== '.' && p[j - 1] !== '*') { + if(i > 0 && p[j - 1] === s[i - 1] && dp[i - 1][j - 1]) { + dp[i][j] = true; + } + } else if(p[j - 1] === '.') { + if(i > 0 && dp[i - 1][j - 1]) { + dp[i][j] = true; + } + } else if(j > 1) { // '*' cannot be the first element + if(dp[i][j - 2]) { // 0 occurance + dp[i][j] = true; + } else if(i > 0 && (p[j - 2] === s[i - 1] || p[j - 2] === '.') && dp[i - 1][j]) { + + // example + // xa and xa* + // s[i-1] === a + // p[j-2] === a + // a === a + // so we can now compare x, xa* + // and x here is dp[i-1][j] + dp[i][j] = true; + } + } + } + } + + return dp[sLen][pLen]; +}; \ No newline at end of file From 115eeff08d94c40cc6568a1e321d26712b701742 Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Sat, 22 Jun 2019 15:07:37 -0700 Subject: [PATCH 42/47] update --- ...js => [0003] Longest Substring Without Repeating Characters.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 3 Longest Substring Without Repeating Characters.js => [0003] Longest Substring Without Repeating Characters.js (100%) diff --git a/3 Longest Substring Without Repeating Characters.js b/[0003] Longest Substring Without Repeating Characters.js similarity index 100% rename from 3 Longest Substring Without Repeating Characters.js rename to [0003] Longest Substring Without Repeating Characters.js From aa9af43396cce8024e43b3bd11d6a2eec5181e7d Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Sun, 23 Jun 2019 18:03:33 -0700 Subject: [PATCH 43/47] update --- 4. Median of Two Sorted Arrays.js | 94 ------------------------------- 1 file changed, 94 deletions(-) delete mode 100644 4. Median of Two Sorted Arrays.js diff --git a/4. Median of Two Sorted Arrays.js b/4. Median of Two Sorted Arrays.js deleted file mode 100644 index 0b85a80..0000000 --- a/4. Median of Two Sorted Arrays.js +++ /dev/null @@ -1,94 +0,0 @@ -// /** -// * @param {number[]} nums1 -// * @param {number[]} nums2 -// * @return {number} -// */ - -// // http://blog.csdn.net/yutianzuijin/article/details/11499917 -// var findMedianSortedArrays = function(nums1, nums2) { -// var m = nums1.length; -// var n = nums2.length; -// var total = m + n; - -// if(total%2 === 1) { -// return findKth(nums1, m, nums2, n, parseInt(total/2) + 1); -// } else { -// return (findKth(nums1, m, nums2, n, parseInt(total/2)) + findKth(nums1, m, nums2, n, parseInt(total/2) + 1))/2; -// } -// }; - - -// function findKth(a, m, b, n, k) { -// // always assume that m is equal or smaller than n -// if(m > n) { -// return findKth(b, n, a, m, k); -// } - -// if(m === 0) { -// return b[k-1]; -// } - -// if(k === 1) { -// return Math.min(a[0],b[0]); -// } - -// // divide k into two parts -// var pa = Math.min(parseInt(k/2), m); -// var pb = k - pa; - -// if(a[pa - 1] < b[pb - 1]) { -// return findKth(a.slice(pa), m - pa, b, n, k - pa); -// } else if(a[pa - 1] > b[pb - 1]) { -// return findKth(a, m, b.slice(pb), n - pb, k - pb); -// } else { -// return a[pa - 1]; -// } -// } - - -/** - * @param {number[]} nums1 - * @param {number[]} nums2 - * @return {number} - */ -var findMedianSortedArrays = function(nums1, nums2) { - var total = nums1.length + nums2.length; - - if (total % 2 === 1) { - return findKth(nums1, 0, nums2, 0, parseInt(total/2) + 1); - } else { - return ( - findKth(nums1, 0, nums2, 0, parseInt(total/2)) - + findKth(nums1, 0, nums2, 0, parseInt(total/2) + 1) - )/2; - } -}; - -function findKth(nums1, start1, nums2, start2, kth) { - var len1 = nums1.length - start1; - var len2 = nums2.length - start2; - - if (len1 > len2) { - return findKth(nums2, start2, nums1, start1, kth); - } - - if (len1 === 0) { - return nums2[kth - 1]; - } - - if (kth === 1) { - return Math.min(nums1[start1], nums2[start2]); - } - - // divide kth into 2 parts - var part1 = Math.min(parseInt(kth/2), len1); - var part2 = kth - part1; - - if (nums1[start1 + part1 - 1] < nums2[start2 + part2 - 1]) { - return findKth(nums1, start1 + part1, nums2, start2, kth - part1); - } else if (nums1[start1 + part1 - 1] > nums2[start2 + part2 - 1]) { - return findKth(nums1, start1, nums2, start2 + part2, kth - part2); - } else { - return nums1[start1 + part1 - 1]; - } -} \ No newline at end of file From 40e026aa3550a3b9d3f9260517f533425e6fc4d1 Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Wed, 11 Mar 2020 09:15:52 -0700 Subject: [PATCH 44/47] add comment --- 11 Container With Most Water.js | 34 +++++++-- 31 Next Permutation.js | 56 ++++++++++++++- 55 Jump Game.js | 3 +- 76 Minimum Window Substring.js | 71 ++++++++++++++++++- ... Substring Without Repeating Characters.js | 3 + 5 files changed, 157 insertions(+), 10 deletions(-) diff --git a/11 Container With Most Water.js b/11 Container With Most Water.js index 4afac2b..3e1a596 100644 --- a/11 Container With Most Water.js +++ b/11 Container With Most Water.js @@ -1,3 +1,29 @@ +// Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. +// +// Note: You may not slant the container and n is at least 2. +// +// The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. +// +// Example: +// +// Input: [1,8,6,2,5,4,8,3,7] +// Output: 49 +// + + +// Given fixed set of vertical bars +// Min case +// +// . . +// . . . . +// . . . . . . + +// Max case +// +// . . +// . . . . +// . . . . . . + /** * @param {number[]} height * @return {number} @@ -6,17 +32,17 @@ var maxArea = function(height) { var left = 0; var right = height.length - 1; var maxVal = 0; - + while(left= height[right]){ right--; } else { left++; } } - + return maxVal; -}; \ No newline at end of file +}; diff --git a/31 Next Permutation.js b/31 Next Permutation.js index 214b022..1f90369 100644 --- a/31 Next Permutation.js +++ b/31 Next Permutation.js @@ -6,13 +6,22 @@ var nextPermutation = function(nums) { var vioIndex = nums.length - 1; + + // example + // 1. 687432 + // the violation index is 1 (number 8) since it's greater than index 0 (number 6) + // 2. 87452 + // the violation index is 3 (number 5) since it's greater than index 2 (number 4) while(vioIndex > 0) { if(nums[vioIndex - 1] < nums[vioIndex]) { break; } vioIndex--; } - + + + // If it's not already the maximum value i.e. 876432 in the example of 687432 the maximum is 876432 + // then swap the the 6 with 7 since 7 a just a tad bigger if(vioIndex > 0) { vioIndex--; var first = nums.length - 1; @@ -37,4 +46,49 @@ var nextPermutation = function(nums) { end--; vioIndex++; } +}; + + + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ +var nextPermutation = function(nums) { + var violatedIndex = nums.length - 1; + + while(violatedIndex > 0) { + if (nums[violatedIndex] > nums[violatedIndex-1]) { + break; + } + violatedIndex--; + } + + // max + if (violatedIndex > 0) { + violatedIndex--; + + var indexToSwapWith = nums.length - 1; + while(indexToSwapWith > violatedIndex) { + if (nums[indexToSwapWith] > nums[violatedIndex]) { + var temp = nums[violatedIndex]; + nums[violatedIndex] = nums[indexToSwapWith]; + nums[indexToSwapWith] = temp; + break; + } + indexToSwapWith-- + } + + violatedIndex++; + } + + var end = nums.length - 1; + + while(end > violatedIndex) { + temp = nums[violatedIndex]; + nums[violatedIndex] = nums[end]; + nums[end] = temp; + end-- + violatedIndex++; + } }; \ No newline at end of file diff --git a/55 Jump Game.js b/55 Jump Game.js index a31f2f4..1433dc6 100644 --- a/55 Jump Game.js +++ b/55 Jump Game.js @@ -11,6 +11,5 @@ var canJump = function(nums) { } numLeft = Math.max(nums[i], numLeft); } - - return numLeft >= 0; + return true; }; \ No newline at end of file diff --git a/76 Minimum Window Substring.js b/76 Minimum Window Substring.js index c5e1262..e18e98b 100644 --- a/76 Minimum Window Substring.js +++ b/76 Minimum Window Substring.js @@ -26,8 +26,8 @@ var minWindow = function(s, t) { var lenS = s.length; var lenT = t.length; var queue = []; - var tRequireCount = {}; - var tFoundCount = {}; + var tRequireCount = {}; // string T required count + var tFoundCount = {}; // string T found count var hasFound = 0; var windowBeg = -1; var windowEnd = lenS; @@ -41,6 +41,7 @@ var minWindow = function(s, t) { } for(i = 0; i < lenS; i++) { + // cannot use tRequireCount[s[i]] !== 0 since tRequireCount[s[i]] might be undefined if(tRequireCount[s[i]] > 0) { // use queue to skip a lot of redudant character // minWindow('aeeeeeebceeeeaeeedcb', 'abc'); @@ -53,7 +54,13 @@ var minWindow = function(s, t) { // if found count is over require count, we don't need those extra, so don't record it to hasFound if(tFoundCount[s[i]] <= tRequireCount[s[i]]) { - hasFound++; + // hasFound is used as a flag for knowing where we should check against T string and when we should start reducing the range + // for example + // minWindow('aaaaebceeeeaeeedcb', 'abc'); + // at index 5 where s[i] is e, hasFound is 1 and tFoundCount['a'] is 4, queue=[0,1,2,3] + // when we arrive at index 7 where s[i] is c, has found is now 3 and is equal to lenT + // now we can start reducing the range all the way from index 0(a) to index 7(c) to index 3(a) to index 7 (c) which will give us the min + hasFound++; } // when the current location which is in queue @@ -73,9 +80,67 @@ var minWindow = function(s, t) { // 1st round 0 8 // 2nd round 7 13 } + // since i must be the last match that leads to hasFound === lenT + hasFound--; + } + } + } + + return windowBeg !== -1 ? s.substring(windowBeg, windowEnd + 1) : ''; +}; + + +/** + * @param {string} s + * @param {string} t + * @return {string} + */ +var minWindow = function(s, t) { + var lenS = s.length; + var lenT = t.length; + var tCharToFoundCount = {}; + var tCharToRequiredCount = {}; + + for(var i = 0; i < lenT; i++) { + var c = t[i]; + tCharToFoundCount[c] = 0; + tCharToRequiredCount[c] = tCharToRequiredCount[c] || 0; + tCharToRequiredCount[c]++; + } + + var windowBeg = -1; + var windowEnd = lenS; + var queue = []; + var hasFound = 0; + for(i = 0; i < lenS; i++) { + c = s[i]; + // skip unneeded char + if (tCharToRequiredCount[c] !== 0) { + tCharToFoundCount[c]++; + queue.push(i); + + if (tCharToFoundCount[c] <= tCharToRequiredCount[c]) { + hasFound++; + } + + if (hasFound === lenT) { + var k; + + do { + k = queue.shift(); + tCharToFoundCount[s[k]]--; + } while(tCharToFoundCount[s[k]] >= tCharToRequiredCount[s[k]]); + + if (windowEnd - windowBeg > i - k) { + windowBeg = k; + windowEnd = i; + } + hasFound--; } + + } } diff --git a/[0003] Longest Substring Without Repeating Characters.js b/[0003] Longest Substring Without Repeating Characters.js index 41f4575..d917b15 100644 --- a/[0003] Longest Substring Without Repeating Characters.js +++ b/[0003] Longest Substring Without Repeating Characters.js @@ -4,6 +4,9 @@ */ +// use map for storing index +// if a repeated character is found, skip directly to the index of the repeated character in the map. + var lengthOfLongestSubstring = function(s) { if(s === null || s.length === 0){ return 0; From dbcd8175871598a72c9f533c8c63ce597cf649e6 Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Wed, 11 Mar 2020 22:44:12 -0700 Subject: [PATCH 45/47] p1 --- ...g with At Most Two Disctinct Characters.js | 48 +++++++++++++++++-- 48 Rotate Image.js | 39 +++++++++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/159 Longest Substring with At Most Two Disctinct Characters.js b/159 Longest Substring with At Most Two Disctinct Characters.js index 2920d0d..19b9ca3 100644 --- a/159 Longest Substring with At Most Two Disctinct Characters.js +++ b/159 Longest Substring with At Most Two Disctinct Characters.js @@ -4,6 +4,9 @@ * @param {string} s * @return {number} */ + + // Time O(N) + // Space O(1) var lengthOfLongestSubstringTwoDistinct = function(s) { var longestSubstr = ""; var maxLength = 0; @@ -15,15 +18,14 @@ var lengthOfLongestSubstringTwoDistinct = function(s) { // if map already contains two distrinct chars and the char is new to the map if(map.size > 1 && map.get(c) === undefined) { - var leftMost = s.length; - // Calc substring len before the new char if(i - start > maxLength) { // Should not include i, since i is the new distinct char's index longestSubstr = s.substring(start, i); maxLength = longestSubstr.length; } - + // Find the left most char + var leftMost = s.length; map.forEach((charIdx, key)=> { if(charIdx < leftMost) { leftMost = charIdx; @@ -44,3 +46,43 @@ var lengthOfLongestSubstringTwoDistinct = function(s) { return maxLength; }; + + + + +/** + * @param {string} s + * @return {number} + */ +var lengthOfLongestSubstringTwoDistinct = function(s) { + var map = new Map(); + var start = 0; + var maxLen = 0; + + for(var i = 0; i < s.length; i++) { + var c = s[i]; + if (map.size === 2 && map.get(c) === undefined) { + var curStr; + if (i - start > maxLen) { + curStr = s.substring(start, i); + maxLen = i - start; + } + var leftMost = s.length; + map.forEach((charIdx, key) => { + if (charIdx < leftMost) { + leftMost = charIdx; + } + }); + start = leftMost + 1; + map.delete(s[leftMost]); + } + + map.set(c, i); + } + + if (s.length - start > maxLen) { + maxLen = s.length - start; + } + + return maxLen; +}; \ No newline at end of file diff --git a/48 Rotate Image.js b/48 Rotate Image.js index 546ab53..46a0072 100644 --- a/48 Rotate Image.js +++ b/48 Rotate Image.js @@ -71,3 +71,42 @@ var swap = function(matrix, i1, j1, i2, j2) { matrix[i2][j2] = aux; }; + + + +/** + * @param {number[][]} matrix + * @return {void} Do not return anything, modify matrix in-place instead. + */ +var rotate = function(matrix) { + rotateDiagonal(matrix); + rotateRow(matrix); +}; + +var swap = function(matrix, x1, y1, x2, y2) { + var temp = matrix[x1][y1]; + matrix[x1][y1] = matrix[x2][y2]; + matrix[x2][y2] = temp; +} + +var rotateRow = function(matrix) { + for(var i = 0; i < matrix.length; i++) { + var row = matrix[i]; + var start = 0; + var end = matrix[i].length - 1; + + while(start < end) { + swap(matrix, i, start, i, end); + start++; + end--; + } + } +} + +var rotateDiagonal = function(matrix) { + for(var i = 0; i < matrix.length; i++) { + for(var j = i; j < matrix.length; j++) { + swap(matrix, i, j, j, i); + } + } +} \ No newline at end of file From b517b1a4b6ae3abfd009a7095f167eee6653968b Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Thu, 12 Mar 2020 21:50:36 -0700 Subject: [PATCH 46/47] update --- 15 3Sum.js | 4 +-- ...ers Give Read4 II - Call Multiple Times.js | 33 +++++++++++++++++++ ...g with At Most Two Disctinct Characters.js | 1 - 66 Plus One.js | 29 ++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/15 3Sum.js b/15 3Sum.js index a2f21ec..cecfe00 100644 --- a/15 3Sum.js +++ b/15 3Sum.js @@ -33,8 +33,8 @@ var threeSum = function(nums) { for(var i = 0; i < len-2; i++){ - if(i === 0 || nums[i] > nums[i-1]){ // very important, same as line 40, remove duplicate as 111 will only run once 1-> rather tan 1 1 1 - target = 0 - nums[i]; + if(i === 0 || nums[i] > nums[i-1]){ // very important, same as line 40, remove duplicate as 111 will only run once 1-> rather than 1 1 1 + var target = 0 - nums[i]; j = i + 1; k = len - 1; diff --git a/158 Read N Characters Give Read4 II - Call Multiple Times.js b/158 Read N Characters Give Read4 II - Call Multiple Times.js index 27efed5..2230a88 100644 --- a/158 Read N Characters Give Read4 II - Call Multiple Times.js +++ b/158 Read N Characters Give Read4 II - Call Multiple Times.js @@ -63,3 +63,36 @@ var solution = function(read4) { return numChrRead; }; }; + +var solution = function(read4) { + /** + * @param {character[]} buf Destination buffer + * @param {number} n Number of characters to read + * @return {number} The number of actual characters read + */ + var read4Buff = []; + var read4NumCharRead = 0; + var read4Remain = 0; + + return function(buf, n) { + var numCharRead = 0; + + // Need to run read4 N times to get n char + while(numCharRead < n) { + // If everything is already read in read4 buffer, re-read + if (read4NumCharRead === read4Remain) { + read4NumCharRead = 0; + read4Remain = read4(read4Buff); + } + while(read4NumCharRead < read4Remain && numCharRead < n) { + buf[numCharRead++] = read4Buff[read4NumCharRead++]; + } + if (read4Remain < 4) { + break; + } + + } + + return numCharRead; + }; +}; \ No newline at end of file diff --git a/159 Longest Substring with At Most Two Disctinct Characters.js b/159 Longest Substring with At Most Two Disctinct Characters.js index 19b9ca3..aae47ba 100644 --- a/159 Longest Substring with At Most Two Disctinct Characters.js +++ b/159 Longest Substring with At Most Two Disctinct Characters.js @@ -64,7 +64,6 @@ var lengthOfLongestSubstringTwoDistinct = function(s) { if (map.size === 2 && map.get(c) === undefined) { var curStr; if (i - start > maxLen) { - curStr = s.substring(start, i); maxLen = i - start; } var leftMost = s.length; diff --git a/66 Plus One.js b/66 Plus One.js index 0d1c6cb..9dae196 100644 --- a/66 Plus One.js +++ b/66 Plus One.js @@ -2,6 +2,35 @@ * @param {number[]} digits * @return {number[]} */ + +// Time complexity : \mathcal{O}(N)O(N) since it's not more than one pass along the input list. + +// Space complexity : \mathcal{O}(1)O(1). +var plusOne = function(digits) { + var carry = 1; + for(var i = digits.length - 1; i > -1; i--) { + var d = digits[i]; + var sum = d + carry; + if (sum === 10) { + digits[i] = 0; + carry = 1; + } else { + digits[i] = sum; + carry = 0; // can directly return since it will not trigger the carry unshift at the end. + break; + } + } + + if (carry === 1) { + digits.unshift(carry); + } + + return digits; +}; + + + + var plusOne = function(digits) { for(var i = digits.length; i--;){ digits[i] = 1 + digits[i]; From fba8bd482360cbc3283169a5cde122e4ac39d2e9 Mon Sep 17 00:00:00 2001 From: Chihung Yu Date: Thu, 12 Mar 2020 21:51:33 -0700 Subject: [PATCH 47/47] update --- 163 Missing Ranges.js | 39 +++ 681 Next Closest Time .js | 75 ++++++ [0004] Median of Two Sorted Arrays.js | 146 +++++++++++ ...ian of Two Sorted Arrays.sublime-workspace | 239 ++++++++++++++++++ key concepts | 3 + 5 files changed, 502 insertions(+) create mode 100644 163 Missing Ranges.js create mode 100644 681 Next Closest Time .js create mode 100644 [0004] Median of Two Sorted Arrays.js create mode 100644 [0004] Median of Two Sorted Arrays.sublime-workspace create mode 100644 key concepts diff --git a/163 Missing Ranges.js b/163 Missing Ranges.js new file mode 100644 index 0000000..ce31cfb --- /dev/null +++ b/163 Missing Ranges.js @@ -0,0 +1,39 @@ +/** + * @param {number[]} nums + * @param {number} lower + * @param {number} upper + * @return {string[]} + */ +var findMissingRanges = function(nums, lower, upper) { + var missing = []; + if (nums.length === 0) { + missing.push(getRange(lower,upper)); + return missing; + } + + // Only need to search range between lower and upper + var next = lower; + for(var i = 0; i < nums.length; i++) { + var val = nums[i]; + + if (val < next) { + continue; + } else if (val === next) { + next++; + continue; + } + // val > next + missing.push(getRange(next, val-1)); + next = val + 1; + } + + if (next <= upper) { + missing.push(getRange(next, upper)); + } + + return missing; +}; + +function getRange(lower, upper) { + return upper === lower ? `${lower}` : `${lower}->${upper}`; +} \ No newline at end of file diff --git a/681 Next Closest Time .js b/681 Next Closest Time .js new file mode 100644 index 0000000..41a2ef9 --- /dev/null +++ b/681 Next Closest Time .js @@ -0,0 +1,75 @@ +// Given a time represented in the format "HH:MM", form the next closest time by reusing the current digits. There is no limit on how many times a digit can be reused. + +// You may assume the given input string is always valid. For example, "01:34", "12:09" are all valid. "1:34", "12:9" are all invalid. + +// Example 1: + +// Input: "19:34" +// Output: "19:39" +// Explanation: The next closest time choosing from digits 1, 9, 3, 4, is 19:39, which occurs 5 minutes later. It is not 19:33, because this occurs 23 hours and 59 minutes later. +// Example 2: + +// Input: "23:59" +// Output: "22:22" +// Explanation: The next closest time choosing from digits 2, 3, 5, 9, is 22:22. It may be assumed that the returned time is next day's time since it is smaller than the input time numerically. + + + + +// Approach #1: Simulation [Accepted] +// Intuition and Algorithm + +// Simulate the clock going forward by one minute. Each time it moves forward, if all the digits are allowed, then return the current time. + +// The natural way to represent the time is as an integer t in the range 0 <= t < 24 * 60. Then the hours are t / 60, the minutes are t % 60, and each digit of the hours and minutes can be found by hours / 10, hours % 10 etc. + +/** + * @param {string} time + * @return {string} + */ +var nextClosestTime = function(time) { + let cur = 60 * parseInt(time.substring(0, 2)); + cur += parseInt(time.substring(3)); + const allowed = new Set(); + + for(var i = 0; i < time.length; i++) { + if (time[i] !== ':') { + allowed.add(parseInt(time[i])); + } + } + + while(true) { + cur = (cur + 1) % (24*60); + var curTime = [ + Math.floor(cur / 60 / 10), // hour 24 -> 2 + Math.floor(cur / 60) % 10, // hour 24 -> 4 + Math.floor((cur % 60) / 10), // minutes 59 -> 5 + cur % 60 % 10, // minutes 59 -> 9 + ]; + + for(i = 0; i < curTime.length; i++) { + var t = curTime[i]; + if (!allowed.has(t)) { + break; + } + if (i === curTime.length - 1) { + let hour = Math.floor(cur / 60); + let min = cur % 60; + + if (hour < 10) { + hour = '0' + hour; + } else { + hour = '' + hour; + } + + if (min < 10) { + min = '0' + min; + } else { + min = '' + min; + } + + return hour + ':' + min; + } + } + } +}; \ No newline at end of file diff --git a/[0004] Median of Two Sorted Arrays.js b/[0004] Median of Two Sorted Arrays.js new file mode 100644 index 0000000..33e7fb2 --- /dev/null +++ b/[0004] Median of Two Sorted Arrays.js @@ -0,0 +1,146 @@ +// /** +// * @param {number[]} nums1 +// * @param {number[]} nums2 +// * @return {number} +// */ + +// // http://blog.csdn.net/yutianzuijin/article/details/11499917 +// var findMedianSortedArrays = function(nums1, nums2) { +// var m = nums1.length; +// var n = nums2.length; +// var total = m + n; + +// if(total%2 === 1) { +// return findKth(nums1, m, nums2, n, parseInt(total/2) + 1); +// } else { +// return (findKth(nums1, m, nums2, n, parseInt(total/2)) + findKth(nums1, m, nums2, n, parseInt(total/2) + 1))/2; +// } +// }; + + +// function findKth(a, m, b, n, k) { +// // always assume that m is equal or smaller than n +// if(m > n) { +// return findKth(b, n, a, m, k); +// } + +// if(m === 0) { +// return b[k-1]; +// } + +// if(k === 1) { +// return Math.min(a[0],b[0]); +// } + +// // divide k into two parts +// var pa = Math.min(parseInt(k/2), m); +// var pb = k - pa; + +// if(a[pa - 1] < b[pb - 1]) { +// return findKth(a.slice(pa), m - pa, b, n, k - pa); +// } else if(a[pa - 1] > b[pb - 1]) { +// return findKth(a, m, b.slice(pb), n - pb, k - pb); +// } else { +// return a[pa - 1]; +// } +// } + + +// /** +// * @param {number[]} nums1 +// * @param {number[]} nums2 +// * @return {number} +// */ +// var findMedianSortedArrays = function(nums1, nums2) { +// var total = nums1.length + nums2.length; +// +// if (total % 2 === 1) { +// return findKth(nums1, 0, nums2, 0, parseInt(total/2) + 1); +// } else { +// return ( +// findKth(nums1, 0, nums2, 0, parseInt(total/2)) +// + findKth(nums1, 0, nums2, 0, parseInt(total/2) + 1) +// )/2; +// } +// }; +// +// function findKth(nums1, start1, nums2, start2, kth) { +// var len1 = nums1.length - start1; +// var len2 = nums2.length - start2; +// +// if (len1 > len2) { +// return findKth(nums2, start2, nums1, start1, kth); +// } +// +// if (len1 === 0) { +// return nums2[kth - 1]; +// } +// +// if (kth === 1) { +// return Math.min(nums1[start1], nums2[start2]); +// } +// +// // divide kth into 2 parts +// var part1 = Math.min(parseInt(kth/2), len1); +// var part2 = kth - part1; +// +// if (nums1[start1 + part1 - 1] < nums2[start2 + part2 - 1]) { +// return findKth(nums1, start1 + part1, nums2, start2, kth - part1); +// } else if (nums1[start1 + part1 - 1] > nums2[start2 + part2 - 1]) { +// return findKth(nums1, start1, nums2, start2 + part2, kth - part2); +// } else { +// return nums1[start1 + part1 - 1]; +// } +// } + + + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var findMedianSortedArrays = function(nums1, nums2) { + const len = nums1.length + nums2.length; + + if (len % 2 === 1) { + return findKth(nums1, 0, nums2, 0, Math.floor(len/2) + 1); + } else { + const first = findKth(nums1, 0, nums2, 0, Math.floor(len/2)); + const second = findKth(nums1, 0, nums2, 0, Math.floor(len/2) + 1); + + return (first + second) / 2; + } +}; + +function findKth(nums1, start1, nums2, start2, kth) { + const len1 = nums1.length - start1; + const len2 = nums2.length - start2; + + if (len1 > len2) { + return findKth(nums2, start2, nums1, start1, kth); + } + + if (len1 === 0) { + return nums2[kth - 1]; + } + + if (kth === 1) { + return Math.min(nums1[start1], nums2[start2]); + } + + // Three conditions here, len1 < kth/2, len1 === kth/2, len1 > kth/2 + const kth1 = Math.min(Math.floor(kth/2), len1); + const kth2 = kth - kth1; + + const nums1Kth = nums1[start1 + kth1 - 1]; + const nums2Kth = nums2[start2 + kth2 - 1]; + + if (nums1Kth < nums2Kth) { + return findKth(nums1, start1 + kth1, nums2, start2, kth2); + } else if (nums1Kth > nums2Kth) { + return findKth(nums1, start1, nums2, start2 + kth2, kth1); + } else { + return nums1Kth; + } +} diff --git a/[0004] Median of Two Sorted Arrays.sublime-workspace b/[0004] Median of Two Sorted Arrays.sublime-workspace new file mode 100644 index 0000000..4942cb0 --- /dev/null +++ b/[0004] Median of Two Sorted Arrays.sublime-workspace @@ -0,0 +1,239 @@ +{ + "auto_complete": + { + "selected_items": + [ + [ + "atta", + "attachEvent" + ] + ] + }, + "buffers": + [ + ], + "build_system": "", + "build_system_choices": + [ + ], + "build_varint": "", + "command_palette": + { + "height": 87.0, + "last_filter": "", + "selected_items": + [ + [ + "package install", + "Package Control: Install Package" + ], + [ + "package install ", + "Package Control: Install Package" + ], + [ + "package insta", + "Package Control: Install Package" + ], + [ + "package", + "Install Package Control" + ] + ], + "width": 485.0 + }, + "console": + { + "height": 0.0, + "history": + [ + ] + }, + "distraction_free": + { + "menu_visible": true, + "show_minimap": false, + "show_open_files": false, + "show_tabs": false, + "side_bar_visible": false, + "status_bar_visible": false + }, + "file_history": + [ + "/Users/cyu0/workspace/perkmon/src/routes/home/Home.js", + "/Users/cyu0/workspace/perkmon/src/routes/home/Home.css", + "/Users/cyu0/Downloads/immutable-js-diff-master/tests/sequenceDiff.test.js", + "/Users/cyu0/workspace/perkmon/src/components/Input/Input.css", + "/Users/cyu0/workspace/perkmon/src/components/Html.js", + "/Users/cyu0/workspace/perkmon/src/components/Input/Input.js", + "/Users/cyu0/workspace/perkmon/src/components/SearchWithBgImage/SearchWithBgImage.css", + "/Users/cyu0/workspace/perkmon/src/components/App.js", + "/Users/cyu0/workspace/perkmon/src/lib/event.js", + "/Users/cyu0/workspace/perkmon/src/lib/Event.js", + "/Users/cyu0/workspace/perkmon/src/components/CtaImageWithSearch/SearchWithBgImage.js", + "/Users/cyu0/workspace/perkmon/src/components/CtaImageWithSearch/SearchWithBgImage.css", + "/Users/cyu0/workspace/perkmon/src/components/Header/Header.css", + "/Users/cyu0/workspace/perkmon/src/routes/home/index.js", + "/Users/cyu0/workspace/perkmon/src/components/Header/Header.js", + "/Users/cyu0/workspace/perkmon/src/routes/index.js", + "/Users/cyu0/workspace/perkmon/build/server.js", + "/Users/cyu0/workspace/perkmon/src/", + "/Users/cyu0/workspace/perkmon/src/components/Navigation/Navigation.js", + "/Users/cyu0/workspace/perkmon/node_modules/enzyme/src/ReactWrapper.jsx", + "/Users/cyu0/workspace/perkmon/node_modules/resolve/test/precedence/aaa.js", + "/Users/cyu0/workspace/perkmon/src/components/variables.css", + "/Users/cyu0/workspace/perkmon/package.json" + ], + "find": + { + "height": 24.0 + }, + "find_in_files": + { + "height": 93.0, + "where_history": + [ + ] + }, + "find_state": + { + "case_sensitive": false, + "find_history": + [ + ], + "highlight": true, + "in_selection": false, + "preserve_case": false, + "regex": false, + "replace_history": + [ + ], + "reverse": false, + "show_context": true, + "use_buffer2": true, + "whole_word": false, + "wrap": true + }, + "groups": + [ + { + "sheets": + [ + ] + } + ], + "incremental_find": + { + "height": 24.0 + }, + "input": + { + "height": 31.0 + }, + "layout": + { + "cells": + [ + [ + 0, + 0, + 1, + 1 + ] + ], + "cols": + [ + 0.0, + 1.0 + ], + "rows": + [ + 0.0, + 1.0 + ] + }, + "menu_visible": true, + "output.SublimeLinter": + { + "height": 0.0 + }, + "output.SublimeLinter Messages": + { + "height": 108.0 + }, + "output.find_results": + { + "height": 0.0 + }, + "pinned_build_system": "", + "project": "[0004] Median of Two Sorted Arrays.sublime-project", + "replace": + { + "height": 44.0 + }, + "save_all_on_build": true, + "select_file": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + [ + "header.css", + "src/components/Header/Header.css" + ], + [ + "navigation", + "src/components/Navigation/Navigation.js" + ], + [ + "variables.css", + "src/components/variables.css" + ], + [ + "aa.js", + "node_modules/resolve/test/precedence/aaa.js" + ], + [ + ".jsx", + "node_modules/enzyme/src/ReactWrapper.jsx" + ], + [ + ".json", + "package.json" + ] + ], + "width": 0.0 + }, + "select_project": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_symbol": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "selected_group": 0, + "settings": + { + }, + "show_minimap": true, + "show_open_files": false, + "show_tabs": true, + "side_bar_visible": true, + "side_bar_width": 300.0, + "status_bar_visible": true, + "template_settings": + { + } +} diff --git a/key concepts b/key concepts new file mode 100644 index 0000000..b8f94bd --- /dev/null +++ b/key concepts @@ -0,0 +1,3 @@ +1. Substring vs subsequnce: substrings are consecutive subsequences +2. substring without repeating character: use map for storing index and use time window +