diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6da324c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,32 @@ +# Global editor config +# Find out more on http://editorconfig.org + +root = true + +# Common config +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = false +indent_style = space +indent_size = 2 + +# File depenedant config +[*.coffee] +indent_size = 2 + +[*.css] +indent_size = 2 + +[*.html] +indent_size = 2 + +[*.js] +indent_size = 4 + +[*.py] +indent_size = 4 + +[*.scss] +indent_size = 4 diff --git a/3sum-closest.js b/3sum-closest.js new file mode 100644 index 0000000..3a32718 --- /dev/null +++ b/3sum-closest.js @@ -0,0 +1,99 @@ +/** + * Source: https://leetcode.com/problems/3sum-closest/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: 3Sum Closest + * Auther: @imcoddy + * Content: Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. + * + * + * For example, given array S = {-1 2 1 -4}, and target = 1. + * + * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ + +/** + * Memo: Just loop to search the best solution + * Complex: O(n^3) + * Runtime: 344ms + * Tests: 120 test cases passed + * Rank: D + */ +var threeSumClosest = function(nums, target) { + function sortNumber(a, b) { + return a - b; + } + + nums = nums.sort(sortNumber); + var result = []; + var min = Number.MAX_VALUE; + + for (var i = 0; i < nums.length - 2; i++) { + for (var j = i + 1; j < nums.length - 1; j++) { + var val = 0 - (nums[i] + nums[j]); + var k = nums.length - 1; + while (k > j) { + var diff = Math.abs(nums[i] + nums[j] + nums[k] - target); + if (diff < min) { + min = diff; + result = [nums[i], nums[j], nums[k]]; + if (min === 0) { + return result[0] + result[1] + result[2]; + } + } + k--; + } + } + } + + return result[0] + result[1] + result[2]; +}; + +/** + * Memo: Since there will be exactly 1 solution, loop i first then use two pointers to get best result. + * Complex: O(n^2) + * Runtime: 127ms + * Tests: 120 test cases passed + * Rank: S + */ +var threeSumClosest = function(nums, target) { + function sortNumber(a, b) { + return a - b; + } + + nums = nums.sort(sortNumber); + var result = nums[0] + nums[1] + nums[2]; + + for (var i = 0; i < nums.length - 2; i++) { + var j = i + 1; + var k = nums.length - 1; + while (j < k) { + var sum = nums[i] + nums[j] + nums[k]; + if (sum === target) { + return sum; + } + + if (Math.abs(sum - target) < Math.abs(result - target)) { + result = sum; + } + + if (sum < target) { + j++; + } else { + k--; + } + } + } + + return result; +}; + +console.log(threeSumClosest([1, 1, 1, 0], 100)); +console.log(threeSumClosest([1, 2, -2, -1], 1)); +console.log(threeSumClosest([1, 2, -2, -1], 5)); \ No newline at end of file diff --git a/3sum.java b/3sum.java new file mode 100644 index 0000000..f0feb74 --- /dev/null +++ b/3sum.java @@ -0,0 +1,82 @@ +/** + * Source: https://leetcode.com/problems/3sum/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: 3Sum + * Auther: @imcoddy + * Content: 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: + * + * Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) + * 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) + */ + + public class Solution { + public List < List < Integer >> threeSum(int[] num) { + List < List < Integer >> solutionList = new LinkedList < List < Integer >> (); + if (num == null || num.length == 0) { + return solutionList; // Return empty list + } + + Arrays.sort(num); + + int pivot = 0; + while (pivot < num.length && num[pivot] < 0) { + pivot++; + } + if(pivot>=num.length-2) pivot = num.length-2; + + // Outer loop iterates through all of the values from left to right, skipping dups + int previousValue = num[0] == 0 ? 1 : 0; + for (int i = 0; i <= pivot; ++i) { + // Progress the outer loop past duplicate values + if (num[i] == previousValue) { + previousValue = num[i]; + continue; + } + + // Inner loop iterates from left to right, starting at outer loop index + 1 + for (int j = i + 1; j < num.length - 1; ++j) { + int desiredValue = 0 - (num[i] + num[j]); + if (desiredValue < num[j]) { + break; // Array is sorted in increasing order; we won't find desired value + } + + // Perform array search from j + 1 to num.length for desired value + int keyIndex = Arrays.binarySearch(num, j + 1, num.length, desiredValue); + if (keyIndex >= 0) { + List < Integer > solutionSet = new LinkedList < Integer > (); + solutionSet.add(num[i]); + solutionSet.add(num[j]); + solutionSet.add(num[keyIndex]); + + solutionList.add(solutionSet); + } + + // Progress the inner loop past duplicate values + while (j + 1 < num.length && num[j] == num[j + 1]) { + ++j; + } + } + + previousValue = num[i]; + } + + return solutionList; + } + } + + public static void main(String[] args) { + Solution s = new Solution(); + s.threeSum([1,2,3]); + } diff --git a/3sum.js b/3sum.js new file mode 100644 index 0000000..c589269 --- /dev/null +++ b/3sum.js @@ -0,0 +1,110 @@ +/** + * Source: https://leetcode.com/problems/3sum/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: 3Sum + * Auther: @imcoddy + * Content: 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: + * + * Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) + * 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) + */ + +/** + * @param {number[]} nums + * @return {number[][]} + */ + +/** + * Memo: A bit tricky that you need to use a hashmap to track duplicate set + * Complex: O(n^2) + * Runtime: 483ms + * Tests: 311 test cases passed + * Rank: D + */ +var threeSum = function(nums) { + function sortNumber(a, b) { + return a - b; + } + + nums = nums.sort(sortNumber); + var result = []; + var pivot = 0; + while (nums[pivot] < 0) { + pivot++; + } + + var map = {}; + for (var i = 0; i <= pivot; i++) { + for (var j = i + 1; j < nums.length - 1; j++) { + var val = 0 - (nums[i] + nums[j]); + if (val >= nums[j] && nums.lastIndexOf(val) > j) { + var a = [nums[i], nums[j], val]; + var k = a.join('_'); + if (!map[k]) { + result.push(a); + map[k] = true; + } + } + } + } + + return result; +}; + +/** + * Memo: Sort nums first, then fix one element and use two pointer to narrow down. Skip duplicates. + * Complex: O(n^2) + * Runtime: 240ms + * Tests: 311 test cases passed + * Rank: B + * Updated: 2015-06-24 + */ +var threeSum = function(nums) { + function sortNumber(a, b) { + return a - b; + } + + nums = nums.sort(sortNumber); + var result = []; + + for (var i = 0; i < nums.length; i++) { + var target = 0 - nums[i]; + var front = i + 1; + var end = nums.length - 1; + + while (front < end) { + var sum = nums[front] + nums[end]; + if (sum < target) { + front++; + } else if (sum > target) { + end--; + } else { + var solution = [nums[i], nums[front], nums[end]]; + result.push(solution); + while (front < i && nums[front] === solution[1]) front++; + while (i < end && nums[end] === solution[2]) end--; + } + while (i + 1 < nums.length && nums[i + 1] === nums[i]) i++; + } + } + return result; +}; + +console.log(threeSum([0, 0, 0])); +console.log(threeSum([-1, -1, -4])); +console.log(threeSum([1, 2, -2, -1])); +console.log(threeSum([-1, 0, 1, 2, -1, -4])); +console.log(threeSum([-1, 3, 1, 2, -2, -4])); +console.log(threeSum([-1, 0, 1, 2, -1, -4, -1, 2, 0])); \ No newline at end of file diff --git a/README.md b/README.md index bcaad72..86bc330 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,22 @@ # README # -This is my repository for personal leetcode solutions. Most code should be written in Javascript, but other language might be used as well. \ No newline at end of file +This is my repository for personal leetcode solutions. Most code should be written in Javascript, but other language might be used as well. + +## Abbreviation Naming + +When trying to use multiple solutions towards one problem, the following abbrevations might be used as postfix. + +Abbreviation | Name +----|------ +BS | Binary Search +BT | Backtracking +BFS | Breadth-first Search +DC | Divide and Conquer +DFS | Depth-first Search +DP | Dynamic Programming +GD | Greedy +HM | Hashmap + +## Note + +To view unsolved problems locally, run `sh ./list-unsolved.sh`, or install this [tampermonkey script](http://git.degree.by/degree/userscripts/raw/master/src/enhance-leetcode.user.js) if you prefer to view from website. diff --git a/add-binary.js b/add-binary.js new file mode 100644 index 0000000..3fed86a --- /dev/null +++ b/add-binary.js @@ -0,0 +1,77 @@ +/** + * Source: https://leetcode.com/problems/add-binary/ + * Tags: [Math,String] + * Level: Easy + * Title: Add Binary + * Auther: @imcoddy + * Content: Given two binary strings, return their sum (also a binary string). + * + * + * + * For example, + * a = "11" + * b = "1" + * Return "100". + */ + +/** + * @param {string} a + * @param {string} b + * @return {string} + * + */ + +var addBinary = function(a, b) { + var length = Math.max(a.length, b.length); + var result = ''; + var up = 0; + + for (var i = 0; i < length; i++) { + var d1 = a[a.length - i - 1] ? a[a.length - i - 1] : '0'; + var d2 = b[b.length - i - 1] ? b[b.length - i - 1] : '0'; + var value = parseInt(d1,10) + parseInt(d2, 10) + up; + result = '' + (value%2) + result; + up = value > 1 ? 1 : 0; + } + if (up) { + result = '1' + result; + } + return result; +}; + +/** + * Rumtime 245ms + */ +/*var addBinary = function(a, b) { + var length = Math.max(a.length, b.length); + var result = ''; + var up = '0'; // 0 for stay, 1 for up + var rules = { + // d1, d2, up or not: result, up or not + '000': '0', + '001': '1', + '010': '1', + '011': '01', + '100': '1', + '101': '01', + '110': '01', + '111': '11', + } + for (var i = 0; i < length; i++) { + var n1 = a[a.length - i - 1] ? a[a.length - i - 1] : '0'; + var n2 = b[b.length - i - 1] ? b[b.length - i - 1] : '0'; + var sum = rules[n1 + n2 + up]; + result = '' + sum[0] + result; + up = sum.length === 2 ? '1' : '0'; + } + if (up === '1') { + result = '1' + result; + } + return result; +};*/ + +console.log(addBinary('0', '0')); // 0 +console.log(addBinary('0', '1')); // 1 +console.log(addBinary('1', '0')); // 1 +console.log(addBinary('1', '1')); // 10 +console.log(addBinary('100', '11100')); // 100000 diff --git a/add-two-numbers.js b/add-two-numbers.js new file mode 100644 index 0000000..01cf668 --- /dev/null +++ b/add-two-numbers.js @@ -0,0 +1,110 @@ +/** + * Source: https://leetcode.com/problems/add-two-numbers/ + * Tags: [Linked List,Math] + * Level: Medium + * Title: Add Two Numbers + * Auther: @imcoddy + * Content: 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) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} l1 + * @param {ListNode} l2 + * @return {ListNode} + */ + +/** + * Memo: Iterate both list and add l2 to l1 until one is finished. + * Complex: O(n) + * Runtime: 288ms + * Tests: 1555 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var addTwoNumbers = function(l1, l2) { + var dummy = new ListNode(0); + dummy.next = l1; + var tail = dummy; + + while (l1 && l2) { + l1.val = l1.val + l2.val + (tail.val >= 10 ? 1 : 0); + tail.val %= 10; + tail = l1; + l1 = l1.next; + l2 = l2.next; + } + if (!l1) tail.next = l2; //append to l2 if l2 is longer + + while (tail && tail.val >= 10) { + tail.val %= 10; + if (tail.next) { + tail.next.val += 1; + tail = tail.next; + } else { + tail.next = new ListNode(1); + } + } + + return dummy.next; +}; + + +/** + * Memo: Iterate both list and add l2 to l1 until one is finished. + * Complex: O(max(m, n)) + * Runtime: 288ms + * Tests: 1555 test cases passed + * Rank: S + * Updated: 2015-08-30 + */ +var addTwoNumbers = function(l1, l2) { + var dummy = new ListNode(null); + dummy.next = l1; + var tail = dummy; + + while (l1 && l2) { + l1.val = l1.val + l2.val; + tail = l1; + l1 = l1.next; + l2 = l2.next; + } + + if (!l1) tail.next = l2; //append to l2 if l2 is longer + + tail = dummy.next; + while (tail) { + if (tail.val > 9) { + tail.val %= 10; + if (tail.next) { + tail.next.val += 1; + } else { + tail.next = new ListNode(1); + } + } + tail = tail.next; + } + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +util.lta(addTwoNumbers(util.atl([2, 4, 3]), util.atl([5, 6, 4]))).should.eql([7, 0, 8]); +util.lta(addTwoNumbers(util.atl([2, 4, 3]), util.atl([5, 6, 4, 1, 2]))).should.eql([7, 0, 8, 1, 2]); +(util.lta(addTwoNumbers(util.atl([1]), util.atl([9, 9, 9]))).should.eql([0, 0, 0, 1])); +(util.lta(addTwoNumbers(util.atl([1]), util.atl([9]))).should.eql([0, 1])); +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/balanced-binary-tree.js b/balanced-binary-tree.js new file mode 100644 index 0000000..019f299 --- /dev/null +++ b/balanced-binary-tree.js @@ -0,0 +1,80 @@ +/** + * Source: https://leetcode.com/problems/balanced-binary-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Balanced Binary Tree + * Auther: @imcoddy + * Content: Given a binary tree, determine if it is height-balanced. + * + * + * + * For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[][]} + */ + +/** + * Memo: Kinda werid to see the result is true when root is null. + * Runtime: 161ms + * Rank: S + */ +var isBalanced = function(root) { + if (!root) { + return true; + } + + if (isBalanced(root.left) && isBalanced(root.right)) { + var dLeft = getDepth(root.left); + var dRight = getDepth(root.right); + return Math.abs(dLeft - dRight) <= 1; + } else { + return false; + } +}; + +/** + * Memo: Recusive solution + * Complex: O(nlogn) + * Runtime: 168ms + * Tests: 226 test cases passed + * Rank: A + * Updated: 2015-10-05 + */ +var isBalanced = function(root) { + if (!root) return true; + if (isBalanced(root.left) && isBalanced(root.right)) return Math.abs(getDepth(root.left) - getDepth(root.right)) <= 1; + return false; +}; + + +var getDepth = function(root) { + return root ? Math.max(getDepth(root.left), getDepth(root.right)) + 1 : 0; +}; + + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.right.left = node; + +console.log(isBalanced(root)); \ No newline at end of file diff --git a/best-time-to-buy-and-sell-stock-ii.js b/best-time-to-buy-and-sell-stock-ii.js new file mode 100644 index 0000000..d62dd6a --- /dev/null +++ b/best-time-to-buy-and-sell-stock-ii.js @@ -0,0 +1,73 @@ +/** + * Source: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + * Tags: [Array,Greedy] + * Level: Medium + * Title: Best Time to Buy and Sell Stock II + * Auther: @imcoddy + * Content: Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). + */ + +/** + * @param {number[]} prices + * @return {number} + */ + +/** + * Memo: + * Runtime: 141ms + * Tests: 198 test cases passed + * Rank: A + */ +var maxProfit = function(prices) { + if (prices.length <= 1) { + return 0; + } + var s = [0]; + for (var i = 1; i < prices.length; i++) { + s[i] = s[i - 1] + Math.max(0, prices[i] - prices[i - 1]); + } + return s[prices.length - 1]; +}; + + +/** + * Memo: Calculate diff and accept it when it is positive. + * Complex: O(n) + * Runtime: 128ms + * Tests: 198 test cases passed + * Rank: S + */ +var maxProfit = function(prices) { + if (prices.length <= 1) { + return 0; + } + + var profit = 0; + for (var i = 0; i < prices.length - 1; i++) { + var diff = prices[i + 1] - prices[i]; + profit += (diff > 0 ? diff : 0); + } + return profit; +}; + +var should = require('should'); +console.time('Runtime'); +maxProfit([]).should.equal(0); +maxProfit([1]).should.equal(0); +maxProfit([1, 2, 3, 4, 5, 6]).should.equal(5); +maxProfit([6, 5, 4, 3, 2, 1]).should.equal(0); +maxProfit([1, 3, 1, 3, 1, 3]).should.equal(6); +maxProfit([1, 3, 1, 4, 1, 5]).should.equal(9); +maxProfit([2, 1, 2, 0, 1]).should.equal(2); +maxProfit([1, 3, 1, 4, 1, 2, 3, 4, 5]).should.equal(9); + +console.timeEnd('Runtime'); + +console.log(maxProfit([3])); //0 +console.log(maxProfit([2, 1, 2, 0, 1])); //2 +console.log(maxProfit([1, 2, 3, 4, 5])); //4 +console.log(maxProfit([5, 4, 3, 2, 1])); //0 +console.log(maxProfit([1, 1, 1, 1, 1])); //0 +console.log(maxProfit([1, 2, 1, 2, 1, 2, 1, 2])); //4 \ No newline at end of file diff --git a/best-time-to-buy-and-sell-stock.js b/best-time-to-buy-and-sell-stock.js new file mode 100644 index 0000000..c7f3bb6 --- /dev/null +++ b/best-time-to-buy-and-sell-stock.js @@ -0,0 +1,67 @@ +/** + * Source: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Best Time to Buy and Sell Stock + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {number[]} prices + * @return {number} + */ + +/** + * Memo: Create an array of prices differences, then turn this problem into maximum subarray. https://leetcode.com/problems/maximum-subarray/ + * Complex: O(n) + * Runtime: 148ms + * Tests: 198 test cases passed + * Rank: B + */ +var maxProfit = function(prices) { + if (prices.length <= 1) { + return 0; + } + + var maxSubArray = function(nums) { + var s = [nums[0]]; + var max = s[0]; + for (var i = 1; i < nums.length; i++) { + s[i] = Math.max(s[i - 1] + nums[i], nums[i]); + if (s[i] > max) { + max = s[i]; + } + } + return max; + }; + + var diff = []; + for (var i = 0; i < prices.length - 1; i++) { + diff[i] = prices[i + 1] - prices[i]; + } + var profit = maxSubArray(diff); + return profit > 0 ? profit : 0; + + // var profit = 0; + // for (var i = 0; i < prices.length - 1; i++) { + // var diff = prices[i + 1] - prices[i]; + // profit += (diff > 0 ? diff : 0); + // } + // return profit; +}; + +var should = require('should'); +console.time('Runtime'); +maxProfit([]).should.equal(0); +maxProfit([1]).should.equal(0); +maxProfit([1, 2, 3, 4, 5, 6]).should.equal(5); +maxProfit([6, 5, 4, 3, 2, 1]).should.equal(0); +maxProfit([1, 3, 1, 3, 1, 3]).should.equal(2); +maxProfit([1, 3, 1, 4, 1, 5]).should.equal(4); +maxProfit([2, 1, 2, 0, 1]).should.equal(1); +maxProfit([1, 3, 1, 4, 1, 2, 3, 4, 5]).should.equal(4); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/binary-tree-inorder-traversal.js b/binary-tree-inorder-traversal.js new file mode 100644 index 0000000..37f55b4 --- /dev/null +++ b/binary-tree-inorder-traversal.js @@ -0,0 +1,93 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-inorder-traversal/ + * Tags: [Tree,Hash Table,Stack] + * Level: Medium + * Title: Binary Tree Inorder Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the inorder traversal of its nodes' values. + * + * + * For example: + * Given binary tree {1,#,2,3}, + * + * 1 + * \ + * 2 + * / + * 3 + * + * + * + * return [1,3,2]. + * + * + * Note: Recursive solution is trivial, could you do it iteratively? + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[]} + */ + +/** + * Memo: + * Runtime: 137ms + * Rank: S + */ +var inorderTraversal = function(root) { + function traversal(root, result) { + if (!root) { + return; + } + + traversal(root.left, result); + result.push(root.val); + traversal(root.right, result); + } + + var result = []; + traversal(root, result); + return result; +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.right.left = node; +console.log(inorderTraversal(root)); \ No newline at end of file diff --git a/binary-tree-level-order-traversal-ii.js b/binary-tree-level-order-traversal-ii.js new file mode 100644 index 0000000..bc682ba --- /dev/null +++ b/binary-tree-level-order-traversal-ii.js @@ -0,0 +1,183 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-level-order-traversal-ii/ + * Tags: [Tree,Breadth-first Search] + * Level: Easy + * Title: Binary Tree Level Order Traversal II + * Auther: @imcoddy + * Content: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). + * + * + * For example: + * Given binary tree {3,9,20,#,#,15,7}, + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * + * + * return its bottom-up level order traversal as: + * + * [ + * [15,7], + * [9,20], + * [3] + * ] + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[][]} + */ + +/** + * Memo: + * Runtime: 134ms + * Rank: S + */ +var levelOrderBottom = function(root) { + if (!root) { + return []; + } + + var current_nodes = [root]; + var result = [ + [root.val] + ]; + var current_count = 1; + + while (current_nodes.length > 0) { + var next_nodes = []; + var node; + for (var i = 0; i < current_count; i++) { + node = current_nodes.shift(); + if (node.left) next_nodes.push(node.left); + if (node.right) next_nodes.push(node.right); + } + current_nodes = next_nodes; + current_count = next_nodes.length; + if (current_count) { + var tmp = []; + for (var i = 0; i < current_count; i++) { + tmp.push(current_nodes[i].val); + } + result.unshift(tmp); + } + } + + return result; +}; + +/** + * Memo: Level traversal + * Complex: O(n) + * Runtime: 140ms + * Tests: 34 test cases passed + * Rank: A + */ +var levelOrderBottom = function(root) { + if (!root) return []; + + var nodes = [root]; // queue of nodes to traverse + var result = []; + var count = 1; + while (nodes.length) { + var new_count = 0; + var array = []; + for (var i = 0; i < count; i++) { + var node = nodes.shift(); + array.push(node.val); + if (node.left) { + new_count++; + nodes.push(node.left); + } + if (node.right) { + new_count++; + nodes.push(node.right); + } + } + result.unshift(array); + count = new_count; + } + return result; +}; + +/** + * Memo: Inorder traversal and push nodes value to that level accordingly. + * Complex: O(n) + * Runtime: 140ms + * Tests: 34 test cases passed + * Rank: S + * Updated: 2015-10-05 + */ +function levelOrderBottom(root) { + var result = []; + + function traverse(root, depth, result) { + if (!root) return; + if (!result[depth]) result[depth] = []; + result[depth].push(root.val); + traverse(root.left, depth + 1, result); + traverse(root.right, depth + 1, result); + } + + traverse(root, 0, result); + return result.reverse(); +} + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +levelOrderBottom(util.arrayToTree([1])).should.eql([ + [1] +]); + + +levelOrderBottom(util.arrayToTree([1, 2, 3, 4])).should.eql([ + [4], + [2, 3], + [1] +]); + +levelOrderBottom(util.arrayToTree([3, 9, 20, '#', '#', 15, 7])).should.eql([ + [15, 7], + [9, 20], + [3] +]) + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/binary-tree-level-order-traversal.js b/binary-tree-level-order-traversal.js new file mode 100644 index 0000000..9e5f0d3 --- /dev/null +++ b/binary-tree-level-order-traversal.js @@ -0,0 +1,207 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-level-order-traversal/ + * Tags: [Tree,Breadth-first Search] + * Level: Easy + * Title: Binary Tree Level Order Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). + * + * + * For example: + * Given binary tree {3,9,20,#,#,15,7}, + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * + * + * return its level order traversal as: + * + * [ + * [3], + * [9,20], + * [15,7] + * ] + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[][]} + */ + +/** + * Memo: + * Runtime: 146ms + * Rank: S + */ + +var levelOrder = function(root) { + if (!root) { + return []; + } + + var current_nodes = [root]; + var result = [ + [root.val] + ]; + var current_count = 1; + + while (current_nodes.length > 0) { + var next_count = 0; + var next_nodes = []; + var node; + for (var i = 0; i < current_count; i++) { + node = current_nodes.shift(); + if (node.left) { + next_count++; + next_nodes.push(node.left); + } + if (node.right) { + next_count++; + next_nodes.push(node.right); + } + } + current_count = next_count; + current_nodes = next_nodes; + if (current_nodes.length) { + var tmp = []; + for (var i = 0; i < current_nodes.length; i++) { + tmp.push(current_nodes[i].val); + } + result.push(tmp); + } + } + return result; +}; + +/** + * Memo: + * Complex: O(n) + * Runtime: 128ms + * Tests: 34 test cases passed + * Rank: A + * Updated: 2015-10-05 + */ +var levelOrder = function(root) { + if (!root) return []; + + var nodes = [root]; + var result = []; + var count = 1; + while (nodes.length) { + var new_count = 0; + var array = []; + for (var i = 0; i < count; i++) { + var node = nodes.shift(); + array.push(node.val); + if (node.left) { + new_count++; + nodes.push(node.left); + } + if (node.right) { + new_count++; + nodes.push(node.right); + } + } + result.push(array); + count = new_count; + } + return result; +}; + +/** + * Memo: Use inorder to traverse the root recursively, record current depth and push current node.val to result of that level accordingly. + * Complex: O(n) + * Runtime: 146ms + * Tests: 34 test cases passed + * Rank: A + */ +var levelOrder = function(root) { + var result = []; + + var traverse = function(root, depth) { + if (!root) return; + if (!result[depth]) result[depth] = []; + result[depth].push(root.val); + traverse(root.left, depth + 1); + traverse(root.right, depth + 1); + }; + + traverse(root, 0); + return result; +}; + +/** + * Memo: Inorder traversal and push nodes value to that level accordingly. + * Complex: O(n) + * Runtime: 120ms + * Tests: 34 test cases passed + * Rank: S + * Updated: 2015-10-05 + */ +function levelOrder(root) { + var result = []; + + function traverse(root, depth, result) { + if (!root) return; + if (!result[depth]) result[depth] = []; + result[depth].push(root.val); + traverse(root.left, depth + 1, result); + traverse(root.right, depth + 1, result); + } + + traverse(root, 0, result); + return result; +} + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +console.log(levelOrder(root)); + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.left = node; + +node = new TreeNode(4); +root.left.left = node; +console.log(levelOrder(root)); \ No newline at end of file diff --git a/binary-tree-postorder-traversal.js b/binary-tree-postorder-traversal.js new file mode 100644 index 0000000..0a06532 --- /dev/null +++ b/binary-tree-postorder-traversal.js @@ -0,0 +1,70 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-postorder-traversal/ + * Tags: [Tree,Stack] + * Level: Hard + * Title: Binary Tree Postorder Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the postorder traversal of its nodes' values. + * + * + * For example: + * Given binary tree {1,#,2,3}, + * + * 1 + * \ + * 2 + * / + * 3 + * + * + * + * return [3,2,1]. + * + * + * Note: Recursive solution is trivial, could you do it iteratively? + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[]} + */ + +//TODO Add iterative solution +var postorderTraversal = function(root) { + + function recursiveTraversal(root, result) { + if (!root) { + return []; + } + recursiveTraversal(root.left, result); + recursiveTraversal(root.right, result); + result.push(root.val); + return result; + } + + return recursiveTraversal(root, []); +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.left = node; + +console.log(postorderTraversal(root)); diff --git a/binary-tree-preorder-traversal.js b/binary-tree-preorder-traversal.js new file mode 100644 index 0000000..35c100c --- /dev/null +++ b/binary-tree-preorder-traversal.js @@ -0,0 +1,124 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-preorder-traversal/ + * Tags: [Tree,Stack] + * Level: Medium + * Title: Binary Tree Preorder Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the preorder traversal of its nodes' values. + * + * + * For example: + * Given binary tree {1,#,2,3}, + * + * 1 + * \ + * 2 + * / + * 3 + * + * + * + * return [1,2,3]. + * + * + * Note: Recursive solution is trivial, could you do it iteratively? + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[]} + */ + + +/** + * Memo: Iterative Solution + * Runtime: 139ms + * Rank: A + */ +var preorderTraversal2 = function(root) { + if (!root) { + return []; + } + + var stack = []; + var result = []; + + stack.push(root); + while (stack.length) { + var node = stack.pop(); + result.push(node.val); + if (node.right) { + stack.push(node.right); + } + if (node.left) { + stack.push(node.left); + } + } + return result; +}; + +/** + * Memo: Recursive Solution + * Runtime: 141ms + * Rank: A + */ +var preorderTraversal = function(root) { + function traverse(root, result) { + if (!root) { + return; + } + + result.push(root.val); + traverse(root.left, result); + traverse(root.right, result); + } + + var result = []; + traverse(root, result); + return result; +}; + + +/** + * Memo: Recursive solution + * Complex: O(n) + * Runtime: 136ms + * Tests: 67 test cases passed + * Rank: A + * Updated: 2015-06-06 + */ +var preorderTraversal = function(root) { + function traverse(root) { + if (!root) return; + + result.push(root.val); + traverse(root.left); + traverse(root.right); + } + var result = []; + traverse(root, result); + return result; +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.right.left = node; +console.log(preorderTraversal(root)); \ No newline at end of file diff --git a/binary-tree-right-side-view.js b/binary-tree-right-side-view.js new file mode 100644 index 0000000..0023646 --- /dev/null +++ b/binary-tree-right-side-view.js @@ -0,0 +1,144 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-right-side-view/ + * Tags: [Tree,Depth-first Search,Breadth-first Search] + * Level: Medium + * Title: Binary Tree Right Side View + * Auther: @imcoddy + * Content: Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. + * + * + * For example: + * Given the following binary tree, + * + * 1 + * + * + * You should return [1, 3, 4]. + * + * + * Credits:Special thanks to @amrsaqr for adding this problem and creating all test cases. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[]} + */ + +/** + * Memo: Breadth-first Search + * Runtime: 149ms + * Rank: A + */ +var rightSideView = function(root) { + if (!root) { + return []; + } + + var queue = [root]; + var result = []; + var level_count = 1; + + while (queue.length) { + var next_level_count = 0; + var node; + for (var i = 0; i < level_count; i++) { + node = queue.shift(); + if (node.left) { + next_level_count++; + queue.push(node.left); + } + if (node.right) { + next_level_count++; + queue.push(node.right); + } + } + level_count = next_level_count; + result.push(node.val); + } + return result; +}; + +/** + * Memo: Use BFS to do a level traversal. Save each level in a queue, and add last element of that level into result. + * Complex: O(n) + * Runtime: 156ms + * Tests: 210 test cases passed + * Rank: A + */ +var rightSideView = function(root) { + if (!root) return []; + var result = []; + var queue = [root]; + var count = 1; + do { + var new_count = 0; + for (var i = 0; i < count; i++) { + var node = queue.shift(); + if (node.left) { + queue.push(node.left); + new_count++; + } + if (node.right) { + queue.push(node.right); + new_count++; + } + } + count = new_count; + result.push(node.val); + } while (queue.length); + + return result; +}; + + +/** + * Memo: Recursive solution. Traverse right child first, and only add to result if it is the first child of that level. + * Complex: O(n) + * Runtime: 164ms + * Tests: 210 test cases passed + * Rank: A + */ +var rightSideView = function(root) { + var deepest = 0; + var result = []; + + function traverse(root, level) { + if (!root) return; + if (level >= deepest) { + deepest++; + result.push(root.val); + } + level++; + traverse(root.right, level); + traverse(root.left, level); + } + + traverse(root, 0); + return result; +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.left = node; + +node = new TreeNode(4); +root.left.left = node; +console.log(rightSideView(root)); \ No newline at end of file diff --git a/binary-tree-zigzag-level-order-traversal.js b/binary-tree-zigzag-level-order-traversal.js new file mode 100644 index 0000000..0171999 --- /dev/null +++ b/binary-tree-zigzag-level-order-traversal.js @@ -0,0 +1,135 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/ + * Tags: [Tree,Breadth-first Search,Stack] + * Level: Medium + * Title: Binary Tree Zigzag Level Order Traversal + * Auther: @imcoddy + * Content: 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,#,#,15,7}, + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * + * + * return its zigzag level order traversal as: + * + * [ + * [3], + * [20,9], + * [15,7] + * ] + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number[][]} + */ + +/** + * Memo: + * Runtime: 160ms + * Tests: 33 test cases passed + * Rank: A + */ +var zigzagLevelOrder = function(root) { + if (!root) { + return []; + } + + var current_nodes = [root]; + var result = [ + [root.val] + ]; + var current_count = 1; + var current_level = 1; + + while (current_nodes.length > 0) { + var next_count = 0; + var next_nodes = []; + var node; + for (var i = 0; i < current_count; i++) { + node = current_nodes.shift(); + if (node.left) { + next_count++; + next_nodes.push(node.left); + } + if (node.right) { + next_count++; + next_nodes.push(node.right); + } + } + current_count = next_count; + current_nodes = next_nodes; + if (current_nodes.length) { + var reverse = current_level % 2 !== 0; + var tmp = []; + for (var i = 0; i < current_nodes.length; i++) { + if (reverse) { + tmp.unshift(current_nodes[i].val); + } else { + tmp.push(current_nodes[i].val); + } + } + result.push(tmp); + current_level++; + } + } + return result; +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +console.log(zigzagLevelOrder(root)); + +node = new TreeNode(2); +root.right = node; +node = new TreeNode(3); +root.left = node; +node = new TreeNode(4); +root.left.left = node; +node = new TreeNode(5); +root.left.right = node; + +console.log(zigzagLevelOrder(root)); \ No newline at end of file diff --git a/climbing-stairs.js b/climbing-stairs.js new file mode 100644 index 0000000..179d37f --- /dev/null +++ b/climbing-stairs.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/climbing-stairs/ + * Tags: [Dynamic Programming] + * Level: Easy + * Title: Climbing Stairs + * Auther: @imcoddy + * Content: 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} + */ + +/** + * Memo: for s[i], it can come from s[i-1] with one step or s[i-2] with two steps. + * Runtime: 131ms + * Tests: 45 test cases passed + * Rank: A + */ +var climbStairs = function(n) { + var s = [0, 1, 2]; + if (n <= 2) { + return s[n]; + } + + for (var i = 3; i <= n; i++) { + s[i] = s[i - 1] + s[i - 2]; + } + return s[n]; +}; + +console.log(climbStairs(3)); +console.log(climbStairs(4)); +console.log(climbStairs(5)); + +var should = require('should'); +climbStairs(3).should.equal(3); +climbStairs(4).should.equal(5); +climbStairs(5).should.equal(8); diff --git a/clone-graph.js b/clone-graph.js new file mode 100644 index 0000000..ac9ed7a --- /dev/null +++ b/clone-graph.js @@ -0,0 +1,86 @@ +/** + * Source: https://leetcode.com/problems/clone-graph/ + * Tags: [Depth-first Search,Breadth-first Search,Graph] + * Level: Medium + * Title: Clone Graph + * Auther: @imcoddy + * Content: 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) { + * this.label = label; + * this.neighbors = []; // Array of UndirectedGraphNode + * } + */ + +/** + * @param {UndirectedGraphNode} graph + * @return {UndirectedGraphNode} + */ + +/** + * Memo: Clone the graph recursively using DFS. + * Complex: O(n) + * Runtime: 264ms + * Tests: 12 test cases passed + * Rank: A + * Updated: 2015-06-04 + */ +var cloneGraph = function(graph) { + var cloned = {}; + + function clone(node) { + if (!node) return null; + if (cloned[node.label]) return cloned[node.label]; + var cloneNode = new UndirectedGraphNode(node.label); + cloned[node.label] = cloneNode; + for (var i = 0; i < node.neighbors.length; i++) { + cloneNode.neighbors.push(clone(node.neighbors[i])); + } + return cloneNode; + } + return clone(graph); +}; + +function UndirectedGraphNode(label) { + this.label = label; + this.neighbors = []; // Array of UndirectedGraphNode +} \ No newline at end of file diff --git a/combinations.js b/combinations.js new file mode 100644 index 0000000..1a4302b --- /dev/null +++ b/combinations.js @@ -0,0 +1,66 @@ +/** + * Source: https://leetcode.com/problems/combinations/ + * Tags: [Backtracking] + * Level: Medium + * Title: Combinations + * Auther: @imcoddy + * Content: 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], + * ] + */ + +/** + * @param {number} n + * @param {number} k + * @return {number[][]} + */ + +/** + * Memo: A bit tricky that solution can not be pushed into result directly, as it will be changed when further backtracking. + * Runtime: 158ms + * Tests: 26 test cases passed + * Rank: S + */ +var combine = function(n, k) { + var result = []; + var solution = []; + + function combineBT(row) { + if (row >= k) { + result.push(solution.slice(0, k)); + } else { + for (var i = 1; i <= n; i++) { + solution[row] = i; + if (isValid(row, i)) { + combineBT(row + 1); + } + } + } + } + + function isValid(row, value) { + for (var i = 0; i < row; i++) { + if (solution[i] >= value) { + return false; + } + } + return true; + } + + combineBT(0); + return result; +}; +console.log(combine(4, 2)); diff --git a/compare-version-numbers.js b/compare-version-numbers.js new file mode 100644 index 0000000..cb20cfb --- /dev/null +++ b/compare-version-numbers.js @@ -0,0 +1,68 @@ +/** + * Source: https://leetcode.com/problems/compare-version-numbers/ + * Tags: [String] + * Level: Easy + * Updated: 2015-04-24 + * Title: Compare Version Numbers + * Auther: @imcoddy + * Content: Compare two version numbers version1 and version2. + * If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. + * + * You may assume that the version strings are non-empty and contain only digits and the . character. + * The . character does not represent a decimal point and is used to separate number sequences. + * For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. + * + * Here is an example of version numbers ordering: + * 0.1 < 1.1 < 1.2 < 13.37 + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + */ + +/** + * @param {string} version1 + * @param {string} version2 + * @return {number} + */ +var compareVersion = function(version1, version2) { + if (!(version1 && version2)) { + return 0; + } + + var v1 = version1.split('.'); + var v2 = version2.split('.'); + for (var i = 0; i < v1.length; i++) { + v1[i] = parseInt(v1[i], 10); + } + for (var i = 0; i < v2.length; i++) { + v2[i] = parseInt(v2[i], 10); + } + while (v1.length < v2.length) { + v1.push(0); + } + while (v2.length < v1.length) { + v2.push(0); + } + + var index = 0; + while (index < v1.length) { + if (v1[index] > v2[index]) { + return 1; + } else if (v1[index] < v2[index]) { + return -1; + } else { + index++; + } + } + return 0; +}; + + +console.log(compareVersion('1.1', '1.1')); +console.log(compareVersion('1.1.1', '1.1.2')); +console.log(compareVersion('1.1.0', '1.1')); +console.log(compareVersion('1.2', '1.13')); +console.log(compareVersion('1.3', '1.31')); +console.log(compareVersion('1.9', '1.31')); +console.log(compareVersion('1', '1.1')); +console.log(compareVersion('1', '1.0')); +console.log(compareVersion('2', '1.1')); diff --git a/container-with-most-water.js b/container-with-most-water.js new file mode 100644 index 0000000..bdfd5de --- /dev/null +++ b/container-with-most-water.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/container-with-most-water/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: Container With Most Water + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {number[]} height + * @return {number} + */ +/** + * Memo: Use two pointers to narrow from start to end, use max to record current maximum + * Complex: O(n) + * Runtime: 140ms + * Tests: 45 test cases passed + * Rank: A + * Updated: 2015-06-22 + */ +var maxArea = function(height) { + var a = 0; + var b = height.length - 1; + var max = 0; + while (a < b) { + max = Math.max(max, + Math.min(height[a], height[b]) * (b - a)); + var tmp = height[a] > height[b] ? b-- : a++; + } + return max; +}; + +var should = require('should'); +console.time('Runtime'); +maxArea([1, 3, 5, 7, 9]).should.equal(10); +maxArea([3, 3, 9, 7, 9]).should.equal(18); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/contains-duplicate.js b/contains-duplicate.js new file mode 100644 index 0000000..e614a7f --- /dev/null +++ b/contains-duplicate.js @@ -0,0 +1,76 @@ +/** + * Source: https://leetcode.com/problems/contains-duplicate/ + * Tags: [Array,Hash Table] + * Level: Easy + * Title: Contains Duplicate + * Auther: @imcoddy + * Content: Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. + */ + +/** + * @param {number[]} nums + * @return {boolean} + */ + +/** + * Memo: use a map to check if the element exists or not + * Complex: O(n) + * Runtime: 132ms + * Tests: 16 test cases passed + * Rank: A + */ +var containsDuplicate = function(nums) { + var map = Object.create(null); + for (var i = 0; i < nums.length; i++) { + if (map[nums[i]]) return true; + map[nums[i]] = true; + } + return false; +}; + + +/** + * Memo: easiest but worst solution probably. + * Complex: O(n^2) + * Runtime: 1384ms + * Tests: 16 test cases passed + * Rank: D + */ +var containsDuplicate = function(nums) { + for (var i = 0; i < nums.length - 1; i++) { + for (var j = i + 1; j < nums.length; j++) { + if (nums[i] === nums[j]) { + return true; + } + } + } + return false; +}; + +/** + * Memo: Sort array first and find element which is duplicate to its next. + * Complex: O(nlgn) + * Runtime: 160ms + * Tests: 16 test cases passed + * Rank: NA + */ +var containsDuplicate = function(nums) { + if (nums.length <= 1) { + return false; + } + var a = nums.sort(); + for (var i = 0; i < a.length - 1; i++) { + if (a[i] === a[i + 1]) { + return true; + } + } + return false; +}; + +var should = require('should'); +console.time('Runtime'); +containsDuplicate([3, 5, 1, 9, 7]).should.equal(false); +containsDuplicate([1, 3, 5, 7, 9]).should.equal(false); +containsDuplicate([1, 3, 5, 7, 1]).should.equal(true); + +console.timeEnd('Runtime'); diff --git a/convert-sorted-array-to-binary-search-tree.js b/convert-sorted-array-to-binary-search-tree.js new file mode 100644 index 0000000..9abf4e3 --- /dev/null +++ b/convert-sorted-array-to-binary-search-tree.js @@ -0,0 +1,63 @@ +/** + * Source: https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Convert Sorted Array to Binary Search Tree + * Auther: @imcoddy + * Content: Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {number[]} num + * @returns {TreeNode} + */ + +/** + * Memo: use binary search in sorted array, find the mid element and use it as root if it exists, then process each left and right half. + * Complex: O(nlogn) + * Runtime: 140ms + * Tests: 32 test cases passed + * Rank: S + */ +var sortedArrayToBST = function(num) { + function convert(start, end) { + var root = null; + if (start <= end) { + var mid = ~~((start + end) / 2); + //if (mid >= 0 && mid < num.length) // this might be easier to understand, but not as fast as the following + if (typeof num[mid] !== 'undefined') { + root = new TreeNode(num[mid]); + root.left = convert(start, mid - 1); + root.right = convert(mid + 1, end); + } + } + return root; + } + + return convert(0, num.length); +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +console.log(sortedArrayToBST([0])); +console.log('-------------------------------------------'); +console.log(sortedArrayToBST([1])); +console.log('-------------------------------------------'); +console.log(sortedArrayToBST([1, 2])); +console.log('-------------------------------------------'); +console.log(sortedArrayToBST([1, 2, 3])); +console.log('-------------------------------------------'); +console.log(sortedArrayToBST([1, 2, 3, 4])); +console.log('-------------------------------------------'); +console.log(sortedArrayToBST([1, 2, 3, 4, 5])); \ No newline at end of file diff --git a/convert-sorted-list-to-binary-search-tree.js b/convert-sorted-list-to-binary-search-tree.js new file mode 100644 index 0000000..e1d1692 --- /dev/null +++ b/convert-sorted-list-to-binary-search-tree.js @@ -0,0 +1,156 @@ +/** + * Source: https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/ + * Tags: [Depth-first Search,Linked List] + * Level: Medium + * Title: Convert Sorted List to Binary Search Tree + * Auther: @imcoddy + * Content: Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +var util = require('./util.js'); +/** + * @param {ListNode} head + * @return {TreeNode} + */ +/** + * Memo: put all nodes in an array then use BS to connect each nodes from root to leaf. + * Runtime: 200ms + * Tests: 32 test cases passed + * Rank: B + */ +var sortedListToBST = function(head) { + if (!head) return null; + + var nodes = []; + var p = head; + while (p) { + var node = new TreeNode(p.val); + nodes.push(node); + p = p.next; + } + + function connectNodes(start, end) { + if (start >= end) { + return; + } + + var mid = ~~((start + end) / 2); + var left = ~~((start + mid) / 2); + var right = ~~((mid + 1 + end) / 2); + if (mid > left) { + nodes[mid].left = nodes[left]; + } + if (mid < right && !nodes[right].left) { + nodes[mid].right = nodes[right]; + } + connectNodes(start, mid); + connectNodes(mid + 1, end); + } + + connectNodes(0, nodes.length - 1); + return nodes[~~((nodes.length - 1) / 2)]; +}; + + +/** + * Memo: Traverse the list and put nodes in an array, then turn it into problem of sortedArrayToBST + * Complex: O(nlogn) + * Runtime: 192ms + * Tests: 32 test cases passed + * Rank: S + */ +var sortedListToBST = function(head) { + var sortedArrayToBST = function(num) { + function convert(start, end) { + var root = null; + if (start <= end) { + var mid = ~~((start + end) / 2); + if (typeof num[mid] !== 'undefined') { + root = new TreeNode(num[mid]); + root.left = convert(start, mid - 1); + root.right = convert(mid + 1, end); + } + } + return root; + } + + return convert(0, num.length); + }; + + + if (!head) return null; + + var nodes = []; + var p = head; + while (p) { + nodes.push(p.val); + p = p.next; + } + + return sortedArrayToBST(nodes); +}; + +/** + * Memo: Use fast and slow pointers to find element mid, use it as root and break it into two lists (by using prev pointer), then solve it recusively. + * Complex: O(nlogn) + * Runtime: 164ms + * Tests: 32 test cases passed + * Rank: S + */ +var sortedListToBST = function(head) { + if (!head) return null; + if (!head.next) return new TreeNode(head.val); //Need to return new TreeNode here + + var fast = head; + var slow = head; + var prev = head; + + while (fast) { + fast = fast.next; + if (fast) { + prev = slow; + slow = slow.next; + fast = fast.next; + } + } + prev.next = null; // break original list into two lists + var root = new TreeNode(slow.val); + root.left = sortedListToBST(head); + root.right = sortedListToBST(slow.next); + return root; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} +console.log(sortedListToBST(util.arrayToLinkList([0]))); +console.log('------------------------------------'); +console.log(sortedListToBST(util.arrayToLinkList([0, 1]))); +console.log('------------------------------------'); +console.log(sortedListToBST(util.arrayToLinkList([0, 1, 2]))); +console.log('------------------------------------'); +console.log(sortedListToBST(util.arrayToLinkList([0, 1, 2, 3]))); +console.log('------------------------------------'); +console.log(sortedListToBST(util.arrayToLinkList([0, 1, 2, 3, 4, 5, 6, 7, 8]))); +console.log('------------------------------------'); +console.log(sortedListToBST(util.arrayToLinkList([-84, -83, -63, -55, -45, -41, -39, -19, -16, -12, -11, 18, 22, 28, 30, 64, 77, 94]))); \ No newline at end of file diff --git a/copy-list-with-random-pointer.js b/copy-list-with-random-pointer.js new file mode 100644 index 0000000..2b1bdb1 --- /dev/null +++ b/copy-list-with-random-pointer.js @@ -0,0 +1,78 @@ +/** + * Source: https://leetcode.com/problems/copy-list-with-random-pointer/ + * Tags: [Hash Table,Linked List] + * Level: Hard + * Title: Copy List with Random Pointer + * Auther: @imcoddy + * Content: 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. + */ + +/** + * 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} + */ + +/** + * Memo: For list A->B->C, create a copy of each node and list it afterwards, as A->A'->B->B'->C->C', then detach the new nodes to make a new list. + * Ref: https://leetcode.com/discuss/12559/my-accepted-java-code-o-n-but-need-to-iterate-the-list-3-times + * Complex: O(n) + * Runtime: 232ms + * Tests: 11 test cases passed + * Rank: A + * Updated: 2015-06-20 + */ +var copyRandomList = function(head) { + if (!head) return null; + + var p = head; + // For each node, create a copy and link it to next. + while (p) { + var np = new RandomListNode(p.label); + np.next = p.next; + p.next = np; + p = p.next.next; + } + + // Link the random pointer + p = head; + while (p) { + if (p.random) p.next.random = p.random.next; + p = p.next.next; + } + + // Detach + var dummy = new RandomListNode(null); + var tail = dummy; + p = head; + while (p) { + tail.next = p.next; + tail = tail.next; + p.next = p.next.next; + p = p.next; + } + + return dummy.next; +}; + +function RandomListNode(label) { + this.label = label; + this.next = this.random = null; +} + +var head = new RandomListNode(-1); +var node = new RandomListNode(2); +head.next = node; + +console.log(copyRandomList(head)); \ No newline at end of file diff --git a/count-and-say.js b/count-and-say.js new file mode 100644 index 0000000..1b6fd36 --- /dev/null +++ b/count-and-say.js @@ -0,0 +1,63 @@ +/** + * Source: https://leetcode.com/problems/count-and-say/ + * Tags: [String] + * Level: Easy + * Title: Count and Say + * Auther: @imcoddy + * Content: The count-and-say sequence is the sequence of integers beginning as follows: + * 1, 11, 21, 1211, 111221, ... + * + * + * + * 1 is read off as "one 1" or 11. + * 11 is read off as "two 1s" or 21. + * 21 is read off as "one 2, then one 1" or 1211. + * + * + * + * Given an integer n, generate the nth sequence. + * + * + * + * Note: The sequence of integers will be represented as a string. + */ + +/** + * @param {number} n + * @return {string} + */ + +/** + * Rumtime: 123ms + * Rank: Top + */ +var countAndSay = function(n) { + var result = '1'; + while (n > 1) { + n--; + result = sayNext(result); + } + return result; +}; +var sayNext = function(num) { + var result = ''; + var str = '' + num; + var index = 0; + while (index < str.length) { + var digit = str[index]; + var count = 1; + while (count + index < str.length && str[index + count] === digit) { + count++; + } + result = result + count + digit; + index = index + count; + } + return result; +}; + +console.log(countAndSay(1)); //1 +console.log(countAndSay(2)); //21 +console.log(countAndSay(3)); //21 +console.log(countAndSay(4)); //1211 +console.log(countAndSay(5)); //111221 +console.log(countAndSay(6)); //312211 diff --git a/count-complete-tree-nodes.js b/count-complete-tree-nodes.js new file mode 100644 index 0000000..64fcc09 --- /dev/null +++ b/count-complete-tree-nodes.js @@ -0,0 +1,145 @@ +/** + * Source: https://leetcode.com/problems/count-complete-tree-nodes/ + * Tags: [Tree,Binary Search] + * Level: Medium + * Title: Count Complete Tree Nodes + * Auther: @imcoddy + * Content: Given a complete binary tree, count the number of nodes. + * + * Definition of a complete binary tree from Wikipedia: + * In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +/** + * Memo: Since this is a complete tree, if root.right could already be a perfect tree already. in this case, calculate its nodes directly as nodes = 2^height - 1. + * Complex: O(logn*logn) + * Runtime: 380ms + * Tests: 19 test cases passed + * Rank: S + */ +var countNodes = function(root) { + function count(root) { + if (!root) return 0; + var left = 1; + var right = 1; + var node = root.left; + while (node) { + node = node.left; + left++; + } + + var node = root.right; + while (node) { + node = node.right; + right++; + } + + return right === left ? Math.pow(2, right) - 1 : count(root.left) + count(root.right) + 1; + } + return count(root); +}; + +/** + * Memo: A bit improve of the solution above. + * Complex: O(logn*logn) + * Runtime: 365ms + * Tests: 19 test cases passed + * Rank: S + * Updated: 2015-06-09 + */ +var countNodes = function(root) { + function count(root) { + if (!root) return 0; + var heightL = 1; + var heightR = 1; + var nodeL = root.left; + var nodeR = root.right; + while (nodeR) { + nodeL = nodeL.left; + nodeR = nodeR.right; + heightL++; + heightR++; + } + + return nodeL === null ? Math.pow(2, heightR) - 1 : count(root.left) + count(root.right) + 1; + } + return count(root); +}; + +/** + * Memo: Binary Search Solution + * Complex: O(logn) + * Runtime: 324ms + * Tests: 18 test cases passed + * Rank: B + * Updated: 2015-06-26 + */ +var countNodes = function(root) { + function count(root) { + if (!root) return 0; + var hl = 1; + var hr = 1; + var node = root; + while (node = node.left) hl++; + node = root; + while (node = node.right) hr++; + if (hl === hr) { + return Math.pow(2, hl) - 1; + } else { + return count(root.left) + count(root.right) + 1; + } + } + return count(root); +}; + +/** + * Memo: Improve version + * Complex: O(log*logn) + * Runtime: 276ms + * Tests: 18 test cases passed + * Rank: S + * Updated: 2015-06-27 + */ +var countNodes = function(root) { + function count(root) { + if (!root) return 0; + var hl = 1; + var hr = 1; + var nl = root.left; + var nr = root.right; + while (nr) { + nl = nl.left; + nr = nr.right; + hl++; + hr++; + } + return nl === null ? Math.pow(2, hl) - 1 : count(root.left) + count(root.right) + 1; + } + return count(root); +}; + + +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +countNodes(util.arrayToTree([])).should.equal(0); +countNodes(util.arrayToTree([1])).should.equal(1); +countNodes(util.arrayToTree([1, 2])).should.equal(2); +countNodes(util.arrayToTree([1, 2, 3])).should.equal(3); +countNodes(util.arrayToTree([1, 2, 3, 4])).should.equal(4); +countNodes(util.arrayToTree([1, 2, 3, 4, 5])).should.equal(5); +countNodes(util.arrayToTree([1, 2, 3, 4, 5, 6, 7])).should.equal(7); +countNodes(util.arrayToTree([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])).should.equal(10); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/count-primes.js b/count-primes.js new file mode 100644 index 0000000..65e8e74 --- /dev/null +++ b/count-primes.js @@ -0,0 +1,185 @@ +/** + * Source: https://leetcode.com/problems/count-primes/ + * Tags: [Hash Table,Math] + * Level: Easy + * Title: Count Primes + * Auther: @imcoddy + * Content: Description: + * Count the number of prime numbers less than a non-negative number, n. + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + * + * Hint: + * Show Hint + * + * + * + * Let's start with a isPrime function. To determine if a number is prime, we need to check if it is not divisible by any number less than n. The runtime complexity of isPrime function would be O(n) and hence counting the total prime numbers up to n would be O(n2). Could we do better? + * Show More Hint + * + * + * As we know the number must not be divisible by any number > n / 2, we can immediately cut the total iterations half by dividing only up to n / 2. Could we still do better? + * Show More Hint + * + * + * Let's write down all of 12's factors: + * + * 2 × 6 = 12 + * 3 × 4 = 12 + * 4 × 3 = 12 + * 6 × 2 = 12 + * + * + * As you can see, calculations of 4 × 3 and 6 × 2 are not necessary. Therefore, we only need to consider factors up to √n because, if n is divisible by some number p, then n = p × q and since p ≤ q, we could derive that p ≤ √n. + * + * Our total runtime has now improved to O(n1.5), which is slightly better. Is there a faster approach? + * + * + * public int countPrimes(int n) { + * int count = 0; + * for (int i = 1; i < n; i++) { + * if (isPrime(i)) count++; + * } + * return count; + * } + * + * private boolean isPrime(int num) { + * if (num + * Show More Hint + * + * + * The Sieve of Eratosthenes is one of the most efficient ways to find all prime numbers up to n. But don't let that name scare you, I promise that the concept is surprisingly simple. + * + * + * + * Sieve of Eratosthenes: algorithm steps for primes below 121. "Sieve of Eratosthenes Animation" by SKopp is licensed under CC BY 2.0. + * + * + * We start off with a table of n numbers. Let's look at the first number, 2. We know all multiples of 2 must not be primes, so we mark them off as non-primes. Then we look at the next number, 3. Similarly, all multiples of 3 such as 3 × 2 = 6, 3 × 3 = 9, ... must not be primes, so we mark them off as well. Now we look at the next number, 4, which was already marked off. What does this tell you? Should you mark off all multiples of 4 as well? + * Show More Hint + * + * + * 4 is not a prime because it is divisible by 2, which means all multiples of 4 must also be divisible by 2 and were already marked off. So we can skip 4 immediately and go to the next number, 5. Now, all multiples of 5 such as 5 × 2 = 10, 5 × 3 = 15, 5 × 4 = 20, 5 × 5 = 25, ... can be marked off. There is a slight optimization here, we do not need to start from 5 × 2 = 10. Where should we start marking off? + * Show More Hint + * + * + * In fact, we can mark off multiples of 5 starting at 5 × 5 = 25, because 5 × 2 = 10 was already marked off by multiple of 2, similarly 5 × 3 = 15 was already marked off by multiple of 3. Therefore, if the current number is p, we can always mark off multiples of p starting at p2, then in increments of p: p2 + p, p2 + 2p, ... Now what should be the terminating loop condition? + * Show More Hint + * + * + * It is easy to say that the terminating loop condition is p < n, which is certainly correct but not efficient. Do you still remember Hint #3? + * Show More Hint + * + * + * Yes, the terminating loop condition can be p < √n, as all non-primes ≥ √n must have already been marked off. When the loop terminates, all the numbers in the table that are non-marked are prime. + * + * The Sieve of Eratosthenes uses an extra O(n) memory and its runtime complexity is O(n log log n). For the more mathematically inclined readers, you can read more about its algorithm complexity on Wikipedia. + * + * + * public int countPrimes(int n) { + * boolean[] isPrime = new boolean[n]; + * for (int i = 2; i < n; i++) { + * isPrime[i] = true; + * } + * // Loop's ending condition is i * i < n instead of i < sqrt(n) + * // to avoid repeatedly calling an expensive function sqrt(). + * for (int i = 2; i * i < n; i++) { + * if (!isPrime[i]) continue; + * for (int j = i * i; j < n; j += i) { + * isPrime[j] = false; + * } + * } + * int count = 0; + * for (int i = 2; i < n; i++) { + * if (isPrime[i]) count++; + * } + * return count; + * } + */ + +/** + * @param {number} n + * @return {number} + */ + +/** + * Memo: Add a method to check if current number is prime or not, then count from 2 to n; + * Complex: O(nlogn) + * Runtime: ms + * Tests: 20 test cases passed + * Rank: D + */ +var countPrimes = function(n) { + var isPrime = function(n) { + if (n <= 1) { + return false; + } + var root = Math.sqrt(n); + for (var i = 2; i <= root; i++) { + if (n % i === 0) { + return false; + } + } + return true; + }; + + var count = 0; + for (var i = 2; i < n; i++) { + if (isPrime(i)) { + count++; + } + } + return count; +}; + + +/** + * Memo: User a map to track if the number is prime or not. Once a prime number is found, mark other multiples as not prime number. + * Complex: O(nlogn) + * Runtime: 304ms + * Tests: 20 test cases passed + * Rank: A + */ +var countPrimes = function(n) { + if (n <= 2) { + return 0; + } + + var isPrime = [0, 0]; + for (var i = 2; i < n; i++) { + isPrime[i] = i; + } + + for (var i = 2; i * i <= n; i++) { + if (isPrime[i]) { + var t = i * i; + while (t < n) { + isPrime[t] = 0; + t += i; + } + } + } + + var count = 0; + for (var i = 2; i < isPrime.length; i++) { + if (isPrime[i]) { + count++; + } + } + //console.log(n, count, isPrime); + return count; +}; + +var should = require('should'); +console.time('Runtime'); +countPrimes(-1).should.equal(0); +countPrimes(0).should.equal(0); +countPrimes(1).should.equal(0); +countPrimes(2).should.equal(0); +countPrimes(3).should.equal(1); +countPrimes(4).should.equal(2); +countPrimes(5).should.equal(2); +countPrimes(6).should.equal(3); +countPrimes(25).should.equal(9); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/decode-ways.js b/decode-ways.js new file mode 100644 index 0000000..3b18a23 --- /dev/null +++ b/decode-ways.js @@ -0,0 +1,80 @@ +/** + * Source: https://leetcode.com/problems/decode-ways/ + * Tags: [Dynamic Programming,String] + * Level: Medium + * Title: Decode Ways + * Auther: @imcoddy + * Content: 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} + */ + +/** + * Memo: The 0 is pretty tricky, need to check if it is valid or not, eg 10, 20 are valid, while 30, 01 are not. + * Complex: O() + * Runtime: 136ms + * Tests: 256 test cases passed + * Rank: A + */ +var numDecodings = function(s) { + if (!s || s.length === 0 || s[0] === '0') { + return 0; + } + var map = {}; + for (var i = 1; i <= 26; i++) { + map[i] = true; + } + + var a = []; + a[0] = map[s[0]] ? 1 : 0; + a[1] = (map[s[1]] ? 1 : 0) + (map[s[0] + s[1]] ? 1 : 0); + for (var i = 2; i < s.length; i++) { + var twoDigits = s[i - 1] + s[i]; + if (s[i] === 0 && !map[twoDigits]) { + return 0; + } + a[i] = (map[s[i]] ? a[i - 1] : 0) + (map[twoDigits] ? a[i - 2] : 0); + } + return a[s.length - 1]; +}; + +var should = require('should'); +console.time('Runtime'); +numDecodings('').should.equal(0); +numDecodings('0').should.equal(0); +numDecodings('1').should.equal(1); +numDecodings('10').should.equal(1); +numDecodings('01').should.equal(0); +numDecodings('12').should.equal(2); +numDecodings('123').should.equal(3); +numDecodings('1234').should.equal(3); +numDecodings('12345678').should.equal(3); +numDecodings('0123').should.equal(0); +numDecodings('120').should.equal(1); +numDecodings('240').should.equal(0); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/delete-node-in-a-linked-list.js b/delete-node-in-a-linked-list.js new file mode 100644 index 0000000..2c1914c --- /dev/null +++ b/delete-node-in-a-linked-list.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/delete-node-in-a-linked-list/ + * Tags: [Linked List] + * Level: Easy + * Title: Delete Node in a Linked List + * Auther: @imcoddy + * Content: Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. + * + * + * + * Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Remove Linked List Elements + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} node + * @return {void} Do not return anything, modify node in-place instead. + */ + +/** + * Memo: Since the node won't be the last one, simply copy its next node's value and link it to its next as well + * Complex: O(1) + * Runtime: 148ms + * Tests: 83 test cases passed + * Rank: S + * Updated: 2015-- + */ +var deleteNode = function(node) { + if (node.next) { + node.val = node.next.val; + node.next = node.next.next; + } +}; \ No newline at end of file diff --git a/evaluate-reverse-polish-notation.js b/evaluate-reverse-polish-notation.js new file mode 100644 index 0000000..24a4450 --- /dev/null +++ b/evaluate-reverse-polish-notation.js @@ -0,0 +1,96 @@ +/** + * Source: https://leetcode.com/problems/evaluate-reverse-polish-notation/ + * Tags: [Stack] + * Level: Medium + * Title: Evaluate Reverse Polish Notation + * Auther: @imcoddy + * Content: 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 + */ + +/** + * @param {string[]} tokens + * @return {number} + */ +/** + * Memo: Use stack and pop operands + * Complex: O(n) + * Runtime: 164ms + * Tests: 20 test cases passed + * Rank: B + * Updated: 2015-06-11 + */ +var evalRPN = function(tokens) { + var stack = []; + + for (var i = 0; i < tokens.length; i++) { + if (!isNaN(tokens[i])) { + stack.push(tokens[i]); + } else { + var b = stack.pop(); + var a = stack.pop(); + token = tokens[i]; + var result; + if (token === '+') { + result = parseInt(a, 10) + parseInt(b, 10); + } else if (token === '-') { + result = parseInt(a, 10) - parseInt(b, 10); + } else if (token === '*') { + result = parseInt(a, 10) * parseInt(b, 10); + } else if (token === '/') { + result = ~~(parseInt(a, 10) / parseInt(b, 10)); + } + stack.push(result); + } + } + + return parseInt(stack.pop(), 10); +}; + +/** + * Memo: Use javascript feature to pass arguments + * Complex: O(n) + * Runtime: 132ms + * Tests: 20 test cases passed + * Rank: S + * Updated: 2015-06-11 + */ +var evalRPN = function(tokens) { + var stack = []; + var map = Object.create(null); + map['+'] = function(b, a) { + return a + b; + }; + map['-'] = function(b, a) { + return a - b; + }; + map['*'] = function(b, a) { + return a * b; + }; + map['/'] = function(b, a) { + return ~~(a / b); + }; + + for (var i = 0; i < tokens.length; i++) { + stack.push(isNaN(tokens[i]) ? map[tokens[i]](parseInt(stack.pop(), 10), parseInt(stack.pop(), 10)) : tokens[i]); + } + return parseInt(stack.pop(), 10); +}; + + +var should = require('should'); +console.time('Runtime'); +evalRPN(["2", "1", "+", "3", "*"]).should.equal(9); +evalRPN(["4", "13", "5", "/", "+"]).should.equal(6); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/excel-sheet-column-number.js b/excel-sheet-column-number.js new file mode 100644 index 0000000..1eb40f2 --- /dev/null +++ b/excel-sheet-column-number.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/excel-sheet-column-number/ + * Tags: [Math] + * Level: Easy + * Updated: 2015-04-24 + * Title: Excel Sheet Column Number + * Auther: @imcoddy + * Content: Related to question Excel Sheet Column Title + * Given a column title as appear in an Excel sheet, return its corresponding column number. + * + * For example: + * A -> 1 + * B -> 2 + * C -> 3 + * ... + * Z -> 26 + * AA -> 27 + * AB -> 28 + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + */ + +/** + * @param {string} s + * @return {number} + */ +var titleToNumber = function(s) { + var str = '0ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + var size = 26; + var result = 0; + for (var i=0; i < s.length; i++) { + result = result * size + str.indexOf(s[i]); + if (str.indexOf(s[i]) === 'Z') { + result += size; + } + } + console.log(result); + return result; +}; + +titleToNumber('Y'); // 25 +titleToNumber('Z'); // 26 +titleToNumber('AA'); // 27 +titleToNumber('YZ'); // 676 +titleToNumber('ZZ'); diff --git a/excel-sheet-column-title.js b/excel-sheet-column-title.js new file mode 100644 index 0000000..fc4c37a --- /dev/null +++ b/excel-sheet-column-title.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/excel-sheet-column-title/ + * Tags: [Math] + * Level: Easy + * Updated: 2015-04-24 + * Title: Excel Sheet Column Title + * Auther: @imcoddy + * Content: Given a positive integer, return its corresponding column title as appear in an Excel sheet. + * + * For example: + * + * 1 -> A + * 2 -> B + * 3 -> C + * ... + * 26 -> Z + * 27 -> AA + * 28 -> AB + * + * Credits:Special thanks to @ifanchu for adding this problem and creating all test cases. + */ + +/** + * @param {number} n + * @return {string} + */ +var convertToTitle = function(n) { + var str = 'ZABCDEFGHIJKLMNOPQRSTUVWXYZ'; + var size = 26; + var result = ''; + while( n > 0 ){ + result = str.charAt(n % size) + result ; + if (n % size === 0) { + n = n - size; + } + n = Math.floor( n / size ); + } + console.log(result); + return result; +}; + +convertToTitle(25); // X +convertToTitle(26); // Z +convertToTitle(27); // AA +convertToTitle(52); // AA +convertToTitle(26*26); // AA diff --git a/factorial-trailing-zeroes.js b/factorial-trailing-zeroes.js new file mode 100644 index 0000000..f914220 --- /dev/null +++ b/factorial-trailing-zeroes.js @@ -0,0 +1,44 @@ +/** + * Source: https://leetcode.com/problems/factorial-trailing-zeroes/ + * Tags: [Math] + * Level: Easy + * Title: Factorial Trailing Zeroes + * Auther: @imcoddy + * Content: Given an integer n, return the number of trailing zeroes in n!. + * + * Note: Your solution should be in logarithmic time complexity. + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + */ + +/** + * @param {number} n + * @return {number} + */ + +/** + * The trailing zeroes will only be added when 5 is encountered, as there are already enough even numbers to multiply to create 10. + * Since n! = (n-1) * n, the problem turns to be counting how many 5 can be generated from n. + * Notice number for 5^x, as when n = 25 (aka 5*5), 125, etc. + * Rumtime: 184ms + * Rumtime: 167ms Using ~~ to convert float to int + * Rank: Middle + */ +var trailingZeroes = function(n) { + if (n < 5) { + return 0; + } + var result = 0; + while (n) { + result += (n=~~(n / 5)); + } + return result; +}; + +console.log(trailingZeroes(-11)); //0 +console.log(trailingZeroes(0)); //0 +console.log(trailingZeroes(1)); //0 +console.log(trailingZeroes(5)); //1 +console.log(trailingZeroes(9)); //1 +console.log(trailingZeroes(10)); //2 +console.log(trailingZeroes(30)); //7 diff --git a/find-minimum-in-rotated-sorted-array-ii.js b/find-minimum-in-rotated-sorted-array-ii.js new file mode 100644 index 0000000..7cd45e8 --- /dev/null +++ b/find-minimum-in-rotated-sorted-array-ii.js @@ -0,0 +1,57 @@ +/** + * Source: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/ + * Tags: [Array,Binary Search] + * Level: Hard + * Title: Find Minimum in Rotated Sorted Array II + * Auther: @imcoddy + * Content: Follow up for "Find Minimum in Rotated Sorted Array": + * What if duplicates are allowed? + * + * Would this affect the run-time complexity? How and why? + * + * + * 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). + * + * Find the minimum element. + * + * The array may contain duplicates. + */ + +/** + * @param {number[]} nums + * @return {number} + */ + +/** + * Memo: Same as the solution before + * Complex: O(n) + * Runtime: 152ms + * Tests: 188 test cases passed + * Rank: A + * Updated: 2015-07-05 + */ +var findMin = function(nums) { + var min = 0; + var i = 0; + while (++i < nums.length) + if (nums[i] < nums[min]) return nums[i]; + return nums[min]; +}; + +// TODO add BS solution + +var should = require('should'); +console.time('Runtime'); +findMin([2, 1]).should.equal(1); +findMin([1, 1]).should.equal(1); +findMin([2, 1, 2]).should.equal(1); +findMin([10, 1, 10, 10, 10]).should.equal(1); +findMin([0, 1, 2, 3, 4, 5, 6, 7]).should.equal(0); +findMin([5, 6, 7, 8, 0, 1, 2, 3, 4]).should.equal(0); +findMin([0, 1, 2, 3, 4, 5, 6, 7]).should.equal(0); +findMin([1, 2, 3, 4, 5, 6, 7, 0]).should.equal(0); +findMin([4, 5, 6, 7, 0, 1, 2, 3]).should.equal(0); +findMin([4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0]).should.equal(0); +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/find-minimum-in-rotated-sorted-array.js b/find-minimum-in-rotated-sorted-array.js new file mode 100644 index 0000000..5f5331c --- /dev/null +++ b/find-minimum-in-rotated-sorted-array.js @@ -0,0 +1,76 @@ +/** + * Source: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Find Minimum in Rotated Sorted Array + * Auther: @imcoddy + * Content: 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). + * + * Find the minimum element. + * + * You may assume no duplicate exists in the array. + */ + +/** + * @param {number[]} nums + * @return {number} + */ + +//TODO try to do this using BS +/** + * Memo: mark first element as minimum and keep finding in one single loop till the turning point found. + * Complexity: O(n) + * Runtime: 140ms + * Tests: 146 test cases passed + * Rank: B + */ +var findMin = function(nums) { + var min = nums[0]; + var i = 1; + while (i <= nums.length) { + if (nums[i] < min) return nums[i]; + i++; + } + return min; +}; + +var findMin = function(nums) { + var min = 0; + var i = 0; + while (++i < nums.length) + if (nums[i] < nums[min]) return nums[i]; + return nums[min]; +}; + +/** + * Memo: If the array is in asc order, then when nums[start] < nums[end], the array is already sorted; when nums[start] > nums[end], the result will be in the middle. In this case, when nums[start] > nums[mid], the result will be in the left half (where nums[mid] could be the one as well), otherwise let start = mid + 1 as nums[mid] is bigger than nums[start] so the result cannot be mid. + * Complex: O(logn) + * Runtime: 156ms + * Tests: 146 test cases passed + * Rank: S + * Updated: 2015-07-05 + */ +var findMin = function(nums) { + var start = 0; + var end = nums.length - 1; + while (start < end) { + if (nums[start] < nums[end]) return nums[start]; // already sorted + + // the turning point will be between start and end + var mid = ~~((start + end) / 2); + nums[start] > nums[mid] ? end = mid : start = mid + 1; + } + return nums[start]; +}; + +var should = require('should'); +console.time('Runtime'); +findMin([2, 1]).should.equal(1); +findMin([0, 1, 2, 3, 4, 5, 6, 7]).should.equal(0); +findMin([5, 6, 7, 8, 0, 1, 2, 3, 4]).should.equal(0); +findMin([0, 1, 2, 3, 4, 5, 6, 7]).should.equal(0); +findMin([1, 2, 3, 4, 5, 6, 7, 0]).should.equal(0); +findMin([4, 5, 6, 7, 0, 1, 2, 3]).should.equal(0); +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/first-bad-version.js b/first-bad-version.js new file mode 100644 index 0000000..99548aa --- /dev/null +++ b/first-bad-version.js @@ -0,0 +1,71 @@ +/** + * Source: https://leetcode.com/problems/first-bad-version/ + * Tags: [Binary Search] + * Level: Easy + * Title: First Bad Version + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Search for a Range + * + * (M) Search Insert Position + */ + +/** + * 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 start = 1; + var end = n; + + while(start < end){ + var mid = ~~((start+end)/2); + isBadVersion(mid) ? end = mid : start = mid+1; + } + return end; + }; +}; diff --git a/flatten-binary-tree-to-linked-list.js b/flatten-binary-tree-to-linked-list.js new file mode 100644 index 0000000..763b8d9 --- /dev/null +++ b/flatten-binary-tree-to-linked-list.js @@ -0,0 +1,213 @@ +/** + * Source: https://leetcode.com/problems/flatten-binary-tree-to-linked-list/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Flatten Binary Tree to Linked List + * Auther: @imcoddy + * Content: Given a binary tree, flatten it to a linked list in-place. + * + * + * + * For example, + * Given + * + * 1 + * / \ + * 2 5 + * / \ \ + * 3 4 6 + * + * + * + * The flattened tree should look like: + * + * 1 + * \ + * 2 + * \ + * 3 + * \ + * 4 + * \ + * 5 + * \ + * 6 + * + * + * click to show hints. + * + * Hints: + * If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {void} Do not return anything, modify nodes in-place instead. + */ + +/** + * Memo: Depth-first Search and put node in a queue, then change all child nodes to root's right child + * Runtime: 174ms + * Rank: S + */ +var flatten = function(root) { + function DFS(root, queue) { + if (!root) { + return []; + } + queue.push(root); + DFS(root.left, queue); + DFS(root.right, queue); + return queue; + } + + var queue = DFS(root, []); + var p = queue.shift(); + while (queue.length > 0) { + p.left = null; + p.right = queue.shift(); + p = p.right; + } +}; + + +/** + * Memo: Use a queue to save traversal order, and then adjust left child to right of each node + * Complex: O(n) + * Runtime: 168ms + * Tests: 225 test cases passed + * Rank: B + */ +var flatten = function(root) { + var queue = []; + + function traverse(root) { + if (root) { + queue.push(root); + traverse(root.left); + traverse(root.right); + } + } + + traverse(root); + var p = queue.shift(); + while (queue.length > 0) { + p.left = null; + p.right = queue.shift(); + p = p.right; + } +}; + + +/** + * Memo: Recusive solution, use flatternTree to return last node of its subtree, then adjust root to combine flatterned left and right, return last node for further operation. + * Complex: O(n) + * Runtime: 156ms + * Tests: 225 test cases passed + * Rank: B + */ +var flatten = function(root) { + // flatten a tree and return its last node + function flatternTree(root) { + if (!root || (!root.left && !root.right)) { + return root; + } + var leftTail = flatternTree(root.left); + var rightTail = flatternTree(root.right); + + if (!leftTail) { + return rightTail ? rightTail : root; + } + leftTail.right = root.right; + root.right = root.left; + root.left = null; + return rightTail ? rightTail : leftTail; + } + + flatternTree(root); +}; + + +/** + * Memo: Non recusive solution. Since this is a inorder traversal, root.right will end up to root.left's farest right child, so move root right there first, move left to right, then can search root.right using the same methodology + * Complex: O(n) + * Runtime: 148ms + * Tests: 225 test cases passed + * Rank: S + */ +var flatten = function(root) { + while (root) { + if (root.left) { + var t = root.left; + while (t.right) { + t = t.right; + } + t.right = root.right; + root.right = root.left; + root.left = null; + } + root = root.right; + } +}; + + +/** + * Memo: A bit better than the above solution, as if root.right is null, there's no need to move root.right instead of jumping to root.left directly, and if root.left is null, there's no need to set it to null again :) + * Ref: https://leetcode.com/discuss/36732/8ms-non-recursive-no-stack-c-solution + * Complex: O(n) + * Runtime: 148ms + * Tests: 225 test cases passed + * Rank: S + */ +var flatten = function(root) { + while (root) { + if (root.left && root.right) { + var t = root.left; + while (t.right) { + t = t.right; + } + t.right = root.right; + } + + if (root.left) { + root.right = root.left; + root.left = null; + } + root = root.right; + } +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.left = node; + +node = new TreeNode(3); +root.right = node; + +node = new TreeNode(4); +root.right.left = node; +node = new TreeNode(5); +root.right.right = node; + +flatten(root); +console.log(root); +var p = root; +while (p) { + console.log(p.val); + p = p.right; +} \ No newline at end of file diff --git a/generate-parentheses.js b/generate-parentheses.js new file mode 100644 index 0000000..38cd772 --- /dev/null +++ b/generate-parentheses.js @@ -0,0 +1,74 @@ +/** + * Source: https://leetcode.com/problems/generate-parentheses/ + * Tags: [Backtracking,String] + * Level: Medium + * Title: Generate Parentheses + * Auther: @imcoddy + * Content: Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + * + * + * + * For example, given n = 3, a solution set is: + * + * + * "((()))", "(()())", "(())()", "()(())", "()()()" + */ + +/** + * @param {number} n + * @return {string[]} + */ + +/** + * Memo: + * Runtime: 130ms + * Tests: 8 test cases passed + * Rank: A + */ +var generateParenthesis = function(n) { + var result = []; + var solution = []; + var parentheses = ['(', ')']; + + function generateBT(row) { + if (row >= 2 * n) { + result.push(solution.join('')); + } else { + for (var i = 0; i < parentheses.length; i++) { + solution[row] = parentheses[i]; + if (isValid(row)) { + generateBT(row + 1); + } + } + } + } + + function isValid(row) { + if (row <= 0) { + return true; + } + + var stack = 0; + var left = 0; + for (var i = 0; i <= row; i++) { + if (solution[i] === '(') { + stack++; + left++; + } else { + stack--; + } + if (stack < 0) { + return false; + } + if (left > n) { + return false; + } + } + return stack <= n; + } + + generateBT(0); + return result; +}; + +console.log(generateParenthesis(3)); \ No newline at end of file diff --git a/happy-number.js b/happy-number.js new file mode 100644 index 0000000..2573692 --- /dev/null +++ b/happy-number.js @@ -0,0 +1,59 @@ +/** + * Source: https://leetcode.com/problems/happy-number/ + * Tags: [Hash Table,Math] + * Level: Easy + * Updated: 2015-04-24 + * Title: Happy Number + * Auther: @imcoddy + * Content: Write an algorithm to determine if a number is "happy". + * + * A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers. + * + * Example: 19 is a happy number + * + * + * 12 + 92 = 82 + * 82 + 22 = 68 + * 62 + 82 = 100 + * 12 + 02 + 02 = 1 + * + * + * Credits:Special thanks to @mithmatt and @ts for adding this problem and creating all test cases. + */ + +/** + * @param {number} n + * @return {boolean} + */ +var isHappy = function(n) { + var result = n; + var map = {}; + // map[n] = 1; + result = getResult(result); + map[result] = 1; + while (result !== 1) { + result = getResult(result); + if (map[result]) { + return false; + } else { + map[result] = 1; + n = result; + } + } + return true; +}; + +var getResult = function(n) { + var result = 0; + while (n) { + var d = n % 10; + result += d * d; + n = Math.floor(n / 10); + } + return result; +}; + +console.log(getResult(1933)); +console.log(isHappy(0)); +console.log(isHappy(10)); +console.log(isHappy(11)); diff --git a/house-robber-ii.js b/house-robber-ii.js new file mode 100644 index 0000000..f0644c7 --- /dev/null +++ b/house-robber-ii.js @@ -0,0 +1,82 @@ +/** + * Source: https://leetcode.com/problems/house-robber-ii/ + * Tags: [Dynamic Programming] + * Level: Medium + * Title: House Robber II + * Auther: @imcoddy + * Content: 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. + * + * Credits:Special thanks to @Freezen for adding this problem and creating all test cases. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +/** + * Memo: Since we have solve the previous problem, try to reduce this problem to previous one. Note that the first and last can not be robbed together, so the result should be the maximum between rob house a1 to an-1 and house a2 to an. + * The result can only be within the three following cases: + * 1, the first house is robbed, so the result is as same as robbing a1 to an-1 + * 2, the last house is robbed, so the result is as same as robbing a2 to an + * 3, the first & last house are not robbed, so the result is as same as robbing a2 to an-1, also same as the 2 cases above. + * So in every case, the result would be to find the maximum of case 1 and case 2. + * Complex: O(1) + * Runtime: 132ms + * Tests: 74 test cases passed + * Rank: NA + */ +var rob = function(nums) { + // preivous solution + var robNoCircle = function(nums) { + var last = nums[0]; + var now = Math.max(nums[0], nums[1]); + for (var i = 2; i < nums.length; i++) { + var tmp = now; + now = Math.max(last + nums[i], now); + last = tmp; + } + return now; + }; + + if (nums.length <= 1) return nums[0] ? nums[0] : 0; + if (nums.length === 2) return Math.max(nums[0], nums[1]); + return Math.max(robNoCircle(nums.slice(0, nums.length - 1)), robNoCircle(nums.slice(1, nums.length))); +}; + +/** + * Memo: Use start and end index to avoid slicing array, should be a bit faster than the solution above. + * Complex: O(n) + * Runtime: 128ms + * Tests: 74 test cases passed + * Rank: S + */ +var rob = function(nums) { + var robNoCircle = function(start, end) { + var last = nums[start]; + var now = Math.max(nums[start], nums[start + 1]); + for (var i = start + 2; i <= end; i++) { + var tmp = now; + now = Math.max(last + nums[i], now); + last = tmp; + } + return now; + }; + + if (nums.length <= 1) return nums[0] ? nums[0] : 0; + if (nums.length === 2) return Math.max(nums[0], nums[1]); + return Math.max(robNoCircle(0, nums.length - 2), robNoCircle(1, nums.length - 1)); +}; + +var should = require('should'); +console.time('Runtime'); +rob([]).should.equal(0); +rob([3]).should.equal(3); +rob([30, 10]).should.equal(30); +rob([1, 2, 3, 4, 5]).should.equal(8); +rob([1, 2, 3, 10, 5]).should.equal(12); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/house-robber.js b/house-robber.js new file mode 100644 index 0000000..8c0657d --- /dev/null +++ b/house-robber.js @@ -0,0 +1,75 @@ +/** + * Source: https://leetcode.com/problems/house-robber/ + * Tags: [Dynamic Programming] + * Level: Easy + * Title: House Robber + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {number[]} nums + * @return {number} + */ + +/** + * Explanation: + * S[i] = Max(S[i-2]+nums[i], S[i-1]) + * Runtime: 127ms + * Rank: S + */ +var rob = function(nums) { + if (nums.length < 2) { + if (nums.length === 1) { + return nums[0]; + } else { + return 0; + } + } + + var s = []; + for (var i = 0; i < nums.length; i++) { + s.push(0); + } + s[0] = nums[0]; + s[1] = Math.max(nums[0], nums[1]); + for (var i = 2; i < s.length; i++) { + s[i] = Math.max(s[i - 2] + nums[i], s[i - 1]); + } + return s[s.length - 1]; +}; + +/** + * Memo: Use now and last to track previous result, and now = Max(last+nums[i], now). + * Complex: O(n) + * Space: O(1) + * Runtime: 108ms + * Tests: 69 test cases passed + * Rank: S + */ +var rob = function(nums) { + if (nums.length <= 1) return nums[0] ? nums[0] : 0; + + var last = nums[0]; + var now = Math.max(nums[0], nums[1]); + for (var i = 2; i < nums.length; i++) { + var tmp = now; + now = Math.max(last + nums[i], now); + last = tmp; + } + return now; +}; + +var should = require('should'); +console.time('Runtime'); +rob([]).should.equal(0); +rob([3]).should.equal(3); +rob([30, 10]).should.equal(30); +rob([1, 2, 3, 4, 5]).should.equal(9); +rob([1, 2, 3, 10, 5]).should.equal(12); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/insertion-sort-list.js b/insertion-sort-list.js new file mode 100644 index 0000000..829c8a1 --- /dev/null +++ b/insertion-sort-list.js @@ -0,0 +1,122 @@ +/** + * Source: https://leetcode.com/problems/insertion-sort-list/ + * Tags: [Linked List,Sort] + * Level: Medium + * Title: Insertion Sort List + * Auther: @imcoddy + * Content: Sort a linked list using insertion sort. + */ +var util = require("./util.js"); + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {ListNode} + */ + +/** + * Memo: Simply search each node and append it to list. + * Complex: O(n^2) + * Runtime: 235ms + * Tests: 21 test cases passed + * Rank: B + */ +var insertionSortList = function(head) { + var dummy = new ListNode(null); + var tail = dummy; + var p = head; + + while (p) { + tail = dummy; + while (tail && tail.next && p.val > tail.next.val) { + tail = tail.next; + } + var q = p.next; + p.next = tail.next; + tail.next = p; + p = q; + } + + return dummy.next; +}; + +/** + * Memo: The link list might contain some sub sorted list, so it will be faster to search the sub sorted list then append it as a whole. + * Complex: O(n^2) + * Runtime: 176ms + * Tests: 21 test cases passed + * Rank: A + */ +var insertionSortList = function(head) { + var dummy = new ListNode(null); + var pointer = dummy; + var start = head; + + while (start) { + pointer = dummy; + while (pointer && pointer.next && start.val > pointer.next.val) { + pointer = pointer.next; + } + var next_val = Number.MAX_VALUE; + if (pointer && pointer.next) { + next_val = pointer.next.val; + } + + var end = start; + var end_next = end.next; + while (end_next && end_next.val > end.val && end_next.val < next_val) { + end = end_next; + end_next = end.next; + } + + end.next = pointer.next; + pointer.next = start; + start = end_next; + } + return dummy.next; +}; + +/** + * Memo: Create a new list using dummy head, and simply append each node to that list. + * Complex: O(n^2) + * Runtime: 232ms + * Tests: 21 test cases passed + * Rank: B + */ +var insertionSortList = function(head) { + var dummy = new ListNode(null); + var p = head; + while (p) { + var tail = dummy; + while (tail.next && tail.next.val < p.val) { + tail = tail.next; + } + var q = p.next; + p.next = tail.next; + tail.next = p; + p = q; + } + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var should = require('should'); +console.time('Runtime'); + +console.timeEnd('Runtime'); +util.lta(insertionSortList(util.atl([]))).should.eql([]); +util.lta(insertionSortList(util.atl([1]))).should.eql([1]); +util.lta(insertionSortList(util.atl([1, 1, 2, 2, 4]))).should.eql([1, 1, 2, 2, 4]); +util.lta(insertionSortList(util.atl([1, 3, 2, 5, 4]))).should.eql([1, 2, 3, 4, 5]); +util.lta(insertionSortList(util.atl([1, 20, 3, 2, 5, 4, 6, 7, 8]))).should.eql([1, 2, 3, 4, 5, 6, 7, 8, 20]); \ No newline at end of file diff --git a/intersection-of-two-linked-lists.js b/intersection-of-two-linked-lists.js new file mode 100644 index 0000000..54c8583 --- /dev/null +++ b/intersection-of-two-linked-lists.js @@ -0,0 +1,124 @@ +/** + * Source: https://leetcode.com/problems/intersection-of-two-linked-lists/ + * Tags: [Linked List] + * Level: Easy + * Title: Intersection of Two Linked Lists + * Auther: @imcoddy + * Content: Write a program to find the node at which the intersection of two singly linked lists begins. + * + * For example, the following two linked lists: + * + * A: a1 → a2 + * ↘ + * c1 → c2 → c3 + * ↗ + * B: b1 → b2 → b3 + * + * begin to intersect at node c1. + * + * Notes: + * + * If the two linked lists have no intersection at all, return null. + * The linked lists must retain their original structure after the function returns. + * You may assume there are no cycles anywhere in the entire linked structure. + * Your code should preferably run in O(n) time and use only O(1) memory. + * + * + * + * Credits:Special thanks to @stellari for adding this problem and creating all test cases. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} headA + * @param {ListNode} headB + * @return {ListNode} + */ + +/** + * Memo: If the two lists have intersection, then L1 + L2 and L2 + L1 will end up with the same intersection. + * More explanation here: https://leetcode.com/discuss/36204/python-ac-solution-with-clear-explanation + * Complex: O(m+n) + * Runtime: 151ms + * Tests: 42 test cases passed + * Rank: S + * Updated: 2015-06-17 + */ +var getIntersectionNode = function(headA, headB) { + if (!headA || !headB) return null; + + var pa = headA; + var pb = headB; + var count = 0; // should stop after link list to each other once + while (count <= 2) { + if (pa === pb) return pa; + + if (pa.next) { + pa = pa.next; + } else { + pa = headB; + count++; + } + + if (pb.next) { + pb = pb.next; + } else { + pb = headA; + count++; + } + } + return null; +}; + +var getIntersectionNode = function(headA, headB){ + var pa = headA; + var pb = headB; + var count = 0; + while (pa && pb) { + if(pa === pb) return pa; + + if (pa.next) { + pa = pa.next; + }else { + pa = headB; + count++; + } + + if (pb.next) { + pb = pb.next; + }else { + pb = headA ; + count++; + } + if (count>2) { + break; + } + } + return null; +}; + +var util = require("./util.js"); + +function concat(list1, list2) { + if (!list1) return list2; + var p = list1; + while (p.next) { + p = p.next; + } + p.next = list2; + return list1; +} + +var list1 = util.arrayToLinkList([1, 2, 3]); +var list2 = util.arrayToLinkList([6, 2, 3]); +var listc = util.arrayToLinkList([7, 8]); +console.log(util.linkListToString(concat(list1, listc))); +console.log(util.linkListToString(concat(list2, listc))); +console.log(util.linkListToString(getIntersectionNode(list1, list2))); diff --git a/invert-binary-tree.js b/invert-binary-tree.js new file mode 100644 index 0000000..b23fcfb --- /dev/null +++ b/invert-binary-tree.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/invert-binary-tree/ + * Tags: [Tree] + * Level: Easy + * Title: Invert Binary Tree + * Auther: @imcoddy + * Content: 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. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ + +/** + * Memo: Recursive solution by swap left and right children + * Complex: O(n) + * Runtime: 124ms + * Tests: 68 test cases passed + * Rank: S + * Updated: 2015-06-15 + */ +var invertTree = function(root) { + if (root === null) return null; + var left = invertTree(root.right); + root.right = invertTree(root.left); + root.left = left; + return root; +}; \ No newline at end of file diff --git a/isomorphic-strings.js b/isomorphic-strings.js new file mode 100644 index 0000000..1094c73 --- /dev/null +++ b/isomorphic-strings.js @@ -0,0 +1,58 @@ +/** + * Source: https://leetcode.com/problems/isomorphic-strings/ + * Tags: [Hash Table] + * Level: Easy + * Title: Isomorphic Strings + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ + +/** + * Memo: + * Runtime: 133ms + * Rank: A + */ +var isIsomorphic = function(s, t) { + var map_s = {}; + var map_t = {}; + var result = true; + for (var i = 0; i < s.length; i++) { + if (map_s[s[i]] || map_t[t[i]]) { + if (map_s[s[i]] !== t[i] || map_t[t[i]] !== s[i]) { + result = false; + break; + } + } else { + map_s[s[i]] = t[i]; + map_t[t[i]] = s[i]; + } + } + + return result; +}; + +console.log(isIsomorphic('egg', 'add')); +console.log(isIsomorphic('foo', 'bar')); +console.log(isIsomorphic('paper', 'title')); +console.log(isIsomorphic('ab', 'ca')); +console.log(isIsomorphic('ab', 'aa')); diff --git a/jump-game.js b/jump-game.js new file mode 100644 index 0000000..742e263 --- /dev/null +++ b/jump-game.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/jump-game/ + * Tags: [Array,Greedy] + * Level: Medium + * Title: Jump Game + * Auther: @imcoddy + * Content: Given an array of non-negative integers, you are initially positioned at the first index of the array. + * + * + * Each element in the array represents your maximum jump length at that position. + * + * + * Determine if you are able to reach the last index. + * + * + * + * For example: + * A = [2,3,1,1,4], return true. + * + * + * A = [3,2,1,0,4], return false. + */ + +/** + * @param {number[]} nums + * @return {boolean} + */ + +/** + * Memo: If we can jump to last position, it means at some point we can reach from last-i if nums[last-i] >= i, as there are i steps from that to last. So we can make this to a smaller problem, until we confirm whether we can reach the 1st location. + * Complex: O(n) + * Runtime: 132ms + * Tests: 71 test cases passed + * Rank: A + * Updated: 2015-06-04 + */ +var canJump = function(nums) { + var last = nums.length - 1; + for (var i = nums.length - 2; i >= 0; i--) { + if (i + nums[i] >= last) last = i; + } + return last === 0; +}; + +var should = require('should'); +console.time('Runtime'); +canJump([2, 3, 1, 1, 4]).should.equal(true); +canJump([3, 2, 1, 0, 4]).should.equal(false); + +console.timeEnd('Runtime'); diff --git a/kth-largest-element-in-an-array.js b/kth-largest-element-in-an-array.js new file mode 100644 index 0000000..016a171 --- /dev/null +++ b/kth-largest-element-in-an-array.js @@ -0,0 +1,92 @@ +/** + * Source: https://leetcode.com/problems/kth-largest-element-in-an-array/ + * Tags: [Divide and Conquer,Heap] + * Level: Medium + * Title: Kth Largest Element in an Array + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ + +/** + * Memo: Use heap sort to build a minHeap with k element, and add the rest to heap top only when it is larger than nums[0], so in the end nums[0] is the result. + * Complex: O(nlogn) + * Runtime: 144ms + * Tests: 27 test cases passed + * Rank: S + * Updated: 2015-06-11 + */ +var findKthLargest = function(nums, k) { + function parent(i) { + return ~~((i - 1) / 2); + } + + function left(i) { + return 2 * i + 1; + } + + function right(i) { + return 2 * i + 2; + } + + function swap(array, i, j) { + var tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; + } + + function buildMinHeap(array, i, size) { + var l = left(i); + var r = right(i); + var min = i; + + if (l < size && array[l] < array[min]) { + min = l; + } + if (r < size && array[r] < array[min]) { + min = r; + } + + if (i !== min) { + swap(array, i, min); + buildMinHeap(array, min, size); + } + } + + function buildHeap(array, k) { + for (var i = ~~(k / 2); i >= 0; i--) { + buildMinHeap(array, i, k); + } + } + + buildHeap(nums, k); + for (var i = k; i < nums.length; i++) { + if (nums[i] > nums[0]) { + nums[0] = nums[i]; + buildMinHeap(nums, 0, k); + } + } + + return nums[0]; +}; + +var should = require('should'); +console.time('Runtime'); +findKthLargest([3, 9, 5, 1, 7], 5).should.equal(1); +findKthLargest([3, 9, 5, 1, 0, 2, 7], 5).should.equal(2); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/length-of-last-word.js b/length-of-last-word.js new file mode 100644 index 0000000..cdb2719 --- /dev/null +++ b/length-of-last-word.js @@ -0,0 +1,36 @@ +/** + * Source: https://leetcode.com/problems/length-of-last-word/ + * Tags: [String] + * Level: Easy + * Updated: 2015-04-24 + * Title: Length of Last Word + * Auther: @imcoddy + * Content: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. + * + * If the last word does not exist, return 0. + * + * Note: A word is defined as a character sequence consists of non-space characters only. + * + * + * For example, + * Given s = "Hello World", + * return 5. + */ + +/** + * @param {string} s + * @return {number} + */ + +var lengthOfLastWord = function(s) { + if (!s) { + return 0; + } + s = s.trim(); + var last_space = s.lastIndexOf(' '); + return s.length - (last_space+1); +}; + +console.log(lengthOfLastWord('This is a Test')); +console.log(lengthOfLastWord('A ')); +console.log(lengthOfLastWord()); diff --git a/letter-combinations-of-a-phone-number.js b/letter-combinations-of-a-phone-number.js new file mode 100644 index 0000000..34faae7 --- /dev/null +++ b/letter-combinations-of-a-phone-number.js @@ -0,0 +1,77 @@ +/** + * Source: https://leetcode.com/problems/letter-combinations-of-a-phone-number/ + * Tags: [Backtracking,String] + * Level: Medium + * Title: Letter Combinations of a Phone Number + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {string} digits + * @return {string[]} + */ + +/** + * Memo: + * Runtime: 131ms + * Tests: 25 test cases passed + * Rank: B + */ +var letterCombinations = function(digits) { + var n = digits.length; + if (n <= 0) { + return []; + } + var map = { + '1': [], + '2': ['a', 'b', 'c'], + '3': ['d', 'e', 'f'], + '4': ['g', 'h', 'i'], + '5': ['j', 'k', 'l'], + '6': ['m', 'n', 'o'], + '7': ['p', 'q', 'r', 's'], + '8': ['t', 'u', 'v'], + '9': ['w', 'x', 'y', 'z'], + '0': [' '], + '*': ['+'], + '#': ['^'], + }; + + var result = []; + var solution = []; + + function letterCombinationsBT(row) { + if (row >= n) { + result.push(solution.join('')); + } else { + var digit = digits[row]; + for (var i = 0; i < map[digit].length; i++) { + solution[row] = map[digit][i]; + letterCombinationsBT(row + 1); + } + } + } + + letterCombinationsBT(0); + return result; +}; + +console.log(letterCombinations('')); +console.log(letterCombinations('2')); +console.log(letterCombinations('22')); +console.log(letterCombinations('234')); diff --git a/linked-list-cycle-ii.js b/linked-list-cycle-ii.js new file mode 100644 index 0000000..782b098 --- /dev/null +++ b/linked-list-cycle-ii.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/linked-list-cycle-ii/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Linked List Cycle II + * Auther: @imcoddy + * Content: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. + * + * + * + * Follow up: + * Can you solve it without using extra space? + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {ListNode} + */ + +/** + * Memo: Mark val to NaN to indicate that this node has been visited. + * * The original list will be modified. and will fail if origianl list contains val of NaN + * Complex: O(n) + * Runtime: 140ms + * Tests: 16 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var detectCycle = function(head) { + while (head) { + if (isNaN(head.val)) { + return head; + } else { + head.val = NaN; + head = head.next; + } + } + return null; +}; + + +//TODO add solution that doesn't change the orignal list \ No newline at end of file diff --git a/linked-list-cycle.js b/linked-list-cycle.js new file mode 100644 index 0000000..ee86270 --- /dev/null +++ b/linked-list-cycle.js @@ -0,0 +1,131 @@ +/** + * Source: https://leetcode.com/problems/linked-list-cycle/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Linked List Cycle + * Auther: @imcoddy + * Content: Given a linked list, determine if it has a cycle in it. + * + * + * + * Follow up: + * Can you solve it without using extra space? + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {boolean} + */ + +/** + * Memo: Create a fast pointer and slow pointer, and see if the fast one can catch up with the slow one when fast is not null. + * Runtime: 150ms + * Rank: A + */ +var hasCycle = function(head) { + if (!head) { + return false; + } + + var slow = head; + var fast = head.next; + + while (fast && fast !== slow) { + slow = slow.next; + fast = fast.next; + if (!fast) { + return false; + } + if (fast === slow) { + return true; + } + + fast = fast.next; + if (!fast) { + return false; + } + if (fast === slow) { + return true; + } + } + return fast !== null; +}; + +/** + * Memo: Imporeve from above version. Return directly when there is only one node and link to itself. + * Complex: O(n) + * Runtime: 124ms + * Tests: 16 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var hasCycle = function(head) { + if (!head || !head.next) return false; + if (head.next === head) return true; + + var slow = head; + var fast = head.next; + while (fast && fast !== slow) { + slow = slow.next; + fast = fast.next; + + if (!fast) return false; + if (fast === slow) return true; + fast = fast.next; + if (!fast) return false; + if (fast === slow) return true; + } + return false; +}; + +/** + * Memo: Imporeve from above version. Return directly when there is only one node and link to itself. + * Complex: O(n) + * Runtime: 124ms + * Tests: 16 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var hasCycle = function(head) { + if (!head || !head.next) return false; + if (head.next === head) return true; + + var slow = head; + var fast = head; + while (fast.next && fast.next.next) { + slow = slow.next; + fast = fast.next.next; + if (fast === slow) return true; + } + return false; +}; + + +/** + * Memo: Mark val to NaN to indicate that this node has been visited. + * * The original list will be modified. and will fail if origianl list contains val of NaN + * Complex: O(n) + * Runtime: 140ms + * Tests: 16 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var hasCycle = function(head) { + while (head) { + if (isNaN(head.val)) { + return true; + } else { + head.val = NaN; + head = head.next; + } + } + return false; +}; \ No newline at end of file diff --git a/list-unsolved.sh b/list-unsolved.sh new file mode 100755 index 0000000..1aa1550 --- /dev/null +++ b/list-unsolved.sh @@ -0,0 +1,2 @@ +# /bin/sh +find . -name '*.js' | awk -F/ '{print $NF}' | sort -f | uniq -c | grep "^[ \t]*1 " | cut -d ' ' -f 5 diff --git a/longest-common-prefix.js b/longest-common-prefix.js new file mode 100644 index 0000000..be415f9 --- /dev/null +++ b/longest-common-prefix.js @@ -0,0 +1,36 @@ +/** + * Source: https://leetcode.com/problems/longest-common-prefix/ + * Tags: [String] + * Level: Easy + * Title: Longest Common Prefix + * Auther: @imcoddy + * Content: Write a function to find the longest common prefix string amongst an array of strings. + */ + +/** + * @param {string[]} strs + * @return {string} + */ + +/** + * Memo: Since it is the longest common prefix, so the result should be "" or it exists in every string. Use the first string as base and search each char to see if they are the same or not. + * Runtime: 141ms + * Tests: 117 test cases passed + * Rank: A + */ +var longestCommonPrefix = function(strs) { + if (strs.length === 0) return ""; + if (strs.length === 1) return strs[0]; + + for (var i = 0; i < strs[0].length; i++) { + for (var j = 1; j < strs.length; j++) { + if (strs[j].length <= i || strs[j][i] !== strs[0][i]) { + return strs[0].substring(0, i); + } + } + } + return strs[0]; +}; + +console.log(longestCommonPrefix(['this is a test', 'this is also a test'])); +console.log(longestCommonPrefix(['this is a test', 'this is a test as well'])); diff --git a/longest-consecutive-sequence.js b/longest-consecutive-sequence.js new file mode 100644 index 0000000..31f6c1c --- /dev/null +++ b/longest-consecutive-sequence.js @@ -0,0 +1,78 @@ +/** + * Source: https://leetcode.com/problems/longest-consecutive-sequence/ + * Tags: [Array] + * Level: Hard + * Title: Longest Consecutive Sequence + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {number[]} nums + * @return {number} + */ + +/** + * Memo: Pretty tricky to use JS built-in hash, as negative intergers have order issue! + * Runtime: 223ms + * Tests: 67 test cases passed + * Rank: C + */ +var longestConsecutive = function(nums) { + if (nums.length < 2) { + return nums.length; + } + + var pos = {}; + var neg = {}; + for (var i = 0; i < nums.length; i++) { + nums[i] >= 0 ? pos[nums[i]] = true : neg[0 - nums[i]] = true; + } + var neg_keys = Object.keys(neg); + for (var i = 0; i < neg_keys.length; i++) { + neg_keys[i] = 0 - neg_keys[i]; + } + neg_keys = neg_keys.reverse(); + pos_keys = Object.keys(pos); + for (var i = 0; i < pos_keys.length; i++) { + pos_keys[i] = parseInt(pos_keys[i], 10); + } + var keys = neg_keys.concat(pos_keys); + var start = keys[0]; + var count = 1; + var max = count; + for (var i = 1; i < keys.length; i++) { + if (keys[i] - start === count) { + count++; + if (count > max) { + max = count; + } + } else { + start = keys[i]; + count = 1; + } + } + return max; +}; + +console.log(longestConsecutive([])); //0 +console.log(longestConsecutive([1])); //1 +console.log(longestConsecutive([0, 0])); //1 +console.log(longestConsecutive([1, 1])); //1 +console.log(longestConsecutive([1, 2])); //2 +console.log(longestConsecutive([-2, -1])); //2 +console.log(longestConsecutive([-2, -1, 0, 1, 2])); //5 +console.log(longestConsecutive([1, 2, 2, 2, 2])); //2 +console.log(longestConsecutive([1, 1, 1, 1, 1])); //1 +console.log(longestConsecutive([1, 2, 3, 4, 5])); //5 +console.log(longestConsecutive([100, 4, 200, 1, 3, 2])); //4 +console.log(longestConsecutive([100, 4, 200, 1, 3, 2, -1, -3, -4])); //4 +console.log(longestConsecutive([4, 0, -4, -2, 2, 5, 2, 0, -8, -8, -8, -8, -1, 7, 4, 5, 5, -4, 6, 6, -3])); //4 diff --git a/lowest-common-ancestor-of-a-binary-search-tree.js b/lowest-common-ancestor-of-a-binary-search-tree.js new file mode 100644 index 0000000..5c2d9fa --- /dev/null +++ b/lowest-common-ancestor-of-a-binary-search-tree.js @@ -0,0 +1,76 @@ +/** + * Source: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/ + * Tags: [Tree] + * Level: Easy + * Title: Lowest Common Ancestor of a Binary Search Tree + * Auther: @imcoddy + * Content: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. + * + * + * + * 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).” + * + * + * + * _______6______ + * / \ + * ___2__ ___8__ + * / \ / \ + * 0 _4 7 9 + * / \ + * 3 5 + * + * + * + * For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Lowest Common Ancestor of a Binary Tree + */ + +/** + * 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} + */ +/** + * Memo: Since it is a BST, if (root-p)*(root-q) > 0, means both p and q are on the same subtree. + * Another way is to find root to node path and compare the path later + * Complex: O(logn) + * Runtime: 180ms + * Tests: 27 test cases passed + * Rank: S + * Updated: 2015-10-29 + */ +var lowestCommonAncestor = function(root, p, q) { + while ((root.val - p.val) * (root.val - q.val) > 0) { + console.log(root.val, p.val, q.val); + root = root.val > p.val ? root.left : root.right; + } + return root; +}; + +var util = require("./util.js"); +var tree = util.arrayToTree([4, 2, 6, 1, 3, 5, 7]); +console.log(tree); + +console.log(lowestCommonAncestor(tree, tree.left.left, tree.right.right)); +//console.log(lowestCommonAncestor(tree,tree.right.right, tree.right.right)); \ No newline at end of file diff --git a/majority-element.js b/majority-element.js new file mode 100644 index 0000000..d45f49c --- /dev/null +++ b/majority-element.js @@ -0,0 +1,72 @@ +/** + * Source: https://leetcode.com/problems/majority-element/ + * Tags: [Divide and Conquer,Array,Bit Manipulation] + * Level: Easy + * Updated: 2015-04-24 + * Title: Majority Element + * Auther: @imcoddy + * Content: Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. + * + * You may assume that the array is non-empty and the majority element always exist in the array. + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + */ + +/** + * @param {number[]} num + * @return {number} + */ + +/** + * Memo: Use a map to record how many thime this element appeared, then find the one passed [n/2] times + * Complex: O(n) + * Runtime: 136ms + * Tests: 40 test cases passed + * Rank: A + * Updated: 2015-06-12 + */ +var majorityElement = function(num) { + var map = {}; + for (var i = 0; i < num.length; i++) { + if (map[num[i]]) { + map[num[i]] += 1; + if (map[num[i]] >= (num.length / 2)) { + return parseInt(num[i], 10); + } + } else { + map[num[i]] = 1; + } + } + + var result = 0; + var max = 0; + for (var k in map) { + if (map[k] > max) { + result = k; + max = map[k]; + } + } + return parseInt(result, 10); +}; + +/** + * Memo: Sort the array first, then the majority element will be located at n/2. + * Complex: O(nlogn) + * Runtime: 148ms + * Tests: 40 test cases passed + * Rank: A + * Updated: 2015-06-12 + */ +var majorityElement = function(num) { + return num.sort()[num.length >> 1]; +}; + +var should = require('should'); +console.time('Runtime'); +majorityElement([1]).should.equal(1); +//majorityElement([1, 2]).should.equal(1); +//majorityElement([2, 1]).should.equal(1); // this is a bit tricky as it could be either 1 or 2 +majorityElement([2, 1, 2]).should.equal(2); +majorityElement([1, 8, 3, 3, 3, 5]).should.equal(3); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/maximum-depth-of-binary-tree.js b/maximum-depth-of-binary-tree.js new file mode 100644 index 0000000..3a59467 --- /dev/null +++ b/maximum-depth-of-binary-tree.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/maximum-depth-of-binary-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Updated: 2015-04-24 + * Title: Maximum Depth of Binary Tree + * Auther: @imcoddy + * Content: Given a binary tree, find its maximum depth. + * + * The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number} + */ + +/** + * Memo: + * Complex: O(logn) + * Runtime: 140ms + * Tests: 38 test cases passed + * Rank: A + */ +var maxDepth = function(root) { + return root ? Math.max(maxDepth(root.left), maxDepth(root.right)) + 1 : 0; +}; + +/** + * Memo: + * Complex: O(logn) + * Runtime: 160ms + * Tests: 38 test cases passed + * Rank: B + */ +var maxDepth = function(root) { + if (!root) { + return 0; + } + var left = maxDepth(root.left); + var right = maxDepth(root.right); + return Math.max(left, right) + 1; +}; \ No newline at end of file diff --git a/maximum-subarray.js b/maximum-subarray.js new file mode 100644 index 0000000..250fdf5 --- /dev/null +++ b/maximum-subarray.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/maximum-subarray/ + * Tags: [Divide and Conquer,Array,Dynamic Programming] + * Level: Medium + * Title: Maximum Subarray + * Auther: @imcoddy + * Content: Find the contiguous subarray within an array (containing at least one number) which has the largest sum. + * + * + * For example, given the array [−2,1,−3,4,−1,2,1,−5,4], + * the contiguous subarray [4,−1,2,1] has the largest sum = 6. + * + * + * click to show more practice. + * + * More practice: + * + * If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. + */ + +/** + * @param {number[]} nums + * @return {number} + */ + +/** + * Memo: Dynamic Programming. Let s[i] = largest maximum-subarray till element i, than it comes from only two + * 1, previous best result plus current number. + * 2, abandon previous result and use only current number. + * Runtime: 147ms + * Tests: 201 test cases passed + * Rank: A + */ +//TODO add divide and conquer solution +var maxSubArray = function(nums) { + var s = [nums[0]]; + var max = s[0]; + for (var i = 1; i < nums.length; i++) { + s[i] = Math.max(s[i - 1] + nums[i], nums[i]); + if (s[i] > max) { + max = s[i]; + } + } + return max; +}; + +console.log(maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4])); diff --git a/merge-k-sorted-lists.js b/merge-k-sorted-lists.js new file mode 100644 index 0000000..10ba864 --- /dev/null +++ b/merge-k-sorted-lists.js @@ -0,0 +1,151 @@ +/** + * Source: https://leetcode.com/problems/merge-k-sorted-lists/ + * Tags: [Divide and Conquer,Linked List,Heap] + * Level: Hard + * Title: Merge k Sorted Lists + * Auther: @imcoddy + * Content: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + */ +var util = require('./util.js'); + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode[]} lists + * @return {ListNode} + */ + +/** + * Memo: use heads to track head of each link list, find min among heads and append that node to link list till every head is handled. + * Runtime: 504ms + * Tests: 130 test cases passed + * Rank: D + */ +var mergeKLists = function(lists) { + var dummy = new ListNode(null); + var tail = dummy; + var heads = []; + + for (var i = 0; i < lists.length; i++) { + if (lists[i]) { + heads.push(lists[i]); + } + } + + if (heads.length === 0) { + return null; + } + + while (heads.length > 1) { + var index = 0; + for (var i = 1; i < heads.length; i++) { + if (heads[index].val > heads[i].val) { + index = i; + } + } + + tail.next = heads[index]; + // remove this list when finished, otherwise move this list to next node + heads[index].next ? heads[index] = heads[index].next : heads.splice(index, 1); + + tail = tail.next; + } + + tail.next = heads[0]; + return dummy.next; +}; + +/** + * Memo: Treat lists as a queue and pop two lists and merge them, then append the new list until there is only one list left. + * Complex: O(kn^2) + * Runtime: 212ms + * Tests: 130 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var mergeKLists = function(lists) { + var mergeTwoLists = function(h1, h2) { + var dummy = new ListNode(null); + var tail = dummy; + while (h1 && h2) { + if (h1.val <= h2.val) { + tail = tail.next = h1; + h1 = h1.next; + } else { + tail = tail.next = h2; + h2 = h2.next; + } + } + tail.next = h1 ? h1 : h2; + return dummy.next; + }; + + if (!lists || lists.length === 0) return null; + while (lists.length > 1) lists.push(mergeTwoLists(lists.shift(), lists.shift())); + return lists[0]; +}; + + +/** + * Memo: Improve the above by moving several nodes at one time while merging, which could reduce linking + * Complex: O(k*n^2) + * Runtime: 172ms + * Tests: 130 test cases passed + * Rank: SS + * Updated: 2015-09-30 + */ +var mergeKLists = function(lists) { + var mergeTwoLists = function(l1, l2) { + if (!(l1 && l2)) return l1 || l2; + + var dummy = new ListNode(null); + var tail = dummy; + var small = l1.val <= l2.val ? l1 : l2; + var large = l1 === small ? l2 : l1; + + while (small && large) { + tail.next = small; + while (small.next && small.next.val <= large.val) small = small.next; + var smallnext = small.next; + tail = small; + tail.next = large; + large = smallnext; + small = tail.next; + } + return dummy.next; + }; + + if (!lists || lists.length === 0) return null; + while (lists.length > 1) lists.push(mergeTwoLists(lists.shift(), lists.shift())); + return lists[0]; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var should = require('should'); +console.time('Runtime'); + +util.linkListToArray(mergeKLists([util.arrayToLinkList([1, 3, 5, 7, 9])])).should.eql([1, 3, 5, 7, 9]); + +util.linkListToArray(mergeKLists([util.arrayToLinkList([1, 3, 5, 7, 9]), util.arrayToLinkList([2, 4, 6, 8, 10])])).should.eql([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + +util.linkListToArray(mergeKLists([util.arrayToLinkList([1, 3, 5, 7, 9]), util.arrayToLinkList([2, 4, 6, 8, 10]), util.arrayToLinkList([2, 4])])).should.eql([1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10]); +console.timeEnd('Runtime'); + +console.log((mergeKLists([]))); +console.log(util.linkListToString(mergeKLists([ + util.arrayToLinkList([]), + util.arrayToLinkList([]) +]))); +var l1 = util.arrayToLinkList([1, 3, 5, 7, 9]); +var l2 = util.arrayToLinkList([2, 4, 6, 8, 10]); +var l3 = util.arrayToLinkList([2, 4]); +console.log(util.linkListToString(mergeKLists([l1, l2, l3]))); \ No newline at end of file diff --git a/merge-sorted-array.js b/merge-sorted-array.js new file mode 100644 index 0000000..63da5ed --- /dev/null +++ b/merge-sorted-array.js @@ -0,0 +1,84 @@ +/** + * Source: https://leetcode.com/problems/merge-sorted-array/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Merge Sorted Array + * Auther: @imcoddy + * Content: Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + * + * + * Note: + * You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. + */ + +/** + * @param {number[]} nums1 + * @param {number} m + * @param {number[]} nums2 + * @param {number} n + * @return {void} Do not return anything, modify nums1 in-place instead. + */ + +/** + * Memo: Append nums2 to nums1, and turn it into problem of sorting nums1. + * Runtime: 145ms + * Tests: 49 test cases passed + * Rank: B + */ +var merge = function(nums1, m, nums2, n) { + for (var i = 0; i < nums2.length; i++) { + nums1[m + i] = nums2[i]; + } + for (var i = 0; i < m + n; i++) { + for (j = i + 1; j < m + n; j++) { + if (nums1[i] > nums1[j]) { + var t = nums1[i]; + nums1[i] = nums1[j]; + nums1[j] = t; + } + } + } +}; + + +/** + * Memo: Compare from back to front, use last as index to put the largest unsolved element. + * Complex: O(m+n) + * Runtime: 136ms + * Tests: 59 test cases passed + * Rank: S + * Updated: 2015-06-10 + */ +var merge = function(nums1, m, nums2, n) { + var last = m + n - 1; + var j = n - 1; + var i = m - 1; + + while (i >= 0 && j >= 0) { + nums1[last--] = nums1[i] > nums2[j] ? nums1[i--] : nums2[j--]; + } + + while (j >= 0) { + nums1[last--] = nums2[j--]; + } +}; + + +/** + * Memo: One line solution by moving m and n, better than the solution above but a bit hard to read. + * Complex: O(m+n) + * Runtime: 140ms + * Tests: 59 test cases passed + * Rank: S + * Updated: 2015-06-11 + */ +var merge = function(nums1, m, nums2, n) { + //while (n) nums1[m + n - 1] = nums1[m - 1] > nums2[n - 1] ? nums1[--m] : nums2[--n]; + // if m is 0, it means the array is already sorted so need to keep comparing + while (n) nums1[m + n - 1] = m && nums1[m - 1] > nums2[n - 1] ? nums1[--m] : nums2[--n]; +}; + +console.log(merge([1, 3, 5, 7, 9], 5, [2, 4, 6], 3)); +console.log(merge([-10, -8, -6, -4, -2], 5, [-5, -3, -1], 3)); +console.log(merge([2, 4, 6], 3, [1, 3, 5, 7, 9], 5)); +console.log(merge([12, 14, 16], 3, [1, 3, 5, 7, 9], 5)); diff --git a/merge-two-sorted-lists.js b/merge-two-sorted-lists.js new file mode 100644 index 0000000..e70db3b --- /dev/null +++ b/merge-two-sorted-lists.js @@ -0,0 +1,171 @@ +/** + * Source: https://leetcode.com/problems/merge-two-sorted-lists/ + * Tags: [Linked List] + * Level: Easy + * Title: Merge Two Sorted Lists + * Auther: @imcoddy + * Content: 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. + */ + +var util = require('./util.js'); +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} l1 + * @param {ListNode} l2 + * @return {ListNode} + */ + +/** + * Memo: + * Runtime: 176ms + * Tests: 208 test cases passed + * Rank: A + */ +var mergeTwoLists = function(l1, l2) { + var dummy = new ListNode(null); + var tail = dummy; + var p1 = l1; + var p2 = l2; + + while (p1 && p2) { + if (p1.val > p2.val) { + tail.next = p2; + p2 = p2.next; + } else { + tail.next = p1; + p1 = p1.next; + } + tail = tail.next; + } + + // link the rest to tail.next when one link list is done + tail.next = p1 ? p1 : p2; + return dummy.next; +}; + + +/** + * Memo: Compare each head and move the smaller one to new list. + * Complex: O(m+n) + * Runtime: 160ms + * Tests: 208 test cases passed + * Rank: B + * Updated: 2015-06-16 + */ +var mergeTwoLists = function(l1, l2) { + var dummy = new ListNode(null); + var tail = dummy; + var p1 = l1; + var p2 = l2; + + while (p1 && p2) { + if (p1.val < p2.val) { + tail.next = p1; + p1 = p1.next; + } else { + tail.next = p2; + p2 = p2.next; + } + tail = tail.next; + } + tail.next = p1 ? p1 : p2; + + return dummy.next; +}; + +/** + * Memo: Use small and large pointer to record current headers, and append small one to tail, and switch small.next to large if it is not null. + * Complex: O(m+n) + * Runtime: 160ms + * Tests: 208 test cases passed + * Rank: S + * Updated: 2015-06-16 + */ +var mergeTwoLists = function(l1, l2) { + if (!l1) return l2; + if (!l2) return l1; + + var dummy = new ListNode(null); + var tail = dummy; + var small = l1.val <= l2.val ? l1 : l2; + var large = l1.val <= l2.val ? l2 : l1; + + while (small && large) { + tail.next = small; + while (small.next && small.next.val <= large.val) { + small = small.next; + } + var smallnext = small.next; + tail = small; + tail.next = large; + if (small.next) { + large = smallnext; + small = tail.next; + } + } + return dummy.next; +}; + +/** + * Memo: Make a dummy node as head add append to its tail + * Complex: O(min(m, n)) + * Runtime: 160ms + * Tests: 208 test cases passed + * Rank: S + * Updated: 2015-08-20 + */ +var mergeTwoLists = function(l1, l2) { + var dummy = new ListNode(null); + var tail = dummy; + + while (l1 && l2) { + var p; + if (l1.val > l2.val) { + p = l2.next; + l2.next = tail.next; + tail.next = l2; + l2 = p; + } else { + p = l1.next; + l1.next = tail.next; + tail.next = l1; + l1 = p; + } + tail = tail.next; + } + tail.next = l1 ? l1 : l2; + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var should = require('should'); +console.time('Runtime'); + +var l1 = util.arrayToLinkList([1, 3, 5, 7, 9]); +var l2 = util.arrayToLinkList([2, 4, 6, 8, 10]); +console.log(util.linkListToString(mergeTwoLists(l1, l2))); +util.linkListToArray(mergeTwoLists(l1, l2)).should.eql([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + +l1 = util.arrayToLinkList([1, 3, 5, 7, 9]); +l2 = util.arrayToLinkList([12, 24, 36, 48, 60]); +console.log(util.linkListToString(mergeTwoLists(l1, l2))); +util.linkListToArray(mergeTwoLists(l1, l2)).should.eql([1, 3, 5, 7, 9, 12, 24, 36, 48, 60]); + +l1 = util.arrayToLinkList([12, 24, 36, 48, 60]); +l2 = util.arrayToLinkList([1, 3, 5, 7, 9]); +console.log(util.linkListToString(mergeTwoLists(l1, l2))); + +l1 = util.arrayToLinkList([1, 3, 5, 7, 9, 11, 13, 25]); +l2 = util.arrayToLinkList([12, 24, 36, 48, 60]); +console.log(util.linkListToString(mergeTwoLists(l1, l2))); +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/minimum-depth-of-binary-tree.js b/minimum-depth-of-binary-tree.js new file mode 100644 index 0000000..bbdb739 --- /dev/null +++ b/minimum-depth-of-binary-tree.js @@ -0,0 +1,124 @@ +/** + * Source: https://leetcode.com/problems/minimum-depth-of-binary-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Minimum Depth of Binary Tree + * Auther: @imcoddy + * Content: Given a binary tree, find its minimum depth. + * + * The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number} + */ + +/** + * Memo: Once reach a leaf, add current level to an array, then find minimum in the array + * Runtime: 152ms + * Rank: B + */ +var minDepth = function(root) { + function DFS(root, level, queue) { + if (!root) { + return []; + } + if (!root.left && !root.right) { + queue.push(level); + } + DFS(root.left, level + 1, queue); + DFS(root.right, level + 1, queue); + return queue; + } + + var levels = DFS(root, 1, []); + if (levels.length <= 0) { + return 0; + } + var min = Number.MAX_VALUE; + for (var i = 0; i < levels.length; i++) { + if (levels[i] < min) { + min = levels[i]; + } + } + return min; +}; + +/** + * Memo: Return 0 if root is null, otherwise use min to record the shortest root-to-leaf level + * Complex: O() + * Runtime: 144ms + * Tests: 41 test cases passed + * Rank: A + */ +var minDepth = function(root) { + if (!root) { + return 0; + } + + var min = Number.MAX_VALUE; + var dfs = function(root, level) { + if (!root) { + return; + } + if (root.left === null && root.right === null) { + if (level < min) { + min = level; + } + return; + } + dfs(root.left, level + 1); + dfs(root.right, level + 1); + }; + + dfs(root, 1); + return min; +}; + + +/** + * Memo: The naming might be a bit ugly, but this minDepth function could just be used to find depth of a tree. + * If left or right is null, it means the result will be the non-empty depth plus 1, while the other is zero. + * If both left and right exists, find the minimum of the two then plus 1 + * Complex: O(n) + * Runtime: 144ms + * Tests: 41 test cases passed + * Rank: S + */ +var minDepth = function(root) { + if (!root) return 0; + if (root.left === null || root.right === null) + return Math.max(minDepth(root.left), minDepth(root.right)) + 1; + + return Math.min(minDepth(root.left), minDepth(root.right)) + 1; +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.left = node; + +node = new TreeNode(3); +root.right = node; + +node = new TreeNode(4); +root.right.left = node; +node = new TreeNode(5); +root.right.right = node; + +console.log(minDepth(root)); \ No newline at end of file diff --git a/minimum-path-sum.js b/minimum-path-sum.js new file mode 100644 index 0000000..dda1bff --- /dev/null +++ b/minimum-path-sum.js @@ -0,0 +1,67 @@ +/** + * Source: https://leetcode.com/problems/minimum-path-sum/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Minimum Path Sum + * Auther: @imcoddy + * Content: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. + * + * Note: You can only move either down or right at any point in time. + */ + +/** + * @param {number[][]} grid + * @return {number} + */ + +/** + * Explanation: + * S[i][j] = min(S[i][j-1], S[i-1][j]) + grid[i][j] + * Runtime: 150ms + * Rank: S + */ +var minPathSum = function(grid) { + /* + *if (grid.length === 0 || grid[0].length === 0) { + * return 0; + *} + */ + + var m = grid.length; + var n = grid[0].length; + var states = []; + var arr = []; + for (var i = 0; i < m; i++) { + arr = []; + for (var j = 0; j < n; j++) { + arr.push(Number.MAX_VALUE); + } + states.push(arr); + } + + // initial states + states[0][0] = grid[0][0]; + for (var i = 1; i < m; i++) { + states[i][0] = states[i - 1][0] + grid[i][0]; + } + for (var j = 1; j < n; j++) { + states[0][j] = states[0][j - 1] + grid[0][j]; + } + + // calculate from states[1][1] + for (var i = 1; i < m; i++) { + for (var j = 1; j < n; j++) { + states[i][j] = Math.min(states[i][j - 1], states[i - 1][j]) + grid[i][j]; + } + } + console.log(states); + return states[m - 1][n - 1]; +}; + + +var grid = [ + [1, 2, 3, 4, 5], + [6, 7, 8, 9, 10], + [11, 12, 13, 14, 15] +]; +console.log(minPathSum(grid)); \ No newline at end of file diff --git a/move-zeroes.js b/move-zeroes.js new file mode 100644 index 0000000..b9ff02b --- /dev/null +++ b/move-zeroes.js @@ -0,0 +1,72 @@ +/** + * Source: https://leetcode.com/problems/move-zeroes/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Move Zeroes + * Auther: @imcoddy + * Content: 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. + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Remove Element + */ + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ + +/** + * Memo: Keep track of the indexes where 0 is + * Complex: O(n) + * Runtime: 140ms + * Tests: 21 test cases passed + * Rank: A + * Updated: 2015-09-30 + */ +var moveZeroes = function(nums) { + var indexes = []; + + for (var i = 0; i < nums.length; i++) { + if (nums[i] === 0) { + indexes.push(i); + } else if (indexes.length) { + var index = indexes.shift(); + nums[index] = nums[i]; + nums[i] = 0; + indexes.push(i); + } + } + return nums; +}; + + +var should = require('should'); +console.time('Runtime'); +moveZeroes([0, 1, 0, 3, 12]).should.eql([1, 3, 12, 0, 0]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/n-queens-ii.js b/n-queens-ii.js new file mode 100644 index 0000000..35c2186 --- /dev/null +++ b/n-queens-ii.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/n-queens-ii/ + * Tags: [Backtracking] + * Level: Hard + * Title: N-Queens II + * Auther: @imcoddy + * Content: Follow up for N-Queens problem. + * + * Now, instead outputting board configurations, return the total number of distinct solutions. + */ + +/** + * @param {number} n + * @return {number} + */ + +/** + * Memo: + * Runtime: 127ms + * Tests: 9 test cases passed + * Rank: S + */ +var totalNQueens = function(n) { + var queens = []; + var count = 0; + + function placeQueen(row) { + if (row >= n) { + count++; + } else { + for (var i = 0; i < n; i++) { + if (isValid(row, i)) { + queens[row] = i; + placeQueen(row + 1); + } + } + } + } + + function isValid(row, index) { + for (var i = 0; i < row; i++) { + if (queens[i] === index || Math.abs(queens[i] - index) === Math.abs(row - i)) { + return false; + } + } + return true; + } + + placeQueen(0); + return count; +}; + +console.log(totalNQueens(4)); +console.log(totalNQueens(8)); \ No newline at end of file diff --git a/n-queens.js b/n-queens.js new file mode 100644 index 0000000..bd31a48 --- /dev/null +++ b/n-queens.js @@ -0,0 +1,95 @@ +/** + * Source: https://leetcode.com/problems/n-queens/ + * Tags: [Backtracking] + * Level: Hard + * Title: N-Queens + * Auther: @imcoddy + * Content: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other. + * + * + * + * Given an integer n, return all distinct solutions to the n-queens puzzle. + * + * Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively. + * + * For example, + * There exist two distinct solutions to the 4-queens puzzle: + * + * [ + * [".Q..", // Solution 1 + * "...Q", + * "Q...", + * "..Q."], + * + * ["..Q.", // Solution 2 + * "Q...", + * "...Q", + * ".Q.."] + * ] + */ + +/** + * @param {number} n + * @return {string[][]} + */ + +/** + * Memo: + * Runtime: 166ms + * Tests: 9 test cases passed + * Rank: B + */ +var solveNQueens = function(n) { + var queens = []; + var result = []; + + function placeQueen(row) { + if (row >= n) { + result.push(buildBoard(queens)); + } else { + for (var i = 0; i < n; i++) { + if (isValid(row, i)) { + queens[row] = i; + placeQueen(row + 1); + } + } + } + } + + function isValid(row, index) { + for (var i = 0; i < row; i++) { + if (queens[i] === index || Math.abs(queens[i] - index) === Math.abs(row - i)) { + return false; + } + } + return true; + } + + function buildBoard(queens) { + var board = []; + for (var i = 0; i < queens.length; i++) { + var str = new Array(queens.length + 1).join('.'); + str = str.substr(0, queens[i]) + 'Q' + str.substr(queens[i] + 1); + board[i] = str; + } + return board; + } + + function getEmptyBoard(n) { + var board = []; + for (var i = 0; i < n; i++) { + var row = ''; + for (var j = 0; j < n; j++) { + row = row + '.'; + } + board.push(row); + } + return board; + } + + placeQueen(0); + return result; +}; + +console.log(solveNQueens(1)); +console.log(solveNQueens(4)); \ No newline at end of file diff --git a/number-of-1-bits.js b/number-of-1-bits.js new file mode 100644 index 0000000..d2f2185 --- /dev/null +++ b/number-of-1-bits.js @@ -0,0 +1,40 @@ +/** + * Source: https://leetcode.com/problems/number-of-1-bits/ + * Tags: [Bit Manipulation] + * Level: Easy + * Title: Number of 1 Bits + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {number} n - a positive integer + * @return {number} + */ + +/** + * Memo: Recursive solution. Check if it is even or odd and divide it by 2. Keep the process until n is 0. + * Complex: O(logn) + * Runtime: 156ms + * Tests: 600 test cases passed + * Rank: A + * Updated: 2015-06-11 + */ +var hammingWeight = function(n) { + return n === 0 ? 0 : (n % 2) + hammingWeight(~~(n / 2)); +}; + +var should = require('should'); +console.time('Runtime'); +hammingWeight(0).should.equal(0); +hammingWeight(1).should.equal(1); +hammingWeight(2).should.equal(1); +hammingWeight(3).should.equal(2); +hammingWeight(7).should.equal(3); +hammingWeight(8).should.equal(1); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/number-of-islands.js b/number-of-islands.js new file mode 100644 index 0000000..84a8203 --- /dev/null +++ b/number-of-islands.js @@ -0,0 +1,91 @@ +/** + * Source: https://leetcode.com/problems/number-of-islands/ + * Tags: [Depth-first Search,Breadth-first Search] + * Level: Medium + * Title: Number of Islands + * Auther: @imcoddy + * Content: 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: + * 11110110101100000000 + * Answer: 1 + * Example 2: + * 11000110000010000011 + * Answer: 3 + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + */ + +/** + * @param {character[][]} grid + * @return {number} + */ + +/** + * Memo: BFS + * Complex: O(m*n) + * Runtime: 180ms + * Tests: 45 test cases passed + * Rank: B + */ +var numIslands = function(grid) { + var m = grid.length; + if (m <= 0) return 0; + var n = grid[0].length; + + var count = 0; + for (var i = 0; i < m; i++) { + for (var j = 0; j < n; j++) { + if (grid[i][j] > 0) { + markIsland(i, j); + } + } + } + + return count; + + function markIsland(i, j) { + var directions = [ + [0, 1], + [1, 0], + [0, -1], + [-1, 0] + ]; + var queue = [ + [i, j] + ]; + + while (queue.length) { + var p = queue.pop(); + grid[p[0]][p[1]] = -1 - count; + for (var i = 0; i < directions.length; i++) { + var next = [directions[i][0] + p[0], directions[i][1] + p[1]]; + if (next[0] >= 0 && next[0] < m && next[1] >= 0 && next[1] < n && grid[next[0]][next[1]] > 0) { + queue.push(next); + } + } + } + count += 1; + } +}; + +var should = require('should'); +console.time('Runtime'); +numIslands([]).should.equal(0); +numIslands([ + [] +]).should.equal(0); + +numIslands([ + [1, 1], + [1, 1], + [1, 0] +]).should.equal(1); + +numIslands([ + [1, 1, 0, 0], + [1, 1, 0, 1], + [1, 0, 1, 0] +]).should.equal(3); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0af40b0 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "leetcode-solution", + "version": "0.1.0", + "description": "my leetcode solutions, mostly written in javascript", + "main": "app.js", + "scripts": { + "test": "mocha" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/imcoddy/leetcode.git" + }, + "keywords": [ + "leetcode", + "algorithm", + "solution", + "javascript" + ], + "author": "imcoddy", + "license": "MIT", + "bugs": { + "url": "https://github.com/imcoddy/leetcode/issues" + }, + "homepage": "https://github.com/imcoddy/leetcode#readme", + "dependencies": { + "should": "^6.0.3" + } +} diff --git a/palindrome-linked-list.js b/palindrome-linked-list.js new file mode 100644 index 0000000..9db8a2a --- /dev/null +++ b/palindrome-linked-list.js @@ -0,0 +1,80 @@ +/** + * Source: https://leetcode.com/problems/palindrome-linked-list/ + * Tags: [Linked List,Two Pointers] + * Level: Easy + * Title: Palindrome Linked List + * Auther: @imcoddy + * Content: Given a singly linked list, determine if it is a palindrome. + * + * Follow up: + * Could you do it in O(n) time and O(1) space? + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Palindrome Number + * + * (E) Valid Palindrome + * + * (E) Reverse Linked List + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {boolean} + */ + +/** + * Memo: Loop the linked list and store its value in an array, check from the middle. + * Complex: O(n) + * Runtime: 152ms + * Tests: 21 test cases passed + * Rank: A + * Updated: 2015-08-07 + */ +var isPalindrome = function(head) { + var array = []; + while (head) { + array.push(head.val); + head = head.next; + } + + var length = array.length; + var right = ~~(length / 2); + var left = length % 2 === 0 ? right - 1 : right; + + while (left >= 0) { + if (array[left] !== array[right]) { + break; + } + left--; + right++; + } + + return left < 0; +}; + +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); + +isPalindrome(util.arrayToLinkList([])).should.equal(true); +isPalindrome(util.arrayToLinkList([1, 2, 3, 2, 1])).should.equal(true); +isPalindrome(util.arrayToLinkList([1, 2, 3, 3, 2, 1])).should.equal(true); +isPalindrome(util.arrayToLinkList([1, 2, 3, 2, 2, 1])).should.equal(false); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/partition-list.js b/partition-list.js new file mode 100644 index 0000000..5bb8aec --- /dev/null +++ b/partition-list.js @@ -0,0 +1,98 @@ +/** + * Source: https://leetcode.com/problems/partition-list/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Partition List + * Auther: @imcoddy + * Content: Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. + * + * + * You should preserve the original relative order of the nodes in each of the two partitions. + * + * + * For example, + * Given 1->4->3->2->5->2 and x = 3, + * return 1->2->2->4->3->5. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} x + * @return {ListNode} + */ + +/** + * Memo: Create two lists and append elements accordingly, then list the first list to the second one. + * Complex: O(n) + * Runtime: 148ms + * Tests: 166 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var partition = function(head, x) { + var dummy1 = new ListNode(null); + var dummy2 = new ListNode(null); + var tail1 = dummy1; + var tail2 = dummy2; + var p = head; + while (p) { + var q = p.next; + if (p.val < x) { + p.next = tail1.next; + tail1.next = p; + tail1 = tail1.next; + } else { + p.next = tail2.next; + tail2.next = p; + tail2 = tail2.next; + } + p = q; + } + + tail1.next = dummy2.next; + + return dummy1.next; +}; + +/** + * Memo: A bit improve than the above. + * Complex: O(n) + * Runtime: 153ms + * Tests: 166 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var partition = function(head, x) { + var dummy1 = new ListNode(null); + var dummy2 = new ListNode(null); + var tails = [dummy1, dummy2]; + while (head) { + var next = head.next; + head.next = null; + var i = head.val < x ? 0 : 1; + tails[i] = tails[i].next = head; + head = next; + } + + tails[0].next = dummy2.next; + return dummy1.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +util.lta(partition(util.atl([1, 4, 3, 2, 5, 2]), 3)).should.eql([1, 2, 2, 4, 3, 5]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/pascals-triangle-ii.js b/pascals-triangle-ii.js new file mode 100644 index 0000000..a67ec06 --- /dev/null +++ b/pascals-triangle-ii.js @@ -0,0 +1,70 @@ +/** + * Source: https://leetcode.com/problems/pascals-triangle-ii/ + * Tags: [Array] + * Level: Easy + * Title: Pascal's Triangle II + * Auther: @imcoddy + * Content: Given an index k, return the kth row of the Pascal's triangle. + * + * + * For example, given k = 3, + * Return [1,3,3,1]. + * + * + * + * Note: + * Could you optimize your algorithm to use only O(k) extra space? + */ + +/** + * @param {number} rowIndex + * @return {number[]} + */ + +/** + * Memo: Create the whole pascals triangle and return kth row + * Complex: O(n^2) + * Runtime: 120ms + * Tests: 34 test cases passed + * Rank: S + */ +var getRow = function(rowIndex) { + var result = []; + for (var i = 0; i <= rowIndex; i++) { + var row = []; + for (var j = 0; j <= i; j++) { + var val = 1; + if (j < i && j > 0 && i >= 1) { + val = result[i - 1][j - 1] + result[i - 1][j]; + } + row.push(val); + } + result.push(row); + } + + return result[rowIndex]; +}; + +/** + * Memo: Use only O(k) extra space + * Complex: O(n^2) + * Runtime: 115ms + * Tests: 34 test cases passed + * Rank: S + */ +var getRow = function(rowIndex) { + var a = []; + for (var i = 0; i <= rowIndex; i++) { + a.push(1); + } + + for (var i = 1; i <= rowIndex; i++) { + for (j = 1; j < i; j++) { + a[j] = a[rowIndex] + a[j]; + a[rowIndex] = a[j] - a[rowIndex]; + } + } + return a; +}; + +console.log(getRow(5)); diff --git a/pascals-triangle.js b/pascals-triangle.js new file mode 100644 index 0000000..00b0c26 --- /dev/null +++ b/pascals-triangle.js @@ -0,0 +1,73 @@ +/** + * Source: https://leetcode.com/problems/pascals-triangle/ + * Tags: [Array] + * Level: Easy + * Title: Pascal's Triangle + * Auther: @imcoddy + * Content: Given numRows, generate the first numRows of Pascal's triangle. + * + * + * For example, given numRows = 5, + * Return + * + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] + */ + +/** + * @param {number} numRows + * @return {number[][]} + */ +/** + * Memo: + * Complex: O(n^2) + * Runtime: 15ms + * Tests: 15 test cases passed + * Rank: A + */ +var generate = function(numRows) { + var result = []; + for (var i = 0; i < numRows; i++) { + var row = []; + for (var j = 0; j <= i; j++) { + var val = 1; + if (j < i && j > 0 && i >= 1) { + val = result[i - 1][j - 1] + result[i - 1][j]; + } + row.push(val); + } + result.push(row); + } + + return result; +}; + +/** + * Memo: Calculate from top to buttom + * Complex: O(n^2) + * Runtime: 116ms + * Tests: 15 test cases passed + * Rank: S + * Updated: 2015-06-14 + */ +var generate = function(numRows) { + var result = []; + for (var i = 0; i < numRows; i++) { + var row = [1]; + for (var j = 1; j <= i; j++) { + row[j] = result[i - 1][j - 1] + (i === j ? 0 : result[i - 1][j]); + } + result.push(row); + } + + return result; +}; +console.log(generate(0)); +console.log(generate(1)); +console.log(generate(3)); +console.log(generate(5)); \ No newline at end of file diff --git a/path-sum-ii.js b/path-sum-ii.js new file mode 100644 index 0000000..d5a5f9a --- /dev/null +++ b/path-sum-ii.js @@ -0,0 +1,98 @@ +/** + * Source: https://leetcode.com/problems/path-sum-ii/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Path Sum II + * Auther: @imcoddy + * Content: Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. + * + * + * For example: + * Given the below binary tree and sum = 22, + * + * 5 + * / \ + * 4 8 + * / / \ + * 11 13 4 + * / \ / \ + * 7 2 5 1 + * + * + * + * return + * + * [ + * [5,4,11,2], + * [5,8,4,5] + * ] + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @param {number} sum + * @returns {number[][]} + */ + +/** + * Memo: check when sum of root-to-leaf path is what we want or not. using a level to record current path index. + * Runtime: 161ms + * Rank: S + */ +var pathSum = function(root, sum) { + var result = []; + var path = []; + + function hasPathSum(root, sum, level) { + if (!root) return; + + path[level] = root.val; + level++; + + if (!root.left && !root.right) { // check leaf + if (sum === root.val) { + var tmp = []; + for (var i = 0; i < level; i++) { + tmp.push(path[i]); + } + result.push(tmp); + } + } else { // continue DFS + hasPathSum(root.left, sum - root.val, level); + hasPathSum(root.right, sum - root.val, level); + } + } + + hasPathSum(root, sum, 0); + return result; +}; + + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(6); +root.left = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(4); +root.right.left = node; +node = new TreeNode(4); +root.right.right = node; + +console.log(pathSum(root, 7)); \ No newline at end of file diff --git a/path-sum.js b/path-sum.js new file mode 100644 index 0000000..d8598f6 --- /dev/null +++ b/path-sum.js @@ -0,0 +1,75 @@ +/** + * Source: https://leetcode.com/problems/path-sum/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Updated: 2015-04-24 + * Title: Path Sum + * Auther: @imcoddy + * Content: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. + * + * + * For example: + * Given the below binary tree and sum = 22, + * + * 5 + * / \ + * 4 8 + * / / \ + * 11 13 4 + * / \ \ + * 7 2 1 + * + * + * + * return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * This one is a bit tricky, as it includes test case like ({}, 0) + * @param {TreeNode} root + * @param {number} sum + * @return {boolean} + */ +var hasPathSum = function(root, sum) { + if (!root) return false; + + if (!root.left && !root.right) { // check leaf + return sum === root.val; + } else { // continue DFS + return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); + } +}; + +/** + * Memo: + * Complex: O(n) + * Runtime: 132ms + * Tests: 114 test cases passed + * Rank: S + * Updated: 2015-10-05 + */ +function hasPathSum(root, sum) { + if (!root) return false; + if (!root.left && !root.right) return sum === root.val; + sum = sum - root.val; + return hasPathSum(root.left, sum) || hasPathSum(root.right, sum); +} + +/** + * Memo: if hasPathSum(root, sum) is true, then left or right will has a pathSum values sum-root.val. + * Complex: O(n) + * Runtime: 144ms + * Tests: 114 test cases passed + * Rank: A + */ +var hasPathSum = function(root, sum) { + return root ? (!root.left && !root.right) ? sum === root.val : (hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val)) : false; +}; \ No newline at end of file diff --git a/plus-one.js b/plus-one.js new file mode 100644 index 0000000..d5716bc --- /dev/null +++ b/plus-one.js @@ -0,0 +1,73 @@ +/** + * Source: https://leetcode.com/problems/plus-one/ + * Tags: [Array,Math] + * Level: Easy + * Title: Plus One + * Auther: @imcoddy + * Content: Given a non-negative number represented as an array of digits, plus one to the number. + * + * The digits are stored such that the most significant digit is at the head of the list. + */ + +/** + * @param {number[]} digits + * @return {number[]} + */ +/** + * Memo: + * Complex: O(n) + * Runtime: 108ms + * Tests: 120 test cases passed + * Rank: S + * Updated: 2015-11-09 + */ +var plusOne = function(digits) { + var length = digits.length; + var index = length - 1; + digits[index] = digits[index] + 1; + + if (digits[index] === 10) { + while (index >= 0 && digits[index] === 10) { + index--; + digits[index] += 1; + digits[index + 1] = 0; + } + } + if (digits[0] === 10) { + digits[0] = 0; + digits.unshift(1); + } + + return digits; +}; + +/** + * Memo: + * Complex: O(n) + * Runtime: 132ms + * Tests: 108 test cases passed + * Rank: S + * Updated: 2015-11-10 + */ +var plusOne = function(digits) { + var i = digits.length - 1; + digits[i] = digits[i] + 1; + + while (digits[i] === 10 && i > 0) { + digits[--i] += 1; + digits[i + 1] = 0; + } + + if (digits[0] === 10) { + digits[0] = 0; + digits.unshift(1); + } + return digits; +}; + +console.log(plusOne([0])); +console.log(plusOne([1])); +console.log(plusOne([9])); +console.log(plusOne([1, 9])); +console.log(plusOne([3, 9, 9])); +console.log(plusOne([9, 9, 9, 9])); \ No newline at end of file diff --git a/populating-next-right-pointers-in-each-node-ii.js b/populating-next-right-pointers-in-each-node-ii.js new file mode 100644 index 0000000..b850f97 --- /dev/null +++ b/populating-next-right-pointers-in-each-node-ii.js @@ -0,0 +1,77 @@ +/** + * Source: https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ + * Tags: [Tree,Depth-first Search] + * Level: Hard + * Title: Populating Next Right Pointers in Each Node II + * Auther: @imcoddy + * Content: 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 + */ + +/** + * 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. + */ + +/** + * Memo: Breadth-first Search. Put nodes of same level in a queue and link them next to each other. Node of the last in a level link to null. + * Complex: O(n) + * Runtime: 196ms + * Tests: 61 test cases passed + * Rank: S + */ +var connect = function(root) { + if (!root) return; + var queue = [root]; + var count = 1; + + while (queue.length) { + var new_count = 0; + for (var i = 0; i < count; i++) { + var node = queue.shift(); + if (i + 1 < coun) { + node.next = queue[0]; + } + if (node.left) { + queue.push(node.left); + new_count++; + } + if (node.right) { + queue.push(node.right); + new_count++; + } + } + count = new_count; + } +}; \ No newline at end of file diff --git a/populating-next-right-pointers-in-each-node.js b/populating-next-right-pointers-in-each-node.js new file mode 100644 index 0000000..106227f --- /dev/null +++ b/populating-next-right-pointers-in-each-node.js @@ -0,0 +1,152 @@ +/** + * Source: https://leetcode.com/problems/populating-next-right-pointers-in-each-node/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Populating Next Right Pointers in Each Node + * Auther: @imcoddy + * Content: Given a binary tree + * + * struct TreeLinkNode { + * TreeLinkNode *left; + * TreeLinkNode *right; + * TreeLinkNode *next; + * } + * + * + * + * Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. + * + * Initially, all next pointers are set to NULL. + * + * + * Note: + * + * You may only use constant extra space. + * You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). + * + * + * + * + * For example, + * Given the following perfect binary tree, + * + * 1 + * / \ + * 2 3 + * / \ / \ + * 4 5 6 7 + * + * + * + * After calling your function, the tree should look like: + * + * 1 -> NULL + * / \ + * 2 -> 3 -> NULL + * / \ / \ + * 4->5->6->7 -> NULL + */ + +/** + * 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. + */ + +/** + * Memo: Breadth-first Search. Put nodes of same level in a queue and link them next to each other. Node of the last in a level link to null. + * Runtime: 161ms + * Rank: S + */ +var connect = function(root) { + if (root) { + var queue = [root]; + var level_count = 1; + + while (queue.length) { + var next_level_count = 0; + var node; + for (var i = 0; i < level_count; i++) { + node = queue.shift(); + if (i < level_count - 1) { + node.next = queue[0]; + } + if (node.left) { + next_level_count++; + queue.push(node.left); + } + if (node.right) { + next_level_count++; + queue.push(node.right); + } + } + level_count = next_level_count; + } + } +}; + + +/** + * Memo: BFS to do a level traversal. Link from left to right if there are on the same level. + * Complex: O(n) + * Runtime: 176ms + * Tests: 14 test cases passed + * Rank: A + */ +var connect = function(root) { + if (!root) return; + var queue = [root]; + var count = 1; + + while (queue.length) { + var new_count = 0; + for (var i = 0; i < count; i++) { + var node = queue.shift(); + if (i + 1 < coun) { + node.next = queue[0]; + } + if (node.left) { + queue.push(node.left); + new_count++; + } + if (node.right) { + queue.push(node.right); + new_count++; + } + } + count = new_count; + } +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = this.next = null; +} + +var node = new TreeNode(0); +var root = node; + +node = new TreeNode(1); +root.left = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.left.left = node; +node = new TreeNode(4); +root.left.right = node; +node = new TreeNode(5); +root.right.left = node; +node = new TreeNode(6); +root.right.right = node; + +connect(root); +console.log(root); \ No newline at end of file diff --git a/power-of-two.js b/power-of-two.js new file mode 100644 index 0000000..b534ea6 --- /dev/null +++ b/power-of-two.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/power-of-two/ + * Tags: [Math,Bit Manipulation] + * Level: Easy + * Title: Power of Two + * Auther: @imcoddy + * Content: 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. + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Number of 1 Bits + */ + +/** + * @param {number} n + * @return {boolean} + */ +/** + * Memo: + * Complex: O(logn) + * Runtime: 204ms + * Tests: 1108 test cases passed + * Rank: B + * Updated: 2015-08-09 + */ +var isPowerOfTwo = function(n) { + while (n > 1) { + if (n % 2 === 1) return false; + n = n >> 1; + } + return n === 1; +}; + +var should = require('should'); +console.time('Runtime'); +isPowerOfTwo(0).should.equal(false); +isPowerOfTwo(1).should.equal(true); +isPowerOfTwo(2).should.equal(true); +isPowerOfTwo(3).should.equal(false); +isPowerOfTwo(4).should.equal(true); +isPowerOfTwo(5).should.equal(false); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/problemset/.gitkeep b/problemset/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/problemset/3sum-closest.js b/problemset/3sum-closest.js new file mode 100644 index 0000000..6bb28bb --- /dev/null +++ b/problemset/3sum-closest.js @@ -0,0 +1,44 @@ +/** + * Source: https://leetcode.com/problems/3sum-closest/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: 3Sum Closest + * Auther: @imcoddy + * Content: Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. + * + * + * For example, given array S = {-1 2 1 -4}, and target = 1. + * + * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) 3Sum + * + * (M) 3Sum Smaller + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var threeSumClosest = function(nums, target) { + +}; diff --git a/problemset/3sum.js b/problemset/3sum.js new file mode 100644 index 0000000..cb16b2d --- /dev/null +++ b/problemset/3sum.js @@ -0,0 +1,56 @@ +/** + * Source: https://leetcode.com/problems/3sum/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: 3Sum + * Auther: @imcoddy + * Content: 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: + * + * Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) + * 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) + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Two Sum + * + * (M) 3Sum Closest + * + * (M) 4Sum + * + * (M) 3Sum Smaller + */ + +/** + * @param {number[]} nums + * @return {number[][]} + */ +var threeSum = function(nums) { + +}; diff --git a/problemset/4sum.js b/problemset/4sum.js new file mode 100644 index 0000000..24eb51c --- /dev/null +++ b/problemset/4sum.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/4sum/ + * Tags: [Array,Hash Table,Two Pointers] + * Level: Medium + * Title: 4Sum + * Auther: @imcoddy + * Content: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. + * + * Note: + * + * Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d) + * The solution set must not contain duplicate quadruplets. + * + * + * + * + * For example, given array S = {1 0 -1 0 -2 2}, and target = 0. + * + * A solution set is: + * (-1, 0, 0, 1) + * (-2, -1, 1, 2) + * (-2, 0, 0, 2) + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Two Sum + * + * (M) 3Sum + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number[][]} + */ +var fourSum = function(nums, target) { + +}; diff --git a/problemset/add-and-search-word-data-structure-design.js b/problemset/add-and-search-word-data-structure-design.js new file mode 100644 index 0000000..8f17bae --- /dev/null +++ b/problemset/add-and-search-word-data-structure-design.js @@ -0,0 +1,90 @@ +/** + * Source: https://leetcode.com/problems/add-and-search-word-data-structure-design/ + * Tags: [Backtracking,Trie,Design] + * Level: Medium + * Title: Add and Search Word - Data structure design + * Auther: @imcoddy + * Content: Design a data structure that supports the following two operations: + * + * + * void addWord(word) + * bool search(word) + * + * + * + * search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter. + * + * + * 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. + * + * You should be familiar with how a Trie works. If not, please work on this problem: Implement Trie (Prefix Tree) first. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Implement Trie (Prefix Tree) + */ + +/** + * @constructor + */ +var WordDictionary = function() { + +}; + +/** + * @param {string} word + * @return {void} + * Adds a word into the data structure. + */ +WordDictionary.prototype.addWord = function(word) { + +}; + +/** + * @param {string} word + * @return {boolean} + * Returns if the word is in the data structure. A word could + * contain the dot character '.' to represent any one letter. + */ +WordDictionary.prototype.search = function(word) { + +}; + +/** + * Your WordDictionary object will be instantiated and called as such: + * var wordDictionary = new WordDictionary(); + * wordDictionary.addWord("word"); + * wordDictionary.search("pattern"); + */ diff --git a/problemset/add-binary.js b/problemset/add-binary.js new file mode 100644 index 0000000..c7ffe06 --- /dev/null +++ b/problemset/add-binary.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/add-binary/ + * Tags: [Math,String] + * Level: Easy + * Title: Add Binary + * Auther: @imcoddy + * Content: Given two binary strings, return their sum (also a binary string). + * + * + * + * For example, + * a = "11" + * b = "1" + * Return "100". + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Add Two Numbers + * + * (M) Multiply Strings + * + * (E) Plus One + */ + +/** + * @param {string} a + * @param {string} b + * @return {string} + */ +var addBinary = function(a, b) { + +}; diff --git a/problemset/add-digits.js b/problemset/add-digits.js new file mode 100644 index 0000000..3849607 --- /dev/null +++ b/problemset/add-digits.js @@ -0,0 +1,56 @@ +/** + * Source: https://leetcode.com/problems/add-digits/ + * Tags: [Math] + * Level: Easy + * Title: Add Digits + * Auther: @imcoddy + * Content: Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. + * + * + * + * For example: + * + * + * Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. + * + * + * Follow up: + * Could you do it without any loop/recursion in O(1) runtime? + * + * + * + * A naive implementation of the above process is trivial. Could you come up with other methods? + * What are all the possible results? + * How do they occur, periodically or randomly? + * You may find this Wikipedia article useful. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Happy Number + */ + +/** + * @param {number} num + * @return {number} + */ +var addDigits = function(num) { + +}; diff --git a/problemset/add-two-numbers.js b/problemset/add-two-numbers.js new file mode 100644 index 0000000..48c21cf --- /dev/null +++ b/problemset/add-two-numbers.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/add-two-numbers/ + * Tags: [Linked List,Math] + * Level: Medium + * Title: Add Two Numbers + * Auther: @imcoddy + * Content: 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 + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Multiply Strings + * + * (E) Add Binary + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} l1 + * @param {ListNode} l2 + * @return {ListNode} + */ +var addTwoNumbers = function(l1, l2) { + +}; diff --git a/problemset/anagrams.js b/problemset/anagrams.js new file mode 100644 index 0000000..04acb32 --- /dev/null +++ b/problemset/anagrams.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/anagrams/ + * Tags: [Hash Table,String] + * Level: Medium + * Title: Group Anagrams + * Auther: @imcoddy + * Content: 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: + * + * For the return value, each inner list's elements must follow the lexicographic order. + * All inputs will be in lower-case. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Valid Anagram + * + * (E) Group Shifted Strings + */ + +/** + * @param {string[]} strs + * @return {string[][]} + */ +var groupAnagrams = function(strs) { + +}; diff --git a/problemset/balanced-binary-tree.js b/problemset/balanced-binary-tree.js new file mode 100644 index 0000000..8b55494 --- /dev/null +++ b/problemset/balanced-binary-tree.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/balanced-binary-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Balanced Binary Tree + * Auther: @imcoddy + * Content: Given a binary tree, determine if it is height-balanced. + * + * + * + * For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Maximum Depth of Binary Tree + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {boolean} + */ +var isBalanced = function(root) { + +}; diff --git a/problemset/basic-calculator-ii.js b/problemset/basic-calculator-ii.js new file mode 100644 index 0000000..12a321d --- /dev/null +++ b/problemset/basic-calculator-ii.js @@ -0,0 +1,55 @@ +/** + * Source: https://leetcode.com/problems/basic-calculator-ii/ + * Tags: [String] + * Level: Medium + * Title: Basic Calculator II + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Basic Calculator + * + * (H) Expression Add Operators + */ + +/** + * @param {string} s + * @return {number} + */ +var calculate = function(s) { + +}; diff --git a/problemset/basic-calculator.js b/problemset/basic-calculator.js new file mode 100644 index 0000000..025b753 --- /dev/null +++ b/problemset/basic-calculator.js @@ -0,0 +1,57 @@ +/** + * Source: https://leetcode.com/problems/basic-calculator/ + * Tags: [Stack,Math] + * Level: Medium + * Title: Basic Calculator + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Evaluate Reverse Polish Notation + * + * (M) Basic Calculator II + * + * (M) Different Ways to Add Parentheses + * + * (H) Expression Add Operators + */ + +/** + * @param {string} s + * @return {number} + */ +var calculate = function(s) { + +}; diff --git a/problemset/best-time-to-buy-and-sell-stock-ii.js b/problemset/best-time-to-buy-and-sell-stock-ii.js new file mode 100644 index 0000000..d9ee39f --- /dev/null +++ b/problemset/best-time-to-buy-and-sell-stock-ii.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + * Tags: [Array,Greedy] + * Level: Medium + * Title: Best Time to Buy and Sell Stock II + * Auther: @imcoddy + * Content: Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Best Time to Buy and Sell Stock + * + * (H) Best Time to Buy and Sell Stock III + * + * (H) Best Time to Buy and Sell Stock IV + */ + +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function(prices) { + +}; diff --git a/problemset/best-time-to-buy-and-sell-stock-iii.js b/problemset/best-time-to-buy-and-sell-stock-iii.js new file mode 100644 index 0000000..3f86470 --- /dev/null +++ b/problemset/best-time-to-buy-and-sell-stock-iii.js @@ -0,0 +1,44 @@ +/** + * Source: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ + * Tags: [Array,Dynamic Programming] + * Level: Hard + * Title: Best Time to Buy and Sell Stock III + * Auther: @imcoddy + * Content: 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). + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Best Time to Buy and Sell Stock + * + * (M) Best Time to Buy and Sell Stock II + * + * (H) Best Time to Buy and Sell Stock IV + */ + +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function(prices) { + +}; diff --git a/problemset/best-time-to-buy-and-sell-stock-iv.js b/problemset/best-time-to-buy-and-sell-stock-iv.js new file mode 100644 index 0000000..47f0228 --- /dev/null +++ b/problemset/best-time-to-buy-and-sell-stock-iv.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/ + * Tags: [Dynamic Programming] + * Level: Hard + * Title: Best Time to Buy and Sell Stock IV + * Auther: @imcoddy + * Content: 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 k transactions. + * + * Note: + * You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). + * + * Credits:Special thanks to @Freezen for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Best Time to Buy and Sell Stock + * + * (M) Best Time to Buy and Sell Stock II + * + * (H) Best Time to Buy and Sell Stock III + */ + +/** + * @param {number} k + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function(k, prices) { + +}; diff --git a/problemset/best-time-to-buy-and-sell-stock.js b/problemset/best-time-to-buy-and-sell-stock.js new file mode 100644 index 0000000..2af3492 --- /dev/null +++ b/problemset/best-time-to-buy-and-sell-stock.js @@ -0,0 +1,43 @@ +/** + * Source: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Best Time to Buy and Sell Stock + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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 + */ + +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function(prices) { + +}; diff --git a/problemset/binary-search-tree-iterator.js b/problemset/binary-search-tree-iterator.js new file mode 100644 index 0000000..c2a39de --- /dev/null +++ b/problemset/binary-search-tree-iterator.js @@ -0,0 +1,80 @@ +/** + * Source: https://leetcode.com/problems/binary-search-tree-iterator/ + * Tags: [Tree,Stack,Design] + * Level: Medium + * Title: Binary Search Tree Iterator + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @constructor + * @param {TreeNode} root - root of the binary search tree + */ +var BSTIterator = function(root) { + +}; + + +/** + * @this BSTIterator + * @returns {boolean} - whether we have a next smallest number + */ +BSTIterator.prototype.hasNext = function() { + +}; + +/** + * @this BSTIterator + * @returns {number} - the next smallest number + */ +BSTIterator.prototype.next = function() { + +}; + +/** + * Your BSTIterator will be called like this: + * var i = new BSTIterator(root), a = []; + * while (i.hasNext()) a.push(i.next()); +*/ diff --git a/problemset/binary-tree-inorder-traversal.js b/problemset/binary-tree-inorder-traversal.js new file mode 100644 index 0000000..07f677f --- /dev/null +++ b/problemset/binary-tree-inorder-traversal.js @@ -0,0 +1,92 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-inorder-traversal/ + * Tags: [Tree,Hash Table,Stack] + * Level: Medium + * Title: Binary Tree Inorder Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the inorder traversal of its nodes' values. + * + * + * For example: + * Given binary tree {1,#,2,3}, + * + * 1 + * \ + * 2 + * / + * 3 + * + * + * + * return [1,3,2]. + * + * + * Note: Recursive solution is trivial, could you do it iteratively? + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Validate Binary Search Tree + * + * (M) Binary Tree Preorder Traversal + * + * (H) Binary Tree Postorder Traversal + * + * (M) Binary Search Tree Iterator + * + * (M) Kth Smallest Element in a BST + * + * (H) Closest Binary Search Tree Value II + * + * (M) Inorder Successor in BST + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[]} + */ +var inorderTraversal = function(root) { + +}; diff --git a/problemset/binary-tree-level-order-traversal-ii.js b/problemset/binary-tree-level-order-traversal-ii.js new file mode 100644 index 0000000..ac57ca3 --- /dev/null +++ b/problemset/binary-tree-level-order-traversal-ii.js @@ -0,0 +1,85 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-level-order-traversal-ii/ + * Tags: [Tree,Breadth-first Search] + * Level: Easy + * Title: Binary Tree Level Order Traversal II + * Auther: @imcoddy + * Content: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). + * + * + * For example: + * Given binary tree {3,9,20,#,#,15,7}, + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * + * + * return its bottom-up level order traversal as: + * + * [ + * [15,7], + * [9,20], + * [3] + * ] + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Binary Tree Level Order Traversal + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ +var levelOrderBottom = function(root) { + +}; diff --git a/problemset/binary-tree-level-order-traversal.js b/problemset/binary-tree-level-order-traversal.js new file mode 100644 index 0000000..5adb699 --- /dev/null +++ b/problemset/binary-tree-level-order-traversal.js @@ -0,0 +1,89 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-level-order-traversal/ + * Tags: [Tree,Breadth-first Search] + * Level: Easy + * Title: Binary Tree Level Order Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). + * + * + * For example: + * Given binary tree {3,9,20,#,#,15,7}, + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * + * + * return its level order traversal as: + * + * [ + * [3], + * [9,20], + * [15,7] + * ] + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Binary Tree Zigzag Level Order Traversal + * + * (E) Binary Tree Level Order Traversal II + * + * (E) Minimum Depth of Binary Tree + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ +var levelOrder = function(root) { + +}; diff --git a/problemset/binary-tree-maximum-path-sum.js b/problemset/binary-tree-maximum-path-sum.js new file mode 100644 index 0000000..94e2992 --- /dev/null +++ b/problemset/binary-tree-maximum-path-sum.js @@ -0,0 +1,60 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-maximum-path-sum/ + * Tags: [Tree,Depth-first Search] + * Level: Hard + * Title: Binary Tree Maximum Path Sum + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Path Sum + * + * (M) Sum Root to Leaf Numbers + */ + +/** + * 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) { + +}; diff --git a/problemset/binary-tree-paths.js b/problemset/binary-tree-paths.js new file mode 100644 index 0000000..f9a7e8a --- /dev/null +++ b/problemset/binary-tree-paths.js @@ -0,0 +1,61 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-paths/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Binary Tree Paths + * Auther: @imcoddy + * Content: 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"] + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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) { + +}; diff --git a/problemset/binary-tree-postorder-traversal.js b/problemset/binary-tree-postorder-traversal.js new file mode 100644 index 0000000..1616da1 --- /dev/null +++ b/problemset/binary-tree-postorder-traversal.js @@ -0,0 +1,59 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-postorder-traversal/ + * Tags: [Tree,Stack] + * Level: Hard + * Title: Binary Tree Postorder Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the postorder traversal of its nodes' values. + * + * + * For example: + * Given binary tree {1,#,2,3}, + * + * 1 + * \ + * 2 + * / + * 3 + * + * + * + * return [3,2,1]. + * + * + * Note: Recursive solution is trivial, could you do it iteratively? + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Binary Tree Inorder Traversal + */ + +/** + * 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) { + +}; diff --git a/problemset/binary-tree-preorder-traversal.js b/problemset/binary-tree-preorder-traversal.js new file mode 100644 index 0000000..3fa2354 --- /dev/null +++ b/problemset/binary-tree-preorder-traversal.js @@ -0,0 +1,61 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-preorder-traversal/ + * Tags: [Tree,Stack] + * Level: Medium + * Title: Binary Tree Preorder Traversal + * Auther: @imcoddy + * Content: Given a binary tree, return the preorder traversal of its nodes' values. + * + * + * For example: + * Given binary tree {1,#,2,3}, + * + * 1 + * \ + * 2 + * / + * 3 + * + * + * + * return [1,2,3]. + * + * + * Note: Recursive solution is trivial, could you do it iteratively? + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Binary Tree Inorder Traversal + * + * (M) Verify Preorder Sequence in Binary Search Tree + */ + +/** + * 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) { + +}; diff --git a/problemset/binary-tree-right-side-view.js b/problemset/binary-tree-right-side-view.js new file mode 100644 index 0000000..ffda1a4 --- /dev/null +++ b/problemset/binary-tree-right-side-view.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-right-side-view/ + * Tags: [Tree,Depth-first Search,Breadth-first Search] + * Level: Medium + * Title: Binary Tree Right Side View + * Auther: @imcoddy + * Content: Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. + * + * + * For example: + * Given the following binary tree, + * + * 1 + * + * + * You should return [1, 3, 4]. + * + * + * Credits:Special thanks to @amrsaqr for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Populating Next Right Pointers in Each Node + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[]} + */ +var rightSideView = function(root) { + +}; diff --git a/problemset/binary-tree-zigzag-level-order-traversal.js b/problemset/binary-tree-zigzag-level-order-traversal.js new file mode 100644 index 0000000..d98699a --- /dev/null +++ b/problemset/binary-tree-zigzag-level-order-traversal.js @@ -0,0 +1,85 @@ +/** + * Source: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/ + * Tags: [Tree,Breadth-first Search,Stack] + * Level: Medium + * Title: Binary Tree Zigzag Level Order Traversal + * Auther: @imcoddy + * Content: 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,#,#,15,7}, + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * + * + * return its zigzag level order traversal as: + * + * [ + * [3], + * [20,9], + * [15,7] + * ] + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Binary Tree Level Order Traversal + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ +var zigzagLevelOrder = function(root) { + +}; diff --git a/problemset/bitwise-and-of-numbers-range.js b/problemset/bitwise-and-of-numbers-range.js new file mode 100644 index 0000000..a19c31c --- /dev/null +++ b/problemset/bitwise-and-of-numbers-range.js @@ -0,0 +1,26 @@ +/** + * Source: https://leetcode.com/problems/bitwise-and-of-numbers-range/ + * Tags: [Bit Manipulation] + * Level: Medium + * Title: Bitwise AND of Numbers Range + * Auther: @imcoddy + * Content: Given a range [m, n] where 0 + * + * + * For example, given the range [5, 7], you should return 4. + * + * + * Credits:Special thanks to @amrsaqr for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number} m + * @param {number} n + * @return {number} + */ +var rangeBitwiseAnd = function(m, n) { + +}; diff --git a/problemset/bulls-and-cows.js b/problemset/bulls-and-cows.js new file mode 100644 index 0000000..fec46ac --- /dev/null +++ b/problemset/bulls-and-cows.js @@ -0,0 +1,43 @@ +/** + * Source: https://leetcode.com/problems/bulls-and-cows/ + * Tags: [Hash Table] + * Level: Easy + * Title: Bulls and Cows + * Auther: @imcoddy + * Content: You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number. + * + * + * For example: + * + * Secret number: "1807" + * Friend's guess: "7810" + * + * Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.) + * + * + * Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B". + * + * Please note that both secret number and friend's guess may contain duplicate digits, for example: + * + * Secret number: "1123" + * Friend's guess: "0111" + * + * In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B". + * + * + * You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal. + * + * Credits:Special thanks to @jeantimex for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} secret + * @param {string} guess + * @return {string} + */ +var getHint = function(secret, guess) { + +}; diff --git a/problemset/candy.js b/problemset/candy.js new file mode 100644 index 0000000..2e15f9d --- /dev/null +++ b/problemset/candy.js @@ -0,0 +1,30 @@ +/** + * Source: https://leetcode.com/problems/candy/ + * Tags: [Greedy] + * Level: Hard + * Title: Candy + * Auther: @imcoddy + * Content: There are N children standing in a line. Each child is assigned a rating value. + * + * + * You are giving candies to these children subjected to the following requirements: + * + * + * Each child must have at least one candy. + * Children with a higher rating get more candies than their neighbors. + * + * + * What is the minimum candies you must give? + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} ratings + * @return {number} + */ +var candy = function(ratings) { + +}; diff --git a/problemset/changelog.txt b/problemset/changelog.txt new file mode 100644 index 0000000..db51a66 --- /dev/null +++ b/problemset/changelog.txt @@ -0,0 +1 @@ +Problem set updated at 2015-11-09 04:59:52 diff --git a/problemset/climbing-stairs.js b/problemset/climbing-stairs.js new file mode 100644 index 0000000..7d28a0f --- /dev/null +++ b/problemset/climbing-stairs.js @@ -0,0 +1,22 @@ +/** + * Source: https://leetcode.com/problems/climbing-stairs/ + * Tags: [Dynamic Programming] + * Level: Easy + * Title: Climbing Stairs + * Auther: @imcoddy + * Content: 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? + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number} n + * @return {number} + */ +var climbStairs = function(n) { + +}; diff --git a/problemset/clone-graph.js b/problemset/clone-graph.js new file mode 100644 index 0000000..cad93ed --- /dev/null +++ b/problemset/clone-graph.js @@ -0,0 +1,83 @@ +/** + * Source: https://leetcode.com/problems/clone-graph/ + * Tags: [Depth-first Search,Breadth-first Search,Graph] + * Level: Medium + * Title: Clone Graph + * Auther: @imcoddy + * Content: 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 + * / \ + * \_/ + * + * + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Copy List with Random Pointer + */ + +/** + * Definition for undirected graph. + * function UndirectedGraphNode(label) { + * this.label = label; + * this.neighbors = []; // Array of UndirectedGraphNode + * } + */ + +/** + * @param {UndirectedGraphNode} graph + * @return {UndirectedGraphNode} + */ +var cloneGraph = function(graph) { + +}; diff --git a/problemset/combination-sum-ii.js b/problemset/combination-sum-ii.js new file mode 100644 index 0000000..4f9fd6b --- /dev/null +++ b/problemset/combination-sum-ii.js @@ -0,0 +1,56 @@ +/** + * Source: https://leetcode.com/problems/combination-sum-ii/ + * Tags: [Array,Backtracking] + * Level: Medium + * Title: Combination Sum II + * Auther: @imcoddy + * Content: 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. + * Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak). + * 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] + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Combination Sum + */ + +/** + * @param {number[]} candidates + * @param {number} target + * @return {number[][]} + */ +var combinationSum2 = function(candidates, target) { + +}; diff --git a/problemset/combination-sum-iii.js b/problemset/combination-sum-iii.js new file mode 100644 index 0000000..78318ac --- /dev/null +++ b/problemset/combination-sum-iii.js @@ -0,0 +1,56 @@ +/** + * Source: https://leetcode.com/problems/combination-sum-iii/ + * Tags: [Array,Backtracking] + * Level: Medium + * Title: Combination Sum III + * Auther: @imcoddy + * Content: Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. + * Ensure that numbers within the set are sorted in ascending order. + * + * + * + * Example 1: + * Input: k = 3, n = 7 + * Output: + * + * [[1,2,4]] + * + * + * Example 2: + * Input: k = 3, n = 9 + * Output: + * + * [[1,2,6], [1,3,5], [2,3,4]] + * + * + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Combination Sum + */ + +/** + * @param {number} k + * @param {number} n + * @return {number[][]} + */ +var combinationSum3 = function(k, n) { + +}; diff --git a/problemset/combination-sum.js b/problemset/combination-sum.js new file mode 100644 index 0000000..5c8a58e --- /dev/null +++ b/problemset/combination-sum.js @@ -0,0 +1,64 @@ +/** + * Source: https://leetcode.com/problems/combination-sum/ + * Tags: [Array,Backtracking] + * Level: Medium + * Title: Combination Sum + * Auther: @imcoddy + * Content: 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. + * Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak). + * 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] + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Letter Combinations of a Phone Number + * + * (M) Combination Sum II + * + * (M) Combinations + * + * (M) Combination Sum III + * + * (M) Factor Combinations + */ + +/** + * @param {number[]} candidates + * @param {number} target + * @return {number[][]} + */ +var combinationSum = function(candidates, target) { + +}; diff --git a/problemset/combinations.js b/problemset/combinations.js new file mode 100644 index 0000000..e34570a --- /dev/null +++ b/problemset/combinations.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/combinations/ + * Tags: [Backtracking] + * Level: Medium + * Title: Combinations + * Auther: @imcoddy + * Content: 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], + * ] + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Combination Sum + * + * (M) Permutations + */ + +/** + * @param {number} n + * @param {number} k + * @return {number[][]} + */ +var combine = function(n, k) { + +}; diff --git a/problemset/compare-version-numbers.js b/problemset/compare-version-numbers.js new file mode 100644 index 0000000..61e5ade --- /dev/null +++ b/problemset/compare-version-numbers.js @@ -0,0 +1,30 @@ +/** + * Source: https://leetcode.com/problems/compare-version-numbers/ + * Tags: [String] + * Level: Easy + * Title: Compare Version Numbers + * Auther: @imcoddy + * Content: Compare two version numbers version1 and version2. + * If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. + * + * You may assume that the version strings are non-empty and contain only digits and the . character. + * The . character does not represent a decimal point and is used to separate number sequences. + * For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. + * + * Here is an example of version numbers ordering: + * 0.1 < 1.1 < 1.2 < 13.37 + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} version1 + * @param {string} version2 + * @return {number} + */ +var compareVersion = function(version1, version2) { + +}; diff --git a/problemset/construct-binary-tree-from-inorder-and-postorder-traversal.js b/problemset/construct-binary-tree-from-inorder-and-postorder-traversal.js new file mode 100644 index 0000000..17e8107 --- /dev/null +++ b/problemset/construct-binary-tree-from-inorder-and-postorder-traversal.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/ + * Tags: [Tree,Array,Depth-first Search] + * Level: Medium + * Title: Construct Binary Tree from Inorder and Postorder Traversal + * Auther: @imcoddy + * Content: Given inorder and postorder traversal of a tree, construct the binary tree. + * + * Note: + * You may assume that duplicates do not exist in the tree. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Construct Binary Tree from Preorder and Inorder Traversal + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {number[]} inorder + * @param {number[]} postorder + * @return {TreeNode} + */ +var buildTree = function(inorder, postorder) { + +}; diff --git a/problemset/construct-binary-tree-from-preorder-and-inorder-traversal.js b/problemset/construct-binary-tree-from-preorder-and-inorder-traversal.js new file mode 100644 index 0000000..0c58838 --- /dev/null +++ b/problemset/construct-binary-tree-from-preorder-and-inorder-traversal.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ + * Tags: [Tree,Array,Depth-first Search] + * Level: Medium + * Title: Construct Binary Tree from Preorder and Inorder Traversal + * Auther: @imcoddy + * Content: Given preorder and inorder traversal of a tree, construct the binary tree. + * + * Note: + * You may assume that duplicates do not exist in the tree. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Construct Binary Tree from Inorder and Postorder Traversal + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {number[]} preorder + * @param {number[]} inorder + * @return {TreeNode} + */ +var buildTree = function(preorder, inorder) { + +}; diff --git a/problemset/container-with-most-water.js b/problemset/container-with-most-water.js new file mode 100644 index 0000000..ed0cb2b --- /dev/null +++ b/problemset/container-with-most-water.js @@ -0,0 +1,38 @@ +/** + * Source: https://leetcode.com/problems/container-with-most-water/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: Container With Most Water + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Trapping Rain Water + */ + +/** + * @param {number[]} height + * @return {number} + */ +var maxArea = function(height) { + +}; diff --git a/problemset/contains-duplicate-ii.js b/problemset/contains-duplicate-ii.js new file mode 100644 index 0000000..f4e82cf --- /dev/null +++ b/problemset/contains-duplicate-ii.js @@ -0,0 +1,39 @@ +/** + * Source: https://leetcode.com/problems/contains-duplicate-ii/ + * Tags: [Array,Hash Table] + * Level: Easy + * Title: Contains Duplicate II + * Auther: @imcoddy + * Content: Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between i and j is at most k. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Contains Duplicate + * + * (M) Contains Duplicate III + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {boolean} + */ +var containsNearbyDuplicate = function(nums, k) { + +}; diff --git a/problemset/contains-duplicate-iii.js b/problemset/contains-duplicate-iii.js new file mode 100644 index 0000000..81958aa --- /dev/null +++ b/problemset/contains-duplicate-iii.js @@ -0,0 +1,40 @@ +/** + * Source: https://leetcode.com/problems/contains-duplicate-iii/ + * Tags: [Binary Search Tree] + * Level: Medium + * Title: Contains Duplicate III + * Auther: @imcoddy + * Content: Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Contains Duplicate + * + * (E) Contains Duplicate II + */ + +/** + * @param {number[]} nums + * @param {number} k + * @param {number} t + * @return {boolean} + */ +var containsNearbyAlmostDuplicate = function(nums, k, t) { + +}; diff --git a/problemset/contains-duplicate.js b/problemset/contains-duplicate.js new file mode 100644 index 0000000..91b5ecd --- /dev/null +++ b/problemset/contains-duplicate.js @@ -0,0 +1,38 @@ +/** + * Source: https://leetcode.com/problems/contains-duplicate/ + * Tags: [Array,Hash Table] + * Level: Easy + * Title: Contains Duplicate + * Auther: @imcoddy + * Content: Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Contains Duplicate II + * + * (M) Contains Duplicate III + */ + +/** + * @param {number[]} nums + * @return {boolean} + */ +var containsDuplicate = function(nums) { + +}; diff --git a/problemset/convert-sorted-array-to-binary-search-tree.js b/problemset/convert-sorted-array-to-binary-search-tree.js new file mode 100644 index 0000000..e3874e5 --- /dev/null +++ b/problemset/convert-sorted-array-to-binary-search-tree.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Convert Sorted Array to Binary Search Tree + * Auther: @imcoddy + * Content: Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Convert Sorted List to Binary Search Tree + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {number[]} nums + * @return {TreeNode} + */ +var sortedArrayToBST = function(nums) { + +}; diff --git a/problemset/convert-sorted-list-to-binary-search-tree.js b/problemset/convert-sorted-list-to-binary-search-tree.js new file mode 100644 index 0000000..7cbc4bb --- /dev/null +++ b/problemset/convert-sorted-list-to-binary-search-tree.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/ + * Tags: [Depth-first Search,Linked List] + * Level: Medium + * Title: Convert Sorted List to Binary Search Tree + * Auther: @imcoddy + * Content: Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Convert Sorted Array to Binary Search Tree + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {ListNode} head + * @return {TreeNode} + */ +var sortedListToBST = function(head) { + +}; diff --git a/problemset/copy-list-with-random-pointer.js b/problemset/copy-list-with-random-pointer.js new file mode 100644 index 0000000..1cc77a2 --- /dev/null +++ b/problemset/copy-list-with-random-pointer.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/copy-list-with-random-pointer/ + * Tags: [Hash Table,Linked List] + * Level: Hard + * Title: Copy List with Random Pointer + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Clone Graph + */ + +/** + * 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) { + +}; diff --git a/problemset/count-and-say.js b/problemset/count-and-say.js new file mode 100644 index 0000000..b297f0b --- /dev/null +++ b/problemset/count-and-say.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/count-and-say/ + * Tags: [String] + * Level: Easy + * Title: Count and Say + * Auther: @imcoddy + * Content: The count-and-say sequence is the sequence of integers beginning as follows: + * 1, 11, 21, 1211, 111221, ... + * + * + * + * 1 is read off as "one 1" or 11. + * 11 is read off as "two 1s" or 21. + * 21 is read off as "one 2, then one 1" or 1211. + * + * + * + * Given an integer n, generate the nth sequence. + * + * + * + * Note: The sequence of integers will be represented as a string. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Encode and Decode Strings + */ + +/** + * @param {number} n + * @return {string} + */ +var countAndSay = function(n) { + +}; diff --git a/problemset/count-complete-tree-nodes.js b/problemset/count-complete-tree-nodes.js new file mode 100644 index 0000000..d35e50e --- /dev/null +++ b/problemset/count-complete-tree-nodes.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/count-complete-tree-nodes/ + * Tags: [Tree,Binary Search] + * Level: Medium + * Title: Count Complete Tree Nodes + * Auther: @imcoddy + * Content: Given a complete binary tree, count the number of nodes. + * + * Definition of a complete binary tree from Wikipedia: + * In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Closest Binary Search Tree Value + */ + +/** + * 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) { + +}; diff --git a/problemset/count-primes.js b/problemset/count-primes.js new file mode 100644 index 0000000..7325a1b --- /dev/null +++ b/problemset/count-primes.js @@ -0,0 +1,114 @@ +/** + * Source: https://leetcode.com/problems/count-primes/ + * Tags: [Hash Table,Math] + * Level: Easy + * Title: Count Primes + * Auther: @imcoddy + * Content: Description: + * Count the number of prime numbers less than a non-negative number, n. + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + * + * + * Let's start with a isPrime function. To determine if a number is prime, we need to check if it is not divisible by any number less than n. The runtime complexity of isPrime function would be O(n) and hence counting the total prime numbers up to n would be O(n2). Could we do better? + * + * As we know the number must not be divisible by any number > n / 2, we can immediately cut the total iterations half by dividing only up to n / 2. Could we still do better? + * + * Let's write down all of 12's factors: + * + * 2 × 6 = 12 + * 3 × 4 = 12 + * 4 × 3 = 12 + * 6 × 2 = 12 + * + * + * As you can see, calculations of 4 × 3 and 6 × 2 are not necessary. Therefore, we only need to consider factors up to √n because, if n is divisible by some number p, then n = p × q and since p ≤ q, we could derive that p ≤ √n. + * + * Our total runtime has now improved to O(n1.5), which is slightly better. Is there a faster approach? + * + * + * public int countPrimes(int n) { + * int count = 0; + * for (int i = 1; i < n; i++) { + * if (isPrime(i)) count++; + * } + * return count; + * } + * + * private boolean isPrime(int num) { + * if (num + * + * The Sieve of Eratosthenes is one of the most efficient ways to find all prime numbers up to n. But don't let that name scare you, I promise that the concept is surprisingly simple. + * + * + * + * Sieve of Eratosthenes: algorithm steps for primes below 121. "Sieve of Eratosthenes Animation" by SKopp is licensed under CC BY 2.0. + * + * + * We start off with a table of n numbers. Let's look at the first number, 2. We know all multiples of 2 must not be primes, so we mark them off as non-primes. Then we look at the next number, 3. Similarly, all multiples of 3 such as 3 × 2 = 6, 3 × 3 = 9, ... must not be primes, so we mark them off as well. Now we look at the next number, 4, which was already marked off. What does this tell you? Should you mark off all multiples of 4 as well? + * + * 4 is not a prime because it is divisible by 2, which means all multiples of 4 must also be divisible by 2 and were already marked off. So we can skip 4 immediately and go to the next number, 5. Now, all multiples of 5 such as 5 × 2 = 10, 5 × 3 = 15, 5 × 4 = 20, 5 × 5 = 25, ... can be marked off. There is a slight optimization here, we do not need to start from 5 × 2 = 10. Where should we start marking off? + * + * In fact, we can mark off multiples of 5 starting at 5 × 5 = 25, because 5 × 2 = 10 was already marked off by multiple of 2, similarly 5 × 3 = 15 was already marked off by multiple of 3. Therefore, if the current number is p, we can always mark off multiples of p starting at p2, then in increments of p: p2 + p, p2 + 2p, ... Now what should be the terminating loop condition? + * + * It is easy to say that the terminating loop condition is p < n, which is certainly correct but not efficient. Do you still remember Hint #3? + * + * Yes, the terminating loop condition can be p < √n, as all non-primes ≥ √n must have already been marked off. When the loop terminates, all the numbers in the table that are non-marked are prime. + * + * The Sieve of Eratosthenes uses an extra O(n) memory and its runtime complexity is O(n log log n). For the more mathematically inclined readers, you can read more about its algorithm complexity on Wikipedia. + * + * + * public int countPrimes(int n) { + * boolean[] isPrime = new boolean[n]; + * for (int i = 2; i < n; i++) { + * isPrime[i] = true; + * } + * // Loop's ending condition is i * i < n instead of i < sqrt(n) + * // to avoid repeatedly calling an expensive function sqrt(). + * for (int i = 2; i * i < n; i++) { + * if (!isPrime[i]) continue; + * for (int j = i * i; j < n; j += i) { + * isPrime[j] = false; + * } + * } + * int count = 0; + * for (int i = 2; i < n; i++) { + * if (isPrime[i]) count++; + * } + * return count; + * } + * + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Ugly Number + * + * (M) Ugly Number II + * + * (M) Perfect Squares + */ + +/** + * @param {number} n + * @return {number} + */ +var countPrimes = function(n) { + +}; diff --git a/problemset/course-schedule-ii.js b/problemset/course-schedule-ii.js new file mode 100644 index 0000000..1ed7b98 --- /dev/null +++ b/problemset/course-schedule-ii.js @@ -0,0 +1,67 @@ +/** + * Source: https://leetcode.com/problems/course-schedule-ii/ + * Tags: [Depth-first Search,Breadth-first Search,Graph,Topological Sort] + * Level: Medium + * Title: Course Schedule II + * Auther: @imcoddy + * Content: 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. + * + * Hints: + * + * This problem is equivalent to finding the topological order in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses. + * Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort. + * Topological sort could also be done via BFS. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Course Schedule + * + * (H) Alien Dictionary + */ + +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {number[]} + */ +var findOrder = function(numCourses, prerequisites) { + +}; diff --git a/problemset/course-schedule.js b/problemset/course-schedule.js new file mode 100644 index 0000000..ad2f7ae --- /dev/null +++ b/problemset/course-schedule.js @@ -0,0 +1,65 @@ +/** + * Source: https://leetcode.com/problems/course-schedule/ + * Tags: [Depth-first Search,Breadth-first Search,Graph,Topological Sort] + * Level: Medium + * Title: Course Schedule + * Auther: @imcoddy + * Content: 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, is it possible for you to finish all courses? + * + * + * 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 it is possible. + * + * 2, [[1,0],[0,1]] + * There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible. + * + * 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. + * + * Hints: + * + * This problem is equivalent to finding if a cycle exists in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses. + * Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort. + * Topological sort could also be done via BFS. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Course Schedule II + * + * (M) Graph Valid Tree + */ + +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {boolean} + */ +var canFinish = function(numCourses, prerequisites) { + +}; diff --git a/problemset/decode-ways.js b/problemset/decode-ways.js new file mode 100644 index 0000000..f163dba --- /dev/null +++ b/problemset/decode-ways.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/decode-ways/ + * Tags: [Dynamic Programming,String] + * Level: Medium + * Title: Decode Ways + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s + * @return {number} + */ +var numDecodings = function(s) { + +}; diff --git a/problemset/delete-node-in-a-linked-list.js b/problemset/delete-node-in-a-linked-list.js new file mode 100644 index 0000000..5d6d665 --- /dev/null +++ b/problemset/delete-node-in-a-linked-list.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/delete-node-in-a-linked-list/ + * Tags: [Linked List] + * Level: Easy + * Title: Delete Node in a Linked List + * Auther: @imcoddy + * Content: Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. + * + * + * + * Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Remove Linked List Elements + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} node + * @return {void} Do not return anything, modify node in-place instead. + */ +var deleteNode = function(node) { + +}; diff --git a/problemset/different-ways-to-add-parentheses.js b/problemset/different-ways-to-add-parentheses.js new file mode 100644 index 0000000..2a8ed0d --- /dev/null +++ b/problemset/different-ways-to-add-parentheses.js @@ -0,0 +1,56 @@ +/** + * Source: https://leetcode.com/problems/different-ways-to-add-parentheses/ + * Tags: [Divide and Conquer] + * Level: Medium + * Title: Different Ways to Add Parentheses + * Auther: @imcoddy + * Content: Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *. + * + * Example 1 + * Input: "2-1-1". + * ((2-1)-1) = 0 + * (2-(1-1)) = 2 + * Output: [0, 2] + * + * Example 2 + * Input: "2*3-4*5" + * (2*(3-(4*5))) = -34 + * ((2*3)-(4*5)) = -14 + * ((2*(3-4))*5) = -10 + * (2*((3-4)*5)) = -10 + * (((2*3)-4)*5) = 10 + * Output: [-34, -14, -10, -10, 10] + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Unique Binary Search Trees II + * + * (M) Basic Calculator + * + * (H) Expression Add Operators + */ + +/** + * @param {string} input + * @return {number[]} + */ +var diffWaysToCompute = function(input) { + +}; diff --git a/problemset/distinct-subsequences.js b/problemset/distinct-subsequences.js new file mode 100644 index 0000000..3c93846 --- /dev/null +++ b/problemset/distinct-subsequences.js @@ -0,0 +1,33 @@ +/** + * Source: https://leetcode.com/problems/distinct-subsequences/ + * Tags: [Dynamic Programming,String] + * Level: Hard + * Title: Distinct Subsequences + * Auther: @imcoddy + * Content: Given a string S and a string T, count the number of distinct subsequences of T in S. + * + * + * + * A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not). + * + * + * + * Here is an example: + * S = "rabbbit", T = "rabbit" + * + * + * Return 3. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s + * @param {string} t + * @return {number} + */ +var numDistinct = function(s, t) { + +}; diff --git a/problemset/divide-two-integers.js b/problemset/divide-two-integers.js new file mode 100644 index 0000000..f35e0a4 --- /dev/null +++ b/problemset/divide-two-integers.js @@ -0,0 +1,24 @@ +/** + * Source: https://leetcode.com/problems/divide-two-integers/ + * Tags: [Math,Binary Search] + * Level: Medium + * Title: Divide Two Integers + * Auther: @imcoddy + * Content: Divide two integers without using multiplication, division and mod operator. + * + * + * If it is overflow, return MAX_INT. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number} dividend + * @param {number} divisor + * @return {number} + */ +var divide = function(dividend, divisor) { + +}; diff --git a/problemset/dungeon-game.js b/problemset/dungeon-game.js new file mode 100644 index 0000000..4ee9cd9 --- /dev/null +++ b/problemset/dungeon-game.js @@ -0,0 +1,85 @@ +/** + * Source: https://leetcode.com/problems/dungeon-game/ + * Tags: [Dynamic Programming,Binary Search] + * Level: Hard + * Title: Dungeon Game + * Auther: @imcoddy + * Content: table.dungeon, .dungeon th, .dungeon td { + * border:3px solid black; + * } + * + * .dungeon th, .dungeon td { + * text-align: center; + * height: 70px; + * width: 70px; + * } + * + * + * The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. + * The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately. + * Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; + * other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). + * In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. + * + * + * Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. + * For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. + * + * + * + * -2 (K) + * -3 + * 3 + * + * + * -5 + * -10 + * 1 + * + * + * 10 + * 30 + * -5 (P) + * + * + * + * + * + * Notes: + * + * The knight's health has no upper bound. + * Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. + * + * + * + * Credits:Special thanks to @stellari for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Unique Paths + * + * (M) Minimum Path Sum + */ + +/** + * @param {number[][]} dungeon + * @return {number} + */ +var calculateMinimumHP = function(dungeon) { + +}; diff --git a/problemset/edit-distance.js b/problemset/edit-distance.js new file mode 100644 index 0000000..7c70354 --- /dev/null +++ b/problemset/edit-distance.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/edit-distance/ + * Tags: [Dynamic Programming,String] + * Level: Hard + * Title: Edit Distance + * Auther: @imcoddy + * Content: 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 + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) One Edit Distance + */ + +/** + * @param {string} word1 + * @param {string} word2 + * @return {number} + */ +var minDistance = function(word1, word2) { + +}; diff --git a/problemset/evaluate-reverse-polish-notation.js b/problemset/evaluate-reverse-polish-notation.js new file mode 100644 index 0000000..bc4f53d --- /dev/null +++ b/problemset/evaluate-reverse-polish-notation.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/evaluate-reverse-polish-notation/ + * Tags: [Stack] + * Level: Medium + * Title: Evaluate Reverse Polish Notation + * Auther: @imcoddy + * Content: 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 + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Basic Calculator + * + * (H) Expression Add Operators + */ + +/** + * @param {string[]} tokens + * @return {number} + */ +var evalRPN = function(tokens) { + +}; diff --git a/problemset/excel-sheet-column-number.js b/problemset/excel-sheet-column-number.js new file mode 100644 index 0000000..e36889a --- /dev/null +++ b/problemset/excel-sheet-column-number.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/excel-sheet-column-number/ + * Tags: [Math] + * Level: Easy + * Title: Excel Sheet Column Number + * Auther: @imcoddy + * Content: Related to question Excel Sheet Column Title + * Given a column title as appear in an Excel sheet, return its corresponding column number. + * + * For example: + * A -> 1 + * B -> 2 + * C -> 3 + * ... + * Z -> 26 + * AA -> 27 + * AB -> 28 + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Excel Sheet Column Title + */ + +/** + * @param {string} s + * @return {number} + */ +var titleToNumber = function(s) { + +}; diff --git a/problemset/excel-sheet-column-title.js b/problemset/excel-sheet-column-title.js new file mode 100644 index 0000000..f101461 --- /dev/null +++ b/problemset/excel-sheet-column-title.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/excel-sheet-column-title/ + * Tags: [Math] + * Level: Easy + * Title: Excel Sheet Column Title + * Auther: @imcoddy + * Content: Given a positive integer, return its corresponding column title as appear in an Excel sheet. + * + * For example: + * + * 1 -> A + * 2 -> B + * 3 -> C + * ... + * 26 -> Z + * 27 -> AA + * 28 -> AB + * + * Credits:Special thanks to @ifanchu for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Excel Sheet Column Number + */ + +/** + * @param {number} n + * @return {string} + */ +var convertToTitle = function(n) { + +}; diff --git a/problemset/expression-add-operators.js b/problemset/expression-add-operators.js new file mode 100644 index 0000000..636db65 --- /dev/null +++ b/problemset/expression-add-operators.js @@ -0,0 +1,53 @@ +/** + * Source: https://leetcode.com/problems/expression-add-operators/ + * Tags: [Divide and Conquer] + * Level: Hard + * Title: Expression Add Operators + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Evaluate Reverse Polish Notation + * + * (M) Basic Calculator + * + * (M) Basic Calculator II + * + * (M) Different Ways to Add Parentheses + */ + +/** + * @param {string} num + * @param {number} target + * @return {string[]} + */ +var addOperators = function(num, target) { + +}; diff --git a/problemset/factorial-trailing-zeroes.js b/problemset/factorial-trailing-zeroes.js new file mode 100644 index 0000000..5866f81 --- /dev/null +++ b/problemset/factorial-trailing-zeroes.js @@ -0,0 +1,39 @@ +/** + * Source: https://leetcode.com/problems/factorial-trailing-zeroes/ + * Tags: [Math] + * Level: Easy + * Title: Factorial Trailing Zeroes + * Auther: @imcoddy + * Content: Given an integer n, return the number of trailing zeroes in n!. + * + * Note: Your solution should be in logarithmic time complexity. + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Number of Digit One + */ + +/** + * @param {number} n + * @return {number} + */ +var trailingZeroes = function(n) { + +}; diff --git a/problemset/find-median-from-data-stream.js b/problemset/find-median-from-data-stream.js new file mode 100644 index 0000000..77b62b9 --- /dev/null +++ b/problemset/find-median-from-data-stream.js @@ -0,0 +1,65 @@ +/** + * Source: https://leetcode.com/problems/find-median-from-data-stream/ + * Tags: [Heap,Design] + * Level: Hard + * Title: Find Median from Data Stream + * Auther: @imcoddy + * Content: Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value. + * Examples: + * [2,3,4] , the median is 3 + * [2,3], the median is (2 + 3) / 2 = 2.5 + * + * + * Design a data structure that supports the following two operations: + * + * + * void addNum(int num) - Add a integer number from the data stream to the data structure. + * double findMedian() - Return the median of all elements so far. + * + * + * + * For example: + * + * add(1) + * add(2) + * findMedian() -> 1.5 + * add(3) + * findMedian() -> 2 + * + * + * Credits:Special thanks to @Louis1992 for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @constructor + */ +var MedianFinder = function() { + +}; + +/** + * @param {integer} word + * @return {void} + * Adds a num into the data structure. + */ +MedianFinder.prototype.addNum = function(num) { + +}; + +/** + * @return {double} + * Return median of current data stream + */ +MedianFinder.prototype.findMedian = function() { + +}; + +/** + * Your MedianFinder object will be instantiated and called as such: + * var mf = new MedianFinder(); + * mf.addNum(1); + * mf.findMedian(); + */ diff --git a/problemset/find-minimum-in-rotated-sorted-array-ii.js b/problemset/find-minimum-in-rotated-sorted-array-ii.js new file mode 100644 index 0000000..6d402d4 --- /dev/null +++ b/problemset/find-minimum-in-rotated-sorted-array-ii.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/ + * Tags: [Array,Binary Search] + * Level: Hard + * Title: Find Minimum in Rotated Sorted Array II + * Auther: @imcoddy + * Content: Follow up for "Find Minimum in Rotated Sorted Array": + * What if duplicates are allowed? + * + * Would this affect the run-time complexity? How and why? + * + * + * 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). + * + * Find the minimum element. + * + * The array may contain duplicates. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Find Minimum in Rotated Sorted Array + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var findMin = function(nums) { + +}; diff --git a/problemset/find-minimum-in-rotated-sorted-array.js b/problemset/find-minimum-in-rotated-sorted-array.js new file mode 100644 index 0000000..c9126a5 --- /dev/null +++ b/problemset/find-minimum-in-rotated-sorted-array.js @@ -0,0 +1,43 @@ +/** + * Source: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Find Minimum in Rotated Sorted Array + * Auther: @imcoddy + * Content: 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). + * + * Find the minimum element. + * + * You may assume no duplicate exists in the array. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Search in Rotated Sorted Array + * + * (H) Find Minimum in Rotated Sorted Array II + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var findMin = function(nums) { + +}; diff --git a/problemset/find-peak-element.js b/problemset/find-peak-element.js new file mode 100644 index 0000000..b0203f7 --- /dev/null +++ b/problemset/find-peak-element.js @@ -0,0 +1,35 @@ +/** + * Source: https://leetcode.com/problems/find-peak-element/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Find Peak Element + * Auther: @imcoddy + * Content: A peak element is an element that is greater than its neighbors. + * + * Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. + * + * The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. + * + * You may imagine that num[-1] = num[n] = -∞. + * + * For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. + * + * click to show spoilers. + * + * Note: + * Your solution should be in logarithmic complexity. + * + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var findPeakElement = function(nums) { + +}; diff --git a/problemset/find-the-duplicate-number.js b/problemset/find-the-duplicate-number.js new file mode 100644 index 0000000..271e484 --- /dev/null +++ b/problemset/find-the-duplicate-number.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/find-the-duplicate-number/ + * Tags: [Array,Two Pointers,Binary Search] + * Level: Hard + * Title: Find the Duplicate Number + * Auther: @imcoddy + * Content: Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. + * + * + * + * Note: + * + * You must not modify the array (assume the array is read only). + * You must use only constant, O(1) extra space. + * Your runtime complexity should be less than O(n2). + * There is only one duplicate number in the array, but it could be repeated more than once. + * + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) First Missing Positive + * + * (M) Single Number + * + * (M) Linked List Cycle II + * + * (M) Missing Number + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var findDuplicate = function(nums) { + +}; diff --git a/problemset/first-bad-version.js b/problemset/first-bad-version.js new file mode 100644 index 0000000..e2831ca --- /dev/null +++ b/problemset/first-bad-version.js @@ -0,0 +1,64 @@ +/** + * Source: https://leetcode.com/problems/first-bad-version/ + * Tags: [Binary Search] + * Level: Easy + * Title: First Bad Version + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Search for a Range + * + * (M) Search Insert Position + */ + +/** + * 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) { + + }; +}; diff --git a/problemset/first-missing-positive.js b/problemset/first-missing-positive.js new file mode 100644 index 0000000..27c717b --- /dev/null +++ b/problemset/first-missing-positive.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/first-missing-positive/ + * Tags: [Array] + * Level: Hard + * Title: First Missing Positive + * Auther: @imcoddy + * Content: Given an unsorted integer array, find the first missing positive integer. + * + * + * + * For example, + * Given [1,2,0] return 3, + * and [3,4,-1,1] return 2. + * + * + * + * Your algorithm should run in O(n) time and uses constant space. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Missing Number + * + * (H) Find the Duplicate Number + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var firstMissingPositive = function(nums) { + +}; diff --git a/problemset/flatten-binary-tree-to-linked-list.js b/problemset/flatten-binary-tree-to-linked-list.js new file mode 100644 index 0000000..02f1b3e --- /dev/null +++ b/problemset/flatten-binary-tree-to-linked-list.js @@ -0,0 +1,60 @@ +/** + * Source: https://leetcode.com/problems/flatten-binary-tree-to-linked-list/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Flatten Binary Tree to Linked List + * Auther: @imcoddy + * Content: Given a binary tree, flatten it to a linked list in-place. + * + * + * + * For example, + * Given + * + * 1 + * / \ + * 2 5 + * / \ \ + * 3 4 6 + * + * + * + * The flattened tree should look like: + * + * 1 + * \ + * 2 + * \ + * 3 + * \ + * 4 + * \ + * 5 + * \ + * 6 + * + * + * click to show hints. + * + * Hints: + * If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {void} Do not return anything, modify root in-place instead. + */ +var flatten = function(root) { + +}; diff --git a/problemset/fraction-to-recurring-decimal.js b/problemset/fraction-to-recurring-decimal.js new file mode 100644 index 0000000..6487282 --- /dev/null +++ b/problemset/fraction-to-recurring-decimal.js @@ -0,0 +1,32 @@ +/** + * Source: https://leetcode.com/problems/fraction-to-recurring-decimal/ + * Tags: [Hash Table,Math] + * Level: Medium + * Title: Fraction to Recurring Decimal + * Auther: @imcoddy + * Content: Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. + * + * If the fractional part is repeating, enclose the repeating part in parentheses. + * + * For example, + * + * Given numerator = 1, denominator = 2, return "0.5". + * Given numerator = 2, denominator = 1, return "2". + * Given numerator = 2, denominator = 3, return "0.(6)". + * + * + * + * Credits:Special thanks to @Shangrila for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number} numerator + * @param {number} denominator + * @return {string} + */ +var fractionToDecimal = function(numerator, denominator) { + +}; diff --git a/problemset/game-of-life.js b/problemset/game-of-life.js new file mode 100644 index 0000000..32166f3 --- /dev/null +++ b/problemset/game-of-life.js @@ -0,0 +1,62 @@ +/** + * Source: https://leetcode.com/problems/game-of-life/ + * Tags: [Array] + * Level: Medium + * Title: Game of Life + * Auther: @imcoddy + * Content: According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970." + * + * + * + * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article): + * + * + * + * + * Any live cell with fewer than two live neighbors dies, as if caused by under-population. + * Any live cell with two or three live neighbors lives on to the next generation. + * Any live cell with more than three live neighbors dies, as if by over-population.. + * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. + * + * + * + * + * Write a function to compute the next state (after one update) of the board given its current state. + * + * + * Follow up: + * + * Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells. + * In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems? + * + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Set Matrix Zeroes + */ + +/** + * @param {number[][]} board + * @return {void} Do not return anything, modify board in-place instead. + */ +var gameOfLife = function(board) { + +}; diff --git a/problemset/gas-station.js b/problemset/gas-station.js new file mode 100644 index 0000000..2bd6b9e --- /dev/null +++ b/problemset/gas-station.js @@ -0,0 +1,34 @@ +/** + * Source: https://leetcode.com/problems/gas-station/ + * Tags: [Greedy] + * Level: Medium + * Title: Gas Station + * Auther: @imcoddy + * Content: There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. + * + * + * + * You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + * + * + * + * Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. + * + * + * + * Note: + * The solution is guaranteed to be unique. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} gas + * @param {number[]} cost + * @return {number} + */ +var canCompleteCircuit = function(gas, cost) { + +}; diff --git a/problemset/generate-parentheses.js b/problemset/generate-parentheses.js new file mode 100644 index 0000000..558dab3 --- /dev/null +++ b/problemset/generate-parentheses.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/generate-parentheses/ + * Tags: [Backtracking,String] + * Level: Medium + * Title: Generate Parentheses + * Auther: @imcoddy + * Content: Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + * + * + * + * For example, given n = 3, a solution set is: + * + * + * "((()))", "(()())", "(())()", "()(())", "()()()" + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Letter Combinations of a Phone Number + * + * (E) Valid Parentheses + */ + +/** + * @param {number} n + * @return {string[]} + */ +var generateParenthesis = function(n) { + +}; diff --git a/problemset/gray-code.js b/problemset/gray-code.js new file mode 100644 index 0000000..6688573 --- /dev/null +++ b/problemset/gray-code.js @@ -0,0 +1,36 @@ +/** + * Source: https://leetcode.com/problems/gray-code/ + * Tags: [Backtracking] + * Level: Medium + * Title: Gray Code + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number} n + * @return {number[]} + */ +var grayCode = function(n) { + +}; diff --git a/problemset/h-index-ii.js b/problemset/h-index-ii.js new file mode 100644 index 0000000..b5d63d8 --- /dev/null +++ b/problemset/h-index-ii.js @@ -0,0 +1,40 @@ +/** + * Source: https://leetcode.com/problems/h-index-ii/ + * Tags: [Binary Search] + * Level: Medium + * Title: H-Index II + * Auther: @imcoddy + * Content: Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimize your algorithm? + * + * + * + * Expected runtime complexity is in O(log n) and the input is sorted. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) H-Index + */ + +/** + * @param {number[]} citations + * @return {number} + */ +var hIndex = function(citations) { + +}; diff --git a/problemset/h-index.js b/problemset/h-index.js new file mode 100644 index 0000000..297c6d2 --- /dev/null +++ b/problemset/h-index.js @@ -0,0 +1,56 @@ +/** + * Source: https://leetcode.com/problems/h-index/ + * Tags: [Hash Table,Sort] + * Level: Medium + * Title: H-Index + * Auther: @imcoddy + * Content: Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. + * + * + * + * According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each." + * + * + * + * For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, his h-index is 3. + * + * + * + * Note: If there are several possible values for h, the maximum one is taken as the h-index. + * + * + * + * An easy approach is to sort the array first. + * What are the possible values of h-index? + * A faster approach is to use extra space. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) H-Index II + */ + +/** + * @param {number[]} citations + * @return {number} + */ +var hIndex = function(citations) { + +}; diff --git a/problemset/happy-number.js b/problemset/happy-number.js new file mode 100644 index 0000000..7830ac7 --- /dev/null +++ b/problemset/happy-number.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/happy-number/ + * Tags: [Hash Table,Math] + * Level: Easy + * Title: Happy Number + * Auther: @imcoddy + * Content: Write an algorithm to determine if a number is "happy". + * + * A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers. + * + * Example: 19 is a happy number + * + * + * 12 + 92 = 82 + * 82 + 22 = 68 + * 62 + 82 = 100 + * 12 + 02 + 02 = 1 + * + * + * Credits:Special thanks to @mithmatt and @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Add Digits + * + * (E) Ugly Number + */ + +/** + * @param {number} n + * @return {boolean} + */ +var isHappy = function(n) { + +}; diff --git a/problemset/house-robber-ii.js b/problemset/house-robber-ii.js new file mode 100644 index 0000000..d914b02 --- /dev/null +++ b/problemset/house-robber-ii.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/house-robber-ii/ + * Tags: [Dynamic Programming] + * Level: Medium + * Title: House Robber II + * Auther: @imcoddy + * Content: 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. + * + * Credits:Special thanks to @Freezen for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) House Robber + * + * (M) Paint House + * + * (E) Paint Fence + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var rob = function(nums) { + +}; diff --git a/problemset/house-robber.js b/problemset/house-robber.js new file mode 100644 index 0000000..4eaf81e --- /dev/null +++ b/problemset/house-robber.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/house-robber/ + * Tags: [Dynamic Programming] + * Level: Easy + * Title: House Robber + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Maximum Product Subarray + * + * (M) House Robber II + * + * (M) Paint House + * + * (E) Paint Fence + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var rob = function(nums) { + +}; diff --git a/problemset/implement-queue-using-stacks.js b/problemset/implement-queue-using-stacks.js new file mode 100644 index 0000000..fe7470f --- /dev/null +++ b/problemset/implement-queue-using-stacks.js @@ -0,0 +1,84 @@ +/** + * Source: https://leetcode.com/problems/implement-queue-using-stacks/ + * Tags: [Stack,Design] + * Level: Easy + * Title: Implement Queue using Stacks + * Auther: @imcoddy + * Content: Implement the following operations of a queue using stacks. + * + * + * push(x) -- Push element x to the back of queue. + * + * + * pop() -- Removes the element from in front of queue. + * + * + * peek() -- Get the front element. + * + * + * empty() -- Return whether the queue is empty. + * + * + * Notes: + * + * You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. + * Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. + * You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Implement Stack using Queues + */ + +/** + * @constructor + */ +var Queue = function() { + +}; + +/** + * @param {number} x + * @returns {void} + */ +Queue.prototype.push = function(x) { + +}; + +/** + * @returns {void} + */ +Queue.prototype.pop = function() { + +}; + +/** + * @returns {number} + */ +Queue.prototype.peek = function() { + +}; + +/** + * @returns {boolean} + */ +Queue.prototype.empty = function() { + +}; diff --git a/problemset/implement-stack-using-queues.js b/problemset/implement-stack-using-queues.js new file mode 100644 index 0000000..e34376f --- /dev/null +++ b/problemset/implement-stack-using-queues.js @@ -0,0 +1,91 @@ +/** + * Source: https://leetcode.com/problems/implement-stack-using-queues/ + * Tags: [Stack,Design] + * Level: Easy + * Title: Implement Stack using Queues + * Auther: @imcoddy + * Content: Implement the following operations of a stack using queues. + * + * + * push(x) -- Push element x onto stack. + * + * + * pop() -- Removes the element on top of the stack. + * + * + * top() -- Get the top element. + * + * + * empty() -- Return whether the stack is empty. + * + * + * Notes: + * + * You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid. + * Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. + * You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). + * + * + * + * + * Update (2015-06-11): + * The class name of the Java function had been updated to MyStack instead of Stack. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Implement Queue using Stacks + */ + +/** + * @constructor + */ +var Stack = function() { + +}; + +/** + * @param {number} x + * @returns {void} + */ +Stack.prototype.push = function(x) { + +}; + +/** + * @returns {void} + */ +Stack.prototype.pop = function() { + +}; + +/** + * @returns {number} + */ +Stack.prototype.top = function() { + +}; + +/** + * @returns {boolean} + */ +Stack.prototype.empty = function() { + +}; diff --git a/problemset/implement-strstr.js b/problemset/implement-strstr.js new file mode 100644 index 0000000..5325bd0 --- /dev/null +++ b/problemset/implement-strstr.js @@ -0,0 +1,40 @@ +/** + * Source: https://leetcode.com/problems/implement-strstr/ + * Tags: [Two Pointers,String] + * Level: Easy + * Title: Implement strStr() + * Auther: @imcoddy + * Content: Implement strStr(). + * + * + * Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Shortest Palindrome + */ + +/** + * @param {string} haystack + * @param {string} needle + * @return {number} + */ +var strStr = function(haystack, needle) { + +}; diff --git a/problemset/implement-trie-prefix-tree.js b/problemset/implement-trie-prefix-tree.js new file mode 100644 index 0000000..0f2cc71 --- /dev/null +++ b/problemset/implement-trie-prefix-tree.js @@ -0,0 +1,80 @@ +/** + * Source: https://leetcode.com/problems/implement-trie-prefix-tree/ + * Tags: [Trie,Design] + * Level: Medium + * Title: Implement Trie (Prefix Tree) + * Auther: @imcoddy + * Content: Implement a trie with insert, search, and startsWith methods. + * + * + * + * Note: + * You may assume that all inputs are consist of lowercase letters a-z. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Add and Search Word - Data structure design + */ + +/** + * @constructor + * Initialize your data structure here. + */ +var TrieNode = function() { + +}; + +var Trie = function() { + this.root = TrieNode(); +}; + +/** + * @param {string} word + * @return {void} + * Inserts a word into the trie. + */ +Trie.prototype.insert = function(word) { + +}; + +/** + * @param {string} word + * @return {boolean} + * Returns if the word is in the trie. + */ +Trie.prototype.search = function(word) { + +}; + +/** + * @param {string} prefix + * @return {boolean} + * Returns if there is any word in the trie + * that starts with the given prefix. + */ +Trie.prototype.startsWith = function(prefix) { + +}; + +/** + * Your Trie object will be instantiated and called as such: + * var trie = new Trie(); + * trie.insert("somestring"); + * trie.search("key"); + */ diff --git a/problemset/insert-interval.js b/problemset/insert-interval.js new file mode 100644 index 0000000..8a5ea9a --- /dev/null +++ b/problemset/insert-interval.js @@ -0,0 +1,59 @@ +/** + * Source: https://leetcode.com/problems/insert-interval/ + * Tags: [Array,Sort] + * Level: Hard + * Title: Insert Interval + * Auther: @imcoddy + * Content: 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]. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Merge Intervals + */ + +/** + * Definition for an interval. + * function Interval(start, end) { + * this.start = start; + * this.end = end; + * } + */ +/** + * @param {Interval[]} intervals + * @param {Interval} newInterval + * @return {Interval[]} + */ +var insert = function(intervals, newInterval) { + +}; diff --git a/problemset/insertion-sort-list.js b/problemset/insertion-sort-list.js new file mode 100644 index 0000000..24d63b9 --- /dev/null +++ b/problemset/insertion-sort-list.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/insertion-sort-list/ + * Tags: [Linked List,Sort] + * Level: Medium + * Title: Insertion Sort List + * Auther: @imcoddy + * Content: Sort a linked list using insertion sort. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Sort List + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var insertionSortList = function(head) { + +}; diff --git a/problemset/integer-to-english-words.js b/problemset/integer-to-english-words.js new file mode 100644 index 0000000..9348853 --- /dev/null +++ b/problemset/integer-to-english-words.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/integer-to-english-words/ + * Tags: [Math,String] + * Level: Medium + * Title: Integer to English Words + * Auther: @imcoddy + * Content: Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1. + * + * + * For example, + * + * 123 -> "One Hundred Twenty Three" + * 12345 -> "Twelve Thousand Three Hundred Forty Five" + * 1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven" + * + * + * Did you see a pattern in dividing the number into chunk of words? For example, 123 and 123000. + * Group the number by thousands (3 digits). You can write a helper function that takes a number less than 1000 and convert just that chunk to words. + * There are many edge cases. What are some good test cases? Does your code work with input such as 0? Or 1000010? (middle chunk is zero and should not be printed out) + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Integer to Roman + */ + +/** + * @param {number} num + * @return {string} + */ +var numberToWords = function(num) { + +}; diff --git a/problemset/integer-to-roman.js b/problemset/integer-to-roman.js new file mode 100644 index 0000000..85617a2 --- /dev/null +++ b/problemset/integer-to-roman.js @@ -0,0 +1,40 @@ +/** + * Source: https://leetcode.com/problems/integer-to-roman/ + * Tags: [Math,String] + * Level: Medium + * Title: Integer to Roman + * Auther: @imcoddy + * Content: Given an integer, convert it to a roman numeral. + * + * + * Input is guaranteed to be within the range from 1 to 3999. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Roman to Integer + * + * (M) Integer to English Words + */ + +/** + * @param {number} num + * @return {string} + */ +var intToRoman = function(num) { + +}; diff --git a/problemset/interleaving-string.js b/problemset/interleaving-string.js new file mode 100644 index 0000000..7b9ebcd --- /dev/null +++ b/problemset/interleaving-string.js @@ -0,0 +1,33 @@ +/** + * Source: https://leetcode.com/problems/interleaving-string/ + * Tags: [Dynamic Programming,String] + * Level: Hard + * Title: Interleaving String + * Auther: @imcoddy + * Content: Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. + * + * + * + * For example, + * Given: + * s1 = "aabcc", + * s2 = "dbbca", + * + * + * When s3 = "aadbbcbcac", return true. + * When s3 = "aadbbbaccc", return false. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s1 + * @param {string} s2 + * @param {string} s3 + * @return {boolean} + */ +var isInterleave = function(s1, s2, s3) { + +}; diff --git a/problemset/intersection-of-two-linked-lists.js b/problemset/intersection-of-two-linked-lists.js new file mode 100644 index 0000000..dfaa05f --- /dev/null +++ b/problemset/intersection-of-two-linked-lists.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/intersection-of-two-linked-lists/ + * Tags: [Linked List] + * Level: Easy + * Title: Intersection of Two Linked Lists + * Auther: @imcoddy + * Content: Write a program to find the node at which the intersection of two singly linked lists begins. + * + * For example, the following two linked lists: + * + * A: a1 → a2 + * ↘ + * c1 → c2 → c3 + * ↗ + * B: b1 → b2 → b3 + * + * begin to intersect at node c1. + * + * Notes: + * + * If the two linked lists have no intersection at all, return null. + * The linked lists must retain their original structure after the function returns. + * You may assume there are no cycles anywhere in the entire linked structure. + * Your code should preferably run in O(n) time and use only O(1) memory. + * + * + * + * Credits:Special thanks to @stellari for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} headA + * @param {ListNode} headB + * @return {ListNode} + */ +var getIntersectionNode = function(headA, headB) { + +}; diff --git a/problemset/invert-binary-tree.js b/problemset/invert-binary-tree.js new file mode 100644 index 0000000..390a3e0 --- /dev/null +++ b/problemset/invert-binary-tree.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/invert-binary-tree/ + * Tags: [Tree] + * Level: Easy + * Title: Invert Binary Tree + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var invertTree = function(root) { + +}; diff --git a/problemset/isomorphic-strings.js b/problemset/isomorphic-strings.js new file mode 100644 index 0000000..58709b8 --- /dev/null +++ b/problemset/isomorphic-strings.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/isomorphic-strings/ + * Tags: [Hash Table] + * Level: Easy + * Title: Isomorphic Strings + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Word Pattern + */ + +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ +var isIsomorphic = function(s, t) { + +}; diff --git a/problemset/jump-game-ii.js b/problemset/jump-game-ii.js new file mode 100644 index 0000000..293b177 --- /dev/null +++ b/problemset/jump-game-ii.js @@ -0,0 +1,34 @@ +/** + * Source: https://leetcode.com/problems/jump-game-ii/ + * Tags: [Array,Greedy] + * Level: Hard + * Title: Jump Game II + * Auther: @imcoddy + * Content: Given an array of non-negative integers, you are initially positioned at the first index of the array. + * + * + * Each element in the array represents your maximum jump length at that position. + * + * + * Your goal is to reach the last index in the minimum number of jumps. + * + * + * + * For example: + * Given array A = [2,3,1,1,4] + * + * + * The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.) + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var jump = function(nums) { + +}; diff --git a/problemset/jump-game.js b/problemset/jump-game.js new file mode 100644 index 0000000..425c313 --- /dev/null +++ b/problemset/jump-game.js @@ -0,0 +1,34 @@ +/** + * Source: https://leetcode.com/problems/jump-game/ + * Tags: [Array,Greedy] + * Level: Medium + * Title: Jump Game + * Auther: @imcoddy + * Content: Given an array of non-negative integers, you are initially positioned at the first index of the array. + * + * + * Each element in the array represents your maximum jump length at that position. + * + * + * Determine if you are able to reach the last index. + * + * + * + * For example: + * A = [2,3,1,1,4], return true. + * + * + * A = [3,2,1,0,4], return false. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {boolean} + */ +var canJump = function(nums) { + +}; diff --git a/problemset/kth-largest-element-in-an-array.js b/problemset/kth-largest-element-in-an-array.js new file mode 100644 index 0000000..a115b2d --- /dev/null +++ b/problemset/kth-largest-element-in-an-array.js @@ -0,0 +1,29 @@ +/** + * Source: https://leetcode.com/problems/kth-largest-element-in-an-array/ + * Tags: [Divide and Conquer,Heap] + * Level: Medium + * Title: Kth Largest Element in an Array + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var findKthLargest = function(nums, k) { + +}; diff --git a/problemset/kth-smallest-element-in-a-bst.js b/problemset/kth-smallest-element-in-a-bst.js new file mode 100644 index 0000000..d526688 --- /dev/null +++ b/problemset/kth-smallest-element-in-a-bst.js @@ -0,0 +1,57 @@ +/** + * Source: https://leetcode.com/problems/kth-smallest-element-in-a-bst/ + * Tags: [Tree,Binary Search] + * Level: Medium + * Title: Kth Smallest Element in a BST + * Auther: @imcoddy + * Content: Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. + * + * Note: + * You may assume k is always valid, 1 ≤ k ≤ BST's total elements. + * + * Follow up: + * What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine? + * + * + * Try to utilize the property of a BST. + * What if you could modify the BST node's structure? + * The optimal runtime complexity is O(height of BST). + * + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Binary Tree Inorder Traversal + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {number} k + * @return {number} + */ +var kthSmallest = function(root, k) { + +}; diff --git a/problemset/largest-number.js b/problemset/largest-number.js new file mode 100644 index 0000000..2c2f7b3 --- /dev/null +++ b/problemset/largest-number.js @@ -0,0 +1,25 @@ +/** + * Source: https://leetcode.com/problems/largest-number/ + * Tags: [Sort] + * Level: Medium + * Title: Largest Number + * Auther: @imcoddy + * Content: Given a list of non negative integers, arrange them such that they form the largest number. + * + * For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330. + * + * Note: The result may be very large, so you need to return a string instead of an integer. + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {string} + */ +var largestNumber = function(nums) { + +}; diff --git a/problemset/largest-rectangle-in-histogram.js b/problemset/largest-rectangle-in-histogram.js new file mode 100644 index 0000000..f2a27f0 --- /dev/null +++ b/problemset/largest-rectangle-in-histogram.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/largest-rectangle-in-histogram/ + * Tags: [Array,Stack] + * Level: Hard + * Title: Largest Rectangle in Histogram + * Auther: @imcoddy + * Content: 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 height = [2,1,5,6,2,3], + * return 10. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Maximal Rectangle + */ + +/** + * @param {number[]} height + * @return {number} + */ +var largestRectangleArea = function(height) { + +}; diff --git a/problemset/length-of-last-word.js b/problemset/length-of-last-word.js new file mode 100644 index 0000000..2e100af --- /dev/null +++ b/problemset/length-of-last-word.js @@ -0,0 +1,29 @@ +/** + * Source: https://leetcode.com/problems/length-of-last-word/ + * Tags: [String] + * Level: Easy + * Title: Length of Last Word + * Auther: @imcoddy + * Content: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. + * + * If the last word does not exist, return 0. + * + * Note: A word is defined as a character sequence consists of non-space characters only. + * + * + * For example, + * Given s = "Hello World", + * return 5. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s + * @return {number} + */ +var lengthOfLastWord = function(s) { + +}; diff --git a/problemset/letter-combinations-of-a-phone-number.js b/problemset/letter-combinations-of-a-phone-number.js new file mode 100644 index 0000000..ce1e706 --- /dev/null +++ b/problemset/letter-combinations-of-a-phone-number.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/letter-combinations-of-a-phone-number/ + * Tags: [Backtracking,String] + * Level: Medium + * Title: Letter Combinations of a Phone Number + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Generate Parentheses + * + * (M) Combination Sum + */ + +/** + * @param {string} digits + * @return {string[]} + */ +var letterCombinations = function(digits) { + +}; diff --git a/problemset/linked-list-cycle-ii.js b/problemset/linked-list-cycle-ii.js new file mode 100644 index 0000000..6653509 --- /dev/null +++ b/problemset/linked-list-cycle-ii.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/linked-list-cycle-ii/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Linked List Cycle II + * Auther: @imcoddy + * Content: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. + * + * + * + * Note: Do not modify the linked list. + * + * + * Follow up: + * Can you solve it without using extra space? + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Linked List Cycle + * + * (H) Find the Duplicate Number + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {ListNode} + */ +var detectCycle = function(head) { + +}; diff --git a/problemset/linked-list-cycle.js b/problemset/linked-list-cycle.js new file mode 100644 index 0000000..6c5f9fd --- /dev/null +++ b/problemset/linked-list-cycle.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/linked-list-cycle/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Linked List Cycle + * Auther: @imcoddy + * Content: Given a linked list, determine if it has a cycle in it. + * + * + * + * Follow up: + * Can you solve it without using extra space? + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Linked List Cycle II + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {boolean} + */ +var hasCycle = function(head) { + +}; diff --git a/problemset/longest-common-prefix.js b/problemset/longest-common-prefix.js new file mode 100644 index 0000000..37c05c0 --- /dev/null +++ b/problemset/longest-common-prefix.js @@ -0,0 +1,20 @@ +/** + * Source: https://leetcode.com/problems/longest-common-prefix/ + * Tags: [String] + * Level: Easy + * Title: Longest Common Prefix + * Auther: @imcoddy + * Content: Write a function to find the longest common prefix string amongst an array of strings. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string[]} strs + * @return {string} + */ +var longestCommonPrefix = function(strs) { + +}; diff --git a/problemset/longest-consecutive-sequence.js b/problemset/longest-consecutive-sequence.js new file mode 100644 index 0000000..69d5fa8 --- /dev/null +++ b/problemset/longest-consecutive-sequence.js @@ -0,0 +1,44 @@ +/** + * Source: https://leetcode.com/problems/longest-consecutive-sequence/ + * Tags: [Array] + * Level: Hard + * Title: Longest Consecutive Sequence + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Binary Tree Longest Consecutive Sequence + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var longestConsecutive = function(nums) { + +}; diff --git a/problemset/longest-increasing-subsequence.js b/problemset/longest-increasing-subsequence.js new file mode 100644 index 0000000..4a218d4 --- /dev/null +++ b/problemset/longest-increasing-subsequence.js @@ -0,0 +1,32 @@ +/** + * Source: https://leetcode.com/problems/longest-increasing-subsequence/ + * Tags: [Dynamic Programming,Binary Search] + * Level: Medium + * Title: Longest Increasing Subsequence + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var lengthOfLIS = function(nums) { + +}; diff --git a/problemset/longest-palindromic-substring.js b/problemset/longest-palindromic-substring.js new file mode 100644 index 0000000..3e0dddd --- /dev/null +++ b/problemset/longest-palindromic-substring.js @@ -0,0 +1,37 @@ +/** + * Source: https://leetcode.com/problems/longest-palindromic-substring/ + * Tags: [String] + * Level: Medium + * Title: Longest Palindromic Substring + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Shortest Palindrome + * + * (E) Palindrome Permutation + */ + +/** + * @param {string} s + * @return {string} + */ +var longestPalindrome = function(s) { + +}; diff --git a/problemset/longest-substring-without-repeating-characters.js b/problemset/longest-substring-without-repeating-characters.js new file mode 100644 index 0000000..cdd9ef0 --- /dev/null +++ b/problemset/longest-substring-without-repeating-characters.js @@ -0,0 +1,35 @@ +/** + * Source: https://leetcode.com/problems/longest-substring-without-repeating-characters/ + * Tags: [Hash Table,Two Pointers,String] + * Level: Medium + * Title: Longest Substring Without Repeating Characters + * Auther: @imcoddy + * Content: Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Longest Substring with At Most Two Distinct Characters + */ + +/** + * @param {string} s + * @return {number} + */ +var lengthOfLongestSubstring = function(s) { + +}; diff --git a/problemset/longest-valid-parentheses.js b/problemset/longest-valid-parentheses.js new file mode 100644 index 0000000..aa85a01 --- /dev/null +++ b/problemset/longest-valid-parentheses.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/longest-valid-parentheses/ + * Tags: [Dynamic Programming,String] + * Level: Hard + * Title: Longest Valid Parentheses + * Auther: @imcoddy + * Content: Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. + * + * + * For "(()", the longest valid parentheses substring is "()", which has length = 2. + * + * + * Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Valid Parentheses + */ + +/** + * @param {string} s + * @return {number} + */ +var longestValidParentheses = function(s) { + +}; diff --git a/problemset/lowest-common-ancestor-of-a-binary-search-tree.js b/problemset/lowest-common-ancestor-of-a-binary-search-tree.js new file mode 100644 index 0000000..a2fb26e --- /dev/null +++ b/problemset/lowest-common-ancestor-of-a-binary-search-tree.js @@ -0,0 +1,62 @@ +/** + * Source: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/ + * Tags: [Tree] + * Level: Easy + * Title: Lowest Common Ancestor of a Binary Search Tree + * Auther: @imcoddy + * Content: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. + * + * + * + * 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).” + * + * + * + * _______6______ + * / \ + * ___2__ ___8__ + * / \ / \ + * 0 _4 7 9 + * / \ + * 3 5 + * + * + * + * For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Lowest Common Ancestor of a Binary Tree + */ + +/** + * 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} + */ +var lowestCommonAncestor = function(root, p, q) { + +}; diff --git a/problemset/lowest-common-ancestor-of-a-binary-tree.js b/problemset/lowest-common-ancestor-of-a-binary-tree.js new file mode 100644 index 0000000..c2a12ea --- /dev/null +++ b/problemset/lowest-common-ancestor-of-a-binary-tree.js @@ -0,0 +1,62 @@ +/** + * Source: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ + * Tags: [Tree] + * Level: Medium + * Title: Lowest Common Ancestor of a Binary Tree + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Lowest Common Ancestor of a Binary Search Tree + */ + +/** + * 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} + */ +var lowestCommonAncestor = function(root, p, q) { + +}; diff --git a/problemset/lru-cache.js b/problemset/lru-cache.js new file mode 100644 index 0000000..c798c28 --- /dev/null +++ b/problemset/lru-cache.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/lru-cache/ + * Tags: [Design] + * Level: Hard + * Title: LRU Cache + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @constructor + */ +var LRUCache = function(capacity) { + +}; + +/** + * @param {number} key + * @returns {number} + */ +LRUCache.prototype.get = function(key) { + +}; + +/** + * @param {number} key + * @param {number} value + * @returns {void} + */ +LRUCache.prototype.set = function(key, value) { + +}; diff --git a/problemset/majority-element-ii.js b/problemset/majority-element-ii.js new file mode 100644 index 0000000..13e6fe0 --- /dev/null +++ b/problemset/majority-element-ii.js @@ -0,0 +1,40 @@ +/** + * Source: https://leetcode.com/problems/majority-element-ii/ + * Tags: [Array] + * Level: Medium + * Title: Majority Element II + * Auther: @imcoddy + * Content: Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space. + * + * + * How many majority elements could it possibly have? + * Do you have a better hint? Suggest it! + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Majority Element + */ + +/** + * @param {number[]} nums + * @return {number[]} + */ +var majorityElement = function(nums) { + +}; diff --git a/problemset/majority-element.js b/problemset/majority-element.js new file mode 100644 index 0000000..1e1e891 --- /dev/null +++ b/problemset/majority-element.js @@ -0,0 +1,39 @@ +/** + * Source: https://leetcode.com/problems/majority-element/ + * Tags: [Divide and Conquer,Array,Bit Manipulation] + * Level: Easy + * Title: Majority Element + * Auther: @imcoddy + * Content: Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. + * + * You may assume that the array is non-empty and the majority element always exist in the array. + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Majority Element II + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var majorityElement = function(nums) { + +}; diff --git a/problemset/max-points-on-a-line.js b/problemset/max-points-on-a-line.js new file mode 100644 index 0000000..db0c3c6 --- /dev/null +++ b/problemset/max-points-on-a-line.js @@ -0,0 +1,26 @@ +/** + * Source: https://leetcode.com/problems/max-points-on-a-line/ + * Tags: [Hash Table,Math] + * Level: Hard + * Title: Max Points on a Line + * Auther: @imcoddy + * Content: Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for a point. + * function Point(x, y) { + * this.x = x; + * this.y = y; + * } + */ +/** + * @param {Point[]} points + * @return {number} + */ +var maxPoints = function(points) { + +}; diff --git a/problemset/maximal-rectangle.js b/problemset/maximal-rectangle.js new file mode 100644 index 0000000..bf2cc22 --- /dev/null +++ b/problemset/maximal-rectangle.js @@ -0,0 +1,38 @@ +/** + * Source: https://leetcode.com/problems/maximal-rectangle/ + * Tags: [Array,Hash Table,Stack,Dynamic Programming] + * Level: Hard + * Title: Maximal Rectangle + * Auther: @imcoddy + * Content: Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Largest Rectangle in Histogram + * + * (M) Maximal Square + */ + +/** + * @param {character[][]} matrix + * @return {number} + */ +var maximalRectangle = function(matrix) { + +}; diff --git a/problemset/maximal-square.js b/problemset/maximal-square.js new file mode 100644 index 0000000..d3cb3bc --- /dev/null +++ b/problemset/maximal-square.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/maximal-square/ + * Tags: [Dynamic Programming] + * Level: Medium + * Title: Maximal Square + * Auther: @imcoddy + * Content: Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Maximal Rectangle + */ + +/** + * @param {character[][]} matrix + * @return {number} + */ +var maximalSquare = function(matrix) { + +}; diff --git a/problemset/maximum-depth-of-binary-tree.js b/problemset/maximum-depth-of-binary-tree.js new file mode 100644 index 0000000..5be757b --- /dev/null +++ b/problemset/maximum-depth-of-binary-tree.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/maximum-depth-of-binary-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Maximum Depth of Binary Tree + * Auther: @imcoddy + * Content: Given a binary tree, find its maximum depth. + * + * The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Balanced Binary Tree + * + * (E) Minimum Depth of Binary Tree + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var maxDepth = function(root) { + +}; diff --git a/problemset/maximum-gap.js b/problemset/maximum-gap.js new file mode 100644 index 0000000..5b3bd1c --- /dev/null +++ b/problemset/maximum-gap.js @@ -0,0 +1,27 @@ +/** + * Source: https://leetcode.com/problems/maximum-gap/ + * Tags: [Sort] + * Level: Hard + * Title: Maximum Gap + * Auther: @imcoddy + * Content: Given an unsorted array, find the maximum difference between the successive elements in its sorted form. + * + * Try to solve it in linear time/space. + * + * Return 0 if the array contains less than 2 elements. + * + * You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range. + * + * Credits:Special thanks to @porker2008 for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var maximumGap = function(nums) { + +}; diff --git a/problemset/maximum-product-subarray.js b/problemset/maximum-product-subarray.js new file mode 100644 index 0000000..80a2175 --- /dev/null +++ b/problemset/maximum-product-subarray.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/maximum-product-subarray/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Maximum Product Subarray + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Maximum Subarray + * + * (E) House Robber + * + * (M) Product of Array Except Self + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var maxProduct = function(nums) { + +}; diff --git a/problemset/maximum-subarray.js b/problemset/maximum-subarray.js new file mode 100644 index 0000000..5f96325 --- /dev/null +++ b/problemset/maximum-subarray.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/maximum-subarray/ + * Tags: [Divide and Conquer,Array,Dynamic Programming] + * Level: Medium + * Title: Maximum Subarray + * Auther: @imcoddy + * Content: Find the contiguous subarray within an array (containing at least one number) which has the largest sum. + * + * + * For example, given the array [−2,1,−3,4,−1,2,1,−5,4], + * the contiguous subarray [4,−1,2,1] has the largest sum = 6. + * + * + * click to show more practice. + * + * More practice: + * + * If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Best Time to Buy and Sell Stock + * + * (M) Maximum Product Subarray + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var maxSubArray = function(nums) { + +}; diff --git a/problemset/median-of-two-sorted-arrays.js b/problemset/median-of-two-sorted-arrays.js new file mode 100644 index 0000000..16944d2 --- /dev/null +++ b/problemset/median-of-two-sorted-arrays.js @@ -0,0 +1,20 @@ +/** + * Source: https://leetcode.com/problems/median-of-two-sorted-arrays/ + * Tags: [Divide and Conquer,Array,Binary Search] + * Level: Hard + * Title: Median of Two Sorted Arrays + * Auther: @imcoddy + * Content: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var findMedianSortedArrays = function(nums1, nums2) { + +}; diff --git a/problemset/merge-intervals.js b/problemset/merge-intervals.js new file mode 100644 index 0000000..da03784 --- /dev/null +++ b/problemset/merge-intervals.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/merge-intervals/ + * Tags: [Array,Sort] + * Level: Hard + * Title: Merge Intervals + * Auther: @imcoddy + * Content: 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]. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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) { + +}; diff --git a/problemset/merge-k-sorted-lists.js b/problemset/merge-k-sorted-lists.js new file mode 100644 index 0000000..6ef29b0 --- /dev/null +++ b/problemset/merge-k-sorted-lists.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/merge-k-sorted-lists/ + * Tags: [Divide and Conquer,Linked List,Heap] + * Level: Hard + * Title: Merge k Sorted Lists + * Auther: @imcoddy + * Content: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Merge Two Sorted Lists + * + * (M) Ugly Number II + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode[]} lists + * @return {ListNode} + */ +var mergeKLists = function(lists) { + +}; diff --git a/problemset/merge-sorted-array.js b/problemset/merge-sorted-array.js new file mode 100644 index 0000000..669ebe1 --- /dev/null +++ b/problemset/merge-sorted-array.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/merge-sorted-array/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Merge Sorted Array + * Auther: @imcoddy + * Content: Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + * + * + * Note: + * You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Merge Two Sorted Lists + */ + +/** + * @param {number[]} nums1 + * @param {number} m + * @param {number[]} nums2 + * @param {number} n + * @return {void} Do not return anything, modify nums1 in-place instead. + */ +var merge = function(nums1, m, nums2, n) { + +}; diff --git a/problemset/merge-two-sorted-lists.js b/problemset/merge-two-sorted-lists.js new file mode 100644 index 0000000..0bf1e46 --- /dev/null +++ b/problemset/merge-two-sorted-lists.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/merge-two-sorted-lists/ + * Tags: [Linked List] + * Level: Easy + * Title: Merge Two Sorted Lists + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} l1 + * @param {ListNode} l2 + * @return {ListNode} + */ +var mergeTwoLists = function(l1, l2) { + +}; diff --git a/problemset/min-stack.js b/problemset/min-stack.js new file mode 100644 index 0000000..4fe29c8 --- /dev/null +++ b/problemset/min-stack.js @@ -0,0 +1,78 @@ +/** + * Source: https://leetcode.com/problems/min-stack/ + * Tags: [Stack,Design] + * Level: Easy + * Title: Min Stack + * Auther: @imcoddy + * Content: Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + * + * + * push(x) -- Push element x onto stack. + * + * + * pop() -- Removes the element on top of the stack. + * + * + * top() -- Get the top element. + * + * + * getMin() -- Retrieve the minimum element in the stack. + * + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Sliding Window Maximum + */ + +/** + * @constructor + */ +var MinStack = function() { + +}; + +/** + * @param {number} x + * @returns {void} + */ +MinStack.prototype.push = function(x) { + +}; + +/** + * @returns {void} + */ +MinStack.prototype.pop = function() { + +}; + +/** + * @returns {number} + */ +MinStack.prototype.top = function() { + +}; + +/** + * @returns {number} + */ +MinStack.prototype.getMin = function() { + +}; diff --git a/problemset/minimum-depth-of-binary-tree.js b/problemset/minimum-depth-of-binary-tree.js new file mode 100644 index 0000000..e4404d5 --- /dev/null +++ b/problemset/minimum-depth-of-binary-tree.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/minimum-depth-of-binary-tree/ + * Tags: [Tree,Depth-first Search,Breadth-first Search] + * Level: Easy + * Title: Minimum Depth of Binary Tree + * Auther: @imcoddy + * Content: Given a binary tree, find its minimum depth. + * + * The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Binary Tree Level Order Traversal + * + * (E) Maximum Depth of Binary Tree + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var minDepth = function(root) { + +}; diff --git a/problemset/minimum-path-sum.js b/problemset/minimum-path-sum.js new file mode 100644 index 0000000..cbf7744 --- /dev/null +++ b/problemset/minimum-path-sum.js @@ -0,0 +1,39 @@ +/** + * Source: https://leetcode.com/problems/minimum-path-sum/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Minimum Path Sum + * Auther: @imcoddy + * Content: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. + * + * Note: You can only move either down or right at any point in time. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Unique Paths + * + * (H) Dungeon Game + */ + +/** + * @param {number[][]} grid + * @return {number} + */ +var minPathSum = function(grid) { + +}; diff --git a/problemset/minimum-size-subarray-sum.js b/problemset/minimum-size-subarray-sum.js new file mode 100644 index 0000000..eab0a6b --- /dev/null +++ b/problemset/minimum-size-subarray-sum.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/minimum-size-subarray-sum/ + * Tags: [Array,Two Pointers,Binary Search] + * Level: Medium + * Title: Minimum Size Subarray Sum + * Auther: @imcoddy + * Content: 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. + * + * More practice: + * + * If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n). + * + * + * Credits:Special thanks to @Freezen for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Minimum Window Substring + */ + +/** + * @param {number} s + * @param {number[]} nums + * @return {number} + */ +var minSubArrayLen = function(s, nums) { + +}; diff --git a/problemset/minimum-window-substring.js b/problemset/minimum-window-substring.js new file mode 100644 index 0000000..6f04cec --- /dev/null +++ b/problemset/minimum-window-substring.js @@ -0,0 +1,58 @@ +/** + * Source: https://leetcode.com/problems/minimum-window-substring/ + * Tags: [Hash Table,Two Pointers,String] + * Level: Hard + * Title: Minimum Window Substring + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Substring with Concatenation of All Words + * + * (M) Minimum Size Subarray Sum + * + * (H) Sliding Window Maximum + */ + +/** + * @param {string} s + * @param {string} t + * @return {string} + */ +var minWindow = function(s, t) { + +}; diff --git a/problemset/missing-number.js b/problemset/missing-number.js new file mode 100644 index 0000000..acd61a9 --- /dev/null +++ b/problemset/missing-number.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/missing-number/ + * Tags: [Array,Math,Bit Manipulation] + * Level: Medium + * Title: Missing Number + * Auther: @imcoddy + * Content: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. + * + * + * For example, + * Given nums = [0, 1, 3] return 2. + * + * + * + * Note: + * Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) First Missing Positive + * + * (M) Single Number + * + * (H) Find the Duplicate Number + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var missingNumber = function(nums) { + +}; diff --git a/problemset/move-zeroes.js b/problemset/move-zeroes.js new file mode 100644 index 0000000..de272f1 --- /dev/null +++ b/problemset/move-zeroes.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/move-zeroes/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Move Zeroes + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Remove Element + */ + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ +var moveZeroes = function(nums) { + +}; diff --git a/problemset/multiply-strings.js b/problemset/multiply-strings.js new file mode 100644 index 0000000..bba6678 --- /dev/null +++ b/problemset/multiply-strings.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/multiply-strings/ + * Tags: [Math,String] + * Level: Medium + * Title: Multiply Strings + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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) { + +}; diff --git a/problemset/n-queens-ii.js b/problemset/n-queens-ii.js new file mode 100644 index 0000000..cbff6c9 --- /dev/null +++ b/problemset/n-queens-ii.js @@ -0,0 +1,39 @@ +/** + * Source: https://leetcode.com/problems/n-queens-ii/ + * Tags: [Backtracking] + * Level: Hard + * Title: N-Queens II + * Auther: @imcoddy + * Content: Follow up for N-Queens problem. + * + * Now, instead outputting board configurations, return the total number of distinct solutions. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) N-Queens + */ + +/** + * @param {number} n + * @return {number} + */ +var totalNQueens = function(n) { + +}; diff --git a/problemset/n-queens.js b/problemset/n-queens.js new file mode 100644 index 0000000..5591f88 --- /dev/null +++ b/problemset/n-queens.js @@ -0,0 +1,57 @@ +/** + * Source: https://leetcode.com/problems/n-queens/ + * Tags: [Backtracking] + * Level: Hard + * Title: N-Queens + * Auther: @imcoddy + * Content: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other. + * + * + * + * Given an integer n, return all distinct solutions to the n-queens puzzle. + * + * Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively. + * + * For example, + * There exist two distinct solutions to the 4-queens puzzle: + * + * [ + * [".Q..", // Solution 1 + * "...Q", + * "Q...", + * "..Q."], + * + * ["..Q.", // Solution 2 + * "Q...", + * "...Q", + * ".Q.."] + * ] + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) N-Queens II + */ + +/** + * @param {number} n + * @return {string[][]} + */ +var solveNQueens = function(n) { + +}; diff --git a/problemset/next-permutation.js b/problemset/next-permutation.js new file mode 100644 index 0000000..a453316 --- /dev/null +++ b/problemset/next-permutation.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/next-permutation/ + * Tags: [Array] + * Level: Medium + * Title: Next Permutation + * Auther: @imcoddy + * Content: Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. + * + * + * If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). + * + * + * The replacement must be in-place, do not allocate extra memory. + * + * + * Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column. + * 1,2,3 → 1,3,2 + * 3,2,1 → 1,2,3 + * 1,1,5 → 1,5,1 + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Permutations + * + * (M) Permutations II + * + * (M) Permutation Sequence + * + * (M) Palindrome Permutation II + */ + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ +var nextPermutation = function(nums) { + +}; diff --git a/problemset/nim-game.js b/problemset/nim-game.js new file mode 100644 index 0000000..a315372 --- /dev/null +++ b/problemset/nim-game.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/nim-game/ + * Tags: [] + * Level: Easy + * Title: Nim Game + * Auther: @imcoddy + * Content: You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones. + * + * + * + * Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap. + * + * + * + * For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend. + * + * + * + * If there are 5 stones in the heap, could you figure out a way to remove the stones such that you will always be the winner? + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Flip Game II + */ + +/** + * @param {number} n + * @return {boolean} + */ +var canWinNim = function(n) { + +}; diff --git a/problemset/number-of-1-bits.js b/problemset/number-of-1-bits.js new file mode 100644 index 0000000..f80e1d3 --- /dev/null +++ b/problemset/number-of-1-bits.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/number-of-1-bits/ + * Tags: [Bit Manipulation] + * Level: Easy + * Title: Number of 1 Bits + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Reverse Bits + * + * (E) Power of Two + */ + +/** + * @param {number} n - a positive integer + * @return {number} + */ +var hammingWeight = function(n) { + +}; diff --git a/problemset/number-of-digit-one.js b/problemset/number-of-digit-one.js new file mode 100644 index 0000000..f03d863 --- /dev/null +++ b/problemset/number-of-digit-one.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/number-of-digit-one/ + * Tags: [Math] + * Level: Medium + * Title: Number of Digit One + * Auther: @imcoddy + * Content: Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n. + * + * + * For example: + * Given n = 13, + * Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13. + * + * + * + * Beware of overflow. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Factorial Trailing Zeroes + */ + +/** + * @param {number} n + * @return {number} + */ +var countDigitOne = function(n) { + +}; diff --git a/problemset/number-of-islands.js b/problemset/number-of-islands.js new file mode 100644 index 0000000..89c0192 --- /dev/null +++ b/problemset/number-of-islands.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/number-of-islands/ + * Tags: [Depth-first Search,Breadth-first Search,Union Find] + * Level: Medium + * Title: Number of Islands + * Auther: @imcoddy + * Content: 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: + * 11110110101100000000 + * Answer: 1 + * Example 2: + * 11000110000010000011 + * Answer: 3 + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Surrounded Regions + * + * (M) Walls and Gates + */ + +/** + * @param {character[][]} grid + * @return {number} + */ +var numIslands = function(grid) { + +}; diff --git a/problemset/palindrome-linked-list.js b/problemset/palindrome-linked-list.js new file mode 100644 index 0000000..bb0300c --- /dev/null +++ b/problemset/palindrome-linked-list.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/palindrome-linked-list/ + * Tags: [Linked List,Two Pointers] + * Level: Easy + * Title: Palindrome Linked List + * Auther: @imcoddy + * Content: Given a singly linked list, determine if it is a palindrome. + * + * Follow up: + * Could you do it in O(n) time and O(1) space? + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Palindrome Number + * + * (E) Valid Palindrome + * + * (E) Reverse Linked List + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {boolean} + */ +var isPalindrome = function(head) { + +}; diff --git a/problemset/palindrome-number.js b/problemset/palindrome-number.js new file mode 100644 index 0000000..85e4511 --- /dev/null +++ b/problemset/palindrome-number.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/palindrome-number/ + * Tags: [Math] + * Level: Easy + * Title: Palindrome Number + * Auther: @imcoddy + * Content: Determine whether an integer is a palindrome. Do this without extra space. + * + * click to show spoilers. + * + * Some hints: + * + * Could negative integers be palindromes? (ie, -1) + * + * If you are thinking of converting the integer to string, note the restriction of using extra space. + * + * You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case? + * + * There is a more generic way of solving this problem. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Palindrome Linked List + */ + +/** + * @param {number} x + * @return {boolean} + */ +var isPalindrome = function(x) { + +}; diff --git a/problemset/palindrome-partitioning-ii.js b/problemset/palindrome-partitioning-ii.js new file mode 100644 index 0000000..42d74f9 --- /dev/null +++ b/problemset/palindrome-partitioning-ii.js @@ -0,0 +1,43 @@ +/** + * Source: https://leetcode.com/problems/palindrome-partitioning-ii/ + * Tags: [Dynamic Programming] + * Level: Hard + * Title: Palindrome Partitioning II + * Auther: @imcoddy + * Content: Given a string s, partition s such that every substring of the partition is a palindrome. + * + * + * Return the minimum cuts needed for a palindrome partitioning of s. + * + * + * For example, given s = "aab", + * Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Palindrome Partitioning + */ + +/** + * @param {string} s + * @return {number} + */ +var minCut = function(s) { + +}; diff --git a/problemset/palindrome-partitioning.js b/problemset/palindrome-partitioning.js new file mode 100644 index 0000000..06f6cfa --- /dev/null +++ b/problemset/palindrome-partitioning.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/palindrome-partitioning/ + * Tags: [Backtracking] + * Level: Medium + * Title: Palindrome Partitioning + * Auther: @imcoddy + * Content: Given a string s, partition s such that every substring of the partition is a palindrome. + * + * + * Return all possible palindrome partitioning of s. + * + * + * For example, given s = "aab", + * + * Return + * + * [ + * ["aa","b"], + * ["a","a","b"] + * ] + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Palindrome Partitioning II + */ + +/** + * @param {string} s + * @return {string[][]} + */ +var partition = function(s) { + +}; diff --git a/problemset/partition-list.js b/problemset/partition-list.js new file mode 100644 index 0000000..870fe8a --- /dev/null +++ b/problemset/partition-list.js @@ -0,0 +1,36 @@ +/** + * Source: https://leetcode.com/problems/partition-list/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Partition List + * Auther: @imcoddy + * Content: Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. + * + * + * You should preserve the original relative order of the nodes in each of the two partitions. + * + * + * For example, + * Given 1->4->3->2->5->2 and x = 3, + * return 1->2->2->4->3->5. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} x + * @return {ListNode} + */ +var partition = function(head, x) { + +}; diff --git a/problemset/pascals-triangle-ii.js b/problemset/pascals-triangle-ii.js new file mode 100644 index 0000000..f8bcc5a --- /dev/null +++ b/problemset/pascals-triangle-ii.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/pascals-triangle-ii/ + * Tags: [Array] + * Level: Easy + * Title: Pascal's Triangle II + * Auther: @imcoddy + * Content: Given an index k, return the kth row of the Pascal's triangle. + * + * + * For example, given k = 3, + * Return [1,3,3,1]. + * + * + * + * Note: + * Could you optimize your algorithm to use only O(k) extra space? + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Pascal's Triangle + */ + +/** + * @param {number} rowIndex + * @return {number[]} + */ +var getRow = function(rowIndex) { + +}; diff --git a/problemset/pascals-triangle.js b/problemset/pascals-triangle.js new file mode 100644 index 0000000..73561ae --- /dev/null +++ b/problemset/pascals-triangle.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/pascals-triangle/ + * Tags: [Array] + * Level: Easy + * Title: Pascal's Triangle + * Auther: @imcoddy + * Content: Given numRows, generate the first numRows of Pascal's triangle. + * + * + * For example, given numRows = 5, + * Return + * + * [ + * [1], + * [1,1], + * [1,2,1], + * [1,3,3,1], + * [1,4,6,4,1] + * ] + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Pascal's Triangle II + */ + +/** + * @param {number} numRows + * @return {number[][]} + */ +var generate = function(numRows) { + +}; diff --git a/problemset/path-sum-ii.js b/problemset/path-sum-ii.js new file mode 100644 index 0000000..a03a4b5 --- /dev/null +++ b/problemset/path-sum-ii.js @@ -0,0 +1,68 @@ +/** + * Source: https://leetcode.com/problems/path-sum-ii/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Path Sum II + * Auther: @imcoddy + * Content: Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. + * + * + * For example: + * Given the below binary tree and sum = 22, + * + * 5 + * / \ + * 4 8 + * / / \ + * 11 13 4 + * / \ / \ + * 7 2 5 1 + * + * + * + * return + * + * [ + * [5,4,11,2], + * [5,8,4,5] + * ] + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Path Sum + * + * (E) Binary Tree Paths + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {number} sum + * @return {number[][]} + */ +var pathSum = function(root, sum) { + +}; diff --git a/problemset/path-sum.js b/problemset/path-sum.js new file mode 100644 index 0000000..22a4f80 --- /dev/null +++ b/problemset/path-sum.js @@ -0,0 +1,63 @@ +/** + * Source: https://leetcode.com/problems/path-sum/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Path Sum + * Auther: @imcoddy + * Content: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. + * + * + * For example: + * Given the below binary tree and sum = 22, + * + * 5 + * / \ + * 4 8 + * / / \ + * 11 13 4 + * / \ \ + * 7 2 1 + * + * + * + * return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Path Sum II + * + * (H) Binary Tree Maximum Path Sum + * + * (M) Sum Root to Leaf Numbers + */ + +/** + * 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) { + +}; diff --git a/problemset/peeking-iterator.js b/problemset/peeking-iterator.js new file mode 100644 index 0000000..49623be --- /dev/null +++ b/problemset/peeking-iterator.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/peeking-iterator/ + * Tags: [Design] + * Level: Medium + * Title: Peeking Iterator + * Auther: @imcoddy + * Content: Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the peek() operation -- it essentially peek() at the element that will be returned by the next call to next(). + * + * + * Here is an example. Assume that the iterator is initialized to the beginning of the list: [1, 2, 3]. + * + * Call next() gets you 1, the first element in the list. + * + * Now you call peek() and it returns 2, the next element. Calling next() after that still return 2. + * + * You call next() the final time and it returns 3, the last element. Calling hasNext() after that should return false. + * + * + * Think of "looking ahead". You want to cache the next element. + * Is one variable sufficient? Why or why not? + * Test your design with call order of peek() before next() vs next() before peek(). + * For a clean implementation, check out Google's guava library source code. + * + * + * + * Follow up: How would you extend your design to be generic and work with all types, not just integer? + * + * Credits:Special thanks to @porker2008 for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Binary Search Tree Iterator + * + * (M) Flatten 2D Vector + * + * (M) Zigzag Iterator + */ + + diff --git a/problemset/perfect-squares.js b/problemset/perfect-squares.js new file mode 100644 index 0000000..9848746 --- /dev/null +++ b/problemset/perfect-squares.js @@ -0,0 +1,44 @@ +/** + * Source: https://leetcode.com/problems/perfect-squares/ + * Tags: [Dynamic Programming,Breadth-first Search,Math] + * Level: Medium + * Title: Perfect Squares + * Auther: @imcoddy + * Content: Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n. + * + * + * + * For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Count Primes + * + * (M) Ugly Number II + */ + +/** + * @param {number} n + * @return {number} + */ +var numSquares = function(n) { + +}; diff --git a/problemset/permutation-sequence.js b/problemset/permutation-sequence.js new file mode 100644 index 0000000..59a49cd --- /dev/null +++ b/problemset/permutation-sequence.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/permutation-sequence/ + * Tags: [Backtracking,Math] + * Level: Medium + * Title: Permutation Sequence + * Auther: @imcoddy + * Content: The set [1,2,3,…,n] contains a total of n! unique permutations. + * + * By listing and labeling all of the permutations in order, + * We get the following sequence (ie, for n = 3): + * + * "123" + * "132" + * "213" + * "231" + * "312" + * "321" + * + * + * + * Given n and k, return the kth permutation sequence. + * + * Note: Given n will be between 1 and 9 inclusive. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Next Permutation + * + * (M) Permutations + */ + +/** + * @param {number} n + * @param {number} k + * @return {string} + */ +var getPermutation = function(n, k) { + +}; diff --git a/problemset/permutations-ii.js b/problemset/permutations-ii.js new file mode 100644 index 0000000..2775ea4 --- /dev/null +++ b/problemset/permutations-ii.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/permutations-ii/ + * Tags: [Backtracking] + * Level: Medium + * Title: Permutations II + * Auther: @imcoddy + * Content: 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], and [2,1,1]. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Next Permutation + * + * (M) Permutations + * + * (M) Palindrome Permutation II + */ + +/** + * @param {number[]} nums + * @return {number[][]} + */ +var permuteUnique = function(nums) { + +}; diff --git a/problemset/permutations.js b/problemset/permutations.js new file mode 100644 index 0000000..eaec059 --- /dev/null +++ b/problemset/permutations.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/permutations/ + * Tags: [Backtracking] + * Level: Medium + * Title: Permutations + * Auther: @imcoddy + * Content: Given a collection of numbers, return all possible permutations. + * + * + * + * For example, + * [1,2,3] have the following permutations: + * [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Next Permutation + * + * (M) Permutations II + * + * (M) Permutation Sequence + * + * (M) Combinations + */ + +/** + * @param {number[]} nums + * @return {number[][]} + */ +var permute = function(nums) { + +}; diff --git a/problemset/plus-one.js b/problemset/plus-one.js new file mode 100644 index 0000000..5c03b58 --- /dev/null +++ b/problemset/plus-one.js @@ -0,0 +1,39 @@ +/** + * Source: https://leetcode.com/problems/plus-one/ + * Tags: [Array,Math] + * Level: Easy + * Title: Plus One + * Auther: @imcoddy + * Content: Given a non-negative number represented as an array of digits, plus one to the number. + * + * The digits are stored such that the most significant digit is at the head of the list. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Multiply Strings + * + * (E) Add Binary + */ + +/** + * @param {number[]} digits + * @return {number[]} + */ +var plusOne = function(digits) { + +}; diff --git a/problemset/populating-next-right-pointers-in-each-node-ii.js b/problemset/populating-next-right-pointers-in-each-node-ii.js new file mode 100644 index 0000000..04054ad --- /dev/null +++ b/problemset/populating-next-right-pointers-in-each-node-ii.js @@ -0,0 +1,69 @@ +/** + * Source: https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ + * Tags: [Tree,Depth-first Search] + * Level: Hard + * Title: Populating Next Right Pointers in Each Node II + * Auther: @imcoddy + * Content: 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 + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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) { + +}; diff --git a/problemset/populating-next-right-pointers-in-each-node.js b/problemset/populating-next-right-pointers-in-each-node.js new file mode 100644 index 0000000..597e7e8 --- /dev/null +++ b/problemset/populating-next-right-pointers-in-each-node.js @@ -0,0 +1,87 @@ +/** + * Source: https://leetcode.com/problems/populating-next-right-pointers-in-each-node/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Populating Next Right Pointers in Each Node + * Auther: @imcoddy + * Content: Given a binary tree + * + * struct TreeLinkNode { + * TreeLinkNode *left; + * TreeLinkNode *right; + * TreeLinkNode *next; + * } + * + * + * + * Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. + * + * Initially, all next pointers are set to NULL. + * + * + * Note: + * + * You may only use constant extra space. + * You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). + * + * + * + * + * For example, + * Given the following perfect binary tree, + * + * 1 + * / \ + * 2 3 + * / \ / \ + * 4 5 6 7 + * + * + * + * After calling your function, the tree should look like: + * + * 1 -> NULL + * / \ + * 2 -> 3 -> NULL + * / \ / \ + * 4->5->6->7 -> NULL + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Populating Next Right Pointers in Each Node II + * + * (M) Binary Tree Right Side View + */ + +/** + * 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) { + +}; diff --git a/problemset/power-of-two.js b/problemset/power-of-two.js new file mode 100644 index 0000000..642826b --- /dev/null +++ b/problemset/power-of-two.js @@ -0,0 +1,38 @@ +/** + * Source: https://leetcode.com/problems/power-of-two/ + * Tags: [Math,Bit Manipulation] + * Level: Easy + * Title: Power of Two + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Number of 1 Bits + */ + +/** + * @param {number} n + * @return {boolean} + */ +var isPowerOfTwo = function(n) { + +}; diff --git a/problemset/powx-n.js b/problemset/powx-n.js new file mode 100644 index 0000000..72995d4 --- /dev/null +++ b/problemset/powx-n.js @@ -0,0 +1,37 @@ +/** + * Source: https://leetcode.com/problems/powx-n/ + * Tags: [Math,Binary Search] + * Level: Medium + * Title: Pow(x, n) + * Auther: @imcoddy + * Content: Implement pow(x, n). + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Sqrt(x) + */ + +/** + * @param {number} x + * @param {number} n + * @return {number} + */ +var myPow = function(x, n) { + +}; diff --git a/problemset/product-of-array-except-self.js b/problemset/product-of-array-except-self.js new file mode 100644 index 0000000..13d19d0 --- /dev/null +++ b/problemset/product-of-array-except-self.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/product-of-array-except-self/ + * Tags: [Array] + * Level: Medium + * Title: Product of Array Except Self + * Auther: @imcoddy + * Content: 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.) + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Trapping Rain Water + * + * (M) Maximum Product Subarray + * + * (H) Paint House II + */ + +/** + * @param {number[]} nums + * @return {number[]} + */ +var productExceptSelf = function(nums) { + +}; diff --git a/problemset/recover-binary-search-tree.js b/problemset/recover-binary-search-tree.js new file mode 100644 index 0000000..652138a --- /dev/null +++ b/problemset/recover-binary-search-tree.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/recover-binary-search-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Hard + * Title: Recover Binary Search Tree + * Auther: @imcoddy + * Content: Two elements of a binary search tree (BST) are swapped by mistake. + * + * Recover the tree without changing its structure. + * + * + * Note: + * A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {void} Do not return anything, modify root in-place instead. + */ +var recoverTree = function(root) { + +}; diff --git a/problemset/rectangle-area.js b/problemset/rectangle-area.js new file mode 100644 index 0000000..825ee21 --- /dev/null +++ b/problemset/rectangle-area.js @@ -0,0 +1,35 @@ +/** + * Source: https://leetcode.com/problems/rectangle-area/ + * Tags: [Math] + * Level: Easy + * Title: Rectangle Area + * Auther: @imcoddy + * Content: Find the total area covered by two rectilinear rectangles in a 2D plane. + * Each rectangle is defined by its bottom left corner and top right corner as shown in the figure. + * + * + * + * + * Assume that the total area is never beyond the maximum possible value of int. + * + * + * Credits:Special thanks to @mithmatt for adding this problem, creating the above image and all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number} A + * @param {number} B + * @param {number} C + * @param {number} D + * @param {number} E + * @param {number} F + * @param {number} G + * @param {number} H + * @return {number} + */ +var computeArea = function(A, B, C, D, E, F, G, H) { + +}; diff --git a/problemset/regular-expression-matching.js b/problemset/regular-expression-matching.js new file mode 100644 index 0000000..815a89b --- /dev/null +++ b/problemset/regular-expression-matching.js @@ -0,0 +1,55 @@ +/** + * Source: https://leetcode.com/problems/regular-expression-matching/ + * Tags: [Dynamic Programming,Backtracking,String] + * Level: Hard + * Title: Regular Expression Matching + * Auther: @imcoddy + * Content: 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 + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Wildcard Matching + */ + +/** + * @param {string} s + * @param {string} p + * @return {boolean} + */ +var isMatch = function(s, p) { + +}; diff --git a/problemset/remove-duplicates-from-sorted-array-ii.js b/problemset/remove-duplicates-from-sorted-array-ii.js new file mode 100644 index 0000000..f66ea94 --- /dev/null +++ b/problemset/remove-duplicates-from-sorted-array-ii.js @@ -0,0 +1,28 @@ +/** + * Source: https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/ + * Tags: [Array,Two Pointers] + * Level: Medium + * Title: Remove Duplicates from Sorted Array II + * Auther: @imcoddy + * Content: Follow up for "Remove Duplicates": + * What if duplicates are allowed at most twice? + * + * + * For example, + * Given sorted array nums = [1,1,1,2,2,3], + * + * + * Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var removeDuplicates = function(nums) { + +}; diff --git a/problemset/remove-duplicates-from-sorted-array.js b/problemset/remove-duplicates-from-sorted-array.js new file mode 100644 index 0000000..f5397ec --- /dev/null +++ b/problemset/remove-duplicates-from-sorted-array.js @@ -0,0 +1,31 @@ +/** + * Source: https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Remove Duplicates from Sorted Array + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var removeDuplicates = function(nums) { + +}; diff --git a/problemset/remove-duplicates-from-sorted-list-ii.js b/problemset/remove-duplicates-from-sorted-list-ii.js new file mode 100644 index 0000000..0585558 --- /dev/null +++ b/problemset/remove-duplicates-from-sorted-list-ii.js @@ -0,0 +1,32 @@ +/** + * Source: https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ + * Tags: [Linked List] + * Level: Medium + * Title: Remove Duplicates from Sorted List II + * Auther: @imcoddy + * Content: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. + * + * + * For example, + * Given 1->2->3->3->4->4->5, return 1->2->5. + * Given 1->1->1->2->3, return 2->3. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var deleteDuplicates = function(head) { + +}; diff --git a/problemset/remove-duplicates-from-sorted-list.js b/problemset/remove-duplicates-from-sorted-list.js new file mode 100644 index 0000000..9716be6 --- /dev/null +++ b/problemset/remove-duplicates-from-sorted-list.js @@ -0,0 +1,32 @@ +/** + * Source: https://leetcode.com/problems/remove-duplicates-from-sorted-list/ + * Tags: [Linked List] + * Level: Easy + * Title: Remove Duplicates from Sorted List + * Auther: @imcoddy + * Content: Given a sorted linked list, delete all duplicates such that each element appear only once. + * + * + * For example, + * Given 1->1->2, return 1->2. + * Given 1->1->2->3->3, return 1->2->3. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var deleteDuplicates = function(head) { + +}; diff --git a/problemset/remove-element.js b/problemset/remove-element.js new file mode 100644 index 0000000..ec4871b --- /dev/null +++ b/problemset/remove-element.js @@ -0,0 +1,43 @@ +/** + * Source: https://leetcode.com/problems/remove-element/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Remove Element + * Auther: @imcoddy + * Content: Given an array and a value, remove all instances of that value in place and return the new length. + * + * + * + * The order of elements can be changed. It doesn't matter what you leave beyond the new length. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Remove Linked List Elements + * + * (E) Move Zeroes + */ + +/** + * @param {number[]} nums + * @param {number} val + * @return {number} + */ +var removeElement = function(nums, val) { + +}; diff --git a/problemset/remove-invalid-parentheses.js b/problemset/remove-invalid-parentheses.js new file mode 100644 index 0000000..a36915e --- /dev/null +++ b/problemset/remove-invalid-parentheses.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/remove-invalid-parentheses/ + * Tags: [Depth-first Search,Breadth-first Search] + * Level: Medium + * Title: Remove Invalid Parentheses + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Valid Parentheses + */ + +/** + * @param {string} s + * @return {string[]} + */ +var removeInvalidParentheses = function(s) { + +}; diff --git a/problemset/remove-linked-list-elements.js b/problemset/remove-linked-list-elements.js new file mode 100644 index 0000000..16a46d6 --- /dev/null +++ b/problemset/remove-linked-list-elements.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/remove-linked-list-elements/ + * Tags: [Linked List] + * Level: Easy + * Title: Remove Linked List Elements + * Auther: @imcoddy + * Content: Remove all elements from a linked list of integers that have value val. + * + * Example + * Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 + * Return: 1 --> 2 --> 3 --> 4 --> 5 + * + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Remove Element + * + * (E) Delete Node in a Linked List + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} val + * @return {ListNode} + */ +var removeElements = function(head, val) { + +}; diff --git a/problemset/remove-nth-node-from-end-of-list.js b/problemset/remove-nth-node-from-end-of-list.js new file mode 100644 index 0000000..5f1adf4 --- /dev/null +++ b/problemset/remove-nth-node-from-end-of-list.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/remove-nth-node-from-end-of-list/ + * Tags: [Linked List,Two Pointers] + * Level: Easy + * Title: Remove Nth Node From End of List + * Auther: @imcoddy + * Content: Given a linked list, remove the nth node from the end of list and return its head. + * + * + * For example, + * + * + * Given linked list: 1->2->3->4->5, and n = 2. + * + * After removing the second node from the end, the linked list becomes 1->2->3->5. + * + * + * + * Note: + * Given n will always be valid. + * Try to do this in one pass. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} n + * @return {ListNode} + */ +var removeNthFromEnd = function(head, n) { + +}; diff --git a/problemset/reorder-list.js b/problemset/reorder-list.js new file mode 100644 index 0000000..35664a8 --- /dev/null +++ b/problemset/reorder-list.js @@ -0,0 +1,35 @@ +/** + * Source: https://leetcode.com/problems/reorder-list/ + * Tags: [Linked List] + * Level: Medium + * Title: Reorder List + * Auther: @imcoddy + * Content: Given a singly linked list L: L0→L1→…→Ln-1→Ln, + * reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… + * + * + * You must do this in-place without altering the nodes' values. + * + * + * For example, + * Given {1,2,3,4}, reorder it to {1,4,2,3}. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {void} Do not return anything, modify head in-place instead. + */ +var reorderList = function(head) { + +}; diff --git a/problemset/repeated-dna-sequences.js b/problemset/repeated-dna-sequences.js new file mode 100644 index 0000000..2f79ec3 --- /dev/null +++ b/problemset/repeated-dna-sequences.js @@ -0,0 +1,30 @@ +/** + * Source: https://leetcode.com/problems/repeated-dna-sequences/ + * Tags: [Hash Table,Bit Manipulation] + * Level: Medium + * Title: Repeated DNA Sequences + * Auther: @imcoddy + * Content: 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"]. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s + * @return {string[]} + */ +var findRepeatedDnaSequences = function(s) { + +}; diff --git a/problemset/restore-ip-addresses.js b/problemset/restore-ip-addresses.js new file mode 100644 index 0000000..35f2d7a --- /dev/null +++ b/problemset/restore-ip-addresses.js @@ -0,0 +1,27 @@ +/** + * Source: https://leetcode.com/problems/restore-ip-addresses/ + * Tags: [Backtracking,String] + * Level: Medium + * Title: Restore IP Addresses + * Auther: @imcoddy + * Content: Given a string containing only digits, restore it by returning all possible valid IP address combinations. + * + * + * For example: + * Given "25525511135", + * + * + * return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s + * @return {string[]} + */ +var restoreIpAddresses = function(s) { + +}; diff --git a/problemset/reverse-bits.js b/problemset/reverse-bits.js new file mode 100644 index 0000000..e3ab54d --- /dev/null +++ b/problemset/reverse-bits.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/reverse-bits/ + * Tags: [Bit Manipulation] + * Level: Easy + * Title: Reverse Bits + * Auther: @imcoddy + * Content: Reverse bits of a given 32 bits unsigned integer. + * + * For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000). + * + * + * Follow up: + * If this function is called many times, how would you optimize it? + * + * + * Related problem: Reverse Integer + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Number of 1 Bits + */ + +/** + * @param {number} n - a positive integer + * @return {number} - a positive integer + */ +var reverseBits = function(n) { + +}; diff --git a/problemset/reverse-integer.js b/problemset/reverse-integer.js new file mode 100644 index 0000000..b532843 --- /dev/null +++ b/problemset/reverse-integer.js @@ -0,0 +1,58 @@ +/** + * Source: https://leetcode.com/problems/reverse-integer/ + * Tags: [Math] + * Level: Easy + * Title: Reverse Integer + * Auther: @imcoddy + * Content: Reverse digits of an integer. + * + * + * Example1: x = 123, return 321 + * Example2: x = -123, return -321 + * + * + * click to show spoilers. + * + * Have you thought about this? + * + * Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! + * + * If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. + * + * Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases? + * + * For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. + * + * + * Update (2014-11-10): + * Test cases had been added to test the overflow behavior. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) String to Integer (atoi) + */ + +/** + * @param {number} x + * @return {number} + */ +var reverse = function(x) { + +}; diff --git a/problemset/reverse-linked-list-ii.js b/problemset/reverse-linked-list-ii.js new file mode 100644 index 0000000..27810f3 --- /dev/null +++ b/problemset/reverse-linked-list-ii.js @@ -0,0 +1,58 @@ +/** + * Source: https://leetcode.com/problems/reverse-linked-list-ii/ + * Tags: [Linked List] + * Level: Medium + * Title: Reverse Linked List II + * Auther: @imcoddy + * Content: Reverse a linked list from position m to n. Do it in-place and in one-pass. + * + * + * + * For example: + * Given 1->2->3->4->5->NULL, m = 2 and n = 4, + * + * + * return 1->4->3->2->5->NULL. + * + * + * Note: + * Given m, n satisfy the following condition: + * 1 ≤ m ≤ n ≤ length of list. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Reverse Linked List + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} m + * @param {number} n + * @return {ListNode} + */ +var reverseBetween = function(head, m, n) { + +}; diff --git a/problemset/reverse-linked-list.js b/problemset/reverse-linked-list.js new file mode 100644 index 0000000..f084e4a --- /dev/null +++ b/problemset/reverse-linked-list.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/reverse-linked-list/ + * Tags: [Linked List] + * Level: Easy + * Title: Reverse Linked List + * Auther: @imcoddy + * Content: Reverse a singly linked list. + * + * click to show more hints. + * + * Hint: + * A linked list can be reversed either iteratively or recursively. Could you implement both? + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Reverse Linked List II + * + * (M) Binary Tree Upside Down + * + * (E) Palindrome Linked List + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var reverseList = function(head) { + +}; diff --git a/problemset/reverse-nodes-in-k-group.js b/problemset/reverse-nodes-in-k-group.js new file mode 100644 index 0000000..b35c9df --- /dev/null +++ b/problemset/reverse-nodes-in-k-group.js @@ -0,0 +1,64 @@ +/** + * Source: https://leetcode.com/problems/reverse-nodes-in-k-group/ + * Tags: [Linked List] + * Level: Hard + * Title: Reverse Nodes in k-Group + * Auther: @imcoddy + * Content: 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 + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Swap Nodes in Pairs + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} k + * @return {ListNode} + */ +var reverseKGroup = function(head, k) { + +}; diff --git a/problemset/reverse-words-in-a-string.js b/problemset/reverse-words-in-a-string.js new file mode 100644 index 0000000..01f6460 --- /dev/null +++ b/problemset/reverse-words-in-a-string.js @@ -0,0 +1,63 @@ +/** + * Source: https://leetcode.com/problems/reverse-words-in-a-string/ + * Tags: [String] + * Level: Medium + * Title: Reverse Words in a String + * Auther: @imcoddy + * Content: Given an input string, reverse the string word by word. + * + * + * + * For example, + * Given s = "the sky is blue", + * return "blue is sky the". + * + * + * + * Update (2015-02-12): + * For C programmers: Try to solve it in-place in O(1) space. + * + * + * click to show clarification. + * + * Clarification: + * + * + * + * What constitutes a word? + * A sequence of non-space characters constitutes a word. + * Could the input string contain leading or trailing spaces? + * Yes. However, your reversed string should not contain leading or trailing spaces. + * How about multiple spaces between two words? + * Reduce them to a single space in the reversed string. + * + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Reverse Words in a String II + */ + +/** + * @param {string} str + * @returns {string} + */ +var reverseWords = function(str) { + +}; diff --git a/problemset/roman-to-integer.js b/problemset/roman-to-integer.js new file mode 100644 index 0000000..ea0f94e --- /dev/null +++ b/problemset/roman-to-integer.js @@ -0,0 +1,37 @@ +/** + * Source: https://leetcode.com/problems/roman-to-integer/ + * Tags: [Math,String] + * Level: Easy + * Title: Roman to Integer + * Auther: @imcoddy + * Content: Given a roman numeral, convert it to an integer. + * + * Input is guaranteed to be within the range from 1 to 3999. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Integer to Roman + */ + +/** + * @param {string} s + * @return {number} + */ +var romanToInt = function(s) { + +}; diff --git a/problemset/rotate-array.js b/problemset/rotate-array.js new file mode 100644 index 0000000..6a8c6db --- /dev/null +++ b/problemset/rotate-array.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/rotate-array/ + * Tags: [Array] + * Level: Easy + * Title: Rotate Array + * Auther: @imcoddy + * Content: Rotate an array of n elements to the right by k steps. + * For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + * + * Note: + * Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + * + * + * [show hint] + * Hint: + * Could you do it in-place with O(1) extra space? + * + * + * Related problem: Reverse Words in a String II + * + * Credits:Special thanks to @Freezen for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Rotate List + * + * (M) Reverse Words in a String II + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {void} Do not return anything, modify nums in-place instead. + */ +var rotate = function(nums, k) { + +}; diff --git a/problemset/rotate-image.js b/problemset/rotate-image.js new file mode 100644 index 0000000..c53ac4b --- /dev/null +++ b/problemset/rotate-image.js @@ -0,0 +1,22 @@ +/** + * Source: https://leetcode.com/problems/rotate-image/ + * Tags: [Array] + * Level: Medium + * Title: Rotate Image + * Auther: @imcoddy + * Content: 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? + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[][]} matrix + * @return {void} Do not return anything, modify matrix in-place instead. + */ +var rotate = function(matrix) { + +}; diff --git a/problemset/rotate-list.js b/problemset/rotate-list.js new file mode 100644 index 0000000..ec0dfb8 --- /dev/null +++ b/problemset/rotate-list.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/rotate-list/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Rotate List + * Auther: @imcoddy + * Content: Given a list, rotate the list to the right by k places, where k is non-negative. + * + * For example: + * Given 1->2->3->4->5->NULL and k = 2, + * return 4->5->1->2->3->NULL. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Rotate Array + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} k + * @return {ListNode} + */ +var rotateRight = function(head, k) { + +}; diff --git a/problemset/same-tree.js b/problemset/same-tree.js new file mode 100644 index 0000000..eb3f315 --- /dev/null +++ b/problemset/same-tree.js @@ -0,0 +1,31 @@ +/** + * Source: https://leetcode.com/problems/same-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Same Tree + * Auther: @imcoddy + * Content: Given two binary trees, write a function to check if they are equal or not. + * + * + * Two binary trees are considered equal if they are structurally identical and the nodes have the same value. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} p + * @param {TreeNode} q + * @return {boolean} + */ +var isSameTree = function(p, q) { + +}; diff --git a/problemset/scramble-string.js b/problemset/scramble-string.js new file mode 100644 index 0000000..1e6ccd7 --- /dev/null +++ b/problemset/scramble-string.js @@ -0,0 +1,69 @@ +/** + * Source: https://leetcode.com/problems/scramble-string/ + * Tags: [Dynamic Programming,String] + * Level: Hard + * Title: Scramble String + * Auther: @imcoddy + * Content: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively. + * + * + * Below is one possible representation of s1 = "great": + * + * + * great + * / \ + * gr eat + * / \ / \ + * g r e at + * / \ + * a t + * + * + * To scramble the string, we may choose any non-leaf node and swap its two children. + * + * + * For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat". + * + * + * rgeat + * / \ + * rg eat + * / \ / \ + * r g e at + * / \ + * a t + * + * + * We say that "rgeat" is a scrambled string of "great". + * + * + * Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae". + * + * + * rgtae + * / \ + * rg tae + * / \ / \ + * r g ta e + * / \ + * t a + * + * + * We say that "rgtae" is a scrambled string of "great". + * + * + * Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s1 + * @param {string} s2 + * @return {boolean} + */ +var isScramble = function(s1, s2) { + +}; diff --git a/problemset/search-a-2d-matrix-ii.js b/problemset/search-a-2d-matrix-ii.js new file mode 100644 index 0000000..ee17bcc --- /dev/null +++ b/problemset/search-a-2d-matrix-ii.js @@ -0,0 +1,61 @@ +/** + * Source: https://leetcode.com/problems/search-a-2d-matrix-ii/ + * Tags: [Divide and Conquer,Binary Search] + * Level: Medium + * Title: Search a 2D Matrix II + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Search a 2D Matrix + */ + +/** + * @param {number[][]} matrix + * @param {number} target + * @return {boolean} + */ +var searchMatrix = function(matrix, target) { + +}; diff --git a/problemset/search-a-2d-matrix.js b/problemset/search-a-2d-matrix.js new file mode 100644 index 0000000..8e706c4 --- /dev/null +++ b/problemset/search-a-2d-matrix.js @@ -0,0 +1,58 @@ +/** + * Source: https://leetcode.com/problems/search-a-2d-matrix/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Search a 2D Matrix + * Auther: @imcoddy + * Content: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: + * + * + * + * Integers in each row are sorted from left to right. + * The first integer of each row is greater than the last integer of the previous row. + * + * + * + * + * For example, + * + * Consider the following matrix: + * + * + * [ + * [1, 3, 5, 7], + * [10, 11, 16, 20], + * [23, 30, 34, 50] + * ] + * + * + * Given target = 3, return true. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Search a 2D Matrix II + */ + +/** + * @param {number[][]} matrix + * @param {number} target + * @return {boolean} + */ +var searchMatrix = function(matrix, target) { + +}; diff --git a/problemset/search-for-a-range.js b/problemset/search-for-a-range.js new file mode 100644 index 0000000..d01897a --- /dev/null +++ b/problemset/search-for-a-range.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/search-for-a-range/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Search for a Range + * Auther: @imcoddy + * Content: Given a sorted array of integers, find the starting and ending position of a given target value. + * + * Your algorithm's runtime complexity must be in the order of O(log n). + * + * If the target is not found in the array, return [-1, -1]. + * + * + * For example, + * Given [5, 7, 7, 8, 8, 10] and target value 8, + * return [3, 4]. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) First Bad Version + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number[]} + */ +var searchRange = function(nums, target) { + +}; diff --git a/problemset/search-in-rotated-sorted-array-ii.js b/problemset/search-in-rotated-sorted-array-ii.js new file mode 100644 index 0000000..6e21f54 --- /dev/null +++ b/problemset/search-in-rotated-sorted-array-ii.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/search-in-rotated-sorted-array-ii/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Search in Rotated Sorted Array II + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Search in Rotated Sorted Array + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {boolean} + */ +var search = function(nums, target) { + +}; diff --git a/problemset/search-in-rotated-sorted-array.js b/problemset/search-in-rotated-sorted-array.js new file mode 100644 index 0000000..b355de2 --- /dev/null +++ b/problemset/search-in-rotated-sorted-array.js @@ -0,0 +1,44 @@ +/** + * Source: https://leetcode.com/problems/search-in-rotated-sorted-array/ + * Tags: [Array,Binary Search] + * Level: Hard + * Title: Search in Rotated Sorted Array + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Search in Rotated Sorted Array II + * + * (M) Find Minimum in Rotated Sorted Array + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var search = function(nums, target) { + +}; diff --git a/problemset/search-insert-position.js b/problemset/search-insert-position.js new file mode 100644 index 0000000..6dfb4e8 --- /dev/null +++ b/problemset/search-insert-position.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/search-insert-position/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Search Insert Position + * Auther: @imcoddy + * Content: Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. + * + * You may assume no duplicates in the array. + * + * + * Here are few examples. + * [1,3,5,6], 5 → 2 + * [1,3,5,6], 2 → 1 + * [1,3,5,6], 7 → 4 + * [1,3,5,6], 0 → 0 + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) First Bad Version + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var searchInsert = function(nums, target) { + +}; diff --git a/problemset/serialize-and-deserialize-binary-tree.js b/problemset/serialize-and-deserialize-binary-tree.js new file mode 100644 index 0000000..04794fc --- /dev/null +++ b/problemset/serialize-and-deserialize-binary-tree.js @@ -0,0 +1,80 @@ +/** + * Source: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ + * Tags: [Tree,Design] + * Level: Medium + * Title: Serialize and Deserialize Binary Tree + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Encode and Decode Strings + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * Encodes a tree to a single string. + * + * @param {TreeNode} root + * @return {string} + */ +var serialize = function(root) { + +}; + +/** + * Decodes your encoded data to tree. + * + * @param {string} data + * @return {TreeNode} + */ +var deserialize = function(data) { + +}; + +/** + * Your functions will be called as such: + * deserialize(serialize(root)); + */ diff --git a/problemset/set-matrix-zeroes.js b/problemset/set-matrix-zeroes.js new file mode 100644 index 0000000..ca0b345 --- /dev/null +++ b/problemset/set-matrix-zeroes.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/set-matrix-zeroes/ + * Tags: [Array] + * Level: Medium + * Title: Set Matrix Zeroes + * Auther: @imcoddy + * Content: Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. + * + * + * click to show follow up. + * + * Follow up: + * + * + * Did you use extra space? + * A straight forward solution using O(mn) space is probably a bad idea. + * A simple improvement uses O(m + n) space, but still not the best solution. + * Could you devise a constant space solution? + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Game of Life + */ + +/** + * @param {number[][]} matrix + * @return {void} Do not return anything, modify matrix in-place instead. + */ +var setZeroes = function(matrix) { + +}; diff --git a/problemset/shortest-palindrome.js b/problemset/shortest-palindrome.js new file mode 100644 index 0000000..fa6e939 --- /dev/null +++ b/problemset/shortest-palindrome.js @@ -0,0 +1,44 @@ +/** + * Source: https://leetcode.com/problems/shortest-palindrome/ + * Tags: [String] + * Level: Hard + * Title: Shortest Palindrome + * Auther: @imcoddy + * Content: Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation. + * + * + * For example: + * Given "aacecaaa", return "aaacecaaa". + * Given "abcd", return "dcbabcd". + * + * Credits:Special thanks to @ifanchu for adding this problem and creating all test cases. Thanks to @Freezen for additional test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Longest Palindromic Substring + * + * (E) Implement strStr() + */ + +/** + * @param {string} s + * @return {string} + */ +var shortestPalindrome = function(s) { + +}; diff --git a/problemset/simplify-path.js b/problemset/simplify-path.js new file mode 100644 index 0000000..edb86fe --- /dev/null +++ b/problemset/simplify-path.js @@ -0,0 +1,37 @@ +/** + * Source: https://leetcode.com/problems/simplify-path/ + * Tags: [Stack,String] + * Level: Medium + * Title: Simplify Path + * Auther: @imcoddy + * Content: Given an absolute path for a file (Unix-style), simplify it. + * + * For example, + * path = "/home/", => "/home" + * path = "/a/./b/../../c/", => "/c" + * + * + * click to show corner cases. + * + * Corner Cases: + * + * + * + * Did you consider the case where path = "/../"? + * In this case, you should return "/". + * Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". + * In this case, you should ignore redundant slashes and return "/home/foo". + * + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} path + * @return {string} + */ +var simplifyPath = function(path) { + +}; diff --git a/problemset/single-number-ii.js b/problemset/single-number-ii.js new file mode 100644 index 0000000..69221ed --- /dev/null +++ b/problemset/single-number-ii.js @@ -0,0 +1,43 @@ +/** + * Source: https://leetcode.com/problems/single-number-ii/ + * Tags: [Bit Manipulation] + * Level: Medium + * Title: Single Number II + * Auther: @imcoddy + * Content: Given an array of integers, every element appears three times except for one. Find that single one. + * + * + * + * Note: + * Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Single Number + * + * (M) Single Number III + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var singleNumber = function(nums) { + +}; diff --git a/problemset/single-number-iii.js b/problemset/single-number-iii.js new file mode 100644 index 0000000..14d0312 --- /dev/null +++ b/problemset/single-number-iii.js @@ -0,0 +1,53 @@ +/** + * Source: https://leetcode.com/problems/single-number-iii/ + * Tags: [Bit Manipulation] + * Level: Medium + * Title: Single Number III + * Auther: @imcoddy + * Content: Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once. + * + * + * For example: + * + * + * Given nums = [1, 2, 1, 3, 2, 5], return [3, 5]. + * + * + * Note: + * + * The order of the result is not important. So in the above example, [5, 3] is also correct. + * Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity? + * + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Single Number + * + * (M) Single Number II + */ + +/** + * @param {number[]} nums + * @return {number[]} + */ +var singleNumber = function(nums) { + +}; diff --git a/problemset/single-number.js b/problemset/single-number.js new file mode 100644 index 0000000..d7a405d --- /dev/null +++ b/problemset/single-number.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/single-number/ + * Tags: [Hash Table,Bit Manipulation] + * Level: Medium + * Title: Single Number + * Auther: @imcoddy + * Content: Given an array of integers, every element appears twice except for one. Find that single one. + * + * + * Note: + * Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Single Number II + * + * (M) Single Number III + * + * (M) Missing Number + * + * (H) Find the Duplicate Number + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var singleNumber = function(nums) { + +}; diff --git a/problemset/sliding-window-maximum.js b/problemset/sliding-window-maximum.js new file mode 100644 index 0000000..130b87e --- /dev/null +++ b/problemset/sliding-window-maximum.js @@ -0,0 +1,70 @@ +/** + * Source: https://leetcode.com/problems/sliding-window-maximum/ + * Tags: [Heap] + * Level: Hard + * Title: Sliding Window Maximum + * Auther: @imcoddy + * Content: 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]. + * + * Note: + * You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array. + * + * Follow up: + * Could you solve it in linear time? + * + * + * How about using a data structure such as deque (double-ended queue)? + * The queue size need not be the same as the window’s size. + * Remove redundant elements and the queue should store only elements that need to be considered. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Minimum Window Substring + * + * (E) Min Stack + * + * (H) Longest Substring with At Most Two Distinct Characters + * + * (H) Paint House II + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number[]} + */ +var maxSlidingWindow = function(nums, k) { + +}; diff --git a/problemset/sort-colors.js b/problemset/sort-colors.js new file mode 100644 index 0000000..6a40726 --- /dev/null +++ b/problemset/sort-colors.js @@ -0,0 +1,57 @@ +/** + * Source: https://leetcode.com/problems/sort-colors/ + * Tags: [Array,Two Pointers,Sort] + * Level: Medium + * Title: Sort Colors + * Auther: @imcoddy + * Content: 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. + * + * + * Follow up: + * A rather straight forward solution is a two-pass algorithm using counting sort. + * First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. + * Could you come up with an one-pass algorithm using only constant space? + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Sort List + * + * (M) Wiggle Sort + */ + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ +var sortColors = function(nums) { + +}; diff --git a/problemset/sort-list.js b/problemset/sort-list.js new file mode 100644 index 0000000..3a82e91 --- /dev/null +++ b/problemset/sort-list.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/sort-list/ + * Tags: [Linked List,Sort] + * Level: Medium + * Title: Sort List + * Auther: @imcoddy + * Content: Sort a linked list in O(n log n) time using constant space complexity. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Merge Two Sorted Lists + * + * (M) Sort Colors + * + * (M) Insertion Sort List + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var sortList = function(head) { + +}; diff --git a/problemset/spiral-matrix-ii.js b/problemset/spiral-matrix-ii.js new file mode 100644 index 0000000..4e478f6 --- /dev/null +++ b/problemset/spiral-matrix-ii.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/spiral-matrix-ii/ + * Tags: [Array] + * Level: Medium + * Title: Spiral Matrix II + * Auther: @imcoddy + * Content: 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 ] + * ] + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Spiral Matrix + */ + +/** + * @param {number} n + * @return {number[][]} + */ +var generateMatrix = function(n) { + +}; diff --git a/problemset/spiral-matrix.js b/problemset/spiral-matrix.js new file mode 100644 index 0000000..309f76c --- /dev/null +++ b/problemset/spiral-matrix.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/spiral-matrix/ + * Tags: [Array] + * Level: Medium + * Title: Spiral Matrix + * Auther: @imcoddy + * Content: 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]. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Spiral Matrix II + */ + +/** + * @param {number[][]} matrix + * @return {number[]} + */ +var spiralOrder = function(matrix) { + +}; diff --git a/problemset/sqrtx.js b/problemset/sqrtx.js new file mode 100644 index 0000000..0f67f10 --- /dev/null +++ b/problemset/sqrtx.js @@ -0,0 +1,37 @@ +/** + * Source: https://leetcode.com/problems/sqrtx/ + * Tags: [Math,Binary Search] + * Level: Medium + * Title: Sqrt(x) + * Auther: @imcoddy + * Content: Implement int sqrt(int x). + * + * Compute and return the square root of x. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Pow(x, n) + */ + +/** + * @param {number} x + * @return {number} + */ +var mySqrt = function(x) { + +}; diff --git a/problemset/string-to-integer-atoi.js b/problemset/string-to-integer-atoi.js new file mode 100644 index 0000000..c86bd2d --- /dev/null +++ b/problemset/string-to-integer-atoi.js @@ -0,0 +1,62 @@ +/** + * Source: https://leetcode.com/problems/string-to-integer-atoi/ + * Tags: [Math,String] + * Level: Easy + * Title: String to Integer (atoi) + * Auther: @imcoddy + * Content: 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. + * + * + * Update (2015-02-10): + * The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition. + * + * + * spoilers alert... click to show requirements for atoi. + * + * Requirements for atoi: + * + * The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. + * + * The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. + * + * If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. + * + * If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned. + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Reverse Integer + * + * (H) Valid Number + */ + +/** + * @param {string} str + * @return {number} + */ +var myAtoi = function(str) { + +}; diff --git a/problemset/subsets-ii.js b/problemset/subsets-ii.js new file mode 100644 index 0000000..cbe34bb --- /dev/null +++ b/problemset/subsets-ii.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/subsets-ii/ + * Tags: [Array,Backtracking] + * Level: Medium + * Title: Subsets II + * Auther: @imcoddy + * Content: Given a collection of integers that might contain duplicates, nums, return all possible subsets. + * + * Note: + * + * Elements in a subset must be in non-descending order. + * The solution set must not contain duplicate subsets. + * + * + * + * For example, + * If nums = [1,2,2], a solution is: + * + * + * + * [ + * [2], + * [1], + * [1,2,2], + * [2,2], + * [1,2], + * [] + * ] + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number[][]} + */ +var subsetsWithDup = function(nums) { + +}; diff --git a/problemset/subsets.js b/problemset/subsets.js new file mode 100644 index 0000000..1ebe4d4 --- /dev/null +++ b/problemset/subsets.js @@ -0,0 +1,43 @@ +/** + * Source: https://leetcode.com/problems/subsets/ + * Tags: [Array,Backtracking,Bit Manipulation] + * Level: Medium + * Title: Subsets + * Auther: @imcoddy + * Content: Given a set of distinct integers, nums, return all possible subsets. + * + * Note: + * + * Elements in a subset must be in non-descending order. + * 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], + * [] + * ] + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[]} nums + * @return {number[][]} + */ +var subsets = function(nums) { + +}; diff --git a/problemset/substring-with-concatenation-of-all-words.js b/problemset/substring-with-concatenation-of-all-words.js new file mode 100644 index 0000000..fdde833 --- /dev/null +++ b/problemset/substring-with-concatenation-of-all-words.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/substring-with-concatenation-of-all-words/ + * Tags: [Hash Table,Two Pointers,String] + * Level: Hard + * Title: Substring with Concatenation of All Words + * Auther: @imcoddy + * Content: You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters. + * + * + * + * For example, given: + * s: "barfoothefoobarman" + * words: ["foo", "bar"] + * + * + * + * You should return the indices: [0,9]. + * (order does not matter). + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Minimum Window Substring + */ + +/** + * @param {string} s + * @param {string[]} words + * @return {number[]} + */ +var findSubstring = function(s, words) { + +}; diff --git a/problemset/sudoku-solver.js b/problemset/sudoku-solver.js new file mode 100644 index 0000000..3ffaeaa --- /dev/null +++ b/problemset/sudoku-solver.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/sudoku-solver/ + * Tags: [Backtracking,Hash Table] + * Level: Hard + * Title: Sudoku Solver + * Auther: @imcoddy + * Content: Write a program to solve a Sudoku puzzle by filling the empty cells. + * + * Empty cells are indicated by the character '.'. + * + * You may assume that there will be only one unique solution. + * + * + * + * A sudoku puzzle... + * + * + * + * + * ...and its solution numbers marked in red. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Valid Sudoku + */ + +/** + * @param {character[][]} board + * @return {void} Do not return anything, modify board in-place instead. + */ +var solveSudoku = function(board) { + +}; diff --git a/problemset/sum-root-to-leaf-numbers.js b/problemset/sum-root-to-leaf-numbers.js new file mode 100644 index 0000000..f4a8a1f --- /dev/null +++ b/problemset/sum-root-to-leaf-numbers.js @@ -0,0 +1,62 @@ +/** + * Source: https://leetcode.com/problems/sum-root-to-leaf-numbers/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Sum Root to Leaf Numbers + * Auther: @imcoddy + * Content: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. + * An example is the root-to-leaf path 1->2->3 which represents the number 123. + * + * Find the total sum of all root-to-leaf numbers. + * + * For example, + * + * 1 + * / \ + * 2 3 + * + * + * + * The root-to-leaf path 1->2 represents the number 12. + * The root-to-leaf path 1->3 represents the number 13. + * + * + * Return the sum = 12 + 13 = 25. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Path Sum + * + * (H) Binary Tree Maximum Path Sum + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var sumNumbers = function(root) { + +}; diff --git a/problemset/summary-ranges.js b/problemset/summary-ranges.js new file mode 100644 index 0000000..2470ffb --- /dev/null +++ b/problemset/summary-ranges.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/summary-ranges/ + * Tags: [Array] + * Level: Easy + * Title: Summary Ranges + * Auther: @imcoddy + * Content: Given a sorted integer array without duplicates, return the summary of its ranges. + * + * + * For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"]. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Missing Ranges + */ + +/** + * @param {number[]} nums + * @return {string[]} + */ +var summaryRanges = function(nums) { + +}; diff --git a/problemset/surrounded-regions.js b/problemset/surrounded-regions.js new file mode 100644 index 0000000..bf035cc --- /dev/null +++ b/problemset/surrounded-regions.js @@ -0,0 +1,60 @@ +/** + * Source: https://leetcode.com/problems/surrounded-regions/ + * Tags: [Breadth-first Search,Union Find] + * Level: Medium + * Title: Surrounded Regions + * Auther: @imcoddy + * Content: Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. + * + * A region is captured by flipping all 'O's into 'X's in that surrounded region. + * + * + * + * For example, + * + * X X X X + * X O O X + * X X O X + * X O X X + * + * + * + * + * After running your function, the board should be: + * + * X X X X + * X X X X + * X X X X + * X O X X + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Number of Islands + * + * (M) Walls and Gates + */ + +/** + * @param {character[][]} board + * @return {void} Do not return anything, modify board in-place instead. + */ +var solve = function(board) { + +}; diff --git a/problemset/swap-nodes-in-pairs.js b/problemset/swap-nodes-in-pairs.js new file mode 100644 index 0000000..64266b8 --- /dev/null +++ b/problemset/swap-nodes-in-pairs.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/swap-nodes-in-pairs/ + * Tags: [Linked List] + * Level: Medium + * Title: Swap Nodes in Pairs + * Auther: @imcoddy + * Content: Given a linked list, swap every two adjacent nodes and return its head. + * + * + * + * For example, + * Given 1->2->3->4, you should return the list as 2->1->4->3. + * + * + * + * Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Reverse Nodes in k-Group + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var swapPairs = function(head) { + +}; diff --git a/problemset/symmetric-tree.js b/problemset/symmetric-tree.js new file mode 100644 index 0000000..de62883 --- /dev/null +++ b/problemset/symmetric-tree.js @@ -0,0 +1,73 @@ +/** + * Source: https://leetcode.com/problems/symmetric-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Symmetric Tree + * Auther: @imcoddy + * Content: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + * + * + * For example, this binary tree is symmetric: + * + * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + * + * + * + * But the following is not: + * + * 1 + * / \ + * 2 2 + * \ \ + * 3 3 + * + * + * + * + * Note: + * Bonus points if you could solve it both recursively and iteratively. + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {boolean} + */ +var isSymmetric = function(root) { + +}; diff --git a/problemset/text-justification.js b/problemset/text-justification.js new file mode 100644 index 0000000..054d14e --- /dev/null +++ b/problemset/text-justification.js @@ -0,0 +1,65 @@ +/** + * Source: https://leetcode.com/problems/text-justification/ + * Tags: [String] + * Level: Hard + * Title: Text Justification + * Auther: @imcoddy + * Content: 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. + * + * + * + * click to show corner cases. + * + * Corner Cases: + * + * + * A line other than the last line might contain only one word. What should you do in this case? + * In this case, that line should be left-justified. + * + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string[]} words + * @param {number} maxWidth + * @return {string[]} + */ +var fullJustify = function(words, maxWidth) { + +}; diff --git a/problemset/the-skyline-problem.js b/problemset/the-skyline-problem.js new file mode 100644 index 0000000..90bcf40 --- /dev/null +++ b/problemset/the-skyline-problem.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/the-skyline-problem/ + * Tags: [Divide and Conquer,Heap] + * Level: Hard + * Title: The Skyline Problem + * Auther: @imcoddy + * Content: A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B). + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0. + * + * For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] . + * + * The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour. + * + * For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ]. + * + * Notes: + * + * The number of buildings in any input list is guaranteed to be in the range [0, 10000]. + * The input list is already sorted in ascending order by the left x position Li. + * The output list must be sorted by the x position. + * There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...] + * + * + * + * Credits:Special thanks to @stellari for adding this problem, creating these two awesome images and all test cases. + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[][]} buildings + * @return {number[][]} + */ +var getSkyline = function(buildings) { + +}; diff --git a/problemset/trapping-rain-water.js b/problemset/trapping-rain-water.js new file mode 100644 index 0000000..dc819b2 --- /dev/null +++ b/problemset/trapping-rain-water.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/trapping-rain-water/ + * Tags: [Array,Stack,Two Pointers] + * Level: Hard + * Title: Trapping Rain Water + * Auther: @imcoddy + * Content: 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! + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Container With Most Water + * + * (M) Product of Array Except Self + */ + +/** + * @param {number[]} height + * @return {number} + */ +var trap = function(height) { + +}; diff --git a/problemset/triangle.js b/problemset/triangle.js new file mode 100644 index 0000000..e478151 --- /dev/null +++ b/problemset/triangle.js @@ -0,0 +1,39 @@ +/** + * Source: https://leetcode.com/problems/triangle/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Triangle + * Auther: @imcoddy + * Content: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. + * + * + * For example, given the following triangle + * + * [ + * [2], + * [3,4], + * [6,5,7], + * [4,1,8,3] + * ] + * + * + * + * The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). + * + * + * + * Note: + * Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle. + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {number[][]} triangle + * @return {number} + */ +var minimumTotal = function(triangle) { + +}; diff --git a/problemset/two-sum.js b/problemset/two-sum.js new file mode 100644 index 0000000..352f3cc --- /dev/null +++ b/problemset/two-sum.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/two-sum/ + * Tags: [Array,Hash Table] + * Level: Medium + * Title: Two Sum + * Auther: @imcoddy + * Content: Given an array of integers, find two numbers such that they add up to a specific target number. + * + * The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. + * + * You may assume that each input would have exactly one solution. + * + * + * Input: numbers={2, 7, 11, 15}, target=9 + * Output: index1=1, index2=2 + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show 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) { + +}; diff --git a/problemset/ugly-number-ii.js b/problemset/ugly-number-ii.js new file mode 100644 index 0000000..31f3071 --- /dev/null +++ b/problemset/ugly-number-ii.js @@ -0,0 +1,59 @@ +/** + * Source: https://leetcode.com/problems/ugly-number-ii/ + * Tags: [Dynamic Programming,Heap,Math] + * Level: Medium + * Title: Ugly Number II + * Auther: @imcoddy + * Content: 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. + * + * + * + * The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones. + * An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number. + * The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3. + * Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5). + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Merge k Sorted Lists + * + * (E) Count Primes + * + * (E) Ugly Number + * + * (M) Perfect Squares + */ + +/** + * @param {number} n + * @return {number} + */ +var nthUglyNumber = function(n) { + +}; diff --git a/problemset/ugly-number.js b/problemset/ugly-number.js new file mode 100644 index 0000000..a7691a3 --- /dev/null +++ b/problemset/ugly-number.js @@ -0,0 +1,50 @@ +/** + * Source: https://leetcode.com/problems/ugly-number/ + * Tags: [Math] + * Level: Easy + * Title: Ugly Number + * Auther: @imcoddy + * Content: 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. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Happy Number + * + * (E) Count Primes + * + * (M) Ugly Number II + */ + +/** + * @param {number} num + * @return {boolean} + */ +var isUgly = function(num) { + +}; diff --git a/problemset/unique-binary-search-trees-ii.js b/problemset/unique-binary-search-trees-ii.js new file mode 100644 index 0000000..b0d7532 --- /dev/null +++ b/problemset/unique-binary-search-trees-ii.js @@ -0,0 +1,78 @@ +/** + * Source: https://leetcode.com/problems/unique-binary-search-trees-ii/ + * Tags: [Tree,Dynamic Programming] + * Level: Medium + * Title: Unique Binary Search Trees II + * Auther: @imcoddy + * Content: 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. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Unique Binary Search Trees + * + * (M) Different Ways to Add Parentheses + */ + +/** + * 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) { + +}; diff --git a/problemset/unique-binary-search-trees.js b/problemset/unique-binary-search-trees.js new file mode 100644 index 0000000..f5d363b --- /dev/null +++ b/problemset/unique-binary-search-trees.js @@ -0,0 +1,48 @@ +/** + * Source: https://leetcode.com/problems/unique-binary-search-trees/ + * Tags: [Tree,Dynamic Programming] + * Level: Medium + * Title: Unique Binary Search Trees + * Auther: @imcoddy + * Content: Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + * + * + * For example, + * Given n = 3, there are a total of 5 unique BST's. + * + * + * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Unique Binary Search Trees II + */ + +/** + * @param {number} n + * @return {number} + */ +var numTrees = function(n) { + +}; diff --git a/problemset/unique-paths-ii.js b/problemset/unique-paths-ii.js new file mode 100644 index 0000000..8f79b73 --- /dev/null +++ b/problemset/unique-paths-ii.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/unique-paths-ii/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Unique Paths II + * Auther: @imcoddy + * Content: Follow up for "Unique Paths": + * + * Now consider if some obstacles are added to the grids. How many unique paths would there be? + * + * An obstacle and empty space is marked as 1 and 0 respectively in the grid. + * + * For example, + * There is one obstacle in the middle of a 3x3 grid as illustrated below. + * + * [ + * [0,0,0], + * [0,1,0], + * [0,0,0] + * ] + * + * The total number of unique paths is 2. + * + * Note: m and n will be at most 100. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Unique Paths + */ + +/** + * @param {number[][]} obstacleGrid + * @return {number} + */ +var uniquePathsWithObstacles = function(obstacleGrid) { + +}; diff --git a/problemset/unique-paths.js b/problemset/unique-paths.js new file mode 100644 index 0000000..d8e7d29 --- /dev/null +++ b/problemset/unique-paths.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/unique-paths/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Unique Paths + * Auther: @imcoddy + * Content: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). + * + * The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). + * + * How many possible unique paths are there? + * + * + * + * Above is a 3 x 7 grid. How many possible unique paths are there? + * + * + * Note: m and n will be at most 100. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Unique Paths II + * + * (M) Minimum Path Sum + * + * (H) Dungeon Game + */ + +/** + * @param {number} m + * @param {number} n + * @return {number} + */ +var uniquePaths = function(m, n) { + +}; diff --git a/problemset/valid-anagram.js b/problemset/valid-anagram.js new file mode 100644 index 0000000..12a703b --- /dev/null +++ b/problemset/valid-anagram.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/valid-anagram/ + * Tags: [Hash Table,Sort] + * Level: Easy + * Title: Valid Anagram + * Auther: @imcoddy + * Content: 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. + * + * + * Note: + * You may assume the string contains only lowercase alphabets. + * + * Follow up: + * What if the inputs contain unicode characters? How would you adapt your solution to such case? + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Group Anagrams + * + * (E) Palindrome Permutation + */ + +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ +var isAnagram = function(s, t) { + +}; diff --git a/problemset/valid-number.js b/problemset/valid-number.js new file mode 100644 index 0000000..79220fa --- /dev/null +++ b/problemset/valid-number.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/valid-number/ + * Tags: [Math,String] + * Level: Hard + * Title: Valid Number + * Auther: @imcoddy + * Content: Validate if a given string is numeric. + * + * + * Some examples: + * "0" => true + * " 0.1 " => true + * "abc" => false + * "1 a" => false + * "2e10" => true + * + * + * Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. + * + * + * + * Update (2015-02-10): + * The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) String to Integer (atoi) + */ + +/** + * @param {string} s + * @return {boolean} + */ +var isNumber = function(s) { + +}; diff --git a/problemset/valid-palindrome.js b/problemset/valid-palindrome.js new file mode 100644 index 0000000..76b22ca --- /dev/null +++ b/problemset/valid-palindrome.js @@ -0,0 +1,49 @@ +/** + * Source: https://leetcode.com/problems/valid-palindrome/ + * Tags: [Two Pointers,String] + * Level: Easy + * Title: Valid Palindrome + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Palindrome Linked List + */ + +/** + * @param {string} s + * @return {boolean} + */ +var isPalindrome = function(s) { + +}; diff --git a/problemset/valid-parentheses.js b/problemset/valid-parentheses.js new file mode 100644 index 0000000..eaff415 --- /dev/null +++ b/problemset/valid-parentheses.js @@ -0,0 +1,42 @@ +/** + * Source: https://leetcode.com/problems/valid-parentheses/ + * Tags: [Stack,String] + * Level: Easy + * Title: Valid Parentheses + * Auther: @imcoddy + * Content: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + * + * The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Generate Parentheses + * + * (H) Longest Valid Parentheses + * + * (M) Remove Invalid Parentheses + */ + +/** + * @param {string} s + * @return {boolean} + */ +var isValid = function(s) { + +}; diff --git a/problemset/valid-sudoku.js b/problemset/valid-sudoku.js new file mode 100644 index 0000000..66c1773 --- /dev/null +++ b/problemset/valid-sudoku.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/valid-sudoku/ + * Tags: [Hash Table] + * Level: Easy + * Title: Valid Sudoku + * Auther: @imcoddy + * Content: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. + * + * The Sudoku board could be partially filled, where empty cells are filled with the character '.'. + * + * + * + * A partially filled sudoku which is valid. + * + * + * Note: + * A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Sudoku Solver + */ + +/** + * @param {character[][]} board + * @return {boolean} + */ +var isValidSudoku = function(board) { + +}; diff --git a/problemset/validate-binary-search-tree.js b/problemset/validate-binary-search-tree.js new file mode 100644 index 0000000..1390fac --- /dev/null +++ b/problemset/validate-binary-search-tree.js @@ -0,0 +1,73 @@ +/** + * Source: https://leetcode.com/problems/validate-binary-search-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Validate Binary Search Tree + * Auther: @imcoddy + * Content: Given a binary tree, determine if it is a valid binary search tree (BST). + * + * + * + * Assume a BST is defined as follows: + * + * The left subtree of a node contains only nodes with keys less than the node's key. + * The right subtree of a node contains only nodes with keys greater than the node's key. + * Both the left and right subtrees must also be binary search trees. + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + * + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Binary Tree Inorder Traversal + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {boolean} + */ +var isValidBST = function(root) { + +}; diff --git a/problemset/wildcard-matching.js b/problemset/wildcard-matching.js new file mode 100644 index 0000000..01f4ce4 --- /dev/null +++ b/problemset/wildcard-matching.js @@ -0,0 +1,55 @@ +/** + * Source: https://leetcode.com/problems/wildcard-matching/ + * Tags: [Dynamic Programming,Backtracking,Greedy,String] + * Level: Hard + * Title: Wildcard Matching + * Auther: @imcoddy + * Content: 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 + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Regular Expression Matching + */ + +/** + * @param {string} s + * @param {string} p + * @return {boolean} + */ +var isMatch = function(s, p) { + +}; diff --git a/problemset/word-break-ii.js b/problemset/word-break-ii.js new file mode 100644 index 0000000..8efb995 --- /dev/null +++ b/problemset/word-break-ii.js @@ -0,0 +1,38 @@ +/** + * Source: https://leetcode.com/problems/word-break-ii/ + * Tags: [Dynamic Programming,Backtracking] + * Level: Hard + * Title: Word Break II + * Auther: @imcoddy + * Content: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word. + * + * + * + * Return all such possible sentences. + * + * + * + * For example, given + * s = "catsanddog", + * dict = ["cat", "cats", "and", "sand", "dog"]. + * + * + * + * A solution is ["cats and dog", "cat sand dog"]. + * + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @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 {string[]} + */ +var wordBreak = function(s, wordDict) { + +}; diff --git a/problemset/word-break.js b/problemset/word-break.js new file mode 100644 index 0000000..a82ef90 --- /dev/null +++ b/problemset/word-break.js @@ -0,0 +1,32 @@ +/** + * Source: https://leetcode.com/problems/word-break/ + * Tags: [] + * Level: Medium + * Title: Word Break + * Auther: @imcoddy + * Content: Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. + * + * + * For example, given + * s = "leetcode", + * dict = ["leet", "code"]. + * + * + * + * Return true because "leetcode" can be segmented as "leet code". + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @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) { + +}; diff --git a/problemset/word-ladder-ii.js b/problemset/word-ladder-ii.js new file mode 100644 index 0000000..15e0e85 --- /dev/null +++ b/problemset/word-ladder-ii.js @@ -0,0 +1,55 @@ +/** + * Source: https://leetcode.com/problems/word-ladder-ii/ + * Tags: [Array,Backtracking,Breadth-first Search,String] + * Level: Hard + * Title: Word Ladder II + * Auther: @imcoddy + * Content: 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. + * + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @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) { + +}; diff --git a/problemset/word-ladder.js b/problemset/word-ladder.js new file mode 100644 index 0000000..cb9af99 --- /dev/null +++ b/problemset/word-ladder.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/word-ladder/ + * Tags: [] + * Level: Medium + * Title: Word Ladder + * Auther: @imcoddy + * Content: 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. + * + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @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 {number} + */ +var ladderLength = function(beginWord, endWord, wordList) { + +}; diff --git a/problemset/word-pattern.js b/problemset/word-pattern.js new file mode 100644 index 0000000..215e0d3 --- /dev/null +++ b/problemset/word-pattern.js @@ -0,0 +1,55 @@ +/** + * Source: https://leetcode.com/problems/word-pattern/ + * Tags: [Hash Table] + * Level: Easy + * Title: Word Pattern + * Auther: @imcoddy + * Content: Given a pattern and a string str, find if str follows the same pattern. + * Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str. + * + * Examples: + * + * pattern = "abba", str = "dog cat cat dog" should return true. + * pattern = "abba", str = "dog cat cat fish" should return false. + * pattern = "aaaa", str = "dog cat cat dog" should return false. + * pattern = "abba", str = "dog dog dog dog" should return false. + * + * + * + * + * Notes: + * You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space. + * + * + * Credits:Special thanks to @minglotus6 for adding this problem and creating all test cases. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Isomorphic Strings + * + * (H) Word Pattern II + */ + +/** + * @param {string} pattern + * @param {string} str + * @return {boolean} + */ +var wordPattern = function(pattern, str) { + +}; diff --git a/problemset/word-search-ii.js b/problemset/word-search-ii.js new file mode 100644 index 0000000..f707896 --- /dev/null +++ b/problemset/word-search-ii.js @@ -0,0 +1,67 @@ +/** + * Source: https://leetcode.com/problems/word-search-ii/ + * Tags: [Backtracking,Trie] + * Level: Hard + * Title: Word Search II + * Auther: @imcoddy + * Content: 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. + * + * You would need to optimize your backtracking to pass the larger test. Could you stop backtracking earlier? + * + * If the current candidate does not exist in all words' prefix, you could stop backtracking immediately. What kind of data structure could answer such query efficiently? Does a hash table work? Why or why not? How about a Trie? If you would like to learn how to implement a basic trie, please work on this problem: Implement Trie (Prefix Tree) first. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Word Search + */ + +/** + * @param {character[][]} board + * @param {string[]} words + * @return {string[]} + */ +var findWords = function(board, words) { + +}; diff --git a/problemset/word-search.js b/problemset/word-search.js new file mode 100644 index 0000000..32a29a3 --- /dev/null +++ b/problemset/word-search.js @@ -0,0 +1,56 @@ +/** + * Source: https://leetcode.com/problems/word-search/ + * Tags: [Array,Backtracking] + * Level: Medium + * Title: Word Search + * Auther: @imcoddy + * Content: 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. + * + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (H) Word Search II + */ + +/** + * @param {character[][]} board + * @param {string} word + * @return {boolean} + */ +var exist = function(board, word) { + +}; diff --git a/problemset/zigzag-conversion.js b/problemset/zigzag-conversion.js new file mode 100644 index 0000000..f1e3638 --- /dev/null +++ b/problemset/zigzag-conversion.js @@ -0,0 +1,35 @@ +/** + * Source: https://leetcode.com/problems/zigzag-conversion/ + * Tags: [String] + * Level: Easy + * Title: ZigZag Conversion + * Auther: @imcoddy + * Content: 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". + * + * + * + * Subscribe to see which companies asked this question + */ + +/** + * @param {string} s + * @param {number} numRows + * @return {string} + */ +var convert = function(s, numRows) { + +}; diff --git a/recover-binary-search-tree.js b/recover-binary-search-tree.js new file mode 100644 index 0000000..9cac331 --- /dev/null +++ b/recover-binary-search-tree.js @@ -0,0 +1,98 @@ +/** + * Source: https://leetcode.com/problems/recover-binary-search-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Hard + * Title: Recover Binary Search Tree + * Auther: @imcoddy + * Content: Two elements of a binary search tree (BST) are swapped by mistake. + * + * Recover the tree without changing its structure. + * + * + * Note: + * A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @return {void} Do not return anything, modify root in-place instead. + */ + +/** + * Memo: use inorder traverse to put each nodes in a row, find out the wrongly swapped pair, and swap it back + * Complex: O(n) + * Runtime: 324ms + * Tests: 1916 test cases passed + * Rank: C + */ +var recoverTree = function(root) { + var nodes = []; + + function traverse(root) { + if (!root) return; + traverse(root.left); + nodes.push(root); + traverse(root.right); + } + + traverse(root); + if (nodes.length < 2) return; + + var head = 0; + var tail = nodes.length - 1; + while (head < tail && nodes[head].val < nodes[head + 1].val) { + head++; + } + while (tail > head && nodes[tail].val > nodes[tail - 1].val) { + tail--; + } + var tmp = nodes[head].val; + nodes[head].val = nodes[tail].val; + nodes[tail].val = tmp; +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(4); +var root = node; + +node = new TreeNode(3); +root.right = node; + +node = new TreeNode(1); +root.left = node; + +node = new TreeNode(2); +root.right.right = node; +recoverTree(root); +console.log(root); \ No newline at end of file diff --git a/remove-duplicates-from-sorted-array.js b/remove-duplicates-from-sorted-array.js new file mode 100644 index 0000000..dd3f3c5 --- /dev/null +++ b/remove-duplicates-from-sorted-array.js @@ -0,0 +1,96 @@ +/** + * Source: https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Remove Duplicates from Sorted Array + * Auther: @imcoddy + * Content: 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 A = [1,1,2], + * + * + * Your function should return length = 2, and A is now [1,2]. + */ + +/** + * @param {number[]} A + * @return {number} + */ + +/** + * Memo: + * Runtime: 189ms + * Rank: S + */ +var removeDuplicates = function(A) { + if (!A || A.length === 0) { + return 0; + } + + if (A.length === 1) { + return 1; + } + + var length = A.length; + var i = 0; + var j = 1; + + while (i < length) { + while (A[i] === A[j] && j < length) { + A[j] = NaN; + j++; + } + + i = j; + j = i + 1; + } + + var count = 0; + for (var i = 0; i < length; i++) { + if (!isNaN(A[i])) { + A[count++] = A[i]; + } + } + console.log(A); + return count; +}; + +/** + * @param {number[]} nums + * @return {number} + */ + + /** + * Memo: Add unique elements to a new array, and put them back to nums. + * Complex: O(n) + * Runtime: 164ms + * Tests: 161 test cases passed + * Rank: S + * Updated: 2015-06-15 + */ +var removeDuplicates = function(nums) { + var array = []; + var i = 0; + while (i < nums.length) { + if (nums[i] !== array[array.length - 1]) { + array.push(nums[i]); + } + i++; + } + + for (var i = 0; i < array.length; i++) { + nums[i] = array[i]; + } + return array.length; +}; + +console.log(removeDuplicates([1])); +console.log(removeDuplicates([1, 1, 1, 1])); +console.log(removeDuplicates([1, 1, 1, 2])); +console.log(removeDuplicates([1, 1, 1, 2, 2, 2, 2, 2])); diff --git a/remove-duplicates-from-sorted-list-ii.js b/remove-duplicates-from-sorted-list-ii.js new file mode 100644 index 0000000..1c46c7f --- /dev/null +++ b/remove-duplicates-from-sorted-list-ii.js @@ -0,0 +1,105 @@ +/** + * Source: https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ + * Tags: [Linked List] + * Level: Medium + * Title: Remove Duplicates from Sorted List II + * Auther: @imcoddy + * Content: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. + * + * + * For example, + * Given 1->2->3->3->4->4->5, return 1->2->5. + * Given 1->1->1->2->3, return 2->3. + */ +var util = require("./util.js"); + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ + +/** + * Memo: find the non-duplicate node and append it to tail, note that need to set tail to null as the rest might need to be deleted + * Runtime: 151ms + * Tests: 166 test cases passed + * Rank: S + */ + +var deleteDuplicates = function(head) { + if (!head) return null; + + var dummy = new ListNode(null); + var tail = dummy; + var p = head; + var duplicate = false; + + while (p) { + while (p.next && p.val === p.next.val) { + p = p.next; + duplicate = true; + } + + if (!duplicate) { + tail.next = p; + tail = tail.next; + } + p = p.next; + duplicate = false; + } + + tail.next = null; + return dummy.next; +}; + + +/** + * Memo: Check if the element is duplicated or not. If not, append it to the list. + * Complex: O(n) + * Runtime: 164ms + * Tests: 166 test cases passed + * Rank: A + * Updated: 2015-06-20 + */ +var deleteDuplicates = function(head) { + if (!head || !head.next) return head; + + var dummy = new ListNode(null); + var tail = dummy; + var p = head; + + while (p) { + var start = p; + while (p && p.next && p.next.val === p.val) { + p = p.next; + } + var next = p.next; + if (start === p) { + tail.next = p; + tail = tail.next; + tail.next = null; + } + p = next; + } + + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +console.log(util.linkListToString(deleteDuplicates(util.arrayToLinkList([1, 1, 2, 2, 2])))); +console.log(util.linkListToString(deleteDuplicates(util.arrayToLinkList([1, 2, 2, 2])))); +console.log(util.linkListToString(deleteDuplicates(util.arrayToLinkList([1, 1, 1, 3, 3, 5])))); +console.log(util.linkListToString(deleteDuplicates(util.arrayToLinkList([1, 1, 1, 3, 5])))); +console.log(util.linkListToString(deleteDuplicates(util.arrayToLinkList([0, 1, 1, 1, 3, 5])))); +console.log(util.linkListToString(deleteDuplicates(util.arrayToLinkList([])))); +console.log(util.linkListToString(deleteDuplicates(util.arrayToLinkList([1])))); \ No newline at end of file diff --git a/remove-duplicates-from-sorted-list.js b/remove-duplicates-from-sorted-list.js new file mode 100644 index 0000000..69a223d --- /dev/null +++ b/remove-duplicates-from-sorted-list.js @@ -0,0 +1,132 @@ +/** + * Source: https://leetcode.com/problems/remove-duplicates-from-sorted-list/ + * Tags: [Linked List] + * Level: Easy + * Updated: 2015-04-24 + * Title: Remove Duplicates from Sorted List + * Auther: @imcoddy + * Content: Given a sorted linked list, delete all duplicates such that each element appear only once. + * + * + * For example, + * Given 1->1->2, return 1->2. + * Given 1->1->2->3->3, return 1->2->3. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +var util = require("./util.js"); + +/** + * @param {ListNode} head + * @return {ListNode} + */ +/** + * Memo: + * Complex: O(n) + * Runtime: 158ms + * Tests: 164 test cases passed + * Rank: S + */ +var deleteDuplicates = function(head) { + var node = head; + while (node) { + var next = node.next; + while (next && node.val === next.val) { + node.next = next.next; + next = null; + next = node.next; + } + node = node.next; + } + return head; +}; + +/** + * Memo: Use dummy head to solve + * Complex: O(n) + * Runtime: 147ms + * Tests: 164 test cases passed + * Rank: S + */ + +var deleteDuplicatesDummy = function(head) { + var dummy = new ListNode(null); + var tail = dummy; + tail.next = head; + + while (tail) { + while (tail.next && tail.next.val === tail.val) { + tail.next = tail.next.next; // remove next node if val is the same + } + tail = tail.next; // move tail to last node + } + return dummy.next; +}; + +/** + * Memo: Remove next element if it is the same as current one. + * Complex: O(n) + * Runtime: 168ms + * Tests: 164 test cases passed + * Rank: A + * Updated: 2015-06-16 + */ +var deleteDuplicates = function(head) { + var tail = head; + while (tail) { + while (tail.next && tail.next.val === tail.val) { + tail.next = tail.next.next; + } + tail = tail.next; + } + return head; +}; + +/** + * Memo: Keep moving next node until it reaches either null or different value. + * Complex: O(n) + * Runtime: 168ms + * Tests: 164 test cases passed + * Rank: S + * Updated: 2015-06-17 + */ +var deleteDuplicates = function(head) { + var node = head; + while (node) { + var next = node.next; + while (next && next.val === node.val) { + next = next.next; + } + node.next = next; + node = node.next; + } + return head; +}; + +var deleteDuplicates = function(head) { + var tail = head; + while (tail) { + while (tail.next && tail.next.val === tail.val) tail.next = tail.next.next; + tail = tail.next; + } + return head; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var should = require('should'); +console.time('Runtime'); +util.lta(deleteDuplicates(util.atl([1, 2, 3, 4]))).should.eql([1, 2, 3, 4]); +util.lta(deleteDuplicates(util.atl([1, 1, 2, 2, 3, 3, 4]))).should.eql([1, 2, 3, 4]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/remove-element.js b/remove-element.js new file mode 100644 index 0000000..c61edde --- /dev/null +++ b/remove-element.js @@ -0,0 +1,145 @@ +/** + * Source: https://leetcode.com/problems/remove-element/ + * Tags: [Array,Two Pointers] + * Level: Easy + * Title: Remove Element + * Auther: @imcoddy + * Content: Given an array and a value, remove all instances of that value in place and return the new length. + * + * + * + * The order of elements can be changed. It doesn't matter what you leave beyond the new length. + */ + +/** + * @param {number[]} A + * @param {number} elem + * @returns {number} + */ + +/** + * Explanation: Using javascript API to remove element directly + * Runtime: 161ms + * Rank: B + */ + +/* + *var removeElement = function(A, elem) { + * if (!A || A.length <= 0) { + * return 0; + * } + * + * while (A.indexOf(elem) !== -1) { + * var index = A.indexOf(elem); + * A.splice(index, 1); + * } + * console.log(A); + * return A.length; + *}; + */ + +/** + * Runtime: 171ms + * Rank: C + */ +var removeElement = function(A, elem) { + if (!A || A.length <= 0) { + return 0; + } + + var tail = A.length - 1; + var head = 0; + + while (head < tail) { + while (A[head] !== elem && head < tail) { + head++; + } + while (A[tail] === elem) { + tail--; + } + if (head < tail) { + var temp = A[head]; + A[head] = A[tail]; + A[tail] = temp; + } + } + + if (A[tail] === elem) { + tail--; + } + return tail + 1; +}; + + +/** + * Memo: Use Javascript API to locate the element in array and delete it. + * Complex: O(n) + * Runtime: 128ms + * Tests: 112 test cases passed + * Rank: S + * Updated: 2015-06-15 + */ +var removeElement = function(nums, val) { + var index; + while ((index = nums.indexOf(val)) !== -1) { + nums.splice(index, 1); + } + return nums.length; +}; + + +/** + * Shorter version of the above + */ +var removeElement = function(nums, val) { + while ((nums.indexOf(val)) !== -1) nums.splice(nums.indexOf(val), 1); + return nums.length; +}; + + +/** + * Memo: Keep moving head and tail pointers until they match + * Complex: O(n) + * Runtime: 140ms + * Tests: 112 test cases passed + * Rank: B + * Updated: 2015-06-15 + */ +var removeElement = function(nums, val) { + var head = 0; + var tail = nums.length; + while (head < tail) { + if (nums[head] === val) { + nums[head] = nums[--tail]; + } else { + head++; + } + } + return tail; +}; + +/** + * Shorter version of the above + */ +var removeElement = function(nums, val) { + var head = 0, + tail = nums.length; + while (head < tail) nums[head] = nums[head] === val ? nums[--tail] : nums[head++]; + return tail; +}; + +var should = require('should'); +console.time('Runtime'); +removeElement([2], 2).should.equal(0); // 0 +removeElement([2], 3).should.equal(1); // 1 +removeElement([3, 3], 3).should.equal(0); // 0 +removeElement([3, 3], 5).should.equal(2); // 2 +removeElement([1, 3, 1, 1, 2, 1, 1, 1], 1).should.equal(2); // 2 +removeElement([1, 1, 1, 1, 1, 1, 1, 1], 1).should.equal(0); // 0 +removeElement([2, 1, 1, 1, 1, 1, 1, 1], 1).should.equal(1); // 1 +removeElement([1, 1, 1, 1, 2, 2, 2, 2], 1).should.equal(4); // 4 +removeElement([2, 1, 1, 1, 2, 2, 2, 2], 1).should.equal(5); // 5 +removeElement([1, 1, 1, 1, 1, 1, 1, 2], 1).should.equal(1); // 1 +removeElement([1, 1, 1, 1, 1, 1, 1, 2], 2).should.equal(7); // 7 +removeElement([2, 2, 2, 2, 2, 2, 2, 2], 1).should.equal(8); // 8 +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/remove-linked-list-elements.js b/remove-linked-list-elements.js new file mode 100644 index 0000000..f750700 --- /dev/null +++ b/remove-linked-list-elements.js @@ -0,0 +1,119 @@ +/** + * Source: https://leetcode.com/problems/remove-linked-list-elements/ + * Tags: [Linked List] + * Level: Easy + * Title: Remove Linked List Elements + * Auther: @imcoddy + * Content: Remove all elements from a linked list of integers that have value val. + * + * Example + * Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 + * Return: 1 --> 2 --> 3 --> 4 --> 5 + * + * + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @param {number} val + * @return {ListNode} + */ + +/** + * Explanation: Many traps in here. + * 1. Head could be needed to delete + * 2. Dont move the pointer until next doesn't need to delete + * Runtime: 177ms + * Rank: S + */ +var removeElements = function(head, val) { + // remove when head is element of val + while (head && head.val === val) { + head = head.next; + } + + var p = head; + while (p) { + while (p.next && p.next.val === val) { + var d = p.next; + p.next = d.next; + d = null; + } + p = p.next; + } + return head; +}; + + +/** + * Memo: Use prev and p to search if p.val is equal to val, if so, delete p and keep searching till the end. + * Complex: O(n) + * Runtime: 204ms + * Tests: 63 test cases passed + * Rank: B + * Updated: 2015-06-16 + */ +var removeElements = function(head, val) { + var dummy = new ListNode(null); + dummy.next = head; + var prev = dummy; + var p = dummy.next; + while (p) { + if (p.val === val) { + prev.next = p.next; + } else { + prev = p; + } + p = p.next; + } + return dummy.next; +}; + +/** + * Memo: Improve from above solution by keep moving if p.next equal val, works better if continous elements need to be removed. + * Complex: O(n) + * Runtime: 168ms + * Tests: 63 test cases passed + * Rank: S + * Updated: 2015-06-16 + */ +var removeElements = function(head, val) { + var dummy = new ListNode(null); + dummy.next = head; + var prev = dummy; + var p = dummy.next; + while (p) { + while (p && p.val === val) p = p.next; + prev.next = p; + if (p) { + prev = prev.next; + p = p.next; + } + } + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +util.lta(removeElements(util.atl([1, 2, 3, 4, 5]), 2)).should.eql([1, 3, 4, 5]); +util.lta(removeElements(util.atl([1, 2, 3, 2, 4, 5, 2, 2]), 2)).should.eql([1, 3, 4, 5]); +util.lta(removeElements(util.atl([1, 1, 1, 1]), 1)).should.eql([]); +util.lta(removeElements(util.atl([1, 2, 1, 2]), 2)).should.eql([1, 1]); +util.lta(removeElements(util.atl([1, 2, 3, 4, 5]), 2)).should.eql([1, 3, 4, 5]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/remove-nth-node-from-end-of-list.js b/remove-nth-node-from-end-of-list.js new file mode 100644 index 0000000..45a3893 --- /dev/null +++ b/remove-nth-node-from-end-of-list.js @@ -0,0 +1,175 @@ +/** + * Source: https://leetcode.com/problems/remove-nth-node-from-end-of-list/ + * Tags: [Linked List,Two Pointers] + * Level: Easy + * Title: Remove Nth Node From End of List + * Auther: @imcoddy + * Content: Given a linked list, remove the nth node from the end of list and return its head. + * + * + * For example, + * + * + * Given linked list: 1->2->3->4->5, and n = 2. + * + * After removing the second node from the end, the linked list becomes 1->2->3->5. + * + * + * + * Note: + * Given n will always be valid. + * Try to do this in one pass. + */ +var util = require('./util.js'); +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} n + * @return {ListNode} + */ + +/** + * Memo: Set two pointers as fast and slow, keep slow is n nodes slower than fast, and keep moving two pointers till fast reaches the end. + * Runtime: 150ms + * Tests: 207 test cases passed + * Rank: S + */ +var removeNthFromEnd = function(head, n) { + var dummy = new ListNode(null); + dummy.next = head; + var fast = dummy; + var slow = dummy; + + while (fast.next) { + fast = fast.next; + if (n-- <= 0) { + slow = slow.next; + } + } + slow.next = slow.next.next; + return dummy.next; +}; + +/** + * Memo: Find out length of the linked list first and search the length - n th element and delete it. + * Complex: O(n) + * Runtime: 152ms + * Tests: 207 test cases passed + * Rank: A + * Updated: 2015-06-16 + */ +var removeNthFromEnd = function(head, n) { + var count = 0; + var p = head; + while (p) { + p = p.next; + count++; + } + + count = count - n; + if (count === 0) { // remove the first element + return head.next; + } + + if (count > 0) { + p = head; + while (count > 1) { + p = p.next; + count--; + } + p.next = p.next.next; + } + //count < 0 is invalid, since the n will always be valid so ignore this case + return head; +}; + + +/** + * Memo: Same solution as above using dummy head. + * Complex: O(n) + * Runtime: 180ms + * Tests: 207 test cases passed + * Rank: B + * Updated: 2015-06-16 + */ +var removeNthFromEnd = function(head, n) { + var p = head; + var count = 0; + while (p) { + p = p.next; + count++; + } + + var dummy = new ListNode(null); + dummy.next = head; + count = count - n; + p = dummy; + while (count > 0) { + p = p.next; + count--; + } + p.next = p.next.next; + return dummy.next; +}; + +/** + * Memo: Use fast and slow pointers and keep n nodes between them. When fast reaches the end, slow will be the element to remove its next node (if exists). + * Complex: O(n) + * Runtime: 148ms + * Tests: 207 test cases passed + * Rank: S + * Updated: 2015-06-16 + */ +var removeNthFromEnd = function(head, n) { + var dummy = new ListNode(null); + dummy.next = head; + var fast = dummy; + var slow = dummy; + while (fast) { + fast = fast.next; + if (n-- < 0) slow = slow.next; + } + if (slow.next) slow.next = slow.next.next; + return dummy.next; +}; + + +/** + * Memo: Use fast and slow pointers and keep n nodes between them. When fast reaches the end, slow will be the element to remove its next node (if exists). + * Complex: O(n) + * Runtime: 148ms + * Tests: 207 test cases passed + * Rank: S + * Updated: 2015-08-20 + */ +var removeNthFromEnd = function(head, n) { + var dummy = new ListNode(null); + dummy.next = head; + var fast = dummy; + var slow = dummy; + while (fast = fast.next) + if (--n < 0) slow = slow.next; + if (slow.next) slow.next = slow.next.next; + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var should = require('should'); +console.time('Runtime'); +util.lta(removeNthFromEnd(util.atl([1]), 1)).should.eql([]); +util.lta(removeNthFromEnd(util.atl([1, 2]), 1)).should.eql([1]); +util.lta(removeNthFromEnd(util.atl([1, 2]), 2)).should.eql([2]); +util.lta(removeNthFromEnd(util.atl([1, 2, 3, 4, 5]), 2)).should.eql([1, 2, 3, 5]); +util.lta(removeNthFromEnd(util.atl([1, 2, 3, 4, 5]), 1)).should.eql([1, 2, 3, 4]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/reorder-list.js b/reorder-list.js new file mode 100644 index 0000000..1507612 --- /dev/null +++ b/reorder-list.js @@ -0,0 +1,67 @@ +/** + * Source: https://leetcode.com/problems/reorder-list/ + * Tags: [Linked List] + * Level: Medium + * Title: Reorder List + * Auther: @imcoddy + * Content: Given a singly linked list L: L0→L1→…→Ln-1→Ln, + * reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… + * + * + * You must do this in-place without altering the nodes' values. + * + * + * For example, + * Given {1,2,3,4}, reorder it to {1,4,2,3}. + */ +var util = require("./util.js"); + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {void} Do not return anything, modify head in-place instead. + */ +/** + * Memo: put each node in an array and link head to tail till the middle + * Complex: O(n) + * Runtime: 212ms + * Tests: 13 test cases passed + * Rank: S + */ +var reorderList = function(head) { + var array = []; + var p = head; + while (p) { + array.push(p); + var q = p; + p = p.next; + q.next = null; + } + + var start = 0; + var end = array.length - 1; + while (end > start + 1) { + array[start++].next = array[end]; + array[end--].next = array[start]; + } + if (start < end) { + array[start].next = array[end]; + } + + return head; +}; + +console.log(util.linkListToString(reorderList(util.arrayToLinkList()))); +console.log(util.linkListToString(reorderList(util.arrayToLinkList([])))); +console.log(util.linkListToString(reorderList(util.arrayToLinkList([1])))); +console.log(util.linkListToString(reorderList(util.arrayToLinkList([1, 2])))); +console.log(util.linkListToString(reorderList(util.arrayToLinkList([1, 2, 3, 4])))); +console.log(util.linkListToString(reorderList(util.arrayToLinkList([1, 2, 3, 4, 5])))); +console.log(util.linkListToString(reorderList(util.arrayToLinkList([1, 2, 3, 4, 5, 6])))); +console.log(util.linkListToString(reorderList(util.arrayToLinkList([1, 2, 3, 4, 5, 6, 7])))); \ No newline at end of file diff --git a/reverse-bits.js b/reverse-bits.js new file mode 100644 index 0000000..b9e6e45 --- /dev/null +++ b/reverse-bits.js @@ -0,0 +1,59 @@ +/** + * Source: https://leetcode.com/problems/reverse-bits/ + * Tags: [Bit Manipulation] + * Level: Easy + * Title: Reverse Bits + * Auther: @imcoddy + * Content: Reverse bits of a given 32 bits unsigned integer. + * + * For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000). + * + * + * Follow up: + * If this function is called many times, how would you optimize it? + * + * + * Related problem: Reverse Integer + * + * Credits:Special thanks to @ts for adding this problem and creating all test cases. + */ + +/** + * @param {number} n - a positive integer + * @return {number} - a positive integer + */ + +/** + * Memo: Since it is a 32-bit integer, simple loop 32 times to calculate the result. + * Complex: O(1) + * Runtime: 164ms + * Tests: 600 test cases passed + * Rank: A + * Updated: 2015-06-11 + */ +var reverseBits = function(n) { + var result = 0; + var count = 32; + while (count) { + result = result * 2 + (n % 2); + n = ~~(n / 2); + count--; + } + return result; +}; + +var reverseBits = function(n) { + var result = 0; + for (var i = 0; i < 32; i++) { + result = result * 2 + (n % 2); + n = ~~(n / 2); + } + + return result; +}; + +var should = require('should'); +console.time('Runtime'); +reverseBits(43261596).should.equal(964176192); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/reverse-integer.js b/reverse-integer.js new file mode 100644 index 0000000..1605daf --- /dev/null +++ b/reverse-integer.js @@ -0,0 +1,65 @@ +/** + * Source: https://leetcode.com/problems/reverse-integer/ + * Tags: [Math] + * Level: Easy + * Updated: 2015-04-24 + * Title: Reverse Integer + * Auther: @imcoddy + * Content: Reverse digits of an integer. + * + * + * Example1: x = 123, return 321 + * Example2: x = -123, return -321 + * + * + * click to show spoilers. + * + * Have you thought about this? + * + * Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! + * + * If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. + * + * Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases? + * + * For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. + * + * + * Update (2014-11-10): + * Test cases had been added to test the overflow behavior. + */ + +/** + * @param {number} x + * @return {number} + */ +var reverse = function(x) { + var negative = false; + var result = 0; + var MAX = 2147483647; + if (x < 0) { + negative = true; + x = -x; + } + + var str = '' + x; + var digits = str.split(''); + + for (var i = digits.length - 1; i >= 0; i--) { + result = result * 10 + parseInt(digits[i]); + } + + if (result > MAX) { + // Overflow as 32-bit integer + result = 0; + } + return negative ? -result : result; +}; + + +console.log(reverse(123)); +console.log(reverse(100)); +console.log(reverse(10001)); +console.log(reverse(1000000003)); +console.log(reverse(-123)); +console.log(reverse(-100)); diff --git a/reverse-linked-list-ii.js b/reverse-linked-list-ii.js new file mode 100644 index 0000000..984ddaa --- /dev/null +++ b/reverse-linked-list-ii.js @@ -0,0 +1,117 @@ +/** + * Source: https://leetcode.com/problems/reverse-linked-list-ii/ + * Tags: [Linked List] + * Level: Medium + * Title: Reverse Linked List II + * Auther: @imcoddy + * Content: Reverse a linked list from position m to n. Do it in-place and in one-pass. + * + * + * + * For example: + * Given 1->2->3->4->5->NULL, m = 2 and n = 4, + * + * + * return 1->4->3->2->5->NULL. + * + * + * Note: + * Given m, n satisfy the following condition: + * 1 ≤ m ≤ n ≤ length of list. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} m + * @param {number} n + * @return {ListNode} + */ + +/** + * Memo: Switch append to tail or insert + * Complex: O(n) + * Runtime: 136ms + * Tests: 44 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var reverseBetween = function(head, m, n) { + if (!head || !head.next || m === n) return head; + var dummy = new ListNode(null); + var tail = dummy; + var p = head; + var count = 0; + + while (p) { + var pnext = p.next; + if (++count >= m && count <= n) { + p.next = tail.next; + tail.next = p; + } else { + while (tail.next) tail = tail.next; + tail.next = p; + tail = tail.next; + tail.next = null; + } + + p = pnext; + } + + return dummy.next; +}; + + +/** + * Memo: Reserve the middle part then append it to original List + * Complex: O(n) + * Runtime: 132ms + * Tests: 44 test cases passed + * Rank: S + * Updated: 2015-08-09 + */ +var reverseBetween = function(head, m, n) { + if (!head || !head.next || m === n) return head; + + var dummy = new ListNode(null); + dummy.next = head; + var p = dummy; + + var count = 1; + while (++count <= m) p = p.next; // find the previous node to break the list + var tail = p; + var next = p.next; + tail.next = null; + p = next; + + var reverse = new ListNode(null); + var tail2 = p; + while (count++ <= 1 + n) { + next = p.next; + p.next = reverse.next; + reverse.next = p; + p = next; + } + + tail.next = reverse.next; + tail2.next = p; + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +util.lta(reverseBetween(util.atl([1, 2, 3, 4, 5]), 2, 4)).should.eql([1, 4, 3, 2, 5]); +util.lta(reverseBetween(util.atl([1, 2]), 1, 2)).should.eql([2, 1]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/reverse-linked-list.js b/reverse-linked-list.js new file mode 100644 index 0000000..261620e --- /dev/null +++ b/reverse-linked-list.js @@ -0,0 +1,95 @@ +/** + * Source: https://leetcode.com/problems/reverse-linked-list/ + * Tags: [Linked List] + * Level: Easy + * Title: Reverse Linked List + * Auther: @imcoddy + * Content: Reverse a singly linked list. + * + * click to show more hints. + * + * Hint: + * A linked list can be reversed either iteratively or recursively. Could you implement both? + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +var util = require('./util.js'); + +/** + * @param {ListNode} head + * @return {ListNode} + */ +//TODO add recursive solution + +/** + * Memo: + * Runtime: 122ms + * Tests: 27 test cases passed + * Rank: NA + */ +var reverseList = function(head) { + var dummy = new ListNode(null); + var p = head; + while (p) { + var q = p.next; + p.next = dummy.next; + dummy.next = p; + p = q; + } + return dummy.next; +}; + +/** + * Memo: + * Complex: O(n) + * Runtime: 128ms + * Tests: 27 test cases passed + * Rank: S + * Updated: 2015-06-15 + */ +var reverseList = function(head) { + var dummy = new ListNode(null); + var p = head; + while (p) { + var q = p.next; + p.next = dummy.next; + dummy.next = p; + p = q; + } + return dummy.next; +}; + +var reverseList = function(head) { + var dummy = new ListNode(null); + while (head) { + var next = head.next; + head.next = dummy.next; + dummy.next = head; + head = next; + } + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var should = require('should'); +console.time('Runtime'); + +var list = util.arrayToLinkList([1, 2, 3, 4, 5]); +util.linkListToArray(reverseList(list)).should.containDeepOrdered([5, 4, 3, 2, 1]); + +list = util.arrayToLinkList([]); +util.linkListToArray(reverseList(list)).should.containDeepOrdered([]); + +list = util.arrayToLinkList([1]); +util.linkListToArray(reverseList(list)).should.containDeepOrdered([1]); +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/reverse-nodes-in-k-group.js b/reverse-nodes-in-k-group.js new file mode 100644 index 0000000..23fd8a8 --- /dev/null +++ b/reverse-nodes-in-k-group.js @@ -0,0 +1,98 @@ +/** + * Source: https://leetcode.com/problems/reverse-nodes-in-k-group/ + * Tags: [Linked List] + * Level: Hard + * Title: Reverse Nodes in k-Group + * Auther: @imcoddy + * Content: 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} + */ + +/** + * Memo: Track a list with k nodes, reverse this short list and append it to result. + * Complex: O(n) + * Runtime: 148ms + * Tests: 81 test cases passed + * Rank: SS + * Updated: 2015-09-30 + */ +var reverseKGroup = function(head, k) { + if (!head || k === 1) return head; + + var dummy = new ListNode(null); + var tail = dummy; + while (head) { + var start = head; + var count = 0; + while (head && ++count < k) head = head.next; + + if (head) { + var next = head.next; + head.next = null; // break from here + tail.next = reverseList(start); + tail = start; // as it has been reversed + head = next; + } else { + tail.next = start; + } + } + + return dummy.next; +}; + +var reverseList = function(head) { + var dummy = new ListNode(null); + while (head) { + var next = head.next; + head.next = dummy.next; + dummy.next = head; + head = next; + } + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +util.lta(reverseKGroup(util.atl([1, 2, 3, 4, 5]), 2)).should.eql([2, 1, 4, 3, 5]); +util.lta(reverseKGroup(util.atl([1, 2, 3, 4, 5]), 3)).should.eql([3, 2, 1, 4, 5]); +util.lta(reverseKGroup(util.atl([1, 2, 3, 4, 5, 6]), 3)).should.eql([3, 2, 1, 6, 5, 4]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/reverse-words-in-a-string.js b/reverse-words-in-a-string.js new file mode 100644 index 0000000..8e45b39 --- /dev/null +++ b/reverse-words-in-a-string.js @@ -0,0 +1,92 @@ +/** + * Source: https://leetcode.com/problems/reverse-words-in-a-string/ + * Tags: [String] + * Level: Medium + * Title: Reverse Words in a String + * Auther: @imcoddy + * Content: Given an input string, reverse the string word by word. + * + * + * + * For example, + * Given s = "the sky is blue", + * return "blue is sky the". + * + * + * + * Update (2015-02-12): + * For C programmers: Try to solve it in-place in O(1) space. + * + * + * click to show clarification. + * + * Clarification: + * + * + * + * What constitutes a word? + * A sequence of non-space characters constitutes a word. + * Could the input string contain leading or trailing spaces? + * Yes. However, your reversed string should not contain leading or trailing spaces. + * How about multiple spaces between two words? + * Reduce them to a single space in the reversed string. + */ + +/** + * @param {string} str + * @returns {string} + */ + +/** + * Memo: + * Runtime: 123ms + * Tests: 22 test cases passed + * Rank: A + */ +var reverseWords = function(str) { + var start = 0; + var end = 0; + var result = []; + str = str.trim(); + + while (start < str.length) { + while (start < str.length && str.charAt(start) === ' ') { + start++; + } + end = start; + while (end < str.length && str.charAt(end) !== ' ') { + end++; + } + // console.log(start, end, str.slice(start, end), str); + result.push(str.slice(start, end)); + start = end; + } + return result.reverse().join(' '); +}; + +/** + * Memo: + * Runtime: 259ms + * Tests: 22 test cases passed + * Rank: D + */ + +var reverseWords = function(str) { + if (!str) { + return ''; + } + var words = str.trim().split(' '); + var result = ''; + words.forEach(function(e) { + if (e !== '') { + result = e + ' ' + result; + } + }); + return result.trim(); +}; + +console.log(reverseWords('')); +console.log(reverseWords('test')); +console.log(reverseWords('this is a test')); +console.log(reverseWords(' this is a test ')); +console.log(reverseWords(' this is a test ')); \ No newline at end of file diff --git a/rotate-array.js b/rotate-array.js new file mode 100644 index 0000000..d293e88 --- /dev/null +++ b/rotate-array.js @@ -0,0 +1,136 @@ +/** + * Source: https://leetcode.com/problems/rotate-array/ + * Tags: [Array] + * Level: Easy + * Updated: 2015-04-24 + * Title: Rotate Array + * Auther: @imcoddy + * Content: Rotate an array of n elements to the right by k steps. + * For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + * + * Note: + * Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + * + * + * [show hint] + * Hint: + * Could you do it in-place with O(1) extra space? + * + * + * Related problem: Reverse Words in a String II + * + * Credits:Special thanks to @Freezen for adding this problem and creating all test cases. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {void} Do not return anything, modify nums in-place instead. + * @time 264ms + */ +var rotate = function(nums, k) { + k = k % nums.length; + while (k) { + var t = nums.pop(); + nums.unshift(t); + k--; + } + //return nums; +}; + + +/** + * @param {number[]} nums + * @param {number} k + * @return {void} Do not return anything, modify nums in-place instead. + * @time 180ms + */ +var rotate = function(nums, k) { + k = k % nums.length; + if (k > 0) { + var first = nums.slice(0, nums.length - k); + var last = nums.slice(nums.length - k); + for (var i = 0; i < last.length; i++) { + nums[i] = last[i]; + } + for (var i = 0; i < first.length; i++) { + nums[i + k] = first[i]; + } + } + // console.log(nums); + // return nums; +}; + +/** + * Memo: Slice the elements which need to be moved, and put it at front of the array. + * Complex: O(n) + * Runtime: 156ms + * Tests: 33 test cases passed + * Rank: A + * Updated: 2015-06-14 + */ +var rotate = function(nums, k) { + if (nums.length > 1) { + k = k % nums.length; + + var to_move = nums.slice(nums.length - k); + for (var i = nums.length - k - 1; i >= 0; i--) { + nums[i + k] = nums[i]; + } + for (var i = 0; i < to_move.length; i++) { + nums[i] = to_move[i]; + } + } +}; + +/** + * Memo: Rotate the array to right k times + * Complex: O(n) + * Runtime: 252ms + * Tests: 33 test cases passed + * Rank: C + * Updated: 2015-11-10 + */ +var rotate = function(nums, k) { + if (nums.length <= 1) return; + k = k % nums.length; + for (var i = 0; i < k; i++) nums.unshift(nums.pop()); +}; + + +/** + * Memo: Almost same as above, but move to left if k is large than half of length, to make less movement. + * Complex: O(n) + * Runtime: 183ms + * Tests: 33 test cases passed + * Rank: B + * Updated: 2015-06-14 + */ +var rotate = function(nums, k) { + if (nums && nums.length) { + k = k % nums.length; + + if (k > (nums.length >> 1)) { + for (var i = 0; i < nums.length - k; i++) { + nums.push(nums.shift()); + } + } else { + for (var i = 0; i < k; i++) { + nums.unshift(nums.pop()); + } + } + } + //console.log(nums); +}; + +console.log(rotate([1], 0)); +console.log(rotate([1, 2], 1)); +console.log(rotate([1, 2, 3, 4], 1)); +console.log(rotate([1, 2, 3, 4], 2)); +console.log(rotate([1, 2, 3, 4], 3)); +console.log(rotate([1, 2, 3, 4], 4)); +console.log(rotate([1, 2, 3, 4], 8)); +console.log(rotate([1, 2, 3, 4], 9)); +console.log(rotate([1, 2, 3, 4, 5, 6, 7, 8], 7)); +console.log(rotate([1, 2, 3, 4, 5, 6, 7, 8], 23)); +console.log(rotate([1, 2, 3, 4, 5, 6, 7, 8], 9)); \ No newline at end of file diff --git a/rotate-image.js b/rotate-image.js new file mode 100644 index 0000000..5d4efe6 --- /dev/null +++ b/rotate-image.js @@ -0,0 +1,73 @@ +/** + * Source: https://leetcode.com/problems/rotate-image/ + * Tags: [Array] + * Level: Medium + * Title: Rotate Image + * Auther: @imcoddy + * Content: 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. + */ + +/** + * Memo: for element matrix[i,j], the relation is below when rotated. A bit tricky it differs on whether n is even or odd. + * 0: [i,j] + * 90: [j,n-1-i] + * 180: [n-1-i, n-1-j] + * 270: [n-1-j,i] + * Runtime: 128ms + * Tests: 20 test cases passed + * Rank: S + */ +var rotate = function(matrix) { + var n = matrix.length; + + for (var i = 0; i < ~~((n + 1) / 2); i++) { + for (var j = 0; j < ~~((n ) / 2); j++) { + var t = matrix[i][j]; + matrix[i][j] = matrix[n - 1 - j][i]; + matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j]; + matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i]; + matrix[j][n - 1 - i] = t; + } + } +}; + +function createMatrix(n) { + var matrix = []; + var count = 1; + for (var i = 0; i < n; i++) { + var a = []; + for (var j = 0; j < n; j++) { + a.push(count++); + } + matrix.push(a); + } + return matrix; +} +var matrix = createMatrix(2); +console.log(matrix); +rotate(matrix); +console.log(matrix); + + +matrix = createMatrix(3); +console.log(matrix); +rotate(matrix); +console.log(matrix); + +matrix = createMatrix(4); +console.log(matrix); +rotate(matrix); +console.log(matrix); + +matrix = createMatrix(5); +console.log(matrix); +rotate(matrix); +console.log(matrix); diff --git a/rotate-list.js b/rotate-list.js new file mode 100644 index 0000000..d649eb5 --- /dev/null +++ b/rotate-list.js @@ -0,0 +1,245 @@ +/** + * Source: https://leetcode.com/problems/rotate-list/ + * Tags: [Linked List,Two Pointers] + * Level: Medium + * Title: Rotate List + * Auther: @imcoddy + * Content: Given a list, rotate the list to the right by k places, where k is non-negative. + * + * For example: + * Given 1->2->3->4->5->NULL and k = 2, + * return 4->5->1->2->3->NULL. + */ +var util = require("./util.js"); + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @param {number} k + * @return {ListNode} + */ + + +/** + * Memo: Calculate link list length and move accordingly + * Complex: O(n) + * Runtime: 182ms + * Tests: 230 test cases passed + * Rank: B + */ +var rotateRight = function(head, k) { + if (!head || !head.next) { + return head; + } + + var dummy = new ListNode(null); + var p = head; + var count = 0; + while (p) { + p = p.next; + count++; + } + + var break_at = count - (k % count); + if (break_at === count) { + return head; + } + + p = head; + while (--break_at > 0) { + p = p.next; + } + dummy.next = p.next; + p.next = null; + + p = dummy; + while (p.next) { + p = p.next; + } + p.next = head; + return dummy.next; +}; + +/** + * Memo: Note that the k could probably larger than length of the link list + * Complex: O(n) + * Runtime: 168ms + * Tests: 230 test cases passed + * Rank: S + */ +var rotateRight = function(head, k) { + if (!head || !head.next) { + return head; + } + + var dummy = new ListNode(null); + dummy.next = head; + var p = head; + var q = head; + + var count = -k; + while (p.next) { + p = p.next; + count++; + if (count > 0) { + q = q.next; + } + } + + var length = count + k + 1; + if (k % length === 0) { + return head; // no need to move as it turns a full round + } + + if (k < length) { + p.next = dummy.next; + dummy.next = q.next; + q.next = null; + } else { + var break_at = length - (k % length); + p = head; + while (--break_at > 0) { + p = p.next; + } + dummy.next = p.next; + p.next = null; + + p = dummy; + while (p.next) { + p = p.next; + } + p.next = head; + } + + return dummy.next; +}; + +/** + * Memo: Keep track of head and tail, then find the node to separate and relink the list as needed. + * Complex: O(n) + * Runtime: 192ms + * Tests: 230 test cases passed + * Rank: S + * Updated: 2015-06-18 + */ +var rotateRight = function(head, k) { + if (!head || !head.next) return head; + + var dummy = new ListNode(null); + dummy.next = head; + var p = head; + var count = 0; + var tail; + while (p) { + tail = p; + p = p.next; + count++; + } + + k = count - (k % count); + if (k > 0) { + p = dummy.next; + while (--k) p = p.next; + + tail.next = dummy.next; + dummy.next = p.next; + p.next = null; + } + return dummy.next; + +}; + +/** + * Memo: Using two pointers to keep fast and slow has k elements in the middle, then relink the list as needed. Note that k might be a lot larger than the length of the list, so need to check that before relinking. + * Ref: // Source: https://leetcode.com/problems/remove-nth-node-from-end-of-list/ + * Complex: O(n) + * Runtime: 157ms + * Tests: 230 test cases passed + * Rank: S + * Updated: 2015-06-18 + */ +var rotateRight = function(head, k) { + if (!head || !head.next) return head; + + var dummy = new ListNode(null); + dummy.next = head; + var fast = head; + var slow = head; + var tail; + var count = 0; + var move = k; + while (fast) { + count++; + tail = fast; + fast = fast.next; + if (move-- < 0) slow = slow.next; + } + + if (move === 0) return dummy.next; + + if (move > 0) { + move = count - (k % count); + while (--move) slow = slow.next; + } + tail.next = dummy.next; + dummy.next = slow.next; + slow.next = null; + return dummy.next; +}; + + +/** + * Memo: Make the list into a circle if we need to rotate, then rotate to the needed location and break the circle. + * Complex: O(n) + * Runtime: 168ms + * Tests: 230 test cases passed + * Rank: S + * Updated: 2015-06-18 + */ +var rotateRight = function(head, k) { + if (!head || !head.next) return head; + + var length = 1; + var tail = head; + while (tail.next) { + length++; + tail = tail.next; + } + + var newHead = head; + if (k %= length) { + tail.next = head; // make a full circle + for (var i = 0; i < length - k; i++) tail = tail.next; // move to the node before breaking point + newHead = tail.next; + tail.next = null; // break the circle + } + return newHead; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var should = require('should'); +console.time('Runtime'); +util.lta(rotateRight(util.atl([1]), 10)).should.eql([1]); +util.lta(rotateRight(util.atl([1, 2]), 2)).should.eql([1, 2]); +util.lta(rotateRight(util.atl([1, 2]), 3)).should.eql([2, 1]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 1)).should.eql([5, 1, 2, 3, 4]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 2)).should.eql([4, 5, 1, 2, 3]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 3)).should.eql([3, 4, 5, 1, 2]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 4)).should.eql([2, 3, 4, 5, 1]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 5)).should.eql([1, 2, 3, 4, 5]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 9)).should.eql([2, 3, 4, 5, 1]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 11)).should.eql([5, 1, 2, 3, 4]); +util.lta(rotateRight(util.atl([1, 2, 3, 4, 5]), 19)).should.eql([2, 3, 4, 5, 1]); + +console.timeEnd('Runtime'); +console.log(util.linkListToString(rotateRight(util.arrayToLinkList([]), 0))); \ No newline at end of file diff --git a/same-tree.js b/same-tree.js new file mode 100644 index 0000000..74f5104 --- /dev/null +++ b/same-tree.js @@ -0,0 +1,71 @@ +/** + * Source: https://leetcode.com/problems/same-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Updated: 2015-04-24 + * Title: Same Tree + * Auther: @imcoddy + * Content: Given two binary trees, write a function to check if they are equal or not. + * + * + * Two binary trees are considered equal if they are structurally identical and the nodes have the same value. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} p + * @param {TreeNode} q + * @returns {boolean} + */ +/** + * Memo: compare root and children recursively. + * Complex: O(nlgn) + * Runtime: ms + * Tests: 54 test cases passed + * Rank: S + */ +var isSameTree = function(p, q) { + if ((!p && q) || (p && !q)) return false; // one is null + if (!p && !q) return true; // cautious both null nodes generates true + if (p.val !== q.val) return false; // val not equal + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); // check children +}; + +/** + * Memo: Check node recursively + * Complex: O(n) + * Runtime: 120ms + * Tests: 54 test cases passed + * Rank: S + * Updated: 2015-10-05 + */ +function isSameTree(p, q) { + if (!p && !q) return true; + if (!p || !q) return false; + if (p.val !== q.val) return false; + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); +} + +var isSameTree = function(p, q) { + if ((p && !q) || (!p && q)) { + return false; + } + if (!p && !q) { + return true; + } + + if (p.val !== q.val) { + return false; + } else { + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); + } +}; + +console.log(isSameTree(null, null)); \ No newline at end of file diff --git a/search-a-2d-matrix-ii.js b/search-a-2d-matrix-ii.js new file mode 100644 index 0000000..0935397 --- /dev/null +++ b/search-a-2d-matrix-ii.js @@ -0,0 +1,123 @@ +/** + * Source: https://leetcode.com/problems/search-a-2d-matrix-ii/ + * Tags: [Divide and Conquer,Binary Search] + * Level: Medium + * Title: Search a 2D Matrix II + * Auther: @imcoddy + * Content: 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. + * + * + * Subscribe to see which companies asked this question + * + * + * + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Search a 2D Matrix + */ + +/** + * @param {number[][]} matrix + * @param {number} target + * @return {boolean} + */ + +/** + * Memo: Find possible rows and apply binary search on each row + * Complex: O(m+mlogn) + * Runtime: 344ms + * Tests: 127 test cases passed + * Rank: B + * Updated: 2015-11-19 + */ +var searchMatrix = function(matrix, target) { + function binarySearch(nums, target) { + var start = 0; + var end = nums.length - 1; + + while (start <= end) { + var mid = ~~((start + end) / 2); + if (nums[mid] === target) return true; + nums[mid] > target ? end = mid - 1 : start = mid + 1; + } + return false; + } + var arrays = []; + var m = matrix.length; + var n = matrix[0].length; + if (target < matrix[0][0] || target > matrix[m - 1][n - 1]) return false; + + for (var i = 0; i < m; i++) { + if (matrix[i][0] === target || matrix[i][n - 1] === target) return true; + if (matrix[i][0] < target && target < matrix[i][n - 1]) arrays.push(matrix[i]); + } + for (var i = 0; i < arrays.length; i++) { + if (binarySearch(arrays[i], target)) return true; + } + return false; +}; + +/** + * Memo: Search from top right cornor and ignore invalid row or column; + * Complex: O(m+n) + * Runtime: 216ms + * Tests: 127 test cases passed + * Rank: S + * Updated: 2015-11-19 + */ +var searchMatrix = function(matrix, target) { + if (!matrix || matrix.length < 1 || matrix[0].length < 1) return false; + + var row = 0; + var col = matrix[0].length - 1; + while (row < matrix.length && col >= 0) { + if (matrix[row][col] === target) return true; + matrix[row][col] < target ? row++ : col--; + } + return false; +}; + +console.log( + searchMatrix( + [ + [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + ], 11 + )); \ No newline at end of file diff --git a/search-a-2d-matrix.js b/search-a-2d-matrix.js new file mode 100644 index 0000000..1a71726 --- /dev/null +++ b/search-a-2d-matrix.js @@ -0,0 +1,160 @@ +/** + * Source: https://leetcode.com/problems/search-a-2d-matrix/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Search a 2D Matrix + * Auther: @imcoddy + * Content: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: + * + * + * + * Integers in each row are sorted from left to right. + * The first integer of each row is greater than the last integer of the previous row. + * + * + * + * + * For example, + * + * Consider the following matrix: + * + * + * [ + * [1, 3, 5, 7], + * [10, 11, 16, 20], + * [23, 30, 34, 50] + * ] + * + * + * Given target = 3, return true. + */ + +/** + * @param {number[][]} matrix + * @param {number} target + * @return {boolean} + */ + +/** + * Memo: Use BS to search, just need to calculate the index into a 2d array. Note that for matrix[i,j], it is (i-1)*n+j th element + * Complex: O(logmn) + * Runtime: 125ms + * Tests: 134 test cases passed + * Rank: S + */ +var searchMatrix = function(matrix, target) { + var m = matrix.length; + var n = matrix[0].length; + + var start = 0; + var end = m * n - 1; + var mid = 0; + while (start <= end) { + mid = ~~((start + end) / 2); + var i = ~~((mid / n)); + var j = mid - i * n; + if (matrix[i][j] === target) return true; + matrix[i][j] < target ? start = mid + 1 : end = mid - 1; + } + return false; +}; + +// Shorter version of the above +var searchMatrix = function(matrix, target) { + var m = matrix.length; + var n = matrix[0].length; + if (target < matrix[0][0] || target > matrix[m - 1][n - 1]) return false; + var start = 0; + var end = m * n - 1; + while (start <= end) { + var mid = ~~((start + end) / 2); + matrix[~~((mid / n))][mid % n] < target ? start = mid + 1 : end = mid - 1; + } + return matrix[~~((start / n))][start % n] === target; +}; + +/** + * Memo: First using binary search to find which row the result might be in, then use binary search to see if the target is in that row. + * Complex: O(logm + logn) + * Runtime: 130ms + * Tests: 134 test cases passed + * Rank: S + * Updated: 2015-06-28 + */ +var searchMatrix = function(matrix, target) { + var m = matrix.length; + var n = matrix[0].length; + if (target < matrix[0][0] || target > matrix[m - 1][n - 1]) return false; + + var start = 0; + var end = m - 1; + while (start <= end) { + var mid = ~~((start + end) / 2); + if (matrix[mid][0] === target) return true; + matrix[mid][0] > target ? end = mid - 1 : start = mid + 1; + } + + var row = start - 1; + start = 0; + end = n - 1; + + while (start <= end) { + var mid = ~~((start + end) / 2); + if (matrix[row][mid] === target) return true; + matrix[row][mid] > target ? end = mid - 1 : start = mid + 1; + } + return false; +}; + + +var should = require('should'); +console.time('Runtime'); +searchMatrix( + [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] + ], 0 +).should.be.exactly(false); + + +searchMatrix( + [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] + ], 2 +).should.be.exactly(false); + +searchMatrix( + [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] + ], 3 +).should.be.exactly(true); + +searchMatrix( + [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] + ], 4 +).should.be.exactly(false); + +searchMatrix( + [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] + ], 40 +).should.be.exactly(false); + +searchMatrix( + [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] + ], 50 +).should.be.exactly(true); +console.timeEnd('Runtime'); diff --git a/search-for-a-range.js b/search-for-a-range.js new file mode 100644 index 0000000..3ba8b28 --- /dev/null +++ b/search-for-a-range.js @@ -0,0 +1,153 @@ +/** + * Source: https://leetcode.com/problems/search-for-a-range/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Search for a Range + * Auther: @imcoddy + * Content: Given a sorted array of integers, find the starting and ending position of a given target value. + * + * Your algorithm's runtime complexity must be in the order of O(log n). + * + * If the target is not found in the array, return [-1, -1]. + * + * + * For example, + * Given [5, 7, 7, 8, 8, 10] and target value 8, + * return [3, 4]. + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number[]} + */ + +/** + * Memo: locate the target first, if it is not in the array then return [-1,-1] directly, otherwise search if same element exists or not and widen range. + * Runtime: 144ms + * Tests: 81 test cases passed + * Rank: A + */ +var searchRange = function(nums, target) { + function BS(nums, target) { + var start = 0; + var end = nums.length - 1; + var mid = 0; + while (start <= end) { + mid = ~~((start + end) / 2); + if (nums[mid] === target) return mid; + nums[mid] < target ? start = mid + 1 : end = mid - 1; + } + return start; + } + + var index = BS(nums, target); + if (nums[index] !== target) { + return [-1, -1]; + } + + var result = [index, index]; + while (result[0] > 0 && nums[result[0] - 1] === target) { + result[0]--; + } + while (result[1] + 1 < nums.length && nums[result[1] + 1] === target) { + result[1]++; + } + return result; +}; + +/** + * Memo: Binary search to see if the target is in array nums, and expand with the index if it exists. + * Complex: O(n) + * Runtime: 136ms + * Tests: 81 test cases passed + * Rank: A + * Updated: 2015-06-28 + */ +var searchRange = function(nums, target) { + function bs(left, right, target) { + var start = left; + var end = right; + while (start <= end) { + var mid = ~~((start + end) / 2); + if (nums[mid] === target) return mid; + nums[mid] > target ? end = mid - 1 : start = mid + 1; + } + return start; + } + var index = bs(0, nums.length - 1, target); + + if (nums[index] !== target) return [-1, -1]; + var result = [index, index]; + while (result[0] > 0 && nums[result[0] - 1] === target) result[0]--; + while (result[1] + 1 < nums.length && nums[result[1] + 1] === target) result[1]++; + return result; +}; + +/** + * Memo: Use two binary search to find left and right boundaries. + * Ref: https://leetcode.com/discuss/18242/clean-iterative-solution-binary-searches-with-explanation + * Complex: O(logn) + * Runtime: 130ms + * Tests: 81 test cases passed + * Rank: S + * Updated: 2015-06-28 + */ +var searchRange = function(nums, target) { + var result = [-1, -1]; + var i = 0; + var j = nums.length - 1; + // found left boundary of the range. + while (i < j) { + var mid = ~~((i + j) / 2); + nums[mid] < target ? i = mid + 1 : j = mid; + } + if (nums[i] !== target) return result; + result[0] = i; + + // reset and find right boundary. + j = nums.length - 1; + while (i < j) { + var mid = ~~((i + j + 1) / 2); + nums[mid] <= target ? i = mid : j = mid - 1; + } + result[1] = j; + return result; +}; + +/** + * Memo: Shorter version of the above + * Complex: O(logn) + * Runtime: 150ms + * Tests: 81 test cases passed + * Rank: A + * Updated: 2015-06-28 + */ +var searchRange = function(nums, target) { + var i = 0; // left boundary + var j = nums.length - 1; // right boundary + var mid = 0; + // found left boundary of the range. + while (i < j) nums[mid = ~~((i + j) / 2)] < target ? i = mid + 1 : j = mid; + if (nums[i] !== target) return [-1, -1]; + // reset and find right boundary. + var left = i; + j = nums.length - 1; + while (i < j) nums[mid = ~~((i + j + 1) / 2)] <= target ? i = mid : j = mid - 1; + return [left, j]; +}; + +var should = require('should'); +console.time('Runtime'); + +searchRange([1, 3, 5, 6], 5).should.eql([2, 2]); +searchRange([1, 3, 5, 6], 1).should.eql([0, 0]); +searchRange([1, 3, 5, 6], 6).should.eql([3, 3]); +searchRange([1, 3, 5, 6], 0).should.eql([-1, -1]); +searchRange([1, 3, 5, 6], 8).should.eql([-1, -1]); +searchRange([1, 1, 1, 1, 1, 3, 5, 6], 1).should.eql([0, 4]); +searchRange([1, 3, 5, 6, 6, 6, 6, 6], 6).should.eql([3, 7]); +searchRange([1, 3, 5, 5, 5, 5, 5, 6, 7], 5).should.eql([2, 6]); +searchRange([0, 0, 1, 1, 1, 4, 5, 5], 2).should.eql([-1, -1]); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/search-in-rotated-sorted-array.js b/search-in-rotated-sorted-array.js new file mode 100644 index 0000000..4af83be --- /dev/null +++ b/search-in-rotated-sorted-array.js @@ -0,0 +1,88 @@ +/** + * Source: https://leetcode.com/problems/search-in-rotated-sorted-array/ + * Tags: [Array,Binary Search] + * Level: Hard + * Title: Search in Rotated Sorted Array + * Auther: @imcoddy + * Content: 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} + */ + +/** + * Memo: Rotate the array to soted state, then try to find if the target is in the array using binary search. + * Complex: O(n) + * Runtime: 152ms + * Tests: 194 test cases passed + * Rank: S + * Updated: 2015-06-28 + */ +var search = function(nums, target) { + var count = 0; + var length = nums.length; + while (nums[0] > nums[length - 1]) { + nums.unshift(nums.pop()); + count++; + } + + var start = 0; + var end = length - 1; + while (start <= end) { + var mid = (start + end) >> 1; + if (nums[mid] === target) return mid >= count ? (mid - count) : (length + mid - count); + nums[mid] < target ? start = mid + 1 : end = mid - 1; + } + return -1; +}; + +/** + * Memo: Find minimum first, then we can figure out how many elements we have rotated. Use that offset we can treat it as a shorted array and perform a binary search using the offse to calculate the real mid + * Ref: https://leetcode.com/discuss/11701/concise-o-log-n-binary-search-solution + * Complex: O(logn) + * Runtime: 140ms + * Tests: 194 test cases passed + * Rank: S + * Updated: 2015-07-05 + */ +var search = function(nums, target) { + var length = nums.length; + var start = 0; + var end = length - 1; + var mid = 0; + while (start < end) { + if (nums[start] < nums[end]) break; // already sorted + mid = ~~((start + end) / 2); + nums[start] > nums[mid] ? end = mid : start = mid + 1; + } + + // now start will be the index of the minimum + var offset = start; + start = 0; + end = length - 1; + while (start <= end) { + mid = ~~((start + end) / 2); + var real_mid = (mid + offset) % length; + if (nums[real_mid] === target) return real_mid; + target < nums[real_mid] ? end = mid - 1 : start = mid + 1; + } + return -1; +}; + +var should = require('should'); +console.time('Runtime'); +search([1], 0).should.equal(-1); +search([2, 1], 1).should.equal(1); +search([4, 5, 6, 7, 0, 1, 2], 3).should.equal(-1); +search([4, 5, 6, 7, 0, 1, 2], 1).should.equal(5); +search([4, 5, 6, 7, 0, 1, 2], 4).should.equal(0); +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/search-insert-position.js b/search-insert-position.js new file mode 100644 index 0000000..fc37b9b --- /dev/null +++ b/search-insert-position.js @@ -0,0 +1,46 @@ +/** + * Source: https://leetcode.com/problems/search-insert-position/ + * Tags: [Array,Binary Search] + * Level: Medium + * Title: Search Insert Position + * Auther: @imcoddy + * Content: Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. + * + * You may assume no duplicates in the array. + * + * + * Here are few examples. + * [1,3,5,6], 5 → 2 + * [1,3,5,6], 2 → 1 + * [1,3,5,6], 7 → 4 + * [1,3,5,6], 0 → 0 + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ + +/** + * Memo: + * Runtime: 130ms + * Tests: 62 test cases passed + * Rank: S + */ +var searchInsert = function(nums, target) { + var start = 0; + var end = nums.length - 1; + var mid = 0; + while (start <= end) { + mid = ~~((start + end) / 2); + if (nums[mid] === target) return mid; + nums[mid] < target ? start = mid + 1 : end = mid - 1; + } + return nums[mid] < target ? mid + 1 : mid; +}; + +console.log(searchInsert([1, 3, 5, 6], 5)); +console.log(searchInsert([1, 3, 5, 6], 2)); +console.log(searchInsert([1, 3, 5, 6], 7)); +console.log(searchInsert([1, 3, 5, 6], 0)); \ No newline at end of file diff --git a/set-matrix-zeroes.js b/set-matrix-zeroes.js new file mode 100644 index 0000000..4b92ca2 --- /dev/null +++ b/set-matrix-zeroes.js @@ -0,0 +1,64 @@ +/** + * Source: https://leetcode.com/problems/set-matrix-zeroes/ + * Tags: [Array] + * Level: Medium + * Title: Set Matrix Zeroes + * Auther: @imcoddy + * Content: Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. + * + * + * click to show follow up. + * + * Follow up: + * + * + * Did you use extra space? + * A straight forward solution using O(mn) space is probably a bad idea. + * A simple improvement uses O(m + n) space, but still not the best solution. + * Could you devise a constant space solution? + */ + +/** + * @param {number[][]} matrix + * @return {void} Do not return anything, modify matrix in-place instead. + */ + + //TODO solve this in a constant space solution + +/** + * Memo: track indexes where element is 0, then set the whole row and column to 0 in a loop. + * Runtime: 238ms + * Tests: 157 test cases passed + * Rank: S + */ +var setZeroes = function(matrix) { + var m = matrix.length; + var n = matrix[0].length; + var indexes = []; + + for (var i = 0; i < m; i++) { + for (var j = 0; j < n; j++) { + if (matrix[i][j] === 0) { + indexes.push([i, j]); + } + } + } + + for (var i = 0; i < indexes.length; i++) { + for (var j = 0; j < m; j++) { + matrix[j][indexes[i][1]] = 0; + } + for (var j = 0; j < n; j++) { + matrix[indexes[i][0]][j] = 0; + } + } +}; + +var matrix = [ + [0, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 0] +]; + +setZeroes(matrix); +console.log(matrix); diff --git a/simplify-path.js b/simplify-path.js new file mode 100644 index 0000000..21bfae5 --- /dev/null +++ b/simplify-path.js @@ -0,0 +1,58 @@ +/** + * Source: https://leetcode.com/problems/simplify-path/ + * Tags: [Stack,String] + * Level: Medium + * Title: Simplify Path + * Auther: @imcoddy + * Content: Given an absolute path for a file (Unix-style), simplify it. + * + * For example, + * path = "/home/", => "/home" + * path = "/a/./b/../../c/", => "/c" + * + * + * click to show corner cases. + * + * Corner Cases: + * + * + * + * Did you consider the case where path = "/../"? + * In this case, you should return "/". + * Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". + * In this case, you should ignore redundant slashes and return "/home/foo". + */ + +/** + * @param {string} path + * @return {string} + */ + +/** + * Memo: + * Runtime: 150ms + * Tests: 252 test cases passed + * Rank: A + */ +var simplifyPath = function(path) { + var directories = path.split('\/'); + var stack = []; + for (var i = 0; i < directories.length; i++) { + var d = directories[i]; + if (d === '..') { + stack.pop(); + } else if (d !== '.' && d !== '') { + stack.push(d); + } + } + + return '/' + stack.join('/'); +}; + + +console.log(simplifyPath('/')); +console.log(simplifyPath('/a')); +console.log(simplifyPath('/a/')); +console.log(simplifyPath('/a/./b/../../c/')); +console.log(simplifyPath('/a/./b/../../c/d/e/f/g/')); +console.log(simplifyPath('///a/.//b/../../c///')); \ No newline at end of file diff --git a/single-number-ii.js b/single-number-ii.js new file mode 100644 index 0000000..ffb42f8 --- /dev/null +++ b/single-number-ii.js @@ -0,0 +1,45 @@ +/** + * Source: https://leetcode.com/problems/single-number-ii/ + * Tags: [Bit Manipulation] + * Level: Medium + * Title: Single Number II + * Auther: @imcoddy + * Content: Given an array of integers, every element appears three times except for one. Find that single one. + * + * + * + * Note: + * Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? + */ + +/** + * @param {number[]} nums + * @return {number} + */ +/** + * Memo: Same as https://leetcode.com/problems/single-number using hashmap + * Complex: O(n) + * Runtime: 128ms + * Tests: 11 test cases passed + * Rank: A + * Updated: 2015-06-12 + */ +var singleNumber = function(nums) { + var map = Object.create(null); + + for (var i = 0; i < nums.length; i++) { + if (map[nums[i]]) { + map[nums[i]]++; + } else { + map[nums[i]] = 1; + } + } + + for (var m in map) { + if (map[m] === 1) { + return parseInt(m); + } + } +}; + +//TODO add Bit Manipulation solution \ No newline at end of file diff --git a/single-number.js b/single-number.js new file mode 100644 index 0000000..1796bc1 --- /dev/null +++ b/single-number.js @@ -0,0 +1,71 @@ +/** + * Source: https://leetcode.com/problems/single-number/ + * Tags: [Hash Table,Bit Manipulation] + * Level: Medium + * Updated: 2015-04-24 + * Title: Single Number + * Auther: @imcoddy + * Content: Given an array of integers, every element appears twice except for one. Find that single one. + * + * + * Note: + * Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? + */ + +/** + * @param {number[]} A + * @return {number} + */ +var singleNumber = function(A) { + var result = 0; + for (var i = 0; i < A.length; i++) result ^= A[i]; + return result; +}; + +/** + * Memo: Bit Manipulation. Note that A^B^B will be A. As there is only one number that appears only once, this will do the trick. + * Complex: O(n) + * Runtime: 140ms + * Tests: 15 test cases passed + * Rank: A + * Updated: 2015-06-12 + */ +var singleNumber = function(nums) { + var result = 0; + for (var i = 0; i < nums.length; i++) { + result ^= nums[i]; + } + return result; +}; + +/** + * Memo: Use a map to record how many times the element has appeared. + * Complex: O(n) + * Runtime: 148ms + * Tests: 15 test cases passed + * Rank: B + * Updated: 2015-06-12 + */ +var singleNumber = function(nums) { + var map = Object.create(null); + + for (var i = 0; i < nums.length; i++) { + if (map[nums[i]]) { + map[nums[i]]++; + } else { + map[nums[i]] = 1; + } + } + + for (var m in map) { + if (map[m] === 1) { + return parseInt(m); + } + } +}; + +var should = require('should'); +console.time('Runtime'); +singleNumber([1, 1, 2, 2, 3]).should.equal(3); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/sort-colors.js b/sort-colors.js new file mode 100644 index 0000000..ce8e651 --- /dev/null +++ b/sort-colors.js @@ -0,0 +1,57 @@ +/** + * Source: https://leetcode.com/problems/sort-colors/ + * Tags: [Array,Two Pointers,Sort] + * Level: Medium + * Title: Sort Colors + * Auther: @imcoddy + * Content: 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. + * + * + * Follow up: + * A rather straight forward solution is a two-pass algorithm using counting sort. + * First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. + * Could you come up with an one-pass algorithm using only constant space? + */ + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ + + /** + * Memo: record how many 0, 1 and 2, then replace the whole array with that result. + * Runtime: 122ms + * Tests: 86 test cases passed + * Rank: S + */ +var sortColors = function(nums) { + var result = [0,0,0]; + for (var i = 0; i < nums.length; i++) { + result[nums[i]]++; + } + for (var i = 0; i < result[0]; i++) { + nums[i] = 0; + } + for (var i = 0; i < result[1]; i++) { + nums[i+result[0]] = 1; + } + for (var i = 0; i < result[2]; i++) { + nums[i+result[0]+result[1]] = 2; + } +}; + +var nums = [0,1,2,0,1,2]; +sortColors(nums); +console.log(nums); diff --git a/sort-list.js b/sort-list.js new file mode 100644 index 0000000..414546c --- /dev/null +++ b/sort-list.js @@ -0,0 +1,70 @@ +/** + * Source: https://leetcode.com/problems/sort-list/ + * Tags: [Linked List,Sort] + * Level: Medium + * Title: Sort List + * Auther: @imcoddy + * Content: Sort a linked list in O(n log n) time using constant space complexity. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +/** + * Memo: Use fast and slow pointer to get the middle node, break it into two lists and use merge sort recursively + * Complex: O(nlogn) + * Runtime: 224ms + * Tests: 15 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var sortList = function(head) { + if (!head || !head.next) return head; + var fast = head.next.next; + var slow = head; + while (fast && fast.next) { + fast = fast.next.next; + slow = slow.next; + } + + var head1 = sortList(slow.next); + slow.next = null; + var head2 = sortList(head); + return mergeList(head1, head2); +}; + +var mergeList = function(h1, h2) { + var dummy = new ListNode(null); + var tail = dummy; + while (h1 && h2) { + if (h1.val <= h2.val) { + tail = tail.next = h1; + h1 = h1.next; + } else { + tail = tail.next = h2; + h2 = h2.next; + } + } + tail.next = h1 ? h1 : h2; + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +util.lta(mergeList(util.atl([1, 3, 5, 8, 9]), util.atl([2, 4, 6, 7, 10]))).should.eql([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); +util.lta(sortList(util.atl([1, 3, 5, 8, 9, 2, 4, 6, 7, 10]))).should.eql([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/spiral-matrix-ii.js b/spiral-matrix-ii.js new file mode 100644 index 0000000..144f29e --- /dev/null +++ b/spiral-matrix-ii.js @@ -0,0 +1,72 @@ +/** + * Source: https://leetcode.com/problems/spiral-matrix-ii/ + * Tags: [Array] + * Level: Medium + * Title: Spiral Matrix II + * Auther: @imcoddy + * Content: 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 ] + * ] + */ + +/** + * @param {number} n + * @return {number[][]} + */ +/** + * Memo: simulate spiral traveral. + * Runtime: 136ms + * Tests: 21 test cases passed + * Rank: B + */ +var generateMatrix = function(n) { + if (n <= 0) { + return []; + } + var directions = [ + [0, 1], + [1, 0], + [0, -1], + [-1, 0] + ]; + + var result = []; + for (var i = 0; i < n; i++) { + var a = []; + for (var j = 0; j < n; j++) { + a.push(0); + } + result.push(a); + } + + var direction = 0; + var index = [0, 0]; + + for (var i = 1; i <= n * n; i++) { + var next = []; + result[index[0]][index[1]] = i; + next[0] = index[0] + directions[direction][0]; + next[1] = index[1] + directions[direction][1]; + if (next[0] < 0 || next[0] > n - 1 || next[1] < 0 || next[1] > n - 1 || result[next[0]][next[1]] > 0) { + direction = (direction + 1) % 4; + next[0] = index[0] + directions[direction][0]; + next[1] = index[1] + directions[direction][1]; + } + index = next; + } + return result; +}; + +console.log(generateMatrix(2)); +console.log(generateMatrix(3)); +console.log(generateMatrix(5)); diff --git a/spiral-matrix.js b/spiral-matrix.js new file mode 100644 index 0000000..a155aa2 --- /dev/null +++ b/spiral-matrix.js @@ -0,0 +1,81 @@ +/** + * Source: https://leetcode.com/problems/spiral-matrix/ + * Tags: [Array] + * Level: Medium + * Title: Spiral Matrix + * Auther: @imcoddy + * Content: 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]. + */ + +/** + * @param {number[][]} matrix + * @return {number[]} + */ + /** + * Memo: mark the visited element to undefined and try to reach next index if valid + * Runtime: 131ms + * Tests: 21 test cases passed + * Rank: S + */ +var spiralOrder = function(matrix) { + if (!matrix || matrix.length === 0) { + return []; + } + var result = []; + var m = matrix.length; + var n = matrix[0].length; + var directions = [ + [0, 1], + [1, 0], + [0, -1], + [-1, 0] + ]; + var direction = 0; + var index = [0, 0]; + + for (var i = 0; i < m * n; i++) { + result.push(matrix[index[0]][index[1]]); + matrix[index[0]][index[1]] = undefined; + var next = []; + next[0] = index[0] + directions[direction][0]; + next[1] = index[1] + directions[direction][1]; + if (next[0] < 0 || next[0] > m - 1 || next[1] < 0 || next[1] > n - 1 || !matrix[next[0]][next[1]]) { + direction = (direction + 1) % 4; + next[0] = index[0] + directions[direction][0]; + next[1] = index[1] + directions[direction][1]; + } + index = next; + } + + return result; +}; + +console.log(spiralOrder([])); + +console.log(spiralOrder([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] +])); + + +console.log(spiralOrder([ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12] +])); diff --git a/sqrtx.js b/sqrtx.js new file mode 100644 index 0000000..17e242d --- /dev/null +++ b/sqrtx.js @@ -0,0 +1,59 @@ +/** + * Source: https://leetcode.com/problems/sqrtx/ + * Tags: [Math,Binary Search] + * Level: Medium + * Title: Sqrt(x) + * Auther: @imcoddy + * Content: Implement int sqrt(int x). + * + * Compute and return the square root of x. + */ + +/** + * @param {number} x + * @return {number} + */ +var mySqrt = function(x) { + if (x === 0) return 0; + var low = 1; + var high = x; + while (low + 1 < high) { + var mid = low + ((high - low) >> 1); + mid * mid > x ? high = mid : low = mid; + } + return low; +}; + +/** + * Memo: + * Complex: O(logn) + * Runtime: 216ms + * Tests: 1017 test cases passed + * Rank: B + * Updated: 2015-11-19 + */ +var mySqrt = function(x) { + if (x <= 0) return 0; + + var start = 1; + var end = x; + while (end - start > 1) { + var mid = ~~((end + start) / 2); + mid * mid <= x ? start = mid : end = mid; + } + return start; +}; +var should = require('should'); +console.time('Runtime'); + +mySqrt(0).should.equal(0); +mySqrt(1).should.equal(1); +mySqrt(2).should.equal(1); +mySqrt(3).should.equal(1); +mySqrt(4).should.equal(2); +mySqrt(15).should.equal(3); +mySqrt(16).should.equal(4); +mySqrt(17).should.equal(4); +mySqrt(25).should.equal(5); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/subsets.js b/subsets.js new file mode 100644 index 0000000..da3b47e --- /dev/null +++ b/subsets.js @@ -0,0 +1,119 @@ +/** + * Source: https://leetcode.com/problems/subsets/ + * Tags: [Array,Backtracking,Bit Manipulation] + * Level: Medium + * Title: Subsets + * Auther: @imcoddy + * Content: Given a set of distinct integers, nums, return all possible subsets. + * + * Note: + * + * Elements in a subset must be in non-descending order. + * 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[][]} + */ +/** + * Memo: + * Runtime: 134ms + * Tests: 10 test cases passed + * Rank: S + */ +var subsets = function(nums) { + var length = nums.length; + if (length <= 0) { + return [ + [] + ]; + } + + var result = []; + var solution = []; + + function subsetsBT(row) { + if (row >= length) { + return; + } else { + for (var i = 0; i < nums.length; i++) { + solution[row] = nums[i]; + if (isValid(row)) { + result.push(solution.slice(0, row + 1)); + subsetsBT(row + 1); + } + } + } + } + + function isValid(row) { + return row >= 1 ? solution[row] > solution[row - 1] : true; + } + + subsetsBT(0); + result.push([]); + return result; +}; + +/** + * Memo: Backtracking solution + * Complex: O(n^n) + * Runtime: 144ms + * Tests: 10 test cases passed + * Rank: A + * Updated: 2015-06-12 + */ +var subsets = function(nums) { + var result = [ + [] + ]; + var subset = []; + + function backTrack(index) { + if (index > nums.length) { + return; + } else { + for (var i = 0; i < nums.length; i++) { + subset[index] = nums[i]; + if (isValid(index)) { + result.push(subset.slice(0, index + 1)); + backTrack(index + 1); + } + } + } + } + + function isValid(i) { + return i >= 1 ? subset[i] > subset[i - 1] : true; + } + + backTrack(0); + return result; +}; + +console.time('Runtime'); + +console.log(subsets([])); +console.log(subsets([1])); +console.log(subsets([1, 2, 3])); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/sum-root-to-leaf-numbers.js b/sum-root-to-leaf-numbers.js new file mode 100644 index 0000000..9088680 --- /dev/null +++ b/sum-root-to-leaf-numbers.js @@ -0,0 +1,90 @@ +/** + * Source: https://leetcode.com/problems/sum-root-to-leaf-numbers/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Sum Root to Leaf Numbers + * Auther: @imcoddy + * Content: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. + * An example is the root-to-leaf path 1->2->3 which represents the number 123. + * + * Find the total sum of all root-to-leaf numbers. + * + * For example, + * + * 1 + * / \ + * 2 3 + * + * + * + * The root-to-leaf path 1->2 represents the number 12. + * The root-to-leaf path 1->3 represents the number 13. + * + * + * Return the sum = 12 + 13 = 25. + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {number} + */ + +/** + * Memo: + * Runtime: 136ms + * Rank: S + */ +var sumNumbers = function(root) { + function DFS(root, sumOfPath) { + if (!root) return 0; //return 0 when node doesn't exists + sumOfPath = 10 * sumOfPath + root.val; // sum of current path (till this node) + if (!root.left && !root.right) return sumOfPath; //return on leaf node + return DFS(root.left, sumOfPath) + DFS(root.right, sumOfPath); //keep on calculating + } + return DFS(root, 0); +}; + +/** + * Memo: Recusive solution from top to bottom + * Complex: O(n) + * Runtime: 120ms + * Tests: 109 test cases passed + * Rank: S + */ +var sumNumbers = function(root) { + function traverse(root, sumOfPath) { + if (!root) return 0; + sumOfPath = 10 * sumOfPath + root.val; + return (!root.left && !root.right) ? sumOfPath : traverse(root.left, sumOfPath) + traverse(root.right, sumOfPath); + } + return traverse(root, 0); +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(3); +root.left = node; + +console.log(sumNumbers(root)); + +node = new TreeNode(4); +root.left.left = node; + +console.log(sumNumbers(root)); \ No newline at end of file diff --git a/summary-ranges.js b/summary-ranges.js new file mode 100644 index 0000000..6e238a6 --- /dev/null +++ b/summary-ranges.js @@ -0,0 +1,71 @@ +/** + * Source: https://leetcode.com/problems/summary-ranges/ + * Tags: [Array] + * Level: Easy + * Title: Summary Ranges + * Auther: @imcoddy + * Content: Given a sorted integer array without duplicates, return the summary of its ranges. + * + * + * For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"]. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (M) Missing Ranges + */ + +/** + * @param {number[]} nums + * @return {string[]} + */ +/** + * Memo: Find each range by iterate all nums + * Complex: O(n) + * Runtime: 116ms + * Tests: 27 test cases passed + * Rank: A + * Updated: 2015-09-30 + */ +var summaryRanges = function(nums) { + var result = []; + var range = []; + while (nums.length > 0) { + range.push(nums.shift()); + if (range.length === 1) { + range.push(range[0]); + while (nums[0] === range[1] + 1) range[1] = nums.shift(); + result.push(range[0] === range[1] ? '' + range[0] : range[0] + '->' + range[1]); + range = []; + } + } + return result; +}; + +var summaryRanges = function(nums) { + var result = []; + var index = 0; + while (index < nums.length) { + var range = [nums[index], nums[index++]]; + while (nums[index] === range[1] + 1) range[1] = nums[index++]; + result.push(range[0] === range[1] ? '' + range[0] : range[0] + '->' + range[1]); + } + return result; +}; + +var should = require('should'); +console.time('Runtime'); +summaryRanges([0, 1, 2, 4, 5, 7]).should.eql(['0->2', '4->5', '7']); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/swap-nodes-in-pairs.js b/swap-nodes-in-pairs.js new file mode 100644 index 0000000..c585600 --- /dev/null +++ b/swap-nodes-in-pairs.js @@ -0,0 +1,101 @@ +/** + * Source: https://leetcode.com/problems/swap-nodes-in-pairs/ + * Tags: [Linked List] + * Level: Medium + * Title: Swap Nodes in Pairs + * Auther: @imcoddy + * Content: Given a linked list, swap every two adjacent nodes and return its head. + * + * + * + * For example, + * Given 1->2->3->4, you should return the list as 2->1->4->3. + * + * + * + * Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ + +/** + * Memo: Need to track one tail node before swap the following! + * Runtime: 135ms + * Tests: 55 test cases passed + * Rank: A + */ +var swapPairs = function(head) { + var p = head; + if (!p) { + return p; + } + + var q = p.next; + if (!q) { + return p; + } + + head = q; + var tail = p; + while (p) { + q = p.next; + if (q) { + tail.next = q; + var n = q.next; + p.next = n; + q.next = p; + } + tail = p; + p = p.next; + } + return head; +}; + + +/** + * Memo: Append two swapped nodes to a new list, and move pointer at two in one loop + * Complex: O(n) + * Runtime: 140ms + * Tests: 55 test cases passed + * Rank: S + * Updated: 2015-06-20 + */ +var swapPairs = function(head) { + if (!head || !head.next) return head; + + var dummy = new ListNode(null); + var tail = dummy; + var p = head; + while (p && p.next) { + var next = p.next.next; + tail = tail.next = p.next; + tail = tail.next = p; + p = next; + } + tail.next = p ? p : null; + + return dummy.next; +}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +var util = require("./util.js"); +var should = require('should'); +console.time('Runtime'); +(util.lta(swapPairs(util.atl([1, 2, 3, 4, 5]))).should.eql([2, 1, 4, 3, 5])); +(util.lta(swapPairs(util.atl([1, 2, 3, 4]))).should.eql([2, 1, 4, 3])); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/symmetric-tree.js b/symmetric-tree.js new file mode 100644 index 0000000..a0c86dc --- /dev/null +++ b/symmetric-tree.js @@ -0,0 +1,138 @@ +/** + * Source: https://leetcode.com/problems/symmetric-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Easy + * Title: Symmetric Tree + * Auther: @imcoddy + * Content: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + * + * + * For example, this binary tree is symmetric: + * + * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + * + * + * + * But the following is not: + * + * 1 + * / \ + * 2 2 + * \ \ + * 3 3 + * + * + * + * + * Note: + * Bonus points if you could solve it both recursively and iteratively. + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ + +/** + * Definition for binary tree + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @returns {boolean} + */ + +/** + * Memo: Traverse the tree by two approaches, leftRight or rightLeft, then see if the orders are the same or not. + * Runtime: 153ms + * Rank: S + */ +var isSymmetric = function(root) { + var travelLeft = function(root, order) { + if (root) { + order.push(root.val); + root.left ? travelLeft(root.left, order) : order.push('#'); + root.right ? travelLeft(root.right, order) : order.push('#'); + } + return order; + }; + + var travelRight = function(root, order) { + if (root) { + order.push(root.val); + root.right ? travelRight(root.right, order) : order.push('#'); + root.left ? travelRight(root.left, order) : order.push('#'); + } + return order; + }; + + var leftOrders = travelLeft(root, []); + var rightOrders = travelRight(root, []); + var result = JSON.stringify(leftOrders) === JSON.stringify(rightOrders); + + console.log(leftOrders); + console.log(rightOrders); + return result; +}; + +/** + * Memo: Check left and right subtree accordingly + * Complex: O(n) + * Runtime: 148ms + * Tests: 192 test cases passed + * Rank: A + */ +var isSymmetric = function(root) { + function checkLeftRight(left, right) { + if (left === null || right === null) return left === right; + return left.val === right.val && checkLeftRight(left.left, right.right) && checkLeftRight(left.right, right.left); + } + + return root ? checkLeftRight(root.left, root.right) : true; +}; + + +function isSymmetric(root) { + function check(left, right) { + return (!left || !right) ? left === right : left.val === right.val && check(left.left, right.right) && check(left.right, right.left); + } + return root ? check(root.left, root.right) : true; +} + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +var node = new TreeNode(1); +var root = node; + +node = new TreeNode(2); +root.right = node; + +node = new TreeNode(2); +root.right.left = node; +console.log(isSymmetric(root)); \ No newline at end of file diff --git a/triangle.js b/triangle.js new file mode 100644 index 0000000..9d06277 --- /dev/null +++ b/triangle.js @@ -0,0 +1,93 @@ +/** + * Source: https://leetcode.com/problems/triangle/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Triangle + * Auther: @imcoddy + * Content: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. + * + * + * For example, given the following triangle + * + * [ + * [2], + * [3,4], + * [6,5,7], + * [4,1,8,3] + * ] + * + * + * + * The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). + * + * + * + * Note: + * Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle. + */ + +/** + * @param {number[][]} triangle + * @return {number} + */ + +/** + * Memo: calculate border first then using DP to get best result + * Runtime: 152ms + * Rank: A + */ +var minimumTotal = function(triangle) { + var s = [0]; + for (var i = 0; i < triangle.length; i++) { + for (var j = 0; j < triangle[i].length; j++) { + var upper = (i - 1) * i / 2; + var lower = (i + 1) * i / 2; + if (j === 0) { + s[lower] = s[upper] + triangle[i][0]; + } else if (i === j) { + s[lower + i] = s[upper + i - 1] + triangle[i][i]; + } else { + s[lower + j] = Math.MAX_VALUE; + } + } + } + + for (var i = 1; i < triangle.length; i++) { + for (var j = 1; j < i; j++) { + var current = (i * (i + 1)) / 2 + j; + var upper = ((i - 1) * i) / 2 + j; + s[current] = Math.min(s[upper - 1], s[upper]) + triangle[i][j]; + } + } + + var min = s[s.length - 1]; + for (var i = 1; i < triangle.length; i++) { + min = Math.min(min, s[s.length - i - 1]) + } + //console.log(s); + return min; +}; + +console.log(minimumTotal([ + [2, 0, 0, 0], + [3, 4, 0, 0], + [6, 5, 7, 0], + [4, 1, 8, 3] +])); + + +console.log(minimumTotal([ + [-1], + [9, -2], + [0, 4, 5], + [7, 4, -4, -5], + [9, 6, 0, 5, 7], + [9, 2, -9, -4, 5, -2], + [-4, -9, -5, -7, -5, -5, -2], + [-9, 5, -6, -4, 4, 1, 6, -4], + [-4, 3, 9, -2, 8, 6, -9, -2, -2], + [7, -6, 9, 8, -4, 2, -4, -2, -1, -2], + [0, 3, 2, 4, 0, -6, 7, 6, 7, -5, 2], + [9, 0, -8, 6, 4, 6, 2, 5, -9, 9, -1, -6], + [6, -3, -4, -5, 0, 3, 3, 4, -6, -4, -7, 7, 3] +])); \ No newline at end of file diff --git a/two-sum.js b/two-sum.js new file mode 100644 index 0000000..6dce579 --- /dev/null +++ b/two-sum.js @@ -0,0 +1,41 @@ +/** + * Source: https://leetcode.com/problems/two-sum/ + * Tags: [Array,Hash Table] + * Level: Medium + * Updated: 2015-04-24 + * Title: Two Sum + * Auther: @imcoddy + * Content: Given an array of integers, find two numbers such that they add up to a specific target number. + * + * The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. + * + * You may assume that each input would have exactly one solution. + * + * + * Input: numbers={2, 7, 11, 15}, target=9 + * Output: index1=1, index2=2 + */ + +/** + * @param {number[]} numbers + * @param {number} target + * @return {number[]} two integers in an array, ie: [index1, index2] + */ +var twoSum = function(numbers, target) { + var map = {}; + var result = [0, 0]; + for (var i = 0; i < numbers.length; i++) { + var number = numbers[i]; + if (!map[number]) { + map[target - number] = i + 1; + } else { + result[0] = map[number]; + result[1] = i + 1; + } + } + return result; +}; + +console.log(twoSum([2, 7, 11, 15], 9)); +console.log(twoSum([2, 7, 11, 15], 13)); +console.log(twoSum([2, 7, 11, 15], 22)); diff --git a/ugly-number.js b/ugly-number.js new file mode 100644 index 0000000..628aaf1 --- /dev/null +++ b/ugly-number.js @@ -0,0 +1,89 @@ +/** + * Source: https://leetcode.com/problems/ugly-number/ + * Tags: [Math] + * Level: Easy + * Title: Ugly Number + * Auther: @imcoddy + * Content: 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. + * + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases. + * + * + * + * + * + * + * + * + * + * Show Similar Problems + * + * + * (E) Happy Number + * + * (E) Count Primes + * + * (M) Ugly Number II + */ + +/** + * @param {number} num + * @return {boolean} + */ +/** + * Memo: keep devide the number till it has no 2, 3 or 5, then check if the result is 1 or not + * Complex: O(lgn) + * Runtime: 176ms + * Tests: 1012 test cases passed + * Rank: S + * Updated: 2015-10-02 + */ +var isUgly = function(num) { + while (num > 1) { + var before = num; + while (num % 2 === 0) num = num / 2; + while (num % 3 === 0) num = num / 3; + while (num % 5 === 0) num = num / 5; + if (num === before) break; + } + return num === 1; +}; + +/** + * Memo: + * Complex: O(lgn) + * Runtime: 180ms + * Tests: 1012 test cases passed + * Rank: S + * Updated: 2015-10-02 + */ +var isUgly = function(num) { + for (var i of[2, 3, 5]) + while (num && num % i === 0) num /= i; + return num === 1; +}; + +var should = require('should'); +console.time('Runtime'); +isUgly(2).should.equal(true); +isUgly(3).should.equal(true); +isUgly(4).should.equal(true); +isUgly(5).should.equal(true); +isUgly(6).should.equal(true); +isUgly(7).should.equal(false); +isUgly(8).should.equal(true); +isUgly(9).should.equal(true); +isUgly(14).should.equal(false); +isUgly(21).should.equal(false); +isUgly(22).should.equal(false); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/unique-binary-search-trees-ii.js b/unique-binary-search-trees-ii.js new file mode 100644 index 0000000..24a477f --- /dev/null +++ b/unique-binary-search-trees-ii.js @@ -0,0 +1,93 @@ +/** + * Source: https://leetcode.com/problems/unique-binary-search-trees-ii/ + * Tags: [Tree,Dynamic Programming] + * Level: Medium + * Title: Unique Binary Search Trees II + * Auther: @imcoddy + * Content: 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. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {number} n + * @return {TreeNode[]} + */ + +/** + * Memo: Recursive solution + * Complex: O(nlogn) + * Runtime: 172ms + * Tests: 9 test cases passed + * Rank: S + * Updated: 2015-06-06 + */ +var generateTrees = function(n) { + /** + * Create all BST with value from start to end + */ + function generate(start, end) { + if (start > end) return [null]; + var result = []; + for (var i = start; i <= end; i++) { + var leftSubTrees = generate(start, i - 1); + var rightSubTrees = generate(i + 1, end); + + for (var j = 0; j < leftSubTrees.length; j++) + for (var k = 0; k < rightSubTrees.length; k++) { + var root = new TreeNode(i); + root.left = leftSubTrees[j]; + root.right = rightSubTrees[k]; + result.push(root); + } + } + + return result; + } + + return generate(1, n); +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +console.log(generateTrees(4)); \ No newline at end of file diff --git a/unique-binary-search-trees.js b/unique-binary-search-trees.js new file mode 100644 index 0000000..b360b4f --- /dev/null +++ b/unique-binary-search-trees.js @@ -0,0 +1,51 @@ +/** + * Source: https://leetcode.com/problems/unique-binary-search-trees/ + * Tags: [Tree,Dynamic Programming] + * Level: Medium + * Title: Unique Binary Search Trees + * Auther: @imcoddy + * Content: Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + * + * + * For example, + * Given n = 3, there are a total of 5 unique BST's. + * + * + * 1 3 3 2 1 + * \ / / / \ \ + * 3 2 1 1 3 2 + * / / \ \ + * 2 1 2 3 + */ + +/** + * @param {number} n + * @return {number} + */ + +/** + * Memo: define s[i] for result of i, when i >= 3, each element in s can be made out from previous stages. + * 1, for each BST in i-1, the ith element can be added as root or furtherest right node, which generate 2*s[i-1] trees. + * 2, the ith element is added in the middle, separating the previous trees into two parts, which turns into a smaller problem that already solved. + * Complex: O(n) + * Runtime: 121ms + * Tests: 19 test cases passed + * Rank: S + */ +var numTrees = function(n) { + var s = [0, 1, 2]; + for (var i = 3; i <= n; i++) { + s[i] = s[i - 1] * 2; + for (var j = 1; j < i - 1; j++) { + s[i] += s[i - 1 - j] * s[j]; + } + } + return s[n]; +}; + +var should = require('should'); +console.time('Runtime'); +numTrees(3).should.equal(5); +numTrees(4).should.equal(14); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/unique-paths-ii.js b/unique-paths-ii.js new file mode 100644 index 0000000..f013e1c --- /dev/null +++ b/unique-paths-ii.js @@ -0,0 +1,101 @@ +/** + * Source: https://leetcode.com/problems/unique-paths-ii/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Unique Paths II + * Auther: @imcoddy + * Content: Follow up for "Unique Paths": + * + * Now consider if some obstacles are added to the grids. How many unique paths would there be? + * + * An obstacle and empty space is marked as 1 and 0 respectively in the grid. + * + * For example, + * There is one obstacle in the middle of a 3x3 grid as illustrated below. + * + * [ + * [0,0,0], + * [0,1,0], + * [0,0,0] + * ] + * + * The total number of unique paths is 2. + * + * Note: m and n will be at most 100. + */ + +/** + * @param {number[][]} obstacleGrid + * @return {number} + */ + +/** + * Memo: Note that you need to mark the initial states to 0 if there is obstacle in the border + * Complex: O(m*n) + * Runtime: 128ms + * Tests: 43 test cases passed + * Rank: A + */ +var uniquePathsWithObstacles = function(obstacleGrid) { + var m = obstacleGrid.length; + var n = obstacleGrid[0].length; + + var s = []; + for (var i = 0; i < m; i++) { + var a = []; + for (var j = 0; j < n; j++) { + a.push(0); + } + s.push(a); + } + + var no_obstacle_in_border = 1; + for (var i = 0; i < m; i++) { + if (obstacleGrid[i][0]) no_obstacle_in_border = 0; + s[i][0] = no_obstacle_in_border; + } + no_obstacle_in_border = 1; + for (var i = 0; i < n; i++) { + if (obstacleGrid[0][i]) no_obstacle_in_border = 0; + s[0][i] = no_obstacle_in_border; + } + + for (var i = 1; i < m; i++) { + for (var j = 1; j < n; j++) { + s[i][j] = obstacleGrid[i][j] ? 0 : (s[i - 1][j] + s[i][j - 1]); + } + } + //console.log(s); + return s[m - 1][n - 1]; +}; + +var should = require('should'); +console.time('Runtime'); +uniquePathsWithObstacles([ + [0, 0, 0], +]).should.equal(1); + +uniquePathsWithObstacles([ + [0, 1, 0], +]).should.equal(0); + +uniquePathsWithObstacles([ + [0, 0, 0], + [0, 1, 0], + [0, 0, 0] +]).should.equal(2); + + +uniquePathsWithObstacles([ + [0, 0, 1], + [0, 1, 0], + [0, 0, 0] +]).should.equal(1); + +uniquePathsWithObstacles([ + [0, 1, 1], + [1, 1, 0], + [0, 0, 0] +]).should.equal(0); + +console.timeEnd('Runtime'); \ No newline at end of file diff --git a/unique-paths.js b/unique-paths.js new file mode 100644 index 0000000..db91828 --- /dev/null +++ b/unique-paths.js @@ -0,0 +1,52 @@ +/** + * Source: https://leetcode.com/problems/unique-paths/ + * Tags: [Array,Dynamic Programming] + * Level: Medium + * Title: Unique Paths + * Auther: @imcoddy + * Content: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). + * + * The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). + * + * How many possible unique paths are there? + * + * + * + * Above is a 3 x 7 grid. How many possible unique paths are there? + * + * + * Note: m and n will be at most 100. + */ + +/** + * @param {number} m + * @param {number} n + * @return {number} + */ + +/** + * Explanation: There are two ways to get to point [i,j], whether from top or from left. And the initial state is assume there is only one way to get to each point. + * S[i][j] = S[i][j-1] + S[i-1][j]; + * Runtime: 134ms + * Rank: A + */ +var uniquePaths = function(m, n) { + var s = []; + for (var i = 0; i < m; i++) { + var a = []; + for (var j = 0; j < n; j++) { + a.push(1); + } + s.push(a); + } + + for (var i = 1; i < m; i++) { + for (var j = 1; j < n; j++) { + s[i][j] = s[i - 1][j] + s[i][j - 1]; + } + } + console.log(s); + return s[m - 1][n - 1]; +}; + +console.log(uniquePaths(3, 7)); \ No newline at end of file diff --git a/util.js b/util.js new file mode 100644 index 0000000..04f2899 --- /dev/null +++ b/util.js @@ -0,0 +1,114 @@ +/** + * This file is used to do some data generating + */ +var util = {}; + +function ListNode(val) { + this.val = val; + this.next = null; +} + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +util.arrayToTree = function(array) { + if (!array || array.length === 0 || array[0] === '#') return null; + var nodes = []; + for (var i = 0; i < array.length; i++) { + nodes[i] = array[i] === '#' ? null : new TreeNode(array[i]); + } + if (nodes.length === 1) return nodes[0]; + + var root = nodes[0]; + var current = 0; + var next = 1; + var is_left = true; + + while (next < nodes.length) { + if (nodes[current]) { + if (is_left) { + nodes[current].left = nodes[next++]; + } else { + nodes[current].right = nodes[next++]; + current++; + } + is_left = !is_left; + } else { + current++; + } + } + + return root; +}; + +util.treeToArray = function(root) { + if (!root) return []; + if (!root.left && !root.right) return [root.val]; + + var result = []; + var queue = [root]; + while (queue.length) { + var n = queue.shift(); + if (n) { + result.push(n.val); + queue.push(n.left); + queue.push(n.right); + } else { + result.push('#'); + } + } + + while (result[result.length - 1] === '#') { + result.pop(); + } + return result; + +}; + + +util.arrayToLinkList = function(array) { + if (!array) { + return null; + } + var nodes = []; + for (var i = 0; i < array.length; i++) { + nodes[i] = new ListNode(array[i]); + if (i > 0) { + nodes[i - 1].next = nodes[i]; + } + } + return nodes[0]; +}; + +util.linkListToArray = function(head) { + var list = []; + if (head) { + var p = head; + while (p) { + list.push(p.val); + p = p.next; + } + } + return list; +}; + +util.linkListToString = function(head) { + var list = util.linkListToArray(head); + if (!list) { + return null; + } + var s = list.filter(function(n) { + return n != undefined + }).join('->'); + return s; +}; + +// Shortcuts +util.atl = util.arrayToLinkList; +util.att = util.arrayToTree; +util.lta = util.linkListToArray; +util.lts = util.linkListToString; + +module.exports = util; \ No newline at end of file diff --git a/valid-palindrome.js b/valid-palindrome.js new file mode 100644 index 0000000..df33cc7 --- /dev/null +++ b/valid-palindrome.js @@ -0,0 +1,54 @@ +/** + * Source: https://leetcode.com/problems/valid-palindrome/ + * Tags: [Two Pointers,String] + * Level: Easy + * Updated: 2015-04-24 + * Title: Valid Palindrome + * Auther: @imcoddy + * Content: 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. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var isPalindrome = function(s) { + var alphanumerics = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + var str = ''; + s = s.toUpperCase(); + for (var i = 0; i < s.length; i++) { + if (alphanumerics.indexOf(s[i]) >= 0) { + str += s[i]; + } + } + + var low = 0; + var high = str.length - 1; + while (low < high) { + if (str[low] !== str[high]) { + return false; + } + low++; + high--; + } + return true; +}; + + +console.log(isPalindrome('1233321')); +console.log(isPalindrome('12334321')); +console.log(isPalindrome('12333321')); +console.log(isPalindrome('ab')); diff --git a/valid-parentheses.js b/valid-parentheses.js new file mode 100644 index 0000000..c3399c4 --- /dev/null +++ b/valid-parentheses.js @@ -0,0 +1,47 @@ +/** + * Source: https://leetcode.com/problems/valid-parentheses/ + * Tags: [Stack,String] + * Level: Easy + * Updated: 2015-04-24 + * Title: Valid Parentheses + * Auther: @imcoddy + * Content: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + * + * The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var isValid = function(s) { + var brackets = '([{'; + var stack = []; + var map = { + ')':'(', + ']':'[', + '}':'{' + }; + + for (var i = 0; i < s.length; i++) { + if (brackets.indexOf(s[i]) >= 0) { + stack.push(s[i]); + }else { + if (stack.length === 0) { + return false; + } + var last = stack[stack.length - 1]; + if (map[s[i]] !== last) { + return false; + }else{ + stack.pop(); + } + } + } + + return stack.length === 0; +}; + +var str; +str = "()[]{}"; console.log(isValid(str.split(''))); +str = "()["; console.log(isValid(str.split(''))); diff --git a/valid-sudoku.js b/valid-sudoku.js new file mode 100644 index 0000000..74fdd43 --- /dev/null +++ b/valid-sudoku.js @@ -0,0 +1,74 @@ +/** + * Source: https://leetcode.com/problems/valid-sudoku/ + * Tags: [Hash Table] + * Level: Easy + * Title: Valid Sudoku + * Auther: @imcoddy + * Content: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. + * + * The Sudoku board could be partially filled, where empty cells are filled with the character '.'. + * + * + * + * A partially filled sudoku which is valid. + * + * + * Note: + * A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated. + */ + +/** + * @param {character[][]} board + * @return {boolean} + */ + +/** + * Memo: Use hashmap to track if the number has been used in a row, column or smaller plate + * Complex: O(n) + * Runtime: 176ms + * Tests: 501 test cases passed + * Rank: S + */ +var isValidSudoku = function(board) { + var rows = []; + var columns = []; + var plates = [ + [], + [], + [] + ]; + + for (var i = 0; i < 9; i++) { + rows[i] = {}; + columns[i] = {}; + plates[~~(i / 3)][i % 3] = {}; + } + + for (var i = 0; i < 9; i++) { + for (var j = 0; j < 9; j++) { + var char = board[i][j]; + if (char !== '.') { + if (rows[i][char]) { + return false; + } else { + rows[i][char] = true; + } + + if (columns[j][char]) { + return false; + } else { + columns[j][char] = true; + } + + if (plates[~~(i / 3)][~~(j / 3)][char]) { + return false; + } else { + plates[~~(i / 3)][~~(j / 3)][char] = true; + } + } + } + } + return true; +}; + +console.log(isValidSudoku([".........", "4........", "......6..", "...38....", ".5...6..1", "8......6.", ".........", "..7.9....", "...6....."])); diff --git a/validate-binary-search-tree.js b/validate-binary-search-tree.js new file mode 100644 index 0000000..232b830 --- /dev/null +++ b/validate-binary-search-tree.js @@ -0,0 +1,102 @@ +/** + * Source: https://leetcode.com/problems/validate-binary-search-tree/ + * Tags: [Tree,Depth-first Search] + * Level: Medium + * Title: Validate Binary Search Tree + * Auther: @imcoddy + * Content: Given a binary tree, determine if it is a valid binary search tree (BST). + * + * + * + * Assume a BST is defined as follows: + * + * The left subtree of a node contains only nodes with keys less than the node's key. + * The right subtree of a node contains only nodes with keys greater than the node's key. + * Both the left and right subtrees must also be binary search trees. + * + * + * + * confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. + * + * OJ's Binary Tree Serialization: + * + * The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}". + */ +var util = require('./util.js'); +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @return {boolean} + */ + +/** + * Memo: need to pass the current min and max as parameters so both left and right trees can fit in range. + * Runtime: 151ms + * Tests: 74 test cases passed + * Rank: S + */ +var isValidBST = function(root) { + function checkBST(root, min, max) { + if (!root) return true; + if (max <= root.val || root.val <= min) return false; + return checkBST(root.left, min, root.val) && checkBST(root.right, root.val, max); + } + + return checkBST(root, 0 - Number.MAX_VALUE, Number.MAX_VALUE); +}; + +var isValidBST = function(root) { + function checkBST(root, min, max) { + if (!root) return true; + if (root.val >= max || root.val <= min) return false; //according to definition, no equal is allowed. + return checkBST(root.left, min, root.val) && checkBST(root.right, root.val, max); + } + return checkBST(root, -Number.MAX_VALUE, Number.MAX_VALUE); +}; + +function TreeNode(val) { + this.val = val; + this.left = this.right = null; +} + +console.log(isValidBST(new TreeNode(0))); + +var node = new TreeNode(2); +var root = node; +console.log(isValidBST(root)); + +node = new TreeNode(2); +root.left = node; +console.log(isValidBST(root)); + +node = new TreeNode(1); +root.left = node; +console.log(isValidBST(root)); + +node = new TreeNode(3); +root.right = node; +console.log(isValidBST(root)); + +node = new TreeNode(6); +root.left.right = node; +console.log(isValidBST(root)); \ No newline at end of file diff --git a/zigzag-conversion.js b/zigzag-conversion.js new file mode 100644 index 0000000..d28c6af --- /dev/null +++ b/zigzag-conversion.js @@ -0,0 +1,55 @@ +/** + * Source: https://leetcode.com/problems/zigzag-conversion/ + * Tags: [String] + * Level: Easy + * Title: ZigZag Conversion + * Auther: @imcoddy + * Content: 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} + */ + +/** + * Memo: Put each charactar to correct level when traverse in zigzag pattern. A bit tricky to calculate the currect level index though. + * Runtime: 193ms + * Tests: 1158 test cases passed + * Rank: A + */ +var convert = function(s, numRows) { + if (numRows === 1) { + return s; + } + + var levels = []; + + for (var i = 0; i < numRows; i++) { + levels[i] = ''; + } + + for (var i = 0; i < s.length; i++) { + var index = i % (2 * numRows - 2); + index = index < numRows - 1 ? index : 2 * (numRows - 1) - index; + levels[index] = levels[index] + s[i]; + } + return levels.join(''); +}; + +console.log(convert('PAYPALISHIRING', 3)); \ No newline at end of file