├── .gitignore
├── .travis.yml
├── LICENSE
├── Makefile
├── README.md
├── bin
├── load
└── runTest
├── js
├── 3sum
│ └── 3sum.js
├── 3sumClosest
│ └── 3sum_closest.js
├── 3sumSmaller
│ └── 3sum_smaller.js
├── 4sum
│ └── 4sum.js
├── addBinary
│ └── add_binary.js
├── addDigits
│ └── add_digits.js
├── anagrams
│ └── anagrams.js
├── binaryTreeInorderTraversal
│ └── binary_tree_inorder_traversal.js
├── binaryTreePaths
│ └── binary_tree_paths.js
├── binaryTreePostorderTraversal
│ └── binary_tree_postorder_traversal.js
├── binaryTreePreorderTraversal
│ └── binary_tree_preorder_traversal.js
├── combinationSum
│ ├── README.md
│ └── combination-sum.js
├── combinationSumIi
│ ├── README.md
│ └── combination-sum-ii.js
├── combinationSumIii
│ ├── README.md
│ └── combination-sum-iii.js
├── combinations
│ ├── README.md
│ └── combinations.js
├── compareVersionNumbers
│ └── compare_version_numbers.js
├── constructBinaryTreeFromInorderAndPostorderTraversal
│ └── construct_binary_tree_from_inorder_and_postorder_traversal.js
├── containerWithMostWater
│ ├── README.md
│ └── container-with-most-water.js
├── containsDuplicate
│ └── contains_duplicate.js
├── countAndSay
│ └── count_and_say.js
├── deleteNodeInALinkedList
│ └── delete_node_in_a_linked_list.js
├── divideTwoIntegers
│ └── divide_two_integers.js
├── excelSheetColumnNumber
│ └── excel_sheet_column_number.js
├── excelSheetColumnTitle
│ └── excel_sheet_column_title.js
├── factorCombinations
│ ├── README.md
│ └── factor-combinations.js
├── findFirstAndLastPositionOfElementInSortedArray
│ ├── README.md
│ ├── find-first-and-last-position-of-element-in-sorted-array.js
│ └── find-first-and-last-position-of-element-in-sorted-array_1.js
├── findTheDuplicateNumber
│ └── find_the_duplicate_number.js
├── firstBadVersion
│ └── first_bad_version.js
├── firstMissingPositive
│ └── first_missing_positive.js
├── generalizedAbbreviation
│ ├── README.md
│ └── generalized-abbreviation.js
├── grayCode
│ ├── README.md
│ └── gray-code.js
├── groupShiftedStrings
│ └── group_shifted_strings.js
├── hIndex
│ └── h_index.js
├── hIndexIi
│ └── h_index_ii.js
├── happyNumber
│ └── happy_number.js
├── integerToEnglishWords
│ └── integer_to_english_words.js
├── integerToRoman
│ └── integer-to-roman.js
├── invertBinaryTree
│ └── invert_binary_tree.js
├── isomorphicStrings
│ └── isomorphic_strings.js
├── letterCombinationsOfAPhoneNumber
│ └── letter_combinations_of_a_phone_number.js
├── linkedListCycleIi
│ └── linked_list_cycle_ii.js
├── longestPalindromicSubstring
│ └── longest_palindromic_substring.js
├── majorityElement
│ └── majority_element.js
├── meetingRooms
│ └── meeting_rooms.js
├── mergeSortedArray
│ └── merge_sorted_array.js
├── missingNumber
│ └── missing_number.js
├── moveZeroes
│ └── move_zeroes.js
├── nextPermutation
│ ├── README.md
│ └── next-permutation.js
├── numberComplement
│ ├── README.md
│ ├── number-complement-2.js
│ └── number-complement.js
├── numberOfDigitOne
│ └── number_of_digit_one.js
├── paintFence
│ └── paint_fence.js
├── palindromePermutation
│ └── palindrome_permutation.js
├── pathSum
│ └── path_sum.js
├── perfectSquares
│ └── perfect_squares.js
├── permutations
│ └── permutations.js
├── permutationsII
│ ├── README.md
│ └── permutations-ii.js
├── plusOne
│ └── plus_one.js
├── powerOfTwo
│ └── power_of_two.js
├── powxN
│ └── powx_n.js
├── productOfArrayExceptSelf
│ └── product_of_array_except_self.js
├── removeDuplicatesFromSortedArray
│ └── remove-duplicates-from-sorted-array.js
├── removeDuplicatesFromSortedArrayIi
│ └── remove_duplicates_from_sorted_array_ii.js
├── removeDuplicatesFromSortedList
│ └── remove_duplicates_from_sorted_list.js
├── removeElement
│ └── remove_element.js
├── removeLinkedListElements
│ └── remove_linked_list_elements.js
├── restoreIpAddresses
│ ├── README.md
│ └── restore-ip-addresses.js
├── reverseLinkedList
│ └── reverse_linked_list.js
├── reverseString
│ └── reverse_string.js
├── reverseVowelsOfAString
│ └── reverse_vowels_of_a_string.js
├── reverseWordsInAString
│ └── reverse_words_in_a_string.js
├── reverseWordsInAStringIi
│ ├── reverse_words_in_a_string_ii-2.js
│ └── reverse_words_in_a_string_ii.js
├── romanToInteger
│ └── roman-to-integer.js
├── rotateArray
│ └── rotate_array.js
├── rotateList
│ └── rotate_list.js
├── sameTree
│ └── same_tree.js
├── searchInRotatedSortedArray
│ └── search_in_rotated_sorted_array.js
├── searchInsertPosition
│ └── search_insert_position.js
├── shortestWordDistance
│ └── shortest_word_distance.js
├── singleNumber
│ └── single_number.js
├── sortColors
│ └── sort_colors.js
├── sqrtx
│ └── sqrtx.js
├── strobogrammaticNumber
│ └── strobogrammatic_number.js
├── strobogrammaticNumberIi
│ └── strobogrammatic_number_ii.js
├── subsets
│ ├── README.md
│ ├── subsets-v1.js
│ └── subsets.js
├── sumOfTwoIntegers
│ └── sum-of-two-integers.js
├── sumRootToLeafNumbers
│ └── sum_root_to_leaf_numbers.js
├── swapNodesInPairs
│ └── swap-nodes-in-pairs.js
├── twoSum
│ └── two_sum.js
├── twoSumIiInputArrayIsSorted
│ └── two_sum_ii_input_array_is_sorted.js
├── twoSumIiiDataStructureDesign
│ └── two_sum_iii_data_structure_design.js
├── uglyNumber
│ └── ugly_number.js
├── uglyNumberIi
│ └── ugly_number_ii.js
├── uniqueWordAbbreviation
│ └── unique_word_abbreviation.js
├── validAnagram
│ └── valid_anagram.js
├── validPalindrome
│ └── valid_palindrome.js
├── validSudoku
│ ├── README.md
│ └── valid-sudoku.js
├── wordBreak
│ └── word_break.js
├── wordPattern
│ └── word_pattern.js
└── wordSearch
│ └── word_search.js
├── package.json
├── python
├── 3sum.py
├── _util.py
├── add_two_numbers.py
├── climbing_stairs.py
├── generate_parentheses.py
├── implement_strstr.py
├── intersection_of_two_linked_lists.py
├── longest_common_prefix.py
├── longest_palindromic_substring.py
├── longest_substring_without_repeating_characters.py
├── lru_cache.py
├── median_of_Two_Sorted_Arrays.py
├── merge_two_sorted_lists.py
├── palindrome_number.py
├── remove_duplicates_from_sorted_array.py
├── remove_nth_node_from_end_of_list.py
├── reverse_integer.py
├── string_to_integer_atoi.py
├── two-sum.py
├── valid_parentheses.py
└── zigzag_conversion.py
├── tenth_line.bash
├── valid_phone_numbers.bash
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 |
5 | # C extensions
6 | *.so
7 |
8 | # Distribution / packaging
9 | .Python
10 | env/
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | lib/
17 | lib64/
18 | parts/
19 | sdist/
20 | var/
21 | *.egg-info/
22 | .installed.cfg
23 | *.egg
24 |
25 | # PyInstaller
26 | # Usually these files are written by a python script from a template
27 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
28 | *.manifest
29 | *.spec
30 |
31 | # Installer logs
32 | pip-log.txt
33 | pip-delete-this-directory.txt
34 |
35 | # Unit test / coverage reports
36 | htmlcov/
37 | .tox/
38 | .coverage
39 | .cache
40 | nosetests.xml
41 | coverage.xml
42 |
43 | # Translations
44 | *.mo
45 | *.pot
46 |
47 | # Django stuff:
48 | *.log
49 |
50 | # Sphinx documentation
51 | docs/_build/
52 |
53 | # PyBuilder
54 | target/
55 | node_modules/
56 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - "12"
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Zhiye Li
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | TESTS = $(shell find js -name '*.js')
3 |
4 | test:
5 | @./bin/runTest $(TESTS)
6 |
7 | .PHONY: test
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # leetcode
2 |
3 | [](https://travis-ci.org/zhiyelee/leetcode)
4 |
5 | Solutions to leetcode in JavaScript and Python.
6 |
7 | ## TEST
8 |
9 | ```js
10 | // install package
11 | npm i
12 |
13 | // run test
14 | npm test
15 | ```
16 |
17 | ## Tools
18 |
19 | ### Create problem folder
20 |
21 | The folder will include an empty js file and a README file which contains the problem description.
22 |
23 | ```
24 | yarn
25 |
26 | # pass the problem url as an argument
27 | yarn load https://leetcode.com/problems/combination-sum/
28 | ```
29 |
30 | which will create folder `js/combinationSum` with two files.
31 |
32 | ```
33 | ➜ leetcode git:(master) ✗ tree js/combinationSum
34 | js/combinationSum
35 | ├── README.md # contains problem description and link to the problem
36 | └── combination-sum.js # empty file
37 | ```
38 |
39 | ## LICENSE
40 | MIT
41 |
42 |
--------------------------------------------------------------------------------
/bin/load:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 | 'use strict';
3 | const request = require('request');
4 | const fs = require('fs');
5 | const camelCase = require('camelcase');
6 | const mkdirp = require('mkdirp');
7 | const url = require('url');
8 | const path = require('path');
9 | const chalk = require('chalk');
10 |
11 | const problemUrl = process.argv[3];
12 |
13 | // problem slug, such as `combination-sum`
14 | const slug = url.parse(problemUrl).pathname.split('/')[2];
15 | const dirPath = path.resolve('js', camelCase(slug));
16 |
17 | mkdirp(dirPath, function () {
18 | const fileContent = `## ${slug.replace(/-/g, ' ')}\n` + `link: <${problemUrl}>\n`;
19 |
20 | createFile(path.resolve(dirPath,'README.md'), fileContent);
21 | createFile(path.resolve(dirPath,`${slug}.js`), '');
22 | });
23 |
24 | // create file with content only when file is not exists
25 | function createFile(f, content) {
26 | fs.access(f, (err) => {
27 | const relativePath = chalk.green(path.relative(__dirname + '/../', f));
28 | if (err) {
29 | fs.writeFileSync(f, content);
30 | console.log(`Create:\n\t ${relativePath}`);
31 | return;
32 | }
33 |
34 | console.log(`${chalk.red.bold('File already exists:')}\n\t ${relativePath}`);
35 | })
36 | }
37 |
--------------------------------------------------------------------------------
/bin/runTest:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export NODE_ENV=test
4 |
5 | echo
6 | for file in $@; do
7 | printf "\033[90m ${file#test/}\033[0m "
8 | node $file 2> /tmp/stderr && echo "\033[36m✓\033[0m"
9 | code=$?
10 | if test $code -ne 0; then
11 | echo "\033[31m✖\033[0m"
12 | cat /tmp/stderr >&2
13 | exit $code
14 | fi
15 | done
16 | echo
--------------------------------------------------------------------------------
/js/3sum/3sum.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[][]}
4 | */
5 | var threeSum = function(nums) {
6 | nums.sort(function (a, b) {
7 | return a - b;
8 | });
9 |
10 | var res = [];
11 | var len = nums.length;
12 |
13 | for (var i = 0; i < len - 2; i ++) {
14 |
15 | if (i !== 0 && nums[i] === nums[i - 1]) continue;
16 | var low = i + 1;
17 | var high = len - 1;
18 | var target = -nums[i];
19 |
20 | while (low < high) {
21 | var val = nums[low] + nums[high];
22 | if (target === val) {
23 | res.push([nums[i], nums[low ++], nums[high]]);
24 |
25 | // skip repeated value
26 | while (low <= high) {
27 | if (nums[low] > nums[low - 1]) break;
28 | low ++;
29 | }
30 | } else if(val < target) {
31 | low++;
32 | } else {
33 | high --;
34 | }
35 | }
36 | }
37 |
38 | return res;
39 | };
40 |
41 | var eq = require('assert').deepEqual;
42 |
43 | // return array has same items but maybe different order
44 | eq(threeSum([-1, 0, 1, 2, -1, -4]), [[-1, -1, 2], [-1, 0, 1]]);
45 | eq(threeSum([-2, 0, 1, 1, 2]), [[-2, 0, 2], [-2, 1, 1]]);
46 |
47 |
--------------------------------------------------------------------------------
/js/3sumClosest/3sum_closest.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number}
5 | */
6 | var threeSumClosest = function(nums, target) {
7 | // first sort, then use 2sum method
8 | nums.sort(function (a, b) {
9 | return a - b;
10 | })
11 |
12 | var len = nums.length;
13 | var min = nums[0] + nums[1] + nums[2];
14 | // suppose length must >= than 3
15 | if (nums.length === 3) return min;
16 |
17 | for (var i = 0; i < len; i++) {
18 | // two pointer, narrow to find the target
19 | var low = i + 1;
20 | var high = len - 1;
21 |
22 | while(low < high) {
23 | var sum = nums[low] + nums[high] + nums[i];
24 |
25 | if (Math.abs(sum - target) < Math.abs(min - target)) {
26 | min = sum;
27 | if (sum === target) return target;
28 | }
29 |
30 | if(sum < target) {
31 | low += 1;
32 | } else {
33 | high = high - 1;
34 | }
35 | }
36 | }
37 |
38 | return min;
39 | };
40 |
41 | var eq = require('assert').equal;
42 |
43 | // -4 -1 1 2, 1
44 | eq(threeSumClosest([-1, 2, 1, -4], 1), 2);
45 | eq(threeSumClosest([-1, 2, 1], 4), 2);
46 | eq(threeSumClosest([-1, 2, 1, 1], 1), 1);
47 | eq(threeSumClosest([0,2,1,-3], 1), 0)
48 |
--------------------------------------------------------------------------------
/js/3sumSmaller/3sum_smaller.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number}
5 | */
6 | var threeSumSmaller = function(nums, target) {
7 | nums.sort(function(a, b) {
8 | return a - b;
9 | });
10 |
11 | var len = nums.length;
12 | var ans = 0;
13 | for (var i = 0; i < len; i++) {
14 | var val = nums[i];
15 | var low = i + 1;
16 | var high = len - 1;
17 |
18 | while(low < high) {
19 | var sum = nums[low] + nums[high];
20 | if (sum + val < target) {
21 | ans += high - low;
22 | low ++;
23 | } else {
24 | high --;
25 | }
26 | }
27 | }
28 |
29 | return ans;
30 | };
31 |
32 |
33 | var eq = require('assert').deepEqual;
34 |
35 | eq(threeSumSmaller([-2, 0, 1, 3], 2), 2);
36 | eq(threeSumSmaller([-2, 0, 3], 2), 1);
37 |
--------------------------------------------------------------------------------
/js/4sum/4sum.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number[][]}
5 | */
6 | var fourSum = function(nums, target) {
7 | nums.sort(function (a, b) {
8 | return a - b;
9 | });
10 |
11 | var len = nums.length;
12 | var ans = [];
13 | for (var i = 0; i < len - 3; i++) {
14 | if (i !== 0 && nums[i] === nums[i - 1]) continue;
15 |
16 | for (var j = i + 1; j < len - 2; j ++) {
17 | if (j !== i + 1 && nums[j] === nums[j - 1]) continue;
18 | var find = target - (nums[i] + nums[j]);
19 | var low = j + 1;
20 | var high = len - 1;
21 |
22 | while(low < high) {
23 | var sum = nums[low] + nums[high];
24 |
25 | if (sum === find) {
26 | ans.push([nums[i], nums[j], nums[low], nums[high]]);
27 | low ++;
28 |
29 | while(low < high) {
30 | if (nums[low] > nums[low - 1]) break;
31 | low ++;
32 | }
33 |
34 | while(low < high) {
35 | if (nums[high - 1] < nums[high]) break;
36 | high --;
37 | }
38 | }
39 |
40 | if (sum < find) {
41 | low ++;
42 | } else {
43 | high --;
44 | }
45 | }
46 | }
47 | }
48 |
49 | return ans;
50 | };
51 |
52 | var eq = require('assert').deepEqual;
53 |
54 | eq(fourSum([1, 0, -1, 0, -2, 2], 0), [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]);
55 |
--------------------------------------------------------------------------------
/js/addBinary/add_binary.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} a
3 | * @param {string} b
4 | * @return {string}
5 | */
6 | var addBinary = function(a, b) {
7 | if (a.length === 0 || b.length === 0) {
8 | return a || b;
9 | }
10 |
11 | var maxL = a.length > b.length ? a.length : b.length;
12 | var carry = 0;
13 |
14 | a = a.split('').reverse();
15 | b = b.split('').reverse();
16 |
17 | var sum = [];
18 |
19 | var i = 0;
20 | while (i < maxL) {
21 | var add1 = b[i] || 0;
22 | var add2 = a[i] || 0;
23 |
24 | var tmp = parseInt(add1) + parseInt(add2) + carry;
25 | sum[i] = tmp%2;
26 | carry = tmp >> 1;
27 | i++;
28 | }
29 |
30 | if (carry) {
31 | sum[i] = carry;
32 | }
33 |
34 | return sum.reverse().join('');
35 | };
36 |
37 | // test
38 | var assert = require('assert');
39 | assert.equal(addBinary('10010', '111'), '11001');
40 |
--------------------------------------------------------------------------------
/js/addDigits/add_digits.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {number}
4 | */
5 | var addDigits = function(num) {
6 | // https://en.wikipedia.org/wiki/Digital_root
7 | return num ? num - 9 * Math.floor((num - 1)/9) : 0;
8 |
9 | };
10 |
11 |
12 | var eq = require('assert').equal;
13 |
14 | eq(addDigits(0), 0);
15 | eq(addDigits(18), 9);
16 | eq(addDigits(21), 3);
17 |
--------------------------------------------------------------------------------
/js/anagrams/anagrams.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string[]} strs
3 | * @return {string[][]}
4 | */
5 | var groupAnagrams = function(strs) {
6 | var dicts = {};
7 | var arrs = [];
8 |
9 | for (var i = 0; i < strs.length; i ++) {
10 | var val = strs[i];
11 | var key = val.split('').sort().join('');
12 |
13 | if (dicts[key]) {
14 | dicts[key].push(val);
15 | } else {
16 | arrs.push([val]);
17 |
18 | dicts[key] = arrs[arrs.length - 1];
19 | }
20 | }
21 |
22 | return arrs;
23 | };
24 |
25 |
26 | var eq = require('assert').deepEqual;
27 |
28 | // cant test with equal, since this problem doesn't require order inner group
29 | // eq(groupAnagrams(['eat', 'tea', 'tan', 'ate', 'nat', 'bat']), [
30 | // ['ate', 'eat', 'tea'],
31 | // ['nat', 'tan'],
32 | // ['bat']
33 | // ]);
34 |
--------------------------------------------------------------------------------
/js/binaryTreeInorderTraversal/binary_tree_inorder_traversal.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {TreeNode} root
3 | * @return {number[]}
4 | */
5 | var inorderTraversal = function(root) {
6 | if (!root) return [];
7 |
8 | var stack = [];
9 | var it;
10 | var ans = [];
11 | it = root;
12 | while(it || stack.length) {
13 | if (it && it.val !== null) {
14 | stack.push(it);
15 | it = it.left;
16 | } else {
17 | var top = stack.pop();
18 | ans.push(top.val);
19 | it = top.right;
20 | }
21 | }
22 |
23 | return ans;
24 | };
25 |
26 | var Tree = require('leetcode').Tree;
27 | var eq = require('assert').deepEqual;
28 |
29 | eq(inorderTraversal(Tree.create([1, null, 2, 3])), [1, 3, 2]);
30 | eq(inorderTraversal(Tree.create([1, null, 2, 3, 4, null, 5])), [1, 3, 5, 2, 4]);
31 |
--------------------------------------------------------------------------------
/js/binaryTreePaths/binary_tree_paths.js:
--------------------------------------------------------------------------------
1 | // Definition for a binary tree node.
2 | function TreeNode(val) {
3 | this.val = val;
4 | this.left = this.right = null;
5 | }
6 | /**
7 | * @param {TreeNode} root
8 | * @return {string[]}
9 | */
10 | var binaryTreePaths = function(root) {
11 | if (!root.left && !root.right) return [ root.val.toString() ];
12 |
13 | var res = [];
14 | getPath(root, res);
15 |
16 | return res;
17 | };
18 |
19 | function getPath(node, res, pre) {
20 | if (!node) return;
21 |
22 | if (pre === undefined) {
23 | pre = node.val;
24 | } else {
25 | pre = pre + '->' + node.val;
26 | }
27 |
28 | if (!node.left && !node.right) {
29 | return res.push(pre);
30 | }
31 |
32 | getPath(node.left, res, pre);
33 | getPath(node.right, res, pre);
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/js/binaryTreePostorderTraversal/binary_tree_postorder_traversal.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {TreeNode} root
3 | * @return {number[]}
4 | */
5 | var postorderTraversal = function(root) {
6 | if (!root) return [];
7 |
8 | var it = root;
9 | var stack = [];
10 | var ans = [];
11 |
12 | while(it || stack.length) {
13 | if (it && it.val !== null) {
14 | stack.push(it);
15 | it = it.left;
16 | } else {
17 | var top = stack.pop();
18 | if (top.visited) {
19 | ans.push(top.val);
20 | } else {
21 | top.visited = true;
22 | stack.push(top);
23 | it = top.right;
24 | }
25 | }
26 | }
27 |
28 | return ans;
29 | };
30 |
31 | // version 2, more directly, same as preodre
32 | var postorderTraversal = function(root) {
33 | if (!root) return [];
34 |
35 | var stack = [root];
36 | var ans = [];
37 | var it;
38 |
39 | while(stack.length) {
40 | it = stack.pop();
41 |
42 | if (it.val === null) continue;
43 | ans.unshift(it.val);
44 |
45 | if (it.left) {
46 | stack.push(it.left);
47 | }
48 |
49 | if (it.right) {
50 | stack.push(it.right)
51 | }
52 | }
53 |
54 | return ans;
55 | };
56 |
57 | var Tree = require('leetcode').Tree;
58 | var eq = require('assert').deepEqual;
59 |
60 | eq(postorderTraversal(Tree.create([1, 2, 3, 4, 5, 6])), [4, 5, 2, 6, 3, 1]);
61 | eq(postorderTraversal(Tree.create([1, null, 2, 3])), [3, 2, 1]);
62 |
--------------------------------------------------------------------------------
/js/binaryTreePreorderTraversal/binary_tree_preorder_traversal.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {TreeNode} root
3 | * @return {number[]}
4 | */
5 | var preorderTraversal = function(root) {
6 | var stack = [];
7 |
8 | if (!root) return [];
9 |
10 | stack.push(root);
11 |
12 | var it;
13 | var ans = [];
14 | while(stack.length) {
15 | it = stack.pop();
16 | if (it.val === null) continue;
17 |
18 | ans.push(it.val);
19 |
20 | if (it.right) {
21 | stack.push(it.right);
22 | }
23 | if (it.left) {
24 | stack.push(it.left);
25 | }
26 |
27 | }
28 |
29 | return ans;
30 | };
31 |
32 | var Tree = require('leetcode').Tree;
33 | var eq = require('assert').deepEqual;
34 |
35 | eq(preorderTraversal(Tree.create([1,null,2,3])), [1,2,3]);
36 | eq(preorderTraversal(Tree.create([1,null,2,3,4, null, 5])), [1,2,3, 5, 4]);
37 |
38 |
--------------------------------------------------------------------------------
/js/combinationSum/README.md:
--------------------------------------------------------------------------------
1 | ## Combination Sum
2 | link:
3 |
4 | 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.
5 |
6 |
7 | The same repeated number may be chosen from C unlimited number of times.
8 |
9 |
10 | Note:
11 |
12 | All numbers (including target) will be positive integers.
13 | The solution set must not contain duplicate combinations.
14 |
15 |
16 |
17 |
18 | For example, given candidate set [2, 3, 6, 7] and target 7,
19 | A solution set is:
20 |
21 | [
22 | [7],
23 | [2, 2, 3]
24 | ]
25 |
26 |
--------------------------------------------------------------------------------
/js/combinationSum/combination-sum.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} candidates
3 | * @param {number} target
4 | * @return {number[][]}
5 | */
6 | var combinationSum = function(candidates, target) {
7 | var nums = candidates.sort(function (a, b) {
8 | return a - b;
9 | })
10 | var result = [];
11 |
12 | getSolution([], nums, target, result);
13 |
14 | return result;
15 | };
16 |
17 | function getSolution(current, arr, target, result) {
18 | var len = arr.length;
19 | if (arr[0] > target) return;
20 |
21 | for (var i = 0; i < len; i ++) {
22 | var val = arr[i];
23 |
24 | if (val > target) continue;
25 |
26 | var t = target;
27 | var newCurrent = current;
28 | while (val <= t) {
29 | newCurrent = [].concat(newCurrent, [val]);
30 |
31 | if (val === t) {
32 | result.push(newCurrent);
33 | break;
34 | }
35 |
36 | getSolution(newCurrent, arr.slice(i + 1), t - val, result);
37 |
38 | t = t - val;
39 | }
40 | }
41 | }
42 |
43 |
44 | var eq = require('assert').deepEqual;
45 | eq(combinationSum([2, 3, 6, 7], 7), [
46 | [2, 2, 3],
47 | [7]
48 | ]);
49 |
50 | // order doesn't matter
51 | eq(combinationSum([48,22,49,24,26,47,33,40,37,39,31,46,36,43,45,34,28,20,29,25,41,32,23], 69), [
52 | [ 20, 23, 26 ],
53 | [ 20, 24, 25 ],
54 | [ 20, 49 ],
55 | [ 20, 20, 29 ],
56 | [ 22, 23, 24 ],
57 | [ 22, 47 ],
58 | [ 22, 22, 25 ],
59 | [ 23, 46 ],
60 | [ 23, 23, 23 ],
61 | [ 24, 45 ],
62 | [ 26, 43 ],
63 | [ 28, 41 ],
64 | [ 29, 40 ],
65 | [ 32, 37 ],
66 | [ 33, 36 ]
67 | ]);
68 |
69 |
--------------------------------------------------------------------------------
/js/combinationSumIi/README.md:
--------------------------------------------------------------------------------
1 | ## Combination Sum II
2 | link:
3 |
4 | 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.
5 |
6 |
7 | Each number in C may only be used once in the combination.
8 |
9 | Note:
10 |
11 | All numbers (including target) will be positive integers.
12 | The solution set must not contain duplicate combinations.
13 |
14 |
15 |
16 |
17 | For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8,
18 | A solution set is:
19 |
20 | [
21 | [1, 7],
22 | [1, 2, 5],
23 | [2, 6],
24 | [1, 1, 6]
25 | ]
26 |
27 |
--------------------------------------------------------------------------------
/js/combinationSumIi/combination-sum-ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} candidates
3 | * @param {number} target
4 | * @return {number[][]}
5 | */
6 | var combinationSum2 = function(candidates, target) {
7 | const nums = candidates.sort(function (a, b) {
8 | return a - b;
9 | })
10 |
11 | const result = [];
12 | getSolution([], nums, target, result);
13 |
14 | return result;
15 | };
16 |
17 | function getSolution(current, arr, target, result) {
18 |
19 | if (arr[0] > target) return;
20 |
21 | const len = arr.length;
22 | var hash = {};
23 | for (var i = 0; i < len; i++) {
24 | var val = arr[i];
25 | var newCurrent = [].concat(current, [val]);
26 |
27 | if (val > target) break;
28 | if (hash[val]) continue;
29 |
30 | if (val === target) {
31 | result.push(newCurrent);
32 | } else {
33 | getSolution(newCurrent, arr.slice(i + 1), target - val, result)
34 | }
35 |
36 | hash[val] = 1;
37 | }
38 | }
39 |
40 |
41 | const eq = require('assert').deepEqual;
42 |
43 | eq(combinationSum2([10, 1, 2, 7, 6, 1, 5], 8), [
44 | [ 1, 1, 6 ],
45 | [ 1, 2, 5 ],
46 | [ 1, 7 ],
47 | [ 2, 6]
48 | ]);
49 |
--------------------------------------------------------------------------------
/js/combinationSumIii/README.md:
--------------------------------------------------------------------------------
1 | ## Combination Sum III
2 | link:
3 |
4 | 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.
5 |
6 | Example 1:
7 | Input: k = 3, n = 7
8 |
9 | Output:
10 |
11 | > [[1,2,4]]
12 |
13 |
14 | Example 2:
15 | Input: k = 3, n = 9
16 | Output:
17 | > [[1,2,6], [1,3,5], [2,3,4]]
18 |
19 |
--------------------------------------------------------------------------------
/js/combinationSumIii/combination-sum-iii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} k
3 | * @param {number} n
4 | * @return {number[][]}
5 | */
6 | var combinationSum3 = function(k, n) {
7 | var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
8 | var result = [];
9 |
10 | getSolution([], arr, n, k, result);
11 |
12 | return result;
13 | };
14 |
15 | function getSolution(current, arr, target, size, result) {
16 | if (size === 1 && (target > 9 || target < arr[0])) return;
17 |
18 | for (var i = 0; i < arr.length; i ++) {
19 | var val = arr[i];
20 | var newCurrent = [].concat(current, [val]);
21 | if (size === 1) {
22 | if (val === target) {
23 | result.push(newCurrent);
24 | break;
25 | }
26 | continue;
27 | } else {
28 | getSolution(newCurrent, arr.slice(i + 1), target - val, size - 1, result);
29 | }
30 | }
31 | }
32 |
33 | var eq = require('assert').deepEqual;
34 |
35 | eq(combinationSum3(3, 7), [[1, 2, 4]]);
36 | eq(combinationSum3(3, 9), [
37 | [1, 2, 6],
38 | [1, 3, 5],
39 | [2, 3, 4]
40 | ]);
41 |
--------------------------------------------------------------------------------
/js/combinations/README.md:
--------------------------------------------------------------------------------
1 | ## Combinations
2 | link:
3 |
4 | Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
5 |
6 | For example,
7 | If n = 4 and k = 2, a solution is:
8 |
9 | ```
10 | [
11 | [2,4],
12 | [3,4],
13 | [2,3],
14 | [1,2],
15 | [1,3],
16 | [1,4],
17 | ]
18 |
19 | ```
20 |
--------------------------------------------------------------------------------
/js/combinations/combinations.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @param {number} k
4 | * @return {number[][]}
5 | */
6 | var combine = function(n, k) {
7 |
8 | var result = [];
9 |
10 | getSolution([], 1, n, k, result);
11 | return result;
12 |
13 | };
14 |
15 | function getSolution(current, begin, n, k, result) {
16 | if (k === 0) {
17 | result.push(current);
18 | return;
19 | }
20 |
21 | for (var i = begin; i <= n; i ++) {
22 |
23 | // concat can't pass leetcode test for Time Limit Exceeded, but slice and push can pass
24 | // getSolution([].concat(current, [i]), i + 1, n, k - 1, result);
25 |
26 | var newCurrent = current.slice(0);
27 | newCurrent.push(i);
28 |
29 | getSolution(newCurrent, i + 1, n, k - 1, result);
30 | }
31 | }
32 |
33 | var eq = require('assert').deepEqual;
34 |
35 | eq(combine(4, 2), [
36 | [1, 2],
37 | [1, 3],
38 | [1, 4],
39 | [2, 3],
40 | [2, 4],
41 | [3, 4],
42 | ])
43 |
--------------------------------------------------------------------------------
/js/compareVersionNumbers/compare_version_numbers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} version1
3 | * @param {string} version2
4 | * @return {number}
5 | */
6 | var compareVersion = function(version1, version2) {
7 | var va = version1.split('.').map(function (val) { return parseInt(val, 10); });
8 | var vb = version2.split('.').map(function (val) { return parseInt(val, 10); });
9 |
10 | var len = Math.max(va.length, vb.length);
11 |
12 | for (var i = 0; i < len; i ++) {
13 | var sa = i < va.length ? va[i] : 0;
14 | var sb = i < vb.length ? vb[i] : 0;
15 |
16 | if (sa === sb) continue;
17 |
18 | return sa > sb ? 1 : -1;
19 | }
20 |
21 | return 0;
22 | };
23 |
24 |
25 | var eq = require('assert').equal;
26 |
27 | eq(compareVersion('12.3.11', '1.2.2.2'), 1);
28 | eq(compareVersion('1.1.11', '1.2.0'), -1);
29 | eq(compareVersion('1.1', '1.1'), 0);
30 | eq(compareVersion('0.1', '0.0.1'), 1);
31 | eq(compareVersion('0.1.1', '1.0.1'), -1);
32 | eq(compareVersion('1.0', '1'), 0);
33 |
--------------------------------------------------------------------------------
/js/constructBinaryTreeFromInorderAndPostorderTraversal/construct_binary_tree_from_inorder_and_postorder_traversal.js:
--------------------------------------------------------------------------------
1 | var Tree = require('leetcode').Tree;
2 | var TreeNode = Tree.node;
3 | /**
4 | * @param {number[]} inorder
5 | * @param {number[]} postorder
6 | * @return {TreeNode}
7 | */
8 | var buildTree = function(inorder, postorder) {
9 | // 4 2 1 3 5
10 | // 4 2 5 3 1
11 | //
12 |
13 | var parent = {};
14 | build(inorder, postorder, parent);
15 |
16 | return parent.next;
17 | };
18 |
19 | function build(inorder, postorder, parent, type) {
20 | if (!inorder.length || inorder.length !== postorder.length) return null;
21 |
22 | var val = postorder.pop();
23 | var root = new TreeNode(val);
24 | var idx = inorder.indexOf(val);
25 | if (type) {
26 | parent[type] = root;
27 | } else {
28 | parent.next = root;
29 | }
30 |
31 |
32 | if (!~idx) return null;
33 |
34 | build(inorder.slice(0, idx), postorder.slice(0, idx), root, 'left');
35 | build(inorder.slice(idx + 1), postorder.slice(idx), root, 'right');
36 | }
37 |
38 | var eq = require('assert').deepEqual;
39 |
40 | var t1 = buildTree([4, 2, 1, 3, 5], [4, 2, 5, 3, 1]);
41 | var t2 = Tree.create([1, 2, 3, 4, null, null, 5]);
42 | // @todo(zhiye) skip fail test
43 | // console.log(t1, t2)
44 | // eq(t1, t2)
45 |
--------------------------------------------------------------------------------
/js/containerWithMostWater/README.md:
--------------------------------------------------------------------------------
1 | ## Container With Most Water
2 | link:
3 |
4 | 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 the line i is at (i, ai) and (i, 0). Find two lines, which, together with the x-axis forms a container, such that the container contains the most water.
5 |
6 | Notice that you may not slant the container.
7 |
8 |
9 |
10 | Example 1:
11 | 
12 |
13 | ```
14 | Input: height = [1,8,6,2,5,4,8,3,7]
15 | Output: 49
16 | ```
17 | Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
18 | Example 2:
19 |
20 | ```
21 | Input: height = [1,1]
22 | Output: 1
23 | ```
24 | Example 3:
25 |
26 | ```
27 | Input: height = [4,3,2,1,4]
28 | Output: 16
29 | ```
30 |
31 | Example 4:
32 |
33 | ```
34 | Input: height = [1,2,1]
35 | Output: 2
36 | ```
37 |
38 |
39 | Constraints:
40 |
41 | - n == height.length
42 | - 2 <= n <= 105
43 | - 0 <= height[i] <= 104
44 |
--------------------------------------------------------------------------------
/js/containerWithMostWater/container-with-most-water.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} height
3 | * @return {number}
4 | */
5 | var maxArea = function(height) {
6 | let max = 0;
7 | const length = height.length;
8 | for (let left = 0; left < length - 1; left ++) {
9 | for (let right = length - 1; right > left; right --) {
10 | const area = (right - left) * Math.min(height[left], height[right]);
11 | if (area > max) max = area;
12 |
13 | if (height[right] >= height[left]) break;
14 | }
15 | }
16 |
17 | return max;
18 | };
19 |
20 |
21 | var eq = require('assert').strictEqual;
22 | eq(maxArea([4,3,2,1,4]), 16);
23 | eq(maxArea([1,8,6,2,5,4,8,3,7]), 49);
24 | eq(maxArea([1,8,6,2,5,4,8,3,7]), 49);
25 |
26 |
--------------------------------------------------------------------------------
/js/containsDuplicate/contains_duplicate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {boolean}
4 | */
5 | // use some
6 | var containsDuplicate = function(nums) {
7 | var hash = {};
8 |
9 | return nums.some(function (val) {
10 | if (hash[val]) return true;
11 | hash[val] = 1;
12 | });
13 | };
14 |
15 | var containsDuplicate = function(nums) {
16 | return nums.length > (new Set(nums)).size;
17 | };
18 |
19 |
20 | var eq = require('assert').equal;
21 |
22 | eq(containsDuplicate([1,2,3]), false);
23 | eq(containsDuplicate([1,2,1]), true);
24 | eq(containsDuplicate([]), false);
25 |
--------------------------------------------------------------------------------
/js/countAndSay/count_and_say.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {string}
4 | */
5 | var countAndSay = function(n) {
6 | var m = '1';
7 | for (var i = 0; i < n - 1; i ++) {
8 | m = f(m);
9 | }
10 |
11 | return m;
12 | };
13 |
14 |
15 | function f(n) {
16 | n = n.toString();
17 | var res = '';
18 | var count = 0;
19 | var pre = '';
20 |
21 | if (n == 1) return '11';
22 | for (var i = 0; i < n.length; i ++) {
23 | if (pre === n.charAt(i)) {
24 | count += 1;
25 | } else {
26 | res += count ? `${count}${pre}` : '';
27 | pre = n.charAt(i);
28 | count = 1;
29 | }
30 | }
31 |
32 | res += `${count}${pre}`;
33 | return res;
34 | }
35 |
36 |
37 | var eq = require('assert').equal;
38 |
39 | eq(countAndSay(1), '1');
40 | eq(countAndSay(4), '1211');
41 | eq(countAndSay(5), '111221');
42 |
--------------------------------------------------------------------------------
/js/deleteNodeInALinkedList/delete_node_in_a_linked_list.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} node
10 | * @return {void} Do not return anything, modify node in-place instead.
11 | */
12 | var deleteNode = function(node) {
13 | var current = node;
14 | var slow = {};
15 |
16 | while(current.next) {
17 | var next = current.next;
18 | current.val = next.val;
19 | slow = current;
20 | current = next;
21 | }
22 |
23 | slow.next = null;
24 | };
25 |
--------------------------------------------------------------------------------
/js/divideTwoIntegers/divide_two_integers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} dividend
3 | * @param {number} divisor
4 | * @return {number}
5 | */
6 | var divide = function(dividend, divisor) {
7 | if (!divisor) return +Infinity;
8 | var sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;
9 |
10 | dividend = Math.abs(dividend);
11 | divisor = Math.abs(divisor);
12 |
13 | if (divisor === 1) return !~sign ? -dividend: dividend;
14 |
15 | var res;
16 | var sum = 0;
17 | while (dividend >= divisor) {
18 | var val = divisor;
19 | var ans = 1;
20 | // val << 1 may overflow to negative
21 | while (dividend >= (val << 1) && (val << 1) > 0) {
22 | val <<= 1;
23 | ans <<= 1;
24 | }
25 |
26 | dividend -= val;
27 | sum += ans;
28 | }
29 |
30 | if (!~sign) sum = -sum;
31 | return sum;
32 | };
33 |
34 |
35 | var eq = require('assert').equal;
36 |
37 | eq(divide(18, 2), 9);
38 | eq(divide(32, -2), -16);
39 | eq(divide(2147483647, 2), 1073741823);
40 |
--------------------------------------------------------------------------------
/js/excelSheetColumnNumber/excel_sheet_column_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {number}
4 | */
5 | var titleToNumber = function(s) {
6 | return s.split('')
7 | .reverse()
8 | .reduce(function (pre, item, i) {
9 | item = item.charCodeAt(0) - 64;
10 | return pre + item * Math.pow(26, i);
11 | }, 0);
12 | };
13 |
14 | var eq = require('assert').equal;
15 |
16 | eq(titleToNumber('Z'), 26);
17 | eq(titleToNumber('AB'), 28);
18 | eq(titleToNumber('AA'), 27);
19 | eq(titleToNumber('AAA'), 703);
20 |
--------------------------------------------------------------------------------
/js/excelSheetColumnTitle/excel_sheet_column_title.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {string}
4 | */
5 | var convertToTitle = function(n) {
6 | // A unicode value 65
7 | var s = 65;
8 | var ans = '';
9 | while (n) {
10 | n -= 1;
11 | var tmp = String.fromCharCode(s + n % 26)
12 | ans = tmp + ans;
13 |
14 | n = Math.floor(n / 26);
15 | }
16 |
17 | return ans;
18 | };
19 |
20 |
21 | var eq = require('assert').equal;
22 |
23 | eq(convertToTitle(27), 'AA')
24 | eq(convertToTitle(26), 'Z')
25 | eq(convertToTitle(703), 'AAA')
26 |
--------------------------------------------------------------------------------
/js/factorCombinations/README.md:
--------------------------------------------------------------------------------
1 | ## Factor Combinations
2 | link:
3 |
4 | Numbers can be regarded as product of its factors. For example,
5 |
6 | ```
7 | 8 = 2 x 2 x 2;
8 | = 2 x 4.
9 | ```
10 |
11 | Write a function that takes an integer n and return all possible combinations of its factors.
12 |
13 |
14 | Note:
15 |
16 | You may assume that n is always positive.
17 | Factors should be greater than 1 and less than n.
18 |
19 |
20 | Examples:
21 | input: 1
22 | output:
23 |
24 | ```
25 | []
26 | ```
27 |
28 | input: 37
29 | output:
30 |
31 | []
32 |
33 | input: 12
34 | output:
35 |
36 | ```
37 | [
38 | [2, 6],
39 | [2, 2, 3],
40 | [3, 4]
41 | ]
42 | ```
43 |
44 | input: 32
45 | output:
46 |
47 | ```
48 | [
49 | [2, 16],
50 | [2, 2, 8],
51 | [2, 2, 2, 4],
52 | [2, 2, 2, 2, 2],
53 | [2, 4, 4],
54 | [4, 8]
55 | ]
56 | ```
57 |
58 |
--------------------------------------------------------------------------------
/js/factorCombinations/factor-combinations.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number[][]}
4 | */
5 | var getFactors = function(n) {
6 | var result = [];
7 |
8 | getSolutions([], 2, n, result);
9 |
10 | return result;
11 | };
12 |
13 | function getSolutions(current, begin, n, result) {
14 | // when target is not integer
15 | if (parseInt(n, 10) !== n) return;
16 |
17 | // instead of `i < n`, reduce complexity to logn
18 | for (var i = begin; i <= Math.sqrt(n); i ++) {
19 | var target = n;
20 | var val = i;
21 | var newCurrent = current;
22 |
23 | // in case of duplicate
24 | while(target > val) {
25 | var left = target % val;
26 | target = target / val;
27 |
28 | if (left !== 0 || target < val) break;
29 |
30 | newCurrent = newCurrent.slice(0).concat([i]);
31 | // only push `target` to result if target >= val
32 | result.push(newCurrent.slice(0).concat([target]));
33 | getSolutions(newCurrent, i + 1, target, result);
34 | }
35 | }
36 | }
37 |
38 |
39 | var eq = require('assert').deepEqual;
40 |
41 | eq(getFactors(1), []);
42 | eq(getFactors(3), []);
43 | eq(getFactors(32), [
44 | [ 2, 16 ],
45 | [ 2, 4, 4 ],
46 | [ 2, 2, 8 ],
47 | [ 2, 2, 2, 4 ],
48 | [ 2, 2, 2, 2, 2 ],
49 | [ 4, 8 ],
50 | ]);
51 |
--------------------------------------------------------------------------------
/js/findFirstAndLastPositionOfElementInSortedArray/README.md:
--------------------------------------------------------------------------------
1 | ## find first and last position of element in sorted array
2 | link:
3 |
--------------------------------------------------------------------------------
/js/findFirstAndLastPositionOfElementInSortedArray/find-first-and-last-position-of-element-in-sorted-array.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number[]}
5 | */
6 | var searchRange = function(nums, target) {
7 | let left = -1;
8 | let right = -1;
9 | let low = 0;
10 | let high = nums.length - 1;
11 |
12 | while (low <= high) {
13 | const mid = Math.floor((high + low) / 2);
14 | const midValue = nums[mid];
15 | if(midValue === target) {
16 | right = left = mid;
17 |
18 | // this approach is easier to understand
19 | // go all the way right until see a non-target value
20 | let i = mid + 1;
21 | while (i <= high && nums[i] === target) {
22 | right = i;
23 | i ++;
24 | }
25 |
26 | // go all the way left until see a non-target value
27 | let j = mid - 1;
28 | while(j >= low && nums[j] === target) {
29 | left = j;
30 | j --;
31 | }
32 |
33 | break;
34 | }
35 |
36 | if (midValue < target) low = mid + 1;
37 | if (midValue > target) high = mid - 1;
38 | }
39 |
40 | return [left, right];
41 | };
42 |
43 | const eq = require('assert').deepStrictEqual
44 |
45 | eq(searchRange([5, 6, 7, 7, 8, 8, 8, 10], 8), [4, 6]);
46 | eq(searchRange([5,7,7,8,8,10], 8), [3, 4]);
47 | eq(searchRange([5,7,7,8,8,10], 6), [-1, -1]);
48 | eq(searchRange([], 0), [-1, -1]);
49 |
--------------------------------------------------------------------------------
/js/findFirstAndLastPositionOfElementInSortedArray/find-first-and-last-position-of-element-in-sorted-array_1.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number[]}
5 | */
6 | var searchRange = function(nums, target) {
7 | let left = -1;
8 | let right = -1;
9 | let low = 0;
10 | let high = nums.length - 1;
11 |
12 | while (low <= high) {
13 | const mid = Math.floor((high + low) / 2);
14 | const midValue = nums[mid];
15 | if(midValue === target) {
16 | right = left = mid;
17 | const [hightLeft, highRight] = searchRange(nums.slice(mid + 1), target);
18 | const [lowLeft, lowRight] = searchRange(nums.slice(low, mid), target);
19 |
20 | if (highRight >= 0) right = mid + 1 + highRight;
21 | if (lowLeft >= 0) left = low + lowLeft;
22 | break;
23 | }
24 |
25 | if (midValue < target) low = mid + 1;
26 | if (midValue > target) high = mid - 1;
27 | }
28 |
29 | return [left, right];
30 | };
31 |
32 | const eq = require('assert').deepStrictEqual
33 |
34 | eq(searchRange([5, 6, 7, 7, 8, 8, 8, 10], 8), [4, 6]);
35 | eq(searchRange([5,7,7,8,8,10], 8), [3, 4]);
36 | eq(searchRange([5,7,7,8,8,10], 6), [-1, -1]);
37 | eq(searchRange([], 0), [-1, -1]);
38 |
--------------------------------------------------------------------------------
/js/findTheDuplicateNumber/find_the_duplicate_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var findDuplicate = function(nums) {
6 | // 1 2 3 3 4
7 | // 1 3 3 3 3
8 | // solution http://keithschwarz.com/interesting/code/?dir=find-duplicate
9 | var len = nums.length;
10 |
11 | var slow = len -1;
12 | var fast = len - 1;
13 | while(true) {
14 | slow = nums[slow] - 1;
15 | fast = nums[nums[fast] - 1] - 1;
16 |
17 | if (slow === fast) {
18 | break;
19 | }
20 | }
21 |
22 | var finder = len - 1;
23 | while(true) {
24 | slow = nums[slow] - 1;
25 | finder = nums[finder] - 1;
26 |
27 | if (slow === finder) {
28 | return finder + 1;
29 | }
30 | }
31 | };
32 |
33 |
34 | var eq = require('assert').equal;
35 |
36 | eq(findDuplicate([1, 2, 3, 3, 4]), 3);
37 | eq(findDuplicate([2, 1, 1]), 1);
38 |
--------------------------------------------------------------------------------
/js/firstBadVersion/first_bad_version.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for isBadVersion()
3 | *
4 | * @param {integer} version number
5 | * @return {boolean} whether the version is bad
6 | * isBadVersion = function(version) {
7 | * ...
8 | * };
9 | */
10 |
11 | /**
12 | * @param {function} isBadVersion()
13 | * @return {function}
14 | */
15 | var solution = function(isBadVersion) {
16 | /**
17 | * @param {integer} n Total versions
18 | * @return {integer} The first bad version
19 | */
20 | return function(n) {
21 | var low = 1;
22 | var high = n;
23 |
24 | var mid;
25 | while(low < high) {
26 | mid = low + ((high -low) >> 1);
27 | if (isBadVersion(mid)) {
28 | high = mid;
29 | } else {
30 | low = mid + 1;
31 | }
32 | }
33 |
34 | return low;
35 | };
36 | };
37 |
--------------------------------------------------------------------------------
/js/firstMissingPositive/first_missing_positive.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | 'use strict';
6 | var firstMissingPositive = function(nums) {
7 | var len = nums.length;
8 | if (len === 0) return 1;
9 |
10 | for (var i = 0; i < nums.length; i++) {
11 | var val = nums[i];
12 | var tmp;
13 | if (val <= 0 || val > len || val === nums[val - 1]) {
14 | continue;
15 | }
16 |
17 | if (i !== val - 1) {
18 | tmp = val;
19 | nums[i] = nums[val - 1];
20 | nums[val - 1] = val;
21 | i--;
22 | }
23 | }
24 | for (var idx = 0; idx < len; idx++) {
25 | if (idx !== nums[idx] - 1) {
26 | return idx + 1;
27 | }
28 | }
29 |
30 | return len + 1
31 | };
32 |
33 | var assert = require('assert');
34 |
35 | var a = [0];
36 | assert.equal(firstMissingPositive(a), 1)
37 | a = [1];
38 | assert.equal(firstMissingPositive(a), 2)
39 |
40 | a = [1, 2, 0];
41 | assert.equal(firstMissingPositive(a), 3)
42 |
43 | a = [3,4,-1,1];
44 | assert.equal(firstMissingPositive(a), 2)
45 |
46 |
--------------------------------------------------------------------------------
/js/generalizedAbbreviation/README.md:
--------------------------------------------------------------------------------
1 | ## 320. Generalized Abbreviation
2 | link:
3 |
4 | Write a function to generate the generalized abbreviations of a word.
5 |
6 | Example:
7 | Given word = "word", return the following list (order does not matter):
8 |
9 | > ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]
10 |
--------------------------------------------------------------------------------
/js/generalizedAbbreviation/generalized-abbreviation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} word
3 | * @return {string[]}
4 | */
5 | var generateAbbreviations = function(word) {
6 | var result = [];
7 | getSolutions('', word, result);
8 | return result;
9 | };
10 |
11 | function getSolutions(current, str, result) {
12 | if (str.length === 0) {
13 | result.push(current);
14 | return;
15 | }
16 |
17 | // add first char without converting
18 | getSolutions(current + str.charAt(0), str.substr(1), result);
19 |
20 | // can't produce continuous numbers in the result
21 | var lastChar = current.substr(-1);
22 | if (lastChar && /[0-9]/.test(lastChar)) return;
23 |
24 | for (var i = 1; i <= str.length; i ++) {
25 | var val = str.substr(0, i);
26 | getSolutions(current + i, str.substr(i), result);
27 | }
28 | }
29 |
30 | var eq = require('assert').deepEqual;
31 | eq(generateAbbreviations('word'), [
32 | 'word',
33 | 'wor1',
34 | 'wo1d',
35 | 'wo2',
36 | 'w1rd',
37 | 'w1r1',
38 | 'w2d',
39 | 'w3',
40 | '1ord',
41 | '1or1',
42 | '1o1d',
43 | '1o2',
44 | '2rd',
45 | '2r1',
46 | '3d',
47 | '4'
48 | ]);
49 |
--------------------------------------------------------------------------------
/js/grayCode/README.md:
--------------------------------------------------------------------------------
1 | ## Gray Code
2 | link:
3 | The gray code is a binary numeral system where two successive values differ in only one bit.
4 |
5 | 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.
6 |
7 | For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
8 |
9 | 00 - 0
10 | 01 - 1
11 | 11 - 3
12 | 10 - 2
13 |
14 |
15 | Note:
16 | For a given n, a gray code sequence is not uniquely defined.
17 |
18 | For example, [0,2,3,1] is also a valid gray code sequence according to the above definition.
19 |
20 | For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
--------------------------------------------------------------------------------
/js/grayCode/gray-code.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number[]}
4 | * @note solution see https://is.gd/MiDHHf
5 | */
6 | var grayCode = function(n) {
7 | var res = [];
8 | res.push(0);
9 | for (var i = 0; i < n; i++) {
10 | var size = res.length;
11 |
12 | for (var k = size - 1; k >= 0; k --) {
13 | res.push(res[k] | 1 << i)
14 | }
15 | }
16 |
17 | return res;
18 | };
19 |
20 | var eq = require('assert').deepEqual;
21 |
22 | eq(grayCode(3), [ 0, 1, 3, 2, 6, 7, 5, 4 ]);
23 | eq(grayCode(2), [ 0, 1, 3, 2 ]);
24 |
--------------------------------------------------------------------------------
/js/groupShiftedStrings/group_shifted_strings.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string[]} strings
3 | * @return {string[][]}
4 | */
5 | var groupStrings = function(strings) {
6 | var dicts = {};
7 | var gs = [];
8 |
9 | for (var i = 0; i < strings.length; i ++) {
10 | var val = strings[i];
11 | var key = getKey(val);
12 |
13 | if (dicts[key]) {
14 | dicts[key].push(val);
15 | } else {
16 | gs.push([val]);
17 | dicts[key] = gs[gs.length - 1];
18 | }
19 | }
20 |
21 | return gs;
22 | };
23 |
24 | // encode string with distance of two adjacent charactors,
25 | // return `-11-2` etc
26 | function getKey(str) {
27 | var key = '';
28 | for(var i = 1; i < str.length; i ++) {
29 | var val = str.charCodeAt(i);
30 | var preVal = str.charCodeAt(i - i);
31 |
32 | var d = val - preVal;
33 | if (val < preVal) {
34 | d = val - preVal + 26;
35 | }
36 |
37 | // distance could be `11`, need to distinguish with `'1'` + `'1'`
38 | key += '-' + d;
39 | }
40 |
41 | return key;
42 | }
43 |
44 | var eq = require('assert').deepEqual;
45 |
46 | // @note this problem doesn't require the order of groups
47 | eq(groupStrings(['abc', 'bcd', 'acef', 'xyz', 'az', 'ba', 'a', 'z']), [
48 | ['abc','bcd','xyz'],
49 | ['acef'],
50 | ['az','ba'],
51 | ['a','z']
52 | ]);
53 |
54 | eq(groupStrings(['abc','am']), [
55 | ['abc'],
56 | ['am']
57 | ]);
58 |
--------------------------------------------------------------------------------
/js/hIndex/h_index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} citations
3 | * @return {number}
4 | */
5 | // var hIndex = function(citations) {
6 | // if (!citations.length) return 0;
7 | // citations = citations.sort(function (a, b) {
8 | // return b - a;
9 | // });
10 | //
11 | // var pre = citations[0];
12 | // var h = Math.min(pre, 1);
13 | // # dummy node at the end
14 | // citations.push(-1);
15 | //
16 | // for (var i = 1; i < citations.length; i++) {
17 | // var val = citations[i];
18 | //
19 | // if (pre >= i) {
20 | // h = i;
21 | // }
22 | // pre = val;
23 | // }
24 | //
25 | // return h;
26 | // };
27 |
28 | // hash solution
29 | var hIndex = function(citations) {
30 | var possible = [];
31 | var len = citations.length;
32 | if (len === 0) return 0;
33 |
34 | // possible array length = citations.length + 1, 0 - citations.length
35 | possible.length = len + 2;
36 | // fill with 0
37 | possible = possible.join('-').split('').map(function() {
38 | return 0;
39 | });
40 |
41 | for (var i = 0; i < len; i ++) {
42 | var val = citations[i];
43 | var idx = val > len ? len : val;
44 |
45 | possible[idx] += 1;
46 | }
47 |
48 | var result = 0;
49 | for (var k = len; k >= 0; k --) {
50 | result += possible[k];
51 | if (result >= k) {
52 | return k;
53 | }
54 | }
55 | }
56 |
57 | var eq = require('assert').equal;
58 |
59 | eq(hIndex([]), 0);
60 | eq(hIndex([0]), 0);
61 | eq(hIndex([2, 2, 2]), 2);
62 | eq(hIndex([3, 0, 6, 1, 5]), 3);
63 | eq(hIndex([5, 4, 6, 1, 5]), 4);
64 | eq(hIndex([5, 6]), 2);
65 |
--------------------------------------------------------------------------------
/js/hIndexIi/h_index_ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} citations
3 | * @return {number}
4 | */
5 | var hIndex = function(citations) {
6 | var len = citations.length;
7 |
8 | citations.unshift(0);
9 | var low = 0;
10 | var high = len;
11 | var mid;
12 | var max = 0;
13 | while (low <= high) {
14 | mid = (low + high) >> 1;
15 |
16 | // numbers count >= citations[mid]
17 | var largetLeft = len - mid + 1;
18 | if (citations[mid] >= largetLeft) {
19 | max = Math.max(max, largetLeft);
20 | high = mid - 1;
21 | } else {
22 | low = mid + 1;
23 | }
24 | }
25 |
26 | return max;
27 | };
28 |
29 | var eq = require('assert').equal;
30 |
31 | eq(hIndex([]), 0);
32 | eq(hIndex([0]), 0);
33 | eq(hIndex([2, 2, 2]), 2);
34 | eq(hIndex([0, 1, 3, 5, 6]), 3);
35 | eq(hIndex([1, 4, 5, 5, 6]), 4);
36 |
--------------------------------------------------------------------------------
/js/happyNumber/happy_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {boolean}
4 | */
5 | var isHappy = function(n) {
6 | var mem = [];
7 |
8 | while (true) {
9 | var arr = n.toString().split('');
10 |
11 | n = arr.reduce(function (pre, current) {
12 | current = parseInt(current);
13 | return pre + current * current;
14 | }, 0);
15 |
16 | if (n === 1) return true;
17 | if (mem.indexOf(n) !== -1) {
18 | return false;
19 | }
20 |
21 | mem.push(n);
22 | }
23 | };
24 |
25 |
26 | var eq = require('assert').equal;
27 |
28 | eq(isHappy(19), true);
29 | eq(isHappy(18), false);
30 |
--------------------------------------------------------------------------------
/js/integerToEnglishWords/integer_to_english_words.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {string}
4 | */
5 | var numberToWords = function(num) {
6 | var quantityHash = ['', 'Thousand', 'Million', 'Billion'];
7 |
8 | if (num === 0) return 'Zero';
9 |
10 | // separate num into 3-nums parts
11 | var parts = [];
12 | num = num.toString().split('');
13 | while (num.length) {
14 | parts.push(num.splice(-3, 3));
15 | }
16 |
17 | return parts.reduce(function (pre, item, index) {
18 | var words = say(item);
19 | var q = quantityHash[index];
20 |
21 | if (words) {
22 | words = q ? [words, q] : [words];
23 | pre = [].concat(words, pre);
24 | }
25 |
26 | return pre;
27 | }, []).join(' ');
28 | };
29 |
30 | function say(num) {
31 | num = parseInt(num.join(''));
32 | if (num === 0) return '';
33 |
34 | var numWords = ['' , 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine'];
35 |
36 | var hash = {
37 | '10': 'Ten',
38 | '11': 'Eleven',
39 | '12': 'Twelve',
40 | '13': 'Thirteen',
41 | '14': 'Fourteen',
42 | '15': 'Fifteen',
43 | '16': 'Sixteen',
44 | '17': 'Seventeen',
45 | '18': 'Eighteen',
46 | '19': 'Nineteen'
47 | };
48 |
49 | var tenHash = [ '', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
50 |
51 | var res = [];
52 | var item;
53 |
54 | num = ('000' + num).substr(-3, 3).split('');
55 |
56 | // hundred
57 | item = num[0];
58 | if (item !== '0') {
59 | res.push(numWords[item] + ' Hundred');
60 | }
61 |
62 | // decade
63 | var skipOne = false;
64 | var val = '';
65 | item = num[1];
66 | if (item !== '0') {
67 | if (item === '1') {
68 | skipOne = true;
69 | val = hash[num.join('').substr(1)];
70 | } else {
71 | val = tenHash[parseInt(item)];
72 | }
73 |
74 | res.push(val);
75 | }
76 |
77 | // one
78 | item = num[2];
79 | if (item !== '0' && !skipOne) {
80 | res.push(numWords[parseInt(item)]);
81 | }
82 |
83 | return res.join(' ');
84 | }
85 |
86 | var eq = require('assert').equal;
87 |
88 | eq(numberToWords(0), 'Zero');
89 | eq(numberToWords(1), 'One');
90 | eq(numberToWords(16), 'Sixteen');
91 | eq(numberToWords(2147), 'Two Thousand One Hundred Forty Seven');
92 | eq(numberToWords(12147), 'Twelve Thousand One Hundred Forty Seven');
93 | eq(numberToWords(1234567), 'One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven');
94 |
--------------------------------------------------------------------------------
/js/integerToRoman/integer-to-roman.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert')
2 | /**
3 | * @param {number} num
4 | * @returns {string}
5 | */
6 | var intToRoman = function(num) {
7 | var steps = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
8 | , dict = {
9 | '1000': 'M', '900': 'CM', '500': 'D', '400': 'CD',
10 | '100': 'C', '90': 'XC', '50': 'L', '40': 'XL',
11 | '10': 'X', '9': 'IX', '5': 'V', '4': 'IV',
12 | '1': 'I'
13 | };
14 |
15 | var res = '';
16 |
17 | for (var i = 0; i < steps.length; i++) {
18 | var step = steps[i]
19 | , m = parseInt(num / step)
20 | , num = num % step;
21 |
22 | if (m > 0) {
23 | res += repeat(dict[step], m);
24 | }
25 |
26 | if (num === 0) break;
27 | }
28 |
29 | return res;
30 | };
31 |
32 | function repeat(str, num) {
33 | var res = '';
34 | while (num > 0) {
35 | res += str;
36 | num --;
37 | }
38 |
39 | return res;
40 | }
41 |
42 |
43 | assert.equal(intToRoman(2015), 'MMXV');
44 | assert.equal(intToRoman(1066), 'MLXVI', 'fail 1066');
45 | assert.equal(intToRoman(1904), 'MCMIV', 'fail 1904');
46 |
--------------------------------------------------------------------------------
/js/invertBinaryTree/invert_binary_tree.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {TreeNode} root
3 | * @return {TreeNode}
4 | */
5 | // solution 1: recursion
6 | var invertTree = function(root) {
7 |
8 | if (!root) return root;
9 | var left = root.left;
10 | var right = root.right;
11 |
12 | if (!right && !left) return root;
13 |
14 | root.right = invertTree(left);
15 | root.left = invertTree(right);
16 |
17 | return root;
18 | };
19 |
20 | invertTree = function(root) {
21 |
22 | if (!root) return root;
23 | var stack = [root];
24 |
25 | var current;
26 | var left;
27 | var right;
28 | while(stack.length) {
29 | current = stack.pop();
30 |
31 | if (!current) continue;
32 |
33 | left = current.left;
34 | right = current.right;
35 |
36 | current.left = right;
37 | current.right = left;
38 |
39 | if (left) stack.push(left);
40 | if (right) stack.push(right);
41 | }
42 |
43 | return root;
44 | };
45 |
46 | var Tree = require('leetcode').Tree;
47 |
48 | var eq = require('assert').deepEqual;
49 | eq(invertTree(Tree.create([1, 2, 3])),
50 | Tree.create([1, 3, 2]));
51 |
52 |
53 | eq(invertTree(Tree.create([4, 2, 7, 1, 3, 6, 9])),
54 | Tree.create([4, 7, 2, 9, 6, 3, 1]));
55 |
--------------------------------------------------------------------------------
/js/isomorphicStrings/isomorphic_strings.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @param {string} t
4 | * @return {boolean}
5 | */
6 | var isIsomorphic = function(s, t) {
7 | var s = s.split('');
8 | var t = t.split('');
9 |
10 | if (new Set(s).size !== new Set(t).size) return false;
11 |
12 | var zip = new Set();
13 | s.forEach(function (item, i) {
14 | zip.add(s[i] + ' ' + t[i])
15 | });
16 |
17 | return new Set(zip).size === new Set(s).size;
18 | };
19 |
20 | var eq = require('assert').equal;
21 |
22 | eq(isIsomorphic('egg', 'add'), true);
23 | eq(isIsomorphic('egg', 'ddd'), false);
24 |
--------------------------------------------------------------------------------
/js/letterCombinationsOfAPhoneNumber/letter_combinations_of_a_phone_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} digits
3 | * @return {string[]}
4 | */
5 | var letterCombinations = function(digits) {
6 | var map = [ '0', '1', ['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i'], ['j', 'k', 'l'], ['m', 'n', 'o'], ['p', 'q', 'r', 's'], ['t', 'u', 'v'], ['w', 'x', 'y', 'z']];
7 |
8 | if (digits.length === 0) return [];
9 | var digitsArr = digits.split('').map((val) => parseInt(val, 10)).map((val) => map[val]);
10 |
11 | var res = [];
12 | for (var i = 0; i < digitsArr.length; i++) {
13 | res = merge(res, digitsArr[i]);
14 | }
15 |
16 | return res;
17 | };
18 |
19 | function merge(srcArr, letters) {
20 | if (srcArr.length === 0) {
21 | return letters.slice(0);
22 | }
23 |
24 | var res = [];
25 |
26 | for (var i = 0; i < letters.length; i ++) {
27 | var val = letters[i];
28 |
29 | srcArr.forEach(item => {
30 | res.push(item + val);
31 | });
32 | }
33 |
34 | return res;
35 | }
36 |
37 | var eq = require('assert').deepEqual;
38 |
39 | eq(letterCombinations('23'), [ 'ad', 'bd', 'cd', 'ae', 'be', 'ce', 'af', 'bf', 'cf']);
40 | eq(letterCombinations(''), []);
41 |
42 |
--------------------------------------------------------------------------------
/js/linkedListCycleIi/linked_list_cycle_ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 |
9 | /**
10 | * @param {ListNode} head
11 | * @return {ListNode}
12 | */
13 | var detectCycle = function(head) {
14 | var slow = head;
15 | var fast = head;
16 |
17 | while(slow && fast) {
18 | slow = slow.next;
19 | fast = fast.next;
20 |
21 | if (!fast) return null;
22 | fast = fast.next;
23 |
24 | if (fast === slow) break;
25 | }
26 | if (!slow || !fast) return null;
27 |
28 | // when head is the loop start
29 | if (slow === head) return head;
30 |
31 | var finder = head;
32 | while(true) {
33 | slow = slow.next;
34 | finder = finder.next;
35 |
36 | if (slow === finder) {
37 | break;
38 | }
39 | }
40 |
41 | return finder;
42 | };
43 |
--------------------------------------------------------------------------------
/js/longestPalindromicSubstring/longest_palindromic_substring.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {string}
4 | */
5 | var longestPalindrome = function(s) {
6 | // 1 3 4 5 6 5 6 5 6 5 7
7 |
8 | var length = s.length;
9 | if (length <= 1) return s;
10 |
11 | var len = 1;
12 | var ans;
13 |
14 | for (var i = 0; i < length - 1; i ++) {
15 | // abba pattern
16 | var even = getSub(s, i, i + 1);
17 | // aba pattern
18 | var odd = getSub(s, i - 1, i + 1)
19 | odd[0] += 1;
20 |
21 | var tmp = even[0] > odd[0] ? even : odd;
22 | if (tmp[0] > len) {
23 | len = tmp[0];
24 | ans = s.substr(tmp[1], len);
25 | }
26 | }
27 |
28 | return ans;
29 | };
30 |
31 | // find longest palindrome
32 | // left and right is the start point to search two direction
33 | function getSub(s, left, right) {
34 | var length = s.length;
35 | var len = 0;
36 | while (left >= 0 && right <= length - 1) {
37 | if (s.charAt(left) === s.charAt(right)) {
38 | len += 2;
39 | left -= 1;
40 | right += 1;
41 | } else {
42 | break;
43 | }
44 | }
45 |
46 | return [len, left + 1];
47 | }
48 |
49 |
50 | var eq = require('assert').equal;
51 |
52 | eq(longestPalindrome('123456654345665'), '56654345665');
53 | eq(longestPalindrome('1232112'), '12321');
54 | eq(longestPalindrome('11'), '11');
55 |
--------------------------------------------------------------------------------
/js/majorityElement/majority_element.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | // a genius solution, check http://is.gd/j5nJsb
6 | var majorityElement = function(nums) {
7 | var major;
8 | var count = 0;
9 | var mid = (nums.length >> 1);
10 |
11 | for (var i = 0; i< nums.length; i ++) {
12 | var val = nums[i];
13 | if (count === 0) {
14 | count = 1;
15 | major = val;
16 | } else if (major === val) {
17 | count ++;
18 | } else {
19 | count --;
20 | }
21 |
22 | if (count > mid) break;
23 | }
24 |
25 | return major;
26 | };
27 |
28 |
29 | var eq = require('assert').equal;
30 | eq(majorityElement([1, 2, 3, 4, 5, 5, 5, 5, 5]), 5);
31 | eq(majorityElement([1, 2, 5, 5, 5, 5]), 5);
32 | eq(majorityElement([5, 5, 3]), 5);
33 |
--------------------------------------------------------------------------------
/js/meetingRooms/meeting_rooms.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for an interval.
3 | * function Interval(start, end) {
4 | * this.start = start;
5 | * this.end = end;
6 | * }
7 | */
8 | /**
9 | * @param {Interval[]} intervals
10 | * @return {boolean}
11 | */
12 | var canAttendMeetings = function(intervals) {
13 | var intervals = intervals.sort(function (a, b) {
14 | return a.start - b.start;
15 | });
16 |
17 | for (var i = 0; i < intervals.length - 1; i ++) {
18 | if (intervals[i].end > intervals[i + 1].start) return false;
19 | }
20 |
21 | return true;
22 | };
23 |
--------------------------------------------------------------------------------
/js/mergeSortedArray/merge_sorted_array.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums1
3 | * @param {number} m
4 | * @param {number[]} nums2
5 | * @param {number} n
6 | * @return {void} Do not return anything, modify nums1 in-place instead.
7 | */
8 | // var merge = function(nums1, m, nums2, n) {
9 | // // only keep m items
10 | // nums1.splice(m, nums1.length - m);
11 | //
12 | // var low = 0;
13 | // var high;
14 | // var mid;
15 | // for (var i = 0; i < n; i++) {
16 | // high = m - 1;
17 | // while (low <= high) {
18 | // mid = low + ((high - low) >> 1);
19 | //
20 | // if (nums2[i] === nums1[mid]) {
21 | // low = mid;
22 | // }
23 | // if(nums2[i] < nums1[mid]) {
24 | // high = mid - 1;
25 | // } else {
26 | // low = mid + 1;
27 | // }
28 | // }
29 | //
30 | // nums1.splice(low, 0, nums2[i]);
31 | // low += 1;
32 | // m++;
33 | // }
34 | // };
35 |
36 | //a much clever solution!!!
37 | var merge = function(nums1, m, nums2, n) {
38 | var i = m - 1;
39 | var j = n - 1;
40 | var k = m + n - 1;
41 |
42 | while (i >= 0 && j >= 0) {
43 | if (nums1[i] > nums2[j]) {
44 | nums1[k--] = nums1[i--];
45 | } else {
46 | nums1[k--] = nums2[j--];
47 | }
48 | }
49 |
50 | while(j >= 0) {
51 | nums1[k--] = nums2[j--];
52 | }
53 | }
54 |
55 |
56 | var eq = require('assert').deepEqual;
57 |
58 | var num = [1,3,5];
59 | merge(num, num.length, [2,4], 2);
60 | eq(num, [1,2,3,4,5]);
61 |
62 | num = [0];
63 | merge(num, 0, [5], 1);
64 | eq(num, [5]);
65 |
66 | num = [4];
67 | merge(num, num.length, [5], 1);
68 | eq(num, [4,5]);
69 |
70 | num = [4];
71 | merge(num, num.length, [3], 1);
72 | eq(num, [3,4]);
73 |
74 | num = [4, 5];
75 | merge(num, num.length, [4, 5], 2);
76 | eq(num, [4,4, 5, 5]);
77 |
--------------------------------------------------------------------------------
/js/missingNumber/missing_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | // this solution may overflow
6 | //var missingNumber = function(nums) {
7 | // var len = nums.length;
8 | // var expect = (len * (len + 1))/2;
9 | //
10 | // var sum = 0;
11 | // for (var i = 0; i < len; i++) {
12 | // sum += nums[i];
13 | // }
14 | //
15 | // return expect - sum;
16 | //};
17 |
18 | var missingNumber = function(nums) {
19 | var sum = 0;
20 |
21 | sum = nums.reduce(function (previous, current, index) {
22 | return previous ^ current ^ index;
23 | }, sum);
24 |
25 | sum ^= nums.length;
26 |
27 | return sum;
28 | };
29 |
30 |
31 | var assert = require('assert');
32 |
33 | assert.equal(missingNumber([1,2,3]), 0);
34 | assert.equal(missingNumber([0,2,3]), 1);
35 | assert.equal(missingNumber([0,1,2,4]), 3);
36 |
--------------------------------------------------------------------------------
/js/moveZeroes/move_zeroes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {void} Do not return anything, modify nums in-place instead.
4 | */
5 | var moveZeroes = function(nums) {
6 | // 1 2 0 3 4 5 0 0 0 6 7
7 | var slow = nums.indexOf(0);
8 |
9 | if (!~slow) return;
10 |
11 | for (var i = 0; i < nums.length; i++) {
12 | if (nums[i] !== 0 && i > slow) {
13 | nums[slow ++] = nums[i];
14 | }
15 | }
16 |
17 | if (slow !== -1) {
18 | while (slow < nums.length) {
19 | nums[slow++] = 0;
20 | }
21 | }
22 | };
23 |
24 |
25 | var eq = require('assert').deepEqual;
26 |
27 | var arr = [1, 2, 3, 0, 0 , 0, 4, 1, 0];
28 | moveZeroes(arr);
29 | eq(arr, [1,2,3,4,1, 0, 0, 0, 0]);
30 |
31 | arr = [1, 2, 3];
32 | moveZeroes(arr);
33 | eq(arr, [1,2,3]);
34 |
35 | arr = [0, 1, 2, 3];
36 | moveZeroes(arr);
37 | eq(arr, [1,2,3, 0]);
38 |
39 | arr = [];
40 | moveZeroes(arr);
41 | eq(arr, []);
42 |
--------------------------------------------------------------------------------
/js/nextPermutation/README.md:
--------------------------------------------------------------------------------
1 | ## next permutation
2 | link:
3 |
--------------------------------------------------------------------------------
/js/nextPermutation/next-permutation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {void} Do not return anything, modify nums in-place instead.
4 | */
5 | var nextPermutation = function(nums) {
6 | let swapped = 0;
7 | for (let index = nums.length - 1; index > 0; index --) {
8 | if (nums[index] > nums [index - 1]) {
9 | // find the closest number and swap, then revese array
10 | const closetIndex = findClosestNumberIndex(nums, index - 1);
11 | swapIndex(nums, index - 1, closetIndex);
12 | reverseArray(nums, index)
13 | swapped = 1;
14 | break;
15 | }
16 | }
17 |
18 | if (!swapped) reverseArray(nums, 0)
19 | };
20 |
21 | // find the closest larger number index
22 | function findClosestNumberIndex(nums, index) {
23 | const value = nums[index];
24 | let swapIndex = index + 1;
25 | for (let i = nums.length - 1; i > index; i --) {
26 | if (nums[i] > value) {
27 | swapIndex = i;
28 | break;
29 | }
30 | }
31 |
32 | return swapIndex;
33 | }
34 |
35 | function swapIndex(nums, i, j) {
36 | const value = nums[i];
37 | nums[i] = nums[j];
38 | nums[j] = value;
39 | }
40 |
41 | // in-place reverse array
42 | function reverseArray(nums, index) {
43 | const len = nums.length;
44 | for (let i = index, j = len - 1; i < j; ) {
45 | swapIndex(nums, i, j);
46 | i ++;
47 | j --;
48 | }
49 | }
50 |
51 | const deepEq = require('assert').deepStrictEqual;
52 |
53 | const inputs = [
54 | [1, 4, 5, 2, 1],
55 | [1, 3, 2],
56 | [3, 2, 1],
57 | [1, 1, 5],
58 | [1]
59 | ];
60 |
61 | const expects = [
62 | [1, 5, 1, 2, 4],
63 | [2, 1, 3],
64 | [1, 2, 3],
65 | [1, 5, 1],
66 | [1]
67 | ];
68 |
69 | inputs.forEach((input, index) => {
70 | nextPermutation(input);
71 | deepEq(input, expects[index])
72 | })
73 |
--------------------------------------------------------------------------------
/js/numberComplement/README.md:
--------------------------------------------------------------------------------
1 | ## Number Complement
2 | link:
3 | Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.
4 |
5 | Note:
6 |
7 | The given integer is guaranteed to fit within the range of a 32-bit signed integer.
8 | You could assume no leading zero bit in the integer’s binary representation.
9 |
10 |
11 |
12 | Example 1:
13 |
14 | Input: 5
15 | Output: 2
16 | Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.
17 |
18 |
19 |
20 | Example 2:
21 |
22 | Input: 1
23 | Output: 0
24 | Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.
25 |
26 |
--------------------------------------------------------------------------------
/js/numberComplement/number-complement-2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {number}
4 | */
5 | var findComplement = function(num) {
6 | return Math.pow(2, num.toString(2).length) - num -1;
7 | };
8 |
9 |
10 | var eq = require('assert').equal;
11 | eq(findComplement(5), 2);
12 | eq(findComplement(1), 0);
13 |
--------------------------------------------------------------------------------
/js/numberComplement/number-complement.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {number}
4 | */
5 | var findComplement = function(num) {
6 | var binaryStr = num.toString(2);
7 |
8 | var flag = false;
9 | var newStr = '';
10 | binaryStr.split('').forEach(function (k) {
11 | var newK = k === '1' ? '0' : '1';
12 |
13 | if (newK) flag = true;
14 | if (flag) newStr += newK;
15 | });
16 |
17 | return parseInt(newStr, 2);
18 | };
19 |
20 |
21 | var eq = require('assert').equal;
22 | eq(findComplement(5), 2);
23 | eq(findComplement(1), 0);
24 |
--------------------------------------------------------------------------------
/js/numberOfDigitOne/number_of_digit_one.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number}
4 | */
5 | var countDigitOne = function(n) {
6 | };
7 |
--------------------------------------------------------------------------------
/js/paintFence/paint_fence.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @param {number} k
4 | * @return {number}
5 | */
6 | var numWays = function(n, k) {
7 |
8 | };
9 |
--------------------------------------------------------------------------------
/js/palindromePermutation/palindrome_permutation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {boolean}
4 | */
5 | var canPermutePalindrome = function(s) {
6 | var hash = {};
7 |
8 | for(var i = 0; i< s.length; i ++) {
9 | val = s.charAt(i);
10 | hash[val] = hash[val] ? (hash[val] + 1) : 1;
11 | }
12 |
13 | return Object.keys(hash).reduce(function (pre, item) {
14 | return pre + (hash[item] % 2 === 0 ? 0 : 1);
15 | }, 0) <= 1;
16 | };
17 |
18 | var eq = require('assert').equal;
19 |
20 | eq(canPermutePalindrome('bba'), true);
21 | eq(canPermutePalindrome('aa'), true);
22 | eq(canPermutePalindrome('a'), true);
23 | eq(canPermutePalindrome('ab'), false);
24 |
--------------------------------------------------------------------------------
/js/pathSum/path_sum.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val) {
4 | * this.val = val;
5 | * this.left = this.right = null;
6 | * }
7 | */
8 | /**
9 | * @param {TreeNode} root
10 | * @param {number} sum
11 | * @return {boolean}
12 | */
13 | var hasPathSum = function(root, sum) {
14 | if (!root) return false;
15 |
16 | // leaf node
17 | if (!root.left && !root.right) {
18 | if (root.val !== sum) {
19 | return false
20 | }
21 |
22 | return true;
23 | }
24 |
25 | var val = root.val;
26 | var match = false;
27 | if (root.left) {
28 | match = hasPathSum(root.left, sum - val)
29 | }
30 |
31 | if (root.right) {
32 | match = match || hasPathSum(root.right, sum - val);
33 | }
34 |
35 | return match;
36 | };
37 |
--------------------------------------------------------------------------------
/js/perfectSquares/perfect_squares.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number}
4 | */
5 | var numSquares = function(n) {
6 | };
7 |
--------------------------------------------------------------------------------
/js/permutations/permutations.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[][]}
4 | */
5 | var permute = function(nums) {
6 | var res = [];
7 |
8 | if(nums.length === 1) {
9 | return [nums];
10 | }
11 |
12 | nums.forEach(function (val, index) {
13 | var newNums = nums.slice(0);
14 | newNums.splice(index, 1);
15 |
16 | var sorts = permute(newNums).map(function (item) {
17 | return [val].concat(item);
18 | });
19 |
20 | res = res.concat(sorts);
21 | })
22 |
23 | return res;
24 | };
25 |
26 |
27 | var eq = require('assert').deepEqual;
28 |
29 | eq(permute([1]), [[1]]);
30 | eq(permute([1, 2]), [[1, 2], [2, 1]]);
31 | eq(permute([1, 2, 3]), [
32 | [1, 2, 3], [1, 3, 2],
33 | [2, 1, 3], [2, 3, 1],
34 | [3, 1, 2], [3, 2, 1]
35 | ]);
36 |
--------------------------------------------------------------------------------
/js/permutationsII/README.md:
--------------------------------------------------------------------------------
1 | # 47 Permutations II
2 | [link](https://leetcode.com/problems/permutations-ii/)
3 |
4 | Given a collection of numbers that might contain duplicates, return all possible unique permutations.
5 |
6 | For example,
7 | `[1,1,2]` have the following unique permutations:
8 |
9 | ```
10 | [
11 | [1,1,2],
12 | [1,2,1],
13 | [2,1,1]
14 | ]
15 |
16 | ```
17 |
--------------------------------------------------------------------------------
/js/permutationsII/permutations-ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[][]}
4 | */
5 | var permuteUnique = function(nums) {
6 | if (nums.length === 1) return [nums];
7 |
8 | var result = [];
9 | getPermute(nums, 0, result);
10 | return result;
11 | };
12 |
13 | // position before `start` is already done
14 | function getPermute(arr, start, result) {
15 | if (start >= arr.length - 1) {
16 | // WARN: be aware of here, use shallow copy
17 | result.push(arr.slice(0));
18 | return;
19 | };
20 |
21 | var res = [];
22 | var hash = {};
23 | for (var i = start; i < arr.length; i ++) {
24 | var val = arr[i];
25 | if (hash[val]) continue;
26 | hash[val] = 1;
27 |
28 | swap(arr, i, start);
29 | getPermute(arr, start + 1, result);
30 | swap(arr, i, start);
31 | }
32 | }
33 |
34 | function swap(arr, i, j) {
35 | var vi = arr[i];
36 |
37 | arr.splice(i, 1, arr[j]);
38 | arr.splice(j, 1, vi);
39 | }
40 |
41 | var eq = require('assert').deepEqual;
42 |
43 | eq(permuteUnique([1, 2, 1]), [
44 | [1, 2, 1],
45 | [1, 1, 2],
46 | [2, 1, 1]
47 | ]);
48 |
--------------------------------------------------------------------------------
/js/plusOne/plus_one.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} digits
3 | * @return {number[]}
4 | */
5 | var plusOne = function(digits) {
6 | var carry = 1;
7 |
8 | for (var i = digits.length - 1; i >= 0; i--) {
9 | var val = digits[i];
10 | digits[i] = (val + carry) % 10;
11 | carry = Math.floor((val + carry) / 10);
12 |
13 | if (!carry) break;
14 | }
15 |
16 | if (carry) digits.unshift(carry);
17 | return digits;
18 | };
19 |
20 |
21 | var eq = require('assert').deepEqual;
22 |
23 | eq(plusOne([0]), [1]);
24 | eq(plusOne([1, 0, 9]), [1, 1, 0]);
25 | eq(plusOne([9]), [1, 0]);
26 |
--------------------------------------------------------------------------------
/js/powerOfTwo/power_of_two.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {boolean}
4 | */
5 | // var isPowerOfTwo = function(n) {
6 | // if (n === 1) return true;
7 | // var str = n.toString(2);
8 | //
9 | // return str.charAt(0) === '1' && parseInt(str.substr(1)) === 0;
10 | // };
11 |
12 |
13 | // method 2
14 | // bit manipulation
15 | var isPowerOfTwo = function(n) {
16 | return (n > 0) && (n & (n-1)) === 0;
17 | };
18 | var eq = require('assert').equal;
19 |
20 | eq(isPowerOfTwo(2), true);
21 | eq(isPowerOfTwo(1), true);
22 | eq(isPowerOfTwo(3), false);
23 | eq(isPowerOfTwo(4), true);
24 |
--------------------------------------------------------------------------------
/js/powxN/powx_n.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} x
3 | * @param {number} n
4 | * @return {number}
5 | */
6 | var myPow = function(x, n) {
7 | if (n === 0) return 1;
8 |
9 | if (n < 0) {
10 | n = -n;
11 | x = 1/x;
12 | }
13 |
14 | var tmp = myPow(x, Math.floor(n/2));
15 | tmp = tmp * tmp;
16 |
17 | if (n % 2 === 0) {
18 | return tmp;
19 | } else {
20 | return tmp * x;
21 | }
22 | }
23 |
24 |
25 | var eq = require('assert').equal;
26 |
27 | eq(myPow(2, 3), 8);
28 | eq(myPow(2, -3), 0.125);
29 | eq(myPow(2, 0), 1);
30 |
--------------------------------------------------------------------------------
/js/productOfArrayExceptSelf/product_of_array_except_self.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[]}
4 | */
5 | var productExceptSelf = function(nums) {
6 | var out = [1];
7 |
8 | for (var i = 1; i < nums.length; i ++) {
9 | out[i] = out[i - 1] * nums[i - 1];
10 | }
11 |
12 | var right = 1;
13 | for (var k = nums.length - 1; k >= 0; k--) {
14 | out[k] *= right;
15 | right *= nums[k];
16 | }
17 |
18 | return out;
19 | };
20 |
21 | var eq = require('assert').deepEqual;
22 |
23 | eq(productExceptSelf([1, 2, 3, 4]), [24,12,8,6]);
24 | eq(productExceptSelf([0, 2, 3, 4]), [24,0,0,0]);
25 |
--------------------------------------------------------------------------------
/js/removeDuplicatesFromSortedArray/remove-duplicates-from-sorted-array.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @return {number}
4 | */
5 | var removeDuplicates = function(A) {
6 |
7 | if (A.length <= 1) return A.length;
8 |
9 | var pre;
10 | for (var i = 0; i < A.length;) {
11 | if (pre === A[i]) {
12 | A.splice(i, 1);
13 | } else {
14 | pre = A[i];
15 | i ++;
16 | }
17 | }
18 |
19 | return A.length;
20 | };
21 |
22 | var eq = require('assert').equal;
23 |
24 | var t = [1,2,3,4,4,5,5,5,6];
25 | eq(removeDuplicates(t), 6);
26 | eq(removeDuplicates([]), 0);
27 | eq(removeDuplicates([1,1,1,1]), 1);
28 |
--------------------------------------------------------------------------------
/js/removeDuplicatesFromSortedArrayIi/remove_duplicates_from_sorted_array_ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var removeDuplicates = function(nums) {
6 | var pre = '#';
7 | var count = 0;
8 | var appear = 0;
9 | for(var i = 0; i < nums.length; i++) {
10 | var val = nums[i];
11 | if (val === pre) {
12 | if (appear < 2) {
13 | count ++;
14 | appear ++;
15 | } else {
16 | nums.splice(i, 1);
17 | i--;
18 | }
19 | } else {
20 | pre = val;
21 | appear = 1;
22 | count ++;
23 | }
24 | }
25 |
26 | return count;
27 | };
28 |
29 | var eq = require('assert').equal;
30 |
31 | eq(removeDuplicates([]), 0)
32 | eq(removeDuplicates(['1', '1', '1']), 2)
33 | eq(removeDuplicates(['1', '1', '1', '2']), 3)
34 | eq(removeDuplicates([1,1,1,2,2,3]), 5)
35 |
--------------------------------------------------------------------------------
/js/removeDuplicatesFromSortedList/remove_duplicates_from_sorted_list.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @return {ListNode}
11 | */
12 | var deleteDuplicates = function(head) {
13 | var current = head;
14 | var pre = null;
15 |
16 | while (current) {
17 | var val = current.val;
18 |
19 | if (pre && pre.val === val) {
20 | pre.next = current.next;
21 | } else {
22 | pre = current;
23 | }
24 |
25 | current = current.next;
26 | }
27 |
28 | return head;
29 | };
30 |
31 | var eq = require('assert').deepEqual;
32 | var nodeList = require('leetcode').List;
33 | var l;
34 |
35 | l = nodeList.create([1, 2, 2, 3]);
36 | eq(nodeList.toArray(deleteDuplicates(l)), [1,2,3]);
37 |
38 | l = nodeList.create([1, 1, 1]);
39 | eq(nodeList.toArray(deleteDuplicates(l)), [1]);
40 | l = nodeList.create([]);
41 | eq(nodeList.toArray(deleteDuplicates(l)), []);
42 |
--------------------------------------------------------------------------------
/js/removeElement/remove_element.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @param {number} elem
4 | * @returns {number}
5 | */
6 | var removeElement = function(A, elem) {
7 | var i;
8 | for (i = 0; i < A.length; ) {
9 | if (A[i] === elem) {
10 | A.splice(i, 1);
11 | } else {
12 | i ++;
13 | }
14 | }
15 |
16 | return A.length;
17 | };
18 |
--------------------------------------------------------------------------------
/js/removeLinkedListElements/remove_linked_list_elements.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @param {number} val
11 | * @return {ListNode}
12 | */
13 | var removeElements = function(head, val) {
14 | var dummy = {};
15 | dummy.next = head;
16 | head = dummy;
17 |
18 | while(head && head.next) {
19 | if (head.next.val === val) {
20 | head.next = head.next.next;
21 | } else {
22 | head = head.next;
23 | }
24 | }
25 |
26 | return dummy.next;
27 | };
28 |
29 |
30 | var eq = require('assert').deepEqual;
31 | var nodeList = require('leetcode').List;
32 |
33 | var list = nodeList.create([1, 2, 3, 4, 4]);
34 | list = removeElements(list, 4);
35 | eq(nodeList.toArray(list), [1,2,3]);
36 |
37 | list = nodeList.create([1, 1]);
38 | list = removeElements(list, 1);
39 | eq(nodeList.toArray(list), []);
40 |
--------------------------------------------------------------------------------
/js/restoreIpAddresses/README.md:
--------------------------------------------------------------------------------
1 | ## Restore IP Addresses
2 | link:
3 | Given a string containing only digits, restore it by returning all possible valid IP address combinations.
4 |
5 | For example:
6 |
7 | > Given "25525511135",
8 |
9 |
10 | return
11 |
12 | > ["255.255.11.135", "255.255.111.35"]. (Order does not matter)
13 |
--------------------------------------------------------------------------------
/js/restoreIpAddresses/restore-ip-addresses.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {string[]}
4 | */
5 | var restoreIpAddresses = function(s) {
6 |
7 | var result = [];
8 | getSolutions([], s, result);
9 | return result;
10 | };
11 |
12 | function getSolutions(current, str, result) {
13 | if (current.length > 3) return;
14 |
15 | for (var l = 1; l <= 3 && l <= str.length; l ++) {
16 | var val = str.slice(0, l);
17 |
18 | // start with 0 but not '0'
19 | if (l > 1 && val.charAt(0) === '0') return;
20 |
21 | // not valid ip number
22 | if (parseInt(val, 10) > 255) return;
23 |
24 | var newCurrent = [].concat(current, [val]);
25 |
26 | // valid
27 | if (val === str && newCurrent.length === 4) {
28 | result.push(newCurrent.join('.'));
29 | return;
30 | }
31 |
32 | getSolutions(newCurrent, str.slice(l), result);
33 | }
34 | }
35 |
36 | var eq = require('assert').deepEqual;
37 |
38 | eq(restoreIpAddresses('25525511135'), [ '255.255.11.135', '255.255.111.35' ]);
39 |
40 | eq(restoreIpAddresses('0000'), ['0.0.0.0']);
41 | eq(restoreIpAddresses('0100'), ['0.1.0.0']);
42 |
--------------------------------------------------------------------------------
/js/reverseLinkedList/reverse_linked_list.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @return {ListNode}
11 | */
12 | var reverseList = function(head) {
13 | var current = head;
14 | var pre = null;
15 | while(current) {
16 | var tmp = current.next;
17 | current.next = pre;
18 | pre = current;
19 | current = tmp;
20 | }
21 |
22 | head = pre;
23 |
24 | return head;
25 | };
26 |
--------------------------------------------------------------------------------
/js/reverseString/reverse_string.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {string}
4 | */
5 |
6 | var reverseString = function(s) {
7 | return s.split('').reverse().join('');
8 | };
9 |
10 | var eq = require('assert').equal;
11 |
12 | eq(reverseString('hello'), 'olleh');
13 | eq(reverseString(''), '');
14 | eq(reverseString('h'), 'h');
15 |
--------------------------------------------------------------------------------
/js/reverseVowelsOfAString/reverse_vowels_of_a_string.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * @param {string} s
4 | * @return {string}
5 | * @example
6 | * Given s = "hello", return "holle".
7 | * Given s = "leetcode", return "leotcede".
8 | */
9 | var reverseVowels = function(s) {
10 | var list = s.split('');
11 | var vowels = ['a', 'e', 'i', 'o', 'u'];
12 | var isVowel = function(c) { return vowels.indexOf(c.toLowerCase()) !== -1; }
13 |
14 | var start = 0;
15 | var end = list.length - 1;
16 | var isStartValid = false;
17 | var isEndValid = false;
18 |
19 | while(start < end) {
20 | if (!isVowel(list[start])) {
21 | start ++;
22 | } else {
23 | isStartValid = true;
24 | }
25 |
26 | if (!isVowel(list[end])) {
27 | end --;
28 | } else {
29 | isEndValid = true;
30 | }
31 |
32 | // swap element and reset flags
33 | if (isStartValid && isEndValid) {
34 | var tmp = list[start];
35 | list[start] = list[end];
36 | list[end] = tmp;
37 |
38 | start ++;
39 | isStartValid = false;
40 | end --;
41 | isEndValid = false;
42 | }
43 | }
44 |
45 | return list.join('');
46 | };
47 |
48 |
49 | var eq = require('assert').equal;
50 |
51 | eq(reverseVowels('leetcode'), 'leotcede')
52 | eq(reverseVowels('lttt'), 'lttt')
53 | eq(reverseVowels('eoot'), 'ooet')
54 | eq(reverseVowels('Aot'), 'oAt')
55 |
56 |
--------------------------------------------------------------------------------
/js/reverseWordsInAString/reverse_words_in_a_string.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} str
3 | * @returns {string}
4 | */
5 | // O(n) space
6 | var reverseWords = function(str) {
7 | var words = str.trim().split(/\s+/);
8 |
9 | return words.reverse().join(' ')
10 | };
11 |
12 | var eq = require('assert').equal;
13 |
14 | eq(reverseWords(' the sky is blue'), 'blue is sky the');
15 | eq(reverseWords('the sky is blue'), 'blue is sky the');
16 | eq(reverseWords('the sky is blue!'), 'blue! is sky the');
17 | eq(reverseWords('the sky is blue !'), '! blue is sky the');
18 |
--------------------------------------------------------------------------------
/js/reverseWordsInAStringIi/reverse_words_in_a_string_ii-2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {character[]} str
3 | * @return {void} Do not return anything, modify the string in-place instead.
4 | */
5 | var reverseWords = function(words) {
6 | // here you are! ==> are! you here
7 | // ['h', 'e', 'r', 'e', ' ', 'y', 'o', 'u', ' ', 'a', 'r', 'e', '!']
8 | words.unshift(' ');
9 | var len = words.length;
10 | var current = 0;
11 | var count = 0;
12 | var word;
13 |
14 | for (var i = len - 1; i >= 0; i--) {
15 | var val = words[len - 1 - count];
16 |
17 | if (val === ' ') {
18 | if (count !== 0) {
19 | word = words.splice(-count, count);
20 | [].splice.apply(words, [current, 0].concat(word));
21 | }
22 | // current move forward
23 | current = current + count;
24 | words.splice(-1, 1);
25 | words.splice(current, 0, ' ');
26 | count = 0;
27 | current ++;
28 | } else {
29 | count ++;
30 | }
31 | }
32 |
33 | words.splice(-1, 1);
34 | };
35 |
36 | var eq = require('assert').deepEqual;
37 | var words;
38 |
39 | words = 'here you are haah'.split('');
40 | reverseWords(words);
41 | eq(words, 'haah are you here'.split(''));
42 |
43 | words = 'here you are haah!'.split('');
44 | reverseWords(words);
45 | eq(words, 'haah! are you here'.split(''));
46 |
47 | words = 'here ! %%%'.split('');
48 | reverseWords(words);
49 | eq(words, '%%% ! here'.split(''));
50 |
51 |
--------------------------------------------------------------------------------
/js/reverseWordsInAStringIi/reverse_words_in_a_string_ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {character[]} str
3 | * @return {void} Do not return anything, modify the string in-place instead.
4 | */
5 |
6 | /**
7 | * a much simple version
8 | **/
9 | var reverseWords = function(words) {
10 | words = words.reverse();
11 |
12 | var start = 0;
13 | var val;
14 | for (var i = 0; i < words.length; i ++) {
15 | val = words[i];
16 | if (val === ' ') {
17 | reverseWord(words, start, i - 1);
18 | start = i + 1;
19 | }
20 | }
21 | reverseWord(words, start, i - 1);
22 | }
23 |
24 | function reverseWord(arr, start, end) {
25 | if (start >= end || end >= arr.length) return;
26 |
27 | while (start < end) {
28 | tmp = arr[start];
29 | arr[start] = arr[end];
30 | arr[end] = tmp;
31 | start ++;
32 | end --;
33 | }
34 | }
35 |
36 | var eq = require('assert').deepEqual;
37 | var words;
38 |
39 | words = 'here you are haah'.split('');
40 | reverseWords(words);
41 | eq(words, 'haah are you here'.split(''));
42 |
43 | words = 'here you are haah!'.split('');
44 | reverseWords(words);
45 | eq(words, 'haah! are you here'.split(''));
46 |
47 | words = 'here ! %%%'.split('');
48 | reverseWords(words);
49 | eq(words, '%%% ! here'.split(''));
50 |
51 |
--------------------------------------------------------------------------------
/js/romanToInteger/roman-to-integer.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert');
2 |
3 | /**
4 | * @param {string} str
5 | * @returns {number}
6 | */
7 | var romanToInt = function(str) {
8 | var dict = {
9 | 'M': 1000
10 | , 'CM': 900
11 | , 'D': 500
12 | , 'CD': 400
13 | , 'C': 100
14 | , 'XC': 90
15 | , 'L': 50
16 | , 'XL': 40
17 | , 'X': 10
18 | , 'IX': 9
19 | , 'V': 5
20 | , 'IV': 4
21 | , 'I': 1
22 | };
23 |
24 | var sum = 0;
25 | for (var i = 0; i < str.length;) {
26 | var part = '';
27 | if ( i + 1 < str.length) {
28 | part = str.substr(i, 2);
29 | if (dict[part]) {
30 | sum += dict[part];
31 | i += 2;
32 | continue;
33 | }
34 | }
35 |
36 | sum += dict[str[i]];
37 | i++;
38 | }
39 |
40 | return sum;
41 | };
42 |
43 |
44 | assert.equal(romanToInt('MMXV'), 2015, 'pass');
45 | assert.equal(romanToInt('MLXVI'), 1066, 'pass');
46 | assert.equal(romanToInt('MCMIV'), 1904, 'pass');
47 |
--------------------------------------------------------------------------------
/js/rotateArray/rotate_array.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} k
4 | * @return {void} Do not return anything, modify nums in-place instead.
5 | */
6 | var rotate = function(nums, k) {
7 | k = k % nums.length;
8 | [].splice.apply(nums, [0, 0].concat(nums.splice(-k, k)));
9 | };
10 |
11 | var eq = require('assert').deepEqual;
12 |
13 | var num = [1,2];
14 | rotate(num, 1);
15 | eq(num, [2, 1]);
16 |
17 | num = [1,2];
18 | rotate(num, 3);
19 | eq(num, [2, 1]);
20 |
21 | num = [1,2,3,4,5,6,7];
22 | rotate(num, 3);
23 | eq(num, [5,6,7,1,2,3,4]);
24 |
--------------------------------------------------------------------------------
/js/rotateList/rotate_list.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @param {number} k
11 | * @return {ListNode}
12 | */
13 | var rotateRight = function(head, k) {
14 | if (!head) return head;
15 |
16 | var tail = head;
17 | var len = 1;
18 | while (tail.next) {
19 | len ++;
20 | tail = tail.next;
21 | }
22 |
23 | // right rotate k = left rotate len - k
24 | k = k % len;
25 | if (k === 0) return head;
26 |
27 | // circle the link list
28 | tail.next = head;
29 |
30 | for (var i = 0; i < (len - k); i++) {
31 | tail = tail.next;
32 | }
33 |
34 | head = tail.next;
35 | tail.next = null;
36 |
37 | return head;
38 | };
39 |
--------------------------------------------------------------------------------
/js/sameTree/same_tree.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val) {
4 | * this.val = val;
5 | * this.left = this.right = null;
6 | * }
7 | */
8 | /**
9 | * @param {TreeNode} p
10 | * @param {TreeNode} q
11 | * @return {boolean}
12 | */
13 | var isSameTree = function(p, q) {
14 | if (!p) {
15 | if (p ^ q) return false;
16 | return true;
17 | }
18 | if (p.val !== q.val) return false;
19 |
20 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
21 | };
22 |
23 |
24 | var tree = require('leetcode').Tree;
25 | var eq = require('assert').equal;
26 |
27 | var t1 = tree.create([1,null,2,3])
28 | var t2 = tree.create([1,null,2,3])
29 |
30 | eq(isSameTree(t1, t2), true);
31 |
32 |
--------------------------------------------------------------------------------
/js/searchInRotatedSortedArray/search_in_rotated_sorted_array.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number}
5 | */
6 | var search = function(nums, target) {
7 | var len = nums.length;
8 | var low = 0;
9 | var high = len - 1;
10 |
11 | while(low <= high) {
12 | mid = low + ((high - low) >> 1);
13 | var midVal = nums[mid];
14 |
15 | if (midVal === target) return mid;
16 |
17 | if (target < midVal) {
18 | if ((midVal >= nums[low] && target >= nums[low]) ||
19 | (target < nums[low] && midVal < nums[low])) {
20 | high = mid - 1;
21 | } else {
22 | low = mid + 1;
23 | }
24 | } else {
25 | if (midVal >= nums[low] ||
26 | (midVal < nums[high] && target <= nums[high])) {
27 | low = mid + 1;
28 | } else {
29 | high = mid - 1;
30 | }
31 | }
32 | }
33 |
34 | return -1;
35 | };
36 |
37 | // another version, logic is much simpler
38 | var search = function(nums, target) {
39 | var len = nums.length;
40 | var low = 0;
41 | var high = len - 1;
42 |
43 | while(low <= high) {
44 | mid = low + ((high - low) >> 1);
45 | var midVal = nums[mid];
46 |
47 | if (midVal === target) return mid;
48 |
49 | if (nums[low] <= midVal) {
50 | if (target >= nums[low] && target < midVal) {
51 | high = mid - 1;
52 | } else {
53 | low = mid + 1;
54 | }
55 | } else {
56 | if (target <= nums[high] && target > midVal) {
57 | low = mid + 1;
58 | } else {
59 | high = mid - 1;
60 | }
61 | }
62 | }
63 |
64 | return -1;
65 | };
66 | var eq = require('assert').equal;
67 |
68 | eq(search([4, 5, 6, 7, 0, 1, 2], 6), 2);
69 | eq(search([4, 5, 6, 7, 0, 1, 2], 1), 5);
70 | eq(search([4,5,6,7,8,1,2,3], 8), 4);
71 | eq(search([4], 6), -1);
72 | eq(search([4, 5], 5), 1);
73 | eq(search([5, 1, 3], 5), 0);
74 | eq(search([1, 3, 5], 1), 0);
75 | eq(search([5, 1, 2, 3, 4], 1), 1);
76 |
--------------------------------------------------------------------------------
/js/searchInsertPosition/search_insert_position.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number}
5 | */
6 | var searchInsert = function(nums, target) {
7 | // 1 3 5 6 5, 2
8 | // 1 3 5 6 2, 1
9 | // 4 2, 0
10 | var len = nums.length;
11 | var l = 0;
12 | var r = nums.length - 1;
13 |
14 | if (len === 0) return 0;
15 |
16 | var mid;
17 | while (l <= r) {
18 | mid = l + ((r - l) >> 1);
19 |
20 | // when equal, insert before the index, means use current index
21 | if (target === nums[mid]) return mid;
22 |
23 | if (target < nums[mid]) {
24 | r = mid - 1;
25 | } else {
26 | l = l + 1;
27 | }
28 | }
29 |
30 | return l;
31 | };
32 |
33 |
34 | var eq = require('assert').equal;
35 |
36 | eq(searchInsert([1, 2, 4, 5, 6], 3), 2);
37 | eq(searchInsert([1, 2, 4, 5, 6], 4), 2);
38 | eq(searchInsert([1, 2, 5, 6], 7), 4);
39 | eq(searchInsert([1], 3), 1);
40 | eq(searchInsert([4], 3), 0);
41 |
--------------------------------------------------------------------------------
/js/shortestWordDistance/shortest_word_distance.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string[]} words
3 | * @param {string} word1
4 | * @param {string} word2
5 | * @return {number}
6 | */
7 | var shortestDistance = function(words, a, b) {
8 | var idxA = -1;
9 | var idxB = -1;
10 | var min = Infinity;
11 |
12 | words.forEach(function (val, i) {
13 | if (val === a) {
14 | idxA = i;
15 | }
16 |
17 | if (val === b) {
18 | idxB = i;
19 | }
20 |
21 | if (~idxA && ~idxB) {
22 | min = Math.min(min, Math.abs(idxA - idxB));
23 | }
24 | });
25 |
26 | return min;
27 | };
28 |
29 | var eq = require('assert').equal;
30 |
31 | eq(shortestDistance(['a', 'b'], 'a', 'b'), 1)
32 | eq(shortestDistance(["a","c","b","a"], 'a', 'b'), 1)
33 |
--------------------------------------------------------------------------------
/js/singleNumber/single_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var singleNumber = function(nums) {
6 | return nums.reduce(function (pre, curr) {
7 | return pre ^ curr;
8 | }, 0)
9 | };
10 |
11 |
12 | var eq = require('assert').equal;
13 | eq(singleNumber([1,1,2]), 2);
14 | eq(singleNumber([1,1,2, 2, 4, 4, 5]), 5);
15 |
--------------------------------------------------------------------------------
/js/sortColors/sort_colors.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {void} Do not return anything, modify nums in-place instead.
4 | */
5 | var sortColors = function(nums) {
6 | var len = nums.length;
7 | var idx2 = len - 1;
8 | var idx0 = 0;
9 | for (var i = 0; i < len; i++) {
10 | while (nums[i] === 2 && i < idx2) {
11 | swap(nums, i, idx2 --);
12 | }
13 | while (nums[i] === 0 && i > idx0) {
14 | swap(nums, i, idx0 ++)
15 | }
16 | }
17 | };
18 |
19 | function swap(arr, i, j) {
20 | var tmp = arr[i];
21 | arr[i] = arr[j];
22 | arr[j] = tmp;
23 | }
24 |
25 | var eq = require('assert').deepEqual;
26 |
27 | var num = [0,1,0,1,2];
28 | sortColors(num);
29 | eq(num, [0,0,1,1,2]);
30 |
--------------------------------------------------------------------------------
/js/sqrtx/sqrtx.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} x
3 | * @return {number}
4 | */
5 | var mySqrt = function(x) {
6 | var low = 0;
7 | var high = x;
8 | var pre;
9 | if (x === 0) return 0;
10 |
11 | while (low <= high) {
12 | var mid = low + ((high - low) >> 1);
13 |
14 | // in case of overflow, use below instead of mid * mid
15 | if (mid === x / mid) return mid;
16 |
17 | if (mid > x / mid) {
18 | high = mid - 1;
19 | } else {
20 | pre = mid;
21 | low = mid + 1;
22 | }
23 | }
24 |
25 | return pre;
26 | };
27 |
28 |
29 | var eq = require('assert').equal;
30 | eq(mySqrt(1), 1);
31 | eq(mySqrt(5), 2);
32 | eq(mySqrt(4), 2);
33 | eq(mySqrt(11), 3);
34 |
--------------------------------------------------------------------------------
/js/strobogrammaticNumber/strobogrammatic_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} num
3 | * @return {boolean}
4 | */
5 | var isStrobogrammatic = function(num) {
6 | var ns = ('' + num).split('');
7 | var len = ns.length;
8 | var specials = [1, 8, 0];
9 | var mid;
10 |
11 | if (len % 2) {
12 | mid = parseInt(ns[len >> 1]);
13 | if (!~specials.indexOf(mid)) return false;
14 | }
15 |
16 | var l = 0;
17 | var r = len - 1;
18 | while (l < r) {
19 | var vl = parseInt(ns[l]);
20 | var vr = parseInt(ns[r]);
21 | if ((vl === vr && ~specials.indexOf(vl)) || (vl === 6 && vr === 9) || (vl === 9 && vr === 6)) {
22 | l ++;
23 | r --;
24 | } else {
25 | return false;
26 | }
27 | }
28 |
29 | return true;
30 | };
31 |
32 | var eq = require('assert').equal;
33 |
34 | eq(isStrobogrammatic(818), true);
35 | eq(isStrobogrammatic(22), false);
36 | eq(isStrobogrammatic(111), true);
37 | eq(isStrobogrammatic(101), true);
38 | eq(isStrobogrammatic(69269), false);
39 | eq(isStrobogrammatic(69169), true);
40 |
--------------------------------------------------------------------------------
/js/strobogrammaticNumberIi/strobogrammatic_number_ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {string[]}
4 | */
5 | var findStrobogrammatic = function(n) {
6 | return sub(n, n);
7 | };
8 |
9 | function sub(n, m) {
10 | if (n === 0) return [''];
11 | if (n === 1) return ['0', '1', '8'];
12 |
13 | var tmp = sub(n - 2, m);
14 | var res = [];
15 |
16 | tmp.forEach(function (item) {
17 | if (n !== m) {
18 | res.push('0' + item + '0');
19 | }
20 |
21 | res.push('1' + item + '1');
22 | res.push('6' + item + '9');
23 | res.push('8' + item + '8');
24 | res.push('9' + item + '6');
25 |
26 | });
27 |
28 | return res;
29 |
30 | }
31 |
32 |
33 | var eq = require('assert').deepEqual;
34 |
35 | eq(findStrobogrammatic(2), ["11","69","88","96"]);
36 | eq(findStrobogrammatic(3),
37 | [
38 | '101',
39 | '609',
40 | '808',
41 | '906',
42 | '111',
43 | '619',
44 | '818',
45 | '916',
46 | '181',
47 | '689',
48 | '888',
49 | '986'
50 | ]
51 | );
52 |
--------------------------------------------------------------------------------
/js/subsets/README.md:
--------------------------------------------------------------------------------
1 | ## Subsets
2 | link:
3 |
4 | Given a set of distinct integers, nums, return all possible subsets.
5 |
6 | Note: The solution set must not contain duplicate subsets.
7 |
8 |
9 | For example,
10 | If nums = [1,2,3], a solution is:
11 |
12 |
13 |
14 | [
15 | [3],
16 | [1],
17 | [2],
18 | [1,2,3],
19 | [1,3],
20 | [2,3],
21 | [1,2],
22 | []
23 | ]
24 |
--------------------------------------------------------------------------------
/js/subsets/subsets-v1.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[][]}
4 | */
5 | var subsets = function(nums) {
6 | return getSolutions(nums);
7 | };
8 |
9 | function getSolutions(nums) {
10 | if (nums.length === 0) {
11 | return [[]];
12 | }
13 |
14 | var resNext = getSolutions(nums.slice(1));
15 | var current = nums[0];
16 |
17 | // n and n - 1
18 | var res = [].concat(resNext);
19 | for (var i = 0; i < resNext.length; i++) {
20 | var val = resNext[i];
21 | res.push([].concat(current, val));
22 | }
23 |
24 | return res;
25 | }
26 |
--------------------------------------------------------------------------------
/js/subsets/subsets.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[][]}
4 | */
5 | var subsets = function(nums) {
6 |
7 | var mem = [];
8 | var len = nums.length;
9 |
10 | for (var i = 0; i < len; i++) {
11 | var min = nums[i];
12 | var idx = i;
13 | for (var k = i + 1; k < len; k++) {
14 | if (nums[k] < min) {
15 | min = nums[k];
16 | idx = k;
17 | }
18 | }
19 |
20 | var tmp = [];
21 | mem.forEach(function (item) {
22 | // use concat instead of push, to clone item, instead of changing
23 | var val = [].concat(item, min);
24 | tmp.push(val);
25 | });
26 |
27 | // make i the latest smallest one
28 | swap(nums, i, idx);
29 | mem = mem.concat(tmp);
30 | mem.push([min]);
31 | }
32 |
33 | mem.push([]);
34 | return mem;
35 | };
36 |
37 | function swap(arr, i, j) {
38 | var tmp = arr[i];
39 | arr[i] = arr[j];
40 | arr[j] = tmp;
41 | }
42 |
43 |
44 | var eq = require('assert').equal;
45 |
46 | eq(subsets([4, 2, 3]).length, 8)
47 |
--------------------------------------------------------------------------------
/js/sumOfTwoIntegers/sum-of-two-integers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} a
3 | * @param {number} b
4 | * @return {number}
5 | */
6 | var getSum = function(a, b) {
7 |
8 | var sum = a;
9 |
10 | // @see https://en.wikipedia.org/wiki/Adder_%28electronics%29#Half_adder
11 | while (b !== 0) {
12 | // calculate sum without the carry
13 | sum = a ^ b;
14 | // calculate carry
15 | b = (a & b) << 1;
16 |
17 | a = sum;
18 | }
19 |
20 | return sum;
21 | };
22 |
23 |
24 | var eq = require('assert').equal;
25 |
26 | eq(getSum(0, 1) , 1);
27 | eq(getSum(1, 0) , 1);
28 | eq(getSum(11, 3) , 14);
29 |
--------------------------------------------------------------------------------
/js/sumRootToLeafNumbers/sum_root_to_leaf_numbers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {TreeNode} root
3 | * @return {number}
4 | **/
5 | var sumNumbers = function(root) {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/js/swapNodesInPairs/swap-nodes-in-pairs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 |
9 | function ListNode(val) {
10 | this.val = val;
11 | this.next = null;
12 | }
13 |
14 | /**
15 | * @param {ListNode} head
16 | * @returns {ListNode}
17 | */
18 | var swapPairs = function(head) {
19 |
20 | if (!(head && head.next)) return head;
21 | var sentinel = new ListNode();
22 | sentinel.next = head;
23 |
24 | var cursor = sentinel;
25 | while(cursor.next && cursor.next.next) {
26 | var n = cursor.next;
27 | var nn = n.next;
28 |
29 | // swap
30 | n.next = nn.next;
31 | nn.next = n;
32 | cursor.next = nn;
33 |
34 | cursor = n;
35 | }
36 |
37 | return sentinel.next;
38 | };
39 |
40 | function a2l(arr) {
41 | var guard = new ListNode()
42 | , curr = guard;
43 | for (var i =0; i < arr.length; i++) {
44 | curr.next = new ListNode(arr[i]);
45 | curr = curr.next;
46 | }
47 |
48 | return guard.next;
49 | }
50 |
51 | function pl(head) {
52 | while (head) {
53 | head = head.next;
54 | }
55 | }
56 |
57 |
58 | pl(swapPairs(a2l(['1', '2', '3'])))
59 | pl(swapPairs(a2l(['1', '2', '3', '4'])))
60 |
61 |
--------------------------------------------------------------------------------
/js/twoSum/two_sum.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number[]}
5 | */
6 | var twoSum = function(nums, target) {
7 | var hash = {};
8 |
9 | var val;
10 | for (var i = 0; i < nums.length; i ++) {
11 | val = nums[i];
12 | if (hash[target - val]) {
13 | return [hash[target - val], i + 1];
14 | }
15 |
16 | hash[val] = i + 1;
17 | }
18 | };
19 |
20 |
21 | var eq = require('assert').deepEqual;
22 |
23 | eq(twoSum([2, 7, 11, 15], 9), [1, 2])
24 | eq(twoSum([2, 11, 13, 15], 17), [1, 4])
25 |
--------------------------------------------------------------------------------
/js/twoSumIiInputArrayIsSorted/two_sum_ii_input_array_is_sorted.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} numbers
3 | * @param {number} target
4 | * @return {number[]}
5 | */
6 | // // binary search solution O(n*n)
7 | // var twoSum = function(numbers, target) {
8 | // var low;
9 | // var high;
10 | // var mid;
11 | //
12 | // for (var i = 0; i < numbers.length; i ++) {
13 | // low = i + 1;
14 | // high = numbers.length - 1;
15 | //
16 | // while(low <= high) {
17 | // mid = low + ((high - low) >> 1);
18 | // var val = numbers[i] + numbers[mid];
19 | //
20 | // if (val === target) return [i + 1, mid + 1];
21 | //
22 | // if (val > target) {
23 | // high = mid - 1;
24 | // } else {
25 | // low = low + 1;
26 | // }
27 | // }
28 | // }
29 | // };
30 |
31 | // two-pointer O(n) time , O(1) space
32 | // var twoSum = function(numbers, target) {
33 | // var len = numbers.length;
34 | // var low = 0;
35 | // var high = len - 1;
36 | // var val;
37 | // while (low < high) {
38 | // val = numbers[low] + numbers[high];
39 | // if (val === target) {
40 | // break;
41 | // }
42 | //
43 | // if(val > target) {
44 | // high = high - 1;
45 | // } else {
46 | // low = low + 1;
47 | // }
48 | //
49 | // }
50 | //
51 | // return [low+ 1, high + 1]
52 | // }
53 |
54 | // use hash, O(n)
55 | var twoSum = function(numbers, target) {
56 | var dict = {};
57 |
58 | var num;
59 | for (var i = 0; i < numbers.length; i++) {
60 | num = numbers[i];
61 | if (dict[target - num] !== undefined) {
62 | return [dict[target - num] + 1, i + 1]
63 | }
64 |
65 | dict[num] = i;
66 | }
67 | }
68 |
69 | var eq = require('assert').deepEqual;
70 |
71 | eq(twoSum([2, 7], 9), [1, 2])
72 | eq(twoSum([2, 7, 11, 15], 17), [1, 4])
73 | eq(twoSum([2, 7, 11, 15], 9), [1, 2])
74 |
--------------------------------------------------------------------------------
/js/twoSumIiiDataStructureDesign/two_sum_iii_data_structure_design.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @constructor
3 | */
4 | var TwoSum = function() {
5 | this.dict = {};
6 | };
7 |
8 | /**
9 | * @param {number} input
10 | * @returns {void}
11 | */
12 | TwoSum.prototype.add = function(input) {
13 | // no need to bigger that 2
14 | this.dict[input] = this.dict[input] ? 2 : 1;
15 | };
16 |
17 | /**
18 | * @param {number} val
19 | * @returns {boolean}
20 | */
21 | TwoSum.prototype.find = function(val) {
22 | var dict = this.dict;
23 | var keys = Object.keys(dict);
24 |
25 | for (var i = 0; i < keys.length; i++) {
26 | var key = parseInt(keys[i]);
27 | var target = val - key;
28 |
29 | if (!dict[target]) continue;
30 |
31 | if ((target === key && dict[target] === 2) ||
32 | target !== key) {
33 | return true;
34 | }
35 | }
36 |
37 | return false;
38 | };
39 |
40 | var eq = require('assert').equal;
41 | var ts = new TwoSum();
42 |
43 | ts.add(0);
44 | ts.find(0)
45 | eq(ts.find(0), false);
46 |
47 | ts = new TwoSum();
48 | ts.add(0);
49 | ts.add(0);
50 | ts.find(0)
51 | eq(ts.find(0), true);
52 |
53 | ts = new TwoSum();
54 | ts.add(1);
55 | ts.add(3);
56 | ts.add(5);
57 | eq(ts.find(1), false);
58 | eq(ts.find(4), true);
59 | eq(ts.find(7), false);
60 |
--------------------------------------------------------------------------------
/js/uglyNumber/ugly_number.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {boolean}
4 | */
5 | var isUgly = function(n) {
6 | if (n <= 0) return false;
7 | if (n === 1) return true;
8 |
9 | while (n > 5) {
10 | if (n % 5 === 0) {
11 | n /= 5;
12 | } else if (n % 3 === 0) {
13 | n /= 3;
14 | } else if (n % 2 === 0) {
15 | n /= 2;
16 | } else {
17 | return false;
18 | }
19 | }
20 |
21 | return true;
22 | };
23 |
24 |
25 | var eq = require('assert').equal;
26 |
27 | eq(isUgly(1), true)
28 | eq(isUgly(2), true)
29 | eq(isUgly(6), true)
30 | eq(isUgly(7), false)
31 | eq(isUgly(14), false)
32 |
33 |
--------------------------------------------------------------------------------
/js/uglyNumberIi/ugly_number_ii.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number}
4 | */
5 | var nthUglyNumber = function(n) {
6 | var idx2 = 0,
7 | idx3 = 0,
8 | idx5 = 0;
9 |
10 | var factor2 = 2,
11 | factor3 = 3,
12 | factor5 =5;
13 |
14 | var ugly = [1];
15 |
16 | for (var i = 1; i < n; i++) {
17 | var min = Math.min.call(null, factor2, factor3, factor5);
18 | ugly.push(min);
19 |
20 | if (factor2 === min) {
21 | factor2 = 2 * ugly[++idx2];
22 | }
23 |
24 | if (factor3 === min) {
25 | factor3 = 3 * ugly[++idx3];
26 | }
27 |
28 | if (factor5 === min) {
29 | factor5 = 5 * ugly[++idx5];
30 | }
31 | }
32 |
33 | return ugly[n-1];
34 | };
35 |
36 |
37 | var eq = require('assert').equal;
38 |
39 | eq(nthUglyNumber(3), 3);
40 | eq(nthUglyNumber(10), 12);
41 |
42 |
--------------------------------------------------------------------------------
/js/uniqueWordAbbreviation/unique_word_abbreviation.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @constructor
3 | * @param {string[]} dictionary
4 | */
5 | var ValidWordAbbr = function(dictionary) {
6 | this.dict = dictionary;
7 | var hash = {};
8 |
9 | dictionary.forEach(function (d) {
10 | var len = d.length;
11 | var abbr = d;
12 |
13 | if (len > 2) {
14 | abbr = d.charAt(0) + (len - 2) + d.charAt(len - 1);
15 | }
16 |
17 | if (hash[abbr]) {
18 | if (!~hash[abbr].indexOf(d)) {
19 | hash[abbr].push(d);
20 | }
21 | } else {
22 | hash[abbr] = [d];
23 | }
24 | });
25 |
26 | this.hash = hash;
27 | };
28 |
29 | /**
30 | * @param {string} word
31 | * @return {bool}
32 | */
33 | ValidWordAbbr.prototype.isUnique = function(word) {
34 | var abbr = word;
35 | var len = word.length;
36 | if (len > 2) {
37 | abbr = word.charAt(0) + (len - 2) + word.charAt(len - 1);
38 | }
39 | var abbrs = this.hash[abbr];
40 |
41 | return !abbrs || (abbrs.length === 1 && abbrs[0] === word);
42 | };
43 |
44 |
45 | /**
46 | * Your ValidWordAbbr object will be instantiated and called as such:
47 | * var vwa = new ValidWordAbbr(dictionary);
48 | * vwa.isUnique("word");
49 | * vwa.isUnique("anotherWord");
50 | */
51 |
52 | var eq = require('assert').equal;
53 |
54 | var v = new ValidWordAbbr([ "deer", "door", "cake", "card" ]);
55 | eq(v.isUnique('dear'), false);
56 | eq(v.isUnique('cart'), true);
57 | eq(v.isUnique('cake'), true);
58 | v = new ValidWordAbbr(['a', 'a']);
59 | eq(v.isUnique('a'), true);
60 |
--------------------------------------------------------------------------------
/js/validAnagram/valid_anagram.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @param {string} t
4 | * @return {boolean}
5 | */
6 | var isAnagram = function(s, t) {
7 | if (s.length !== t.length) return false;
8 |
9 | var hashA = hashrify(s);
10 | var hashB = hashrify(t);
11 |
12 | if (Object.keys(hashA).length !== Object.keys(hashB).length) return false;
13 |
14 | return !Object.keys(hashA).some(function (key) {
15 | return hashA[key] !== hashB[key];
16 | })
17 |
18 | };
19 |
20 | function hashrify(s) {
21 | var hash = {};
22 | var i;
23 | for (i = 0; i< s.length; i++) {
24 | var val = s.charAt(i);
25 |
26 | if (hash[val]) {
27 | hash[val] ++;
28 | } else {
29 | hash[val] = 1;
30 | }
31 | }
32 |
33 | return hash;
34 | }
35 |
36 | var assertEq = require('assert').equal;
37 |
38 | assertEq(isAnagram('a', 'b'), false)
39 | assertEq(isAnagram('abbba', 'bbbab'), false)
40 | assertEq(isAnagram('aaaa', 'aaaa'), true)
41 |
42 |
--------------------------------------------------------------------------------
/js/validPalindrome/valid_palindrome.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {boolean}
4 | */
5 | var isPalindrome = function(s) {
6 | s = s.replace(/[\W]*/g, '').toLowerCase();
7 | if (s === s.split('').reverse().join('')) return true;
8 |
9 | return false;
10 | };
11 |
12 | var eq = require('assert').equal;
13 |
14 | eq(isPalindrome('A man, a plan, a canal: Panama'), true);
15 | eq(isPalindrome('race a car'), false);
16 | eq(isPalindrome(''), true);
17 |
--------------------------------------------------------------------------------
/js/validSudoku/README.md:
--------------------------------------------------------------------------------
1 | ## valid sudoku
2 | link:
3 |
--------------------------------------------------------------------------------
/js/validSudoku/valid-sudoku.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {character[][]} board
3 | * @return {boolean}
4 | */
5 | var isValidSudoku = function(board) {
6 |
7 | // check all rows and columns along diagonal line, board[0][0], board[1][1], .., board[8][8]
8 | for (let i = 0; i < 9; i ++) {
9 | const isRowValid = isRowOrColumnValid(board, i);
10 | if (!isRowValid) return false;
11 | const isColumnValid = isRowOrColumnValid(board, i, true);
12 | if (!isColumnValid) return false;
13 | }
14 |
15 | // check boxes
16 | for (let i = 0; i < 3; i ++) {
17 | const rowStart = i * 3;
18 | for (let j = 0; j < 3; j ++) {
19 | const columnStart = j * 3;
20 | const isValid = isBoxValid(board, rowStart, columnStart)
21 | if (!isValid) return false;
22 | }
23 | }
24 |
25 | return true;
26 | };
27 |
28 | function isRowOrColumnValid(board, index, isColumn) {
29 | const valueSet = new Set();
30 | for (let i = 0; i < board.length; i ++) {
31 | let value = isColumn ? board[i][index] : board[index][i];
32 | if (valueSet.has(value)) return false;
33 | if (value !== '.') {
34 | valueSet.add(value);
35 | }
36 | }
37 |
38 | return true;
39 | }
40 |
41 | function isBoxValid(board, rowStart, columnStart) {
42 | const valueSet = new Set();
43 | for (let i = rowStart; i < rowStart + 3; i ++) {
44 | for (let j = columnStart; j < columnStart + 3; j ++) {
45 | const value = board[i][j];
46 | if (valueSet.has(value)) return false;
47 | if (value !== '.') {
48 | valueSet.add(value);
49 | }
50 | }
51 | }
52 | return true;
53 | }
54 |
55 | const eq = require('assert').strictEqual;
56 | eq(isValidSudoku(
57 | [["5","3",".",".","7",".",".",".","."]
58 | ,["6",".",".","1","9","5",".",".","."]
59 | ,[".","9","8",".",".",".",".","6","."]
60 | ,["8",".",".",".","6",".",".",".","3"]
61 | ,["4",".",".","8",".","3",".",".","1"]
62 | ,["7",".",".",".","2",".",".",".","6"]
63 | ,[".","6",".",".",".",".","2","8","."]
64 | ,[".",".",".","4","1","9",".",".","5"]
65 | ,[".",".",".",".","8",".",".","7","9"]
66 | ]), true);
67 |
68 | eq(isValidSudoku(
69 | [["8","3",".",".","7",".",".",".","."]
70 | ,["6",".",".","1","9","5",".",".","."]
71 | ,[".","9","8",".",".",".",".","6","."]
72 | ,["8",".",".",".","6",".",".",".","3"]
73 | ,["4",".",".","8",".","3",".",".","1"]
74 | ,["7",".",".",".","2",".",".",".","6"]
75 | ,[".","6",".",".",".",".","2","8","."]
76 | ,[".",".",".","4","1","9",".",".","5"]
77 | ,[".",".",".",".","8",".",".","7","9"]
78 | ]), false);
79 |
80 | eq(isValidSudoku(
81 | [[".",".","4",".",".",".","6","3","."]
82 | ,[".",".",".",".",".",".",".",".","."]
83 | ,["5",".",".",".",".",".",".","9","."]
84 | ,[".",".",".","5","6",".",".",".","."]
85 | ,["4",".","3",".",".",".",".",".","1"]
86 | ,[".",".",".","7",".",".",".",".","."]
87 | ,[".",".",".","5",".",".",".",".","."]
88 | ,[".",".",".",".",".",".",".",".","."]
89 | ,[".",".",".",".",".",".",".",".","."]]
90 | ), false);
91 |
92 | eq(isValidSudoku(
93 | [[".",".",".",".","5",".",".","1","."]
94 | ,[".","4",".","3",".",".",".",".","."]
95 | ,[".",".",".",".",".","3",".",".","1"]
96 | ,["8",".",".",".",".",".",".","2","."]
97 | ,[".",".","2",".","7",".",".",".","."]
98 | ,[".","1","5",".",".",".",".",".","."]
99 | ,[".",".",".",".",".","2",".",".","."]
100 | ,[".","2",".","9",".",".",".",".","."]
101 | ,[".",".","4",".",".",".",".",".","."]]
102 | ), false)
103 |
--------------------------------------------------------------------------------
/js/wordBreak/word_break.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @param {set} wordDict
4 | * @return {boolean}
5 | */
6 | var wordBreak = function(s, wordDict) {
7 | s = '#' + s;
8 | var dp = [true];
9 |
10 | for (var i = 1; i < s.length; i ++) {
11 | for (var k = 0; k < i; k ++) {
12 | if (dp[k] && wordDict.has(s.substr(k + 1, i-k))) {
13 | dp[i] = true;
14 | break;
15 | }
16 | }
17 | }
18 |
19 | return !!dp[s.length - 1]
20 | };
21 |
22 |
23 |
24 | var eq = require('assert').equal;
25 | eq(wordBreak('leetcode', new Set(['leet', 'code'])), true);
26 | eq(wordBreak('leettcode', new Set(['leet', 'code'])), false);
27 | eq(wordBreak('leet', new Set(['leet'])), true);
28 | eq(wordBreak('a', new Set(['a'])), true);
29 | eq(wordBreak('a', new Set([])), false);
30 |
--------------------------------------------------------------------------------
/js/wordPattern/word_pattern.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} pattern
3 | * @param {string} str
4 | * @return {boolean}
5 | */
6 | var wordPattern = function(pattern, str) {
7 | var ph = pattern.split('');
8 | var sh = str.split(' ');
9 | var hash = {};
10 |
11 | if (ph.length !== sh.length) return false;
12 | if (new Set(ph).size !== new Set(sh).size) return false;
13 |
14 | var zip = new Set();
15 |
16 | ph.forEach(function (item, i) {
17 | zip.add(ph[i] + ' ' + sh[i]);
18 | });
19 |
20 | return zip.size === new Set(ph).size;
21 | };
22 |
23 |
24 | var eq = require('assert').equal;
25 |
26 | eq(wordPattern('abba', 'a b b a'), true);
27 | eq(wordPattern('abba', 'a b b b'), false);
28 | eq(wordPattern('abba', 'b b b b'), false);
29 |
--------------------------------------------------------------------------------
/js/wordSearch/word_search.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * @param {character[][]} board
4 | * @param {string} word
5 | * @return {boolean}
6 | */
7 | var exist = function(board, word) {
8 |
9 | board = board.map(function (item) {
10 | return item[0].split('');
11 | });
12 |
13 | for (var i = 0; i < board.length; i++) {
14 | for (var j = 0; j < board[0].length; j++) {
15 | if (isMatch(board, j, i, word, 0)) return true;
16 | }
17 | }
18 |
19 | return false;
20 | };
21 |
22 | function isMatch(b, i, j, word, idx) {
23 | var mX = b[0].length;
24 | var mY = b.length;
25 | if (idx === word.length) return true;
26 |
27 | if (i < 0 || i >= mX || j < 0 || j >= mY || b[j][i] !== word.charAt(idx)) return false;
28 |
29 | b[j][i] = '&';
30 |
31 | if (isMatch(b, i + 1, j, word, idx + 1) ||
32 | isMatch(b, i - 1, j, word, idx + 1) ||
33 | isMatch(b, i, j + 1, word, idx + 1) ||
34 | isMatch(b, i, j - 1, word, idx + 1)) {
35 | return true;
36 | }
37 |
38 | b[j][i] = word.charAt(idx);
39 | return false;
40 | }
41 |
42 |
43 | var eq = require('assert').equal;
44 |
45 | var b = [
46 | ["ABCE"],
47 | ["SFCS"],
48 | ["ADEE"]
49 | ];
50 |
51 | eq(exist(b, 'ABCCED'), true);
52 | eq(exist(b, 'SEE'), true);
53 | eq(exist(b, 'SEEA'), false);
54 |
55 | b = [ ['aa'] ];
56 | eq(exist(b, 'aa'), true);
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "leetcode": "^1.2.0"
4 | },
5 | "scripts": {
6 | "test": "make test",
7 | "load": "./bin/load bin/loadProblem.js"
8 | },
9 | "devDependencies": {
10 | "camelcase": "^6.2.0",
11 | "chalk": "^1.1.3",
12 | "cheerio": "^0.20.0",
13 | "mkdirp": "^0.5.1",
14 | "request": "^2.73.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/python/3sum.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a list of lists of length 3, [[val1,val2,val3]]
3 | def threeSum(self, num):
4 | num.sort();
5 | l = len(num)
6 | if l < 3:
7 | return []
8 |
9 | res = []
10 | for i in range(l-2):
11 | # avoid duplicate
12 | if (i != 0 and num[i] == num[i - 1]):
13 | continue
14 |
15 | left = i + 1
16 | right = l - 1
17 | target = -num[i]
18 |
19 | while left < right:
20 | s = num[left] + num[right]
21 | if target == s:
22 | res.append([-target, num[left], num[right]])
23 |
24 | # avoid duplicate
25 | while left < right:
26 | left += 1
27 | if num[left] > num[left - 1]: break
28 |
29 | # avoid duplicate
30 | while left < right:
31 | right -= 1
32 | if num[right] < num[right + 1]: break
33 |
34 | elif s < target:
35 | # avoid duplicate
36 | while left < right:
37 | left += 1
38 | if num[left] > num[left - 1]: break
39 | else:
40 | # avoid duplicate
41 | while left < right:
42 | right -= 1
43 | if num[right] < num[right + 1]: break
44 |
45 | return res
46 |
47 |
48 | s = Solution()
49 | assert s.threeSum([-1, 0, 1, 2, -1, -4]) == [[-1, -1, 2], [-1, 0, 1]]
50 | assert s.threeSum([-1, 0, 0, 0, 1, 2]) == [[-1, 0, 1], [0, 0 ,0]]
51 |
--------------------------------------------------------------------------------
/python/_util.py:
--------------------------------------------------------------------------------
1 |
2 | # test code
3 | class ListNode:
4 | def __init__(self, x):
5 | self.val = x
6 | self.next = None
7 |
8 | def a2ll(l):
9 | ll = ListNode(l[0])
10 |
11 | cursor = ll
12 | for i in range(1, len(l)):
13 | cursor.next = ListNode(l[i])
14 | cursor = cursor.next
15 |
16 | return ll
17 | def pl(ll):
18 | while ll:
19 | print ll.val,
20 | ll = ll.next
21 | print
22 |
--------------------------------------------------------------------------------
/python/add_two_numbers.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | # class ListNode:
3 | # def __init__(self, x):
4 | # self.val = x
5 | # self.next = None
6 |
7 | class Solution:
8 | # @return a ListNode
9 | def addTwoNumbers(self, l1, l2):
10 |
11 | sum0 = (l1.val + l2.val) % 10
12 | carry = (l1.val + l2.val) / 10
13 |
14 | # root
15 | root = ListNode(sum0)
16 | l1 = l1.next
17 | l2 = l2.next
18 | cursor = root
19 | while l1 and l2:
20 | v1 = l1.val
21 | v2 = l2.val
22 |
23 | s = (v1 + v2 + carry)
24 | val = s % 10
25 | carry = s / 10
26 |
27 | cursor.next = ListNode(val)
28 | cursor = cursor.next
29 | l1 = l1.next
30 | l2 = l2.next
31 |
32 | l2 = l2 if l2 else l1
33 | while l2:
34 | s = l2.val + carry
35 | val = s % 10
36 | carry = s / 10
37 |
38 | cursor.next = ListNode(val)
39 | cursor = cursor.next
40 |
41 | l2 = l2.next
42 | if carry != 0:
43 | cursor.next = ListNode(carry)
44 |
45 | return root
46 |
47 |
48 | ## test code
49 | # class ListNode:
50 | # def __init__(self, x):
51 | # self.val = x
52 | # self.next = None
53 | #
54 | # def a2ll(l):
55 | # ll = ListNode(l[0])
56 | #
57 | # cursor = ll
58 | # for i in range(1, len(l)):
59 | # cursor.next = ListNode(l[i])
60 | # cursor = cursor.next
61 | #
62 | # return ll
63 | #
64 | # s = Solution()
65 | # ll = s.addTwoNumbers(a2ll([7,0,3,6,7,3,2,1,5]), a2ll([9,2,5,5,6,1,2,2,4]))
66 | # while ll:
67 | # print ll.val,
68 | # ll = ll.next
69 |
--------------------------------------------------------------------------------
/python/climbing_stairs.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @param n, an integer
3 | # @return an integer
4 | def climbStairs(self, n):
5 | if (n == 1):
6 | return 1
7 | count = 0
8 | d = {}
9 | for i in range(n + 1):
10 | m = n - i
11 | if m == 0:
12 | count += 1
13 | elif m % 2 == 0:
14 | key = str(i) + '_' + str(m)
15 | if key in d:
16 | val = d[key]
17 | else:
18 | val = self.getAn_m(i, m/2)
19 |
20 | count += val
21 |
22 | return count
23 |
24 | # A_m/n+1
25 | def getAn_m(self, n, m):
26 | if m == 0 or n == 0:
27 | return 1
28 | if m > n:
29 | return self.getAn_m(m, n)
30 | anm = 1
31 | amm = 1
32 | n = m + n
33 | for i in range(m):
34 | anm *= n - i
35 | amm *= i + 1
36 |
37 | return anm/amm
38 |
39 |
40 | s = Solution()
41 | assert s.climbStairs(1) == 1
42 | assert s.climbStairs(2) == 2
43 | assert s.climbStairs(3) == 3
44 | assert s.climbStairs(4) == 5
45 | assert s.climbStairs(5) == 8
46 | assert s.climbStairs(6) == 13
47 |
--------------------------------------------------------------------------------
/python/generate_parentheses.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @param an integer
3 | # @return a list of string
4 | def generateParenthesis(self, n):
5 | if (n <= 0):
6 | return []
7 |
8 | arr = []
9 | self.g(n, 0, 0, '', arr)
10 | return arr
11 |
12 | ##
13 | # generate
14 | # @param n the length of the pairs
15 | # @param `left` the length the the left parentheses `(`
16 | # @param `right` the length the the right parentheses `)`
17 | # @param `s` current string of parentheses
18 | # @param `arr` list of the pairs
19 | ##
20 | def g(self, n, left, right, s, arr):
21 | if left < right:
22 | return
23 |
24 | if (left == right and left == n):
25 | arr.append(s)
26 | return
27 | if (left == n):
28 | self.g(n,left, right + 1, s + ')', arr)
29 | return
30 |
31 | self.g(n, left + 1, right, s + '(', arr);
32 | self.g(n, left, right + 1, s + ')', arr);
33 |
34 |
35 | s = Solution()
36 | assert s.generateParenthesis(3) == ["((()))", "(()())", "(())()", "()(())", "()()()"]
37 | assert s.generateParenthesis(2) == ["(())", "()()"]
38 | assert s.generateParenthesis(4) != ["(())", "()()"]
39 |
--------------------------------------------------------------------------------
/python/implement_strstr.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @param haystack, a string
3 | # @param needle, a string
4 | # @return an integer
5 | def strStr(self, haystack, needle):
6 | lenh = len(haystack)
7 | lenn = len(needle)
8 |
9 | if (lenh < lenn):
10 | return -1
11 |
12 | lenSub = lenh
13 | idx = 0
14 | while lenSub >= lenn:
15 | if haystack[idx: idx + lenn] == needle:
16 | return idx
17 | else:
18 | idx += 1
19 | lenSub -= 1
20 |
21 | return -1
22 |
23 | s = Solution()
24 | assert s.strStr('abcdedggg', 'ggg') == 6
25 | assert s.strStr('ab', 'ggg') == -1
26 | assert s.strStr('abc', 'ggg') == -1
27 |
--------------------------------------------------------------------------------
/python/intersection_of_two_linked_lists.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | # class ListNode:
3 | # def __init__(self, x):
4 | # self.val = x
5 | # self.next = None
6 |
7 | class Solution:
8 | # @param two ListNodes
9 | # @return the intersected ListNode
10 | def getIntersectionNode(self, headA, headB):
11 | lA = self.getlen(headA)
12 | lB = self.getlen(headB)
13 | if lA > lB:
14 | tmp = headA
15 | headA = headB
16 | headB = tmp
17 | tmp = lA
18 | lA = lB
19 | lB = tmp
20 |
21 | pA = headA
22 | pB = headB
23 | intersection = None
24 | for i in range(lB - lA):
25 | pB = pB.next
26 | while pB:
27 | if pB.val != pA.val:
28 | intersection = None
29 | elif not intersection:
30 | intersection = pB
31 | pB = pB.next
32 | pA = pA.next
33 |
34 | return intersection
35 |
36 | def getlen(self, head):
37 | c = head
38 | l = 0
39 | while c:
40 | l += 1
41 | c = c.next
42 | return l
43 |
44 | from _util import *
45 | s = Solution()
46 | # list A < list B
47 | n = s.getIntersectionNode(a2ll([1,2,4,5,6]), a2ll([2,1,3,6,5,6]));
48 | assert n.val == 5
49 | # list A > list B
50 | n = s.getIntersectionNode(a2ll([1,2,4,5,6]), a2ll([4,7,6]));
51 | assert n.val == 6
52 | # list A = list B
53 | n = s.getIntersectionNode(a2ll([4,5,6]), a2ll([4,7,6]));
54 | assert n.val == 6
55 |
--------------------------------------------------------------------------------
/python/longest_common_prefix.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a string
3 | def longestCommonPrefix(self, strs):
4 | lenstrs = len(strs)
5 | if lenstrs == 0:
6 | return ''
7 | if lenstrs == 1:
8 | return strs[0]
9 |
10 | d = {}
11 | s = len(strs[0])
12 | for i in range(len(strs)):
13 | val = strs[i]
14 | lens = len(val)
15 | if lens < s:
16 | s = lens
17 |
18 | if lens not in d:
19 | d[lens] = []
20 |
21 | d[lens].append(val)
22 |
23 | if s == 0:
24 | return ''
25 | # forEach from small to high
26 | search = d[s][0]
27 | for i in range(len(search), 0, -1):
28 | val = search[:i]
29 | isLongest = True
30 | for key in d:
31 | contain = self.contains(d[key], val)
32 | if not contain:
33 | isLongest = False
34 | break
35 | if isLongest:
36 | return val
37 |
38 | return ''
39 |
40 | def contains(self, strs, s):
41 | for i in range(len(strs)):
42 | val = strs[i]
43 | if val.find(s) != 0:
44 | return False
45 |
46 | return True
47 |
48 |
49 |
50 | s = Solution()
51 | assert s.longestCommonPrefix(['abcded', 'abcdef', 'abc', 'abc', 'abd']) == 'ab'
52 | assert s.longestCommonPrefix(['abcded', 'abcdef', 'abc', 'a', 'abd']) == 'a'
53 | assert s.longestCommonPrefix(['', 'abcdef', 'abc', 'a', 'abd']) == ''
54 | assert s.longestCommonPrefix(['mmm', 'abcdef', 'abc', 'a', 'abd']) == ''
55 |
--------------------------------------------------------------------------------
/python/longest_palindromic_substring.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a string
3 | def longestPalindrome(self, s):
4 | lens = len(s)
5 | if (lens == 0):
6 | return 0
7 |
8 | maxLen = 1
9 | sIdx = 0
10 |
11 | for i in range(lens):
12 | # when increase 1 element, the maxLen can add 1, 2, 0
13 | # add 2, then compare s[i - maxLen -1] and i s[i - maxLen -1]
14 | if i - maxLen >=1 and s[i-maxLen - 1: i+1] == s[i-maxLen - 1: i +1][::-1]:
15 | sIdx = i - maxLen -1
16 | maxLen += 2
17 | # add 1, then compare s[i - maxLen] and i s[i - maxLen]
18 | elif i - maxLen >= 0 and s[i - maxLen :i + 1] == s[i - maxLen :i + 1][::-1]:
19 | sIdx = i - maxLen
20 | maxLen += 1
21 |
22 | return s[sIdx:sIdx + maxLen]
23 |
24 |
25 |
26 | # test
27 |
28 | s = Solution()
29 |
30 | print s.longestPalindrome('abcdedcba')
31 | assert s.longestPalindrome('abcdedcba') == 'abcdedcba'
32 | assert s.longestPalindrome('abcdedcbadddd') == 'abcdedcba'
33 |
--------------------------------------------------------------------------------
/python/longest_substring_without_repeating_characters.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return an integer
3 | def lengthOfLongestSubstring(self, s):
4 | d = {}
5 | lenS = len(s)
6 |
7 | if lenS <=1:
8 | return lenS
9 |
10 | ls = 0
11 | sls = 0
12 | sidx = 0
13 | for i in range(lenS):
14 | val = s[i]
15 |
16 | if val in d:
17 | d = self.clearD(d, s[sidx:d[val]])
18 | sidx = d[val] + 1
19 | d[val] = i
20 | sls = len(d)
21 | else:
22 | sls = sls + 1
23 | d[val] = i
24 |
25 | ls = sls if sls > ls else ls
26 |
27 | return ls
28 | def clearD(self, d, s):
29 | for i in range(len(s)):
30 | del d[s[i]]
31 |
32 | return d
33 |
34 |
35 |
36 | s = Solution()
37 |
38 | assert s.lengthOfLongestSubstring('') == 0
39 | assert s.lengthOfLongestSubstring('ddddd') == 1
40 | assert s.lengthOfLongestSubstring('abcdefgab') == 7
41 | assert s.lengthOfLongestSubstring('abcdabcde') == 5
42 |
43 |
44 |
--------------------------------------------------------------------------------
/python/lru_cache.py:
--------------------------------------------------------------------------------
1 | class LRUCache:
2 |
3 | # @param capacity, an integer
4 | def __init__(self, capacity):
5 | self.q = []
6 | self.capacity = capacity;
7 | self.store = {}
8 | self.dbl = DBLinkedList()
9 |
10 |
11 | # @return an integer
12 | def get(self, key):
13 | if key in self.store:
14 | self.dbl.lift(self.store[key])
15 | return self.store[key].value
16 | return -1
17 |
18 |
19 | # @param key, an integer
20 | # @param value, an integer
21 | # @return nothing
22 | def set(self, key, value):
23 | if key in self.store:
24 | n = self.store[key]
25 | n.value = value
26 | self.dbl.remove(n)
27 | self.dbl.append(n)
28 | else:
29 | if self.capacity == len(self.store):
30 | k = self.dbl.pop()
31 | del self.store[k]
32 | n = Node(key, value)
33 | self.dbl.append(n)
34 | self.store[key] = n
35 |
36 |
37 | class Node:
38 | def __init__(self, key, value):
39 | self.value = value
40 | self.key = key
41 | self.pre = None
42 | self.next = None
43 |
44 | class DBLinkedList:
45 | def __init__(self):
46 | self.head = Node(None, None)
47 | self.tail = Node(None, None)
48 | self.head.next = self.tail
49 | self.tail.pre = self.head
50 |
51 | def append(self, node):
52 | tmp = self.tail.pre
53 | tmp.next = node
54 | node.pre = tmp
55 | node.next = self.tail
56 | self.tail.pre = node
57 | def remove(self, node):
58 | node.pre.next = node.next
59 | node.next.pre = node.pre
60 | def pop(self):
61 | tmp = self.head.next
62 | self.head.next = tmp.next
63 | tmp.next.pre = self.head
64 | return tmp.key
65 |
66 | def lift(self, node):
67 | self.remove(node)
68 | self.append(node)
69 |
70 |
71 | s = LRUCache(3)
72 | s.set(1, 1)
73 | s.set(2, 2)
74 | s.set(3, 3)
75 | s.set(2, 4)
76 | s.set(4, 5)
77 | assert s.get(1) == -1
78 | assert s.get(2) == 4
79 |
80 | s = LRUCache(2)
81 | s.set(2,1)
82 | s.set(1,1)
83 | assert s.get(2) == 1
84 | s.set(4,1)
85 | assert s.get(1) == -1
86 | assert s.get(2) == 1
87 |
88 | s = LRUCache(1)
89 | s.set(2,1)
90 | assert s.get(2) == 1
91 |
--------------------------------------------------------------------------------
/python/median_of_Two_Sorted_Arrays.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a float
3 | def findMedianSortedArrays(self, A, B):
4 | lenA = len(A)
5 | lenB = len(B)
6 |
7 | # the mid for both even and odd
8 | k = (lenA + lenB + 1)/2
9 | if (lenA + lenB)%2 == 1:
10 | return self.findK(A, B, k)
11 | else:
12 | return (self.findK(A, B, k) + self.findK(A, B, k + 1)) * 0.5
13 |
14 | # find the k-th smallest number
15 | def findK(self, A, B, k):
16 | lenA = len(A)
17 | lenB = len(B)
18 |
19 | # keep lenA <= lenB
20 | if (lenA > lenB):
21 | return self.findK(B, A, k)
22 | if (lenA == 0):
23 | return B[k-1]
24 | if (k == 1):
25 | return min(A[0], B[0])
26 |
27 | # k/2
28 | # get the k smallest numbers in A+B
29 | midA = min(k/2, lenA)
30 | midB = k - midA
31 |
32 | if A [midA - 1] < B[midB - 1]:
33 | return self.findK(A[midA:], B, midB)
34 | else:
35 | return self.findK(A, B[midB:], midA)
36 |
37 | # tests
38 | s = Solution()
39 | assert s.findMedianSortedArrays([1,2,3,5], [2,5]) == 2.5
40 | assert s.findMedianSortedArrays([1,2,3,5], [2]) == 2
41 | assert s.findMedianSortedArrays([1,2,3,5], [8]) == 3
42 | assert s.findMedianSortedArrays([1,2], [1, 1]) == 1
43 | assert s.findMedianSortedArrays([2,3,4,5], [1]) == 3
44 | assert s.findMedianSortedArrays([2,3,4, 5, 6], [1]) == 3.5
45 |
--------------------------------------------------------------------------------
/python/merge_two_sorted_lists.py:
--------------------------------------------------------------------------------
1 | # Definition for singly-linked list.
2 | # class ListNode:
3 | # def __init__(self, x):
4 | # self.val = x
5 | # self.next = None
6 |
7 | class Solution:
8 | # @param two ListNodes
9 | # @return a ListNode
10 | def mergeTwoLists(self, l1, l2):
11 | if not l1:
12 | return l2
13 | if not l2:
14 | return l1
15 |
16 |
17 | s = ListNode(0)
18 | curr = s
19 | while l1 and l2:
20 | if l1.val < l2.val:
21 | val = l1.val
22 | l1 = l1.next
23 | else:
24 | val = l2.val
25 | l2 = l2.next
26 | curr.next = ListNode(val)
27 | curr = curr.next
28 | if l1:
29 | curr.next = l1
30 | if l2:
31 | curr.next = l2
32 |
33 | return s.next
34 |
35 |
36 |
37 | # # test code
38 | # class ListNode:
39 | # def __init__(self, x):
40 | # self.val = x
41 | # self.next = None
42 | #
43 | # def a2ll(l):
44 | # ll = ListNode(l[0])
45 | #
46 | # cursor = ll
47 | # for i in range(1, len(l)):
48 | # cursor.next = ListNode(l[i])
49 | # cursor = cursor.next
50 | #
51 | # return ll
52 | # def pl(ll):
53 | # while ll.next:
54 | # print ll.val,
55 | # ll = ll.next
56 | # print ll.val
57 | #
58 | # s = Solution()
59 | # ll = s.mergeTwoLists(a2ll([1,2,3,6,7]), a2ll([1,4,5,8]))
60 | # # output 1 1 2 3 4 5 6 7 8
61 | # pl(ll)
62 |
--------------------------------------------------------------------------------
/python/palindrome_number.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a boolean
3 | def isPalindrome(self, x):
4 | if x < 0:
5 | return False
6 | if (x < 10):
7 | return True
8 | prefix = x
9 | suffix = x % 10
10 | p = 10
11 | # for 1213445443121
12 | # get x/10**n < 10**4 1213 and x%10**4 3121
13 | while suffix * suffix < x:
14 |
15 | prefix = x
16 | while prefix >= p:
17 | prefix = prefix / 10
18 |
19 | l = suffix / (p/10)
20 | h = prefix % 10
21 | if (l != h):
22 | return False
23 | p = p * 10
24 | suffix = x % p
25 |
26 | return True
27 |
28 |
29 | # test
30 |
31 | s = Solution()
32 |
33 | assert s.isPalindrome(10) == False
34 | assert s.isPalindrome(1) == True
35 | assert s.isPalindrome(-1) == False
36 | assert s.isPalindrome(1213) == False
37 | assert s.isPalindrome(12133121) == True
38 | assert s.isPalindrome(121313121) == True
39 |
--------------------------------------------------------------------------------
/python/remove_duplicates_from_sorted_array.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @param a list of integers
3 | # @return an integer
4 | def removeDuplicates(self, A):
5 | # 1 1 2 2 2 2 3 4 5
6 | i = 0
7 | val = None
8 | while i < len(A):
9 | if val == A[i]:
10 | # A.pop(i)
11 | A[i-1:i+1] = [A[i-1]]
12 | else:
13 | val = A[i]
14 | i += 1
15 |
16 | print A
17 | return len(A)
18 |
19 | s = Solution()
20 |
21 | assert s.removeDuplicates([1,1,2,2,3,3,4,5,6]) == 6
22 | assert s.removeDuplicates([1,1]) == 1
23 | assert s.removeDuplicates([]) == 0
24 |
--------------------------------------------------------------------------------
/python/remove_nth_node_from_end_of_list.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a ListNode
3 | def removeNthFromEnd(self, head, n):
4 | if n < 0 or head == None:
5 | return head
6 |
7 | d = {}
8 | d[0] = ListNode(0)
9 | d[0].next = head
10 |
11 | current = head
12 | # the length of the list
13 | lens = 1
14 | while current:
15 | d[lens] = current
16 | current = current.next
17 | lens += 1
18 |
19 | lens -= 1
20 |
21 | if n == 0:
22 | d[lens-1].next = None
23 | elif n <= lens:
24 | idx = lens - n + 1
25 | d[idx - 1].next = d[idx].next
26 | return d[0].next
27 |
28 |
29 | # test
30 | from _util import *
31 | s = Solution()
32 | r = s.removeNthFromEnd(a2ll([1,2]), 1)
33 | pl(r)
34 |
--------------------------------------------------------------------------------
/python/reverse_integer.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return an integer
3 | def reverse(self, x):
4 | maxint = 2**31 - 1
5 | sign = 1
6 | if x < 0:
7 | sign = -1
8 | strx = str(abs(x))
9 | res = strx[::-1]
10 | if (int(res)) > maxint:
11 | return 0
12 | return sign*int(res)
13 |
14 |
15 |
16 |
17 | assert 1212 == 1212
18 | # test
19 | s = Solution()
20 | assert s.reverse(0) == 0
21 | assert s.reverse(100000) == 1
22 | assert s.reverse(1212) == 2121
23 | assert s.reverse(-899) == -998
24 | assert s.reverse(99989787387873**2) == 0
25 |
--------------------------------------------------------------------------------
/python/string_to_integer_atoi.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return an integer
3 | def atoi(self, str):
4 | str = str.lstrip(' ').rstrip(' ');
5 |
6 | if str == '':
7 | return 0
8 |
9 | sign = 1
10 | if str[0] == '-':
11 | sign = -1
12 | str = str[1:]
13 | elif str[0] == '+':
14 | str = str[1:]
15 |
16 | lens = len(str)
17 | if lens == 0:
18 | return 0
19 |
20 |
21 | s = ''
22 | for i in range(lens):
23 | if str[i].isdigit():
24 | s = s + str[i]
25 | else:
26 | break
27 |
28 | if s == '':
29 | return 0
30 |
31 | res = sign * int(s)
32 |
33 | if res > 2147483647:
34 | return 2147483647
35 | elif res < -2147483648:
36 | return -2147483648
37 | else:
38 | return res
39 |
40 |
41 | s = Solution()
42 |
43 | assert s.atoi('') == 0
44 | assert s.atoi('aaa') == 0
45 | assert s.atoi('1213fa ') == 1213
46 | assert s.atoi('+1213fa') == 1213
47 | assert s.atoi('-1213fa') == -1213
48 | assert s.atoi('2147483648') == 2147483647
49 | assert s.atoi('+-2') == 0
50 |
--------------------------------------------------------------------------------
/python/two-sum.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a tuple, (index1, index2)
3 | def twoSum(self, num, target):
4 | length = len(num)
5 | # use dict: value: index + 1
6 | # since there is only one solution, the right value must not be duplicated
7 | dic = {}
8 | for i in xrange(0, length):
9 | val = num[i]
10 | if (target - val) in dic:
11 | return (dic[target - val], i + 1)
12 | dic[val] = i + 1
13 |
14 |
15 |
16 | ## test code
17 | # num=[2, 7, 11, 15]
18 | # t= 26
19 | # s = Solution()
20 | # print s.twoSum(num, t)
21 |
--------------------------------------------------------------------------------
/python/valid_parentheses.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a boolean
3 | def isValid(self, s):
4 | lens = len(s)
5 | if s == 0 or lens % 2 != 0:
6 | return False
7 |
8 | leftSets = set('{[(')
9 | rightSets = {
10 | ']': '[',
11 | '}': '{',
12 | ')': '(',
13 | }
14 |
15 | # check first char, avoid check range for stack[-1] later
16 | if s[0] not in leftSets:
17 | return False
18 |
19 | stack = []
20 | for i in range(lens):
21 | val = s[i]
22 | if val in leftSets:
23 | stack.append(val)
24 | # pop corresponding parentheses of the stack
25 | elif val in rightSets and rightSets[val] == stack[len(stack) - 1]:
26 | stack.pop()
27 | else:
28 | return False
29 |
30 | # after the iteration, check whether the stack is empty
31 | if len(stack) != 0:
32 | return False
33 | return True
34 |
35 | s = Solution()
36 | assert s.isValid('[[[{{}}]]]') == True
37 | assert s.isValid('{}}') == False
38 | assert s.isValid('[[') == False
39 | assert s.isValid('][') == False
40 |
--------------------------------------------------------------------------------
/python/zigzag_conversion.py:
--------------------------------------------------------------------------------
1 | class Solution:
2 | # @return a string
3 | def convert(self, s, nRows):
4 |
5 | if nRows == 1 or len(s) <= 2:
6 | return s
7 |
8 | # compute the length of the zigzag
9 | zigzagLen = 2*nRows - 2;
10 | lens = len(s)
11 | res = ''
12 | for i in range(nRows):
13 | idx = i
14 | while idx < lens:
15 | res = res + s[idx]
16 | if i != 0 and i != nRows - 1:
17 | x = idx + (zigzagLen - 2*i)
18 | if (x < lens):
19 | res = res + s[x]
20 |
21 | idx = idx + zigzagLen
22 |
23 | return res
24 |
25 |
26 | s = Solution()
27 |
28 | assert s.convert('0123456789', 5) == '0817926354'
29 | assert s.convert('0123456789', 3) == '0481357926'
30 | assert s.convert('0123456789', 2) == '0246813579'
31 | assert s.convert('012', 1) == '012'
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/tenth_line.bash:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # sed version
4 | sed -n 10p file.txt
5 |
--------------------------------------------------------------------------------
/valid_phone_numbers.bash:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # Read from the file file.txt and output all valid phone numbers to stdout.
4 | # # first version, with while
5 | # while read num
6 | # do
7 | # if [[ "$num" =~ ^\([0-9]{3}\)\ [0-9]{3}-[0-9]{4}$ ]] || [[ "$num" =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]];then
8 | # echo $num
9 | # fi
10 | # done < file.txt
11 |
12 | # sed version
13 |
14 | # sed -nE '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/p' file.txt
15 |
16 | # grep version
17 | grep -E '^(\([0-9]{3}\) |[0-9]{3}\-)[0-9]{3}\-[0-9]{4}$' file.txt
18 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | ajv@^6.12.3:
6 | version "6.12.6"
7 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
8 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
9 | dependencies:
10 | fast-deep-equal "^3.1.1"
11 | fast-json-stable-stringify "^2.0.0"
12 | json-schema-traverse "^0.4.1"
13 | uri-js "^4.2.2"
14 |
15 | ansi-regex@^2.0.0:
16 | version "2.1.1"
17 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
18 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
19 |
20 | ansi-styles@^2.2.1:
21 | version "2.2.1"
22 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
23 | integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
24 |
25 | asn1@~0.2.3:
26 | version "0.2.4"
27 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
28 | integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
29 | dependencies:
30 | safer-buffer "~2.1.0"
31 |
32 | assert-plus@1.0.0, assert-plus@^1.0.0:
33 | version "1.0.0"
34 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
35 | integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
36 |
37 | asynckit@^0.4.0:
38 | version "0.4.0"
39 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
40 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
41 |
42 | aws-sign2@~0.7.0:
43 | version "0.7.0"
44 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
45 | integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
46 |
47 | aws4@^1.8.0:
48 | version "1.11.0"
49 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
50 | integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
51 |
52 | bcrypt-pbkdf@^1.0.0:
53 | version "1.0.2"
54 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
55 | integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
56 | dependencies:
57 | tweetnacl "^0.14.3"
58 |
59 | camelcase@^6.2.0:
60 | version "6.2.0"
61 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
62 | integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
63 |
64 | caseless@~0.12.0:
65 | version "0.12.0"
66 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
67 | integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
68 |
69 | chalk@^1.1.3:
70 | version "1.1.3"
71 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
72 | integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
73 | dependencies:
74 | ansi-styles "^2.2.1"
75 | escape-string-regexp "^1.0.2"
76 | has-ansi "^2.0.0"
77 | strip-ansi "^3.0.0"
78 | supports-color "^2.0.0"
79 |
80 | combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
81 | version "1.0.8"
82 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
83 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
84 | dependencies:
85 | delayed-stream "~1.0.0"
86 |
87 | core-util-is@1.0.2:
88 | version "1.0.2"
89 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
90 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
91 |
92 | cross-fetch@^3.0.6:
93 | version "3.1.4"
94 | resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39"
95 | integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==
96 | dependencies:
97 | node-fetch "2.6.1"
98 |
99 | dashdash@^1.12.0:
100 | version "1.14.1"
101 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
102 | integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
103 | dependencies:
104 | assert-plus "^1.0.0"
105 |
106 | delayed-stream@~1.0.0:
107 | version "1.0.0"
108 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
109 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
110 |
111 | ecc-jsbn@~0.1.1:
112 | version "0.1.2"
113 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
114 | integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
115 | dependencies:
116 | jsbn "~0.1.0"
117 | safer-buffer "^2.1.0"
118 |
119 | escape-string-regexp@^1.0.2:
120 | version "1.0.5"
121 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
122 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
123 |
124 | extend@~3.0.2:
125 | version "3.0.2"
126 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
127 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
128 |
129 | extract-files@^9.0.0:
130 | version "9.0.0"
131 | resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a"
132 | integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==
133 |
134 | extsprintf@1.3.0:
135 | version "1.3.0"
136 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
137 | integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
138 |
139 | extsprintf@^1.2.0:
140 | version "1.4.0"
141 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
142 | integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
143 |
144 | fast-deep-equal@^3.1.1:
145 | version "3.1.3"
146 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
147 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
148 |
149 | fast-json-stable-stringify@^2.0.0:
150 | version "2.1.0"
151 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
152 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
153 |
154 | forever-agent@~0.6.1:
155 | version "0.6.1"
156 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
157 | integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
158 |
159 | form-data@^3.0.0:
160 | version "3.0.1"
161 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
162 | integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
163 | dependencies:
164 | asynckit "^0.4.0"
165 | combined-stream "^1.0.8"
166 | mime-types "^2.1.12"
167 |
168 | form-data@~2.3.2:
169 | version "2.3.3"
170 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
171 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
172 | dependencies:
173 | asynckit "^0.4.0"
174 | combined-stream "^1.0.6"
175 | mime-types "^2.1.12"
176 |
177 | getpass@^0.1.1:
178 | version "0.1.7"
179 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
180 | integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
181 | dependencies:
182 | assert-plus "^1.0.0"
183 |
184 | graphql-request@^3.4.0:
185 | version "3.4.0"
186 | resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-3.4.0.tgz#3a400cd5511eb3c064b1873afb059196bbea9c2b"
187 | integrity sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg==
188 | dependencies:
189 | cross-fetch "^3.0.6"
190 | extract-files "^9.0.0"
191 | form-data "^3.0.0"
192 |
193 | graphql@^15.5.0:
194 | version "15.5.0"
195 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5"
196 | integrity sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==
197 |
198 | har-schema@^2.0.0:
199 | version "2.0.0"
200 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
201 | integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
202 |
203 | har-validator@~5.1.3:
204 | version "5.1.5"
205 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
206 | integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
207 | dependencies:
208 | ajv "^6.12.3"
209 | har-schema "^2.0.0"
210 |
211 | has-ansi@^2.0.0:
212 | version "2.0.0"
213 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
214 | integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
215 | dependencies:
216 | ansi-regex "^2.0.0"
217 |
218 | http-signature@~1.2.0:
219 | version "1.2.0"
220 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
221 | integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
222 | dependencies:
223 | assert-plus "^1.0.0"
224 | jsprim "^1.2.2"
225 | sshpk "^1.7.0"
226 |
227 | is-typedarray@~1.0.0:
228 | version "1.0.0"
229 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
230 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
231 |
232 | isstream@~0.1.2:
233 | version "0.1.2"
234 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
235 | integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
236 |
237 | jsbn@~0.1.0:
238 | version "0.1.1"
239 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
240 | integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
241 |
242 | json-schema-traverse@^0.4.1:
243 | version "0.4.1"
244 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
245 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
246 |
247 | json-schema@0.2.3:
248 | version "0.2.3"
249 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
250 | integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
251 |
252 | json-stringify-safe@~5.0.1:
253 | version "5.0.1"
254 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
255 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
256 |
257 | jsprim@^1.2.2:
258 | version "1.4.1"
259 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
260 | integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
261 | dependencies:
262 | assert-plus "1.0.0"
263 | extsprintf "1.3.0"
264 | json-schema "0.2.3"
265 | verror "1.10.0"
266 |
267 | leetcode@^1.2.0:
268 | version "1.2.0"
269 | resolved "https://registry.yarnpkg.com/leetcode/-/leetcode-1.2.0.tgz#0fec69246035e43b4637dc88dfe86af9c193623e"
270 | integrity sha1-D+xpJGA15DtGN9yI3+hq+cGTYj4=
271 |
272 | mime-db@1.47.0:
273 | version "1.47.0"
274 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
275 | integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
276 |
277 | mime-types@^2.1.12, mime-types@~2.1.19:
278 | version "2.1.30"
279 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
280 | integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
281 | dependencies:
282 | mime-db "1.47.0"
283 |
284 | minimist@^1.2.5:
285 | version "1.2.5"
286 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
287 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
288 |
289 | mkdirp@^0.5.1:
290 | version "0.5.5"
291 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
292 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
293 | dependencies:
294 | minimist "^1.2.5"
295 |
296 | node-fetch@2.6.1:
297 | version "2.6.1"
298 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
299 | integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
300 |
301 | oauth-sign@~0.9.0:
302 | version "0.9.0"
303 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
304 | integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
305 |
306 | performance-now@^2.1.0:
307 | version "2.1.0"
308 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
309 | integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
310 |
311 | psl@^1.1.28:
312 | version "1.8.0"
313 | resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
314 | integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
315 |
316 | punycode@^2.1.0, punycode@^2.1.1:
317 | version "2.1.1"
318 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
319 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
320 |
321 | qs@~6.5.2:
322 | version "6.5.2"
323 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
324 | integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
325 |
326 | request@^2.73.0:
327 | version "2.88.2"
328 | resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
329 | integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
330 | dependencies:
331 | aws-sign2 "~0.7.0"
332 | aws4 "^1.8.0"
333 | caseless "~0.12.0"
334 | combined-stream "~1.0.6"
335 | extend "~3.0.2"
336 | forever-agent "~0.6.1"
337 | form-data "~2.3.2"
338 | har-validator "~5.1.3"
339 | http-signature "~1.2.0"
340 | is-typedarray "~1.0.0"
341 | isstream "~0.1.2"
342 | json-stringify-safe "~5.0.1"
343 | mime-types "~2.1.19"
344 | oauth-sign "~0.9.0"
345 | performance-now "^2.1.0"
346 | qs "~6.5.2"
347 | safe-buffer "^5.1.2"
348 | tough-cookie "~2.5.0"
349 | tunnel-agent "^0.6.0"
350 | uuid "^3.3.2"
351 |
352 | safe-buffer@^5.0.1, safe-buffer@^5.1.2:
353 | version "5.2.1"
354 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
355 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
356 |
357 | safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
358 | version "2.1.2"
359 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
360 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
361 |
362 | sshpk@^1.7.0:
363 | version "1.16.1"
364 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
365 | integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
366 | dependencies:
367 | asn1 "~0.2.3"
368 | assert-plus "^1.0.0"
369 | bcrypt-pbkdf "^1.0.0"
370 | dashdash "^1.12.0"
371 | ecc-jsbn "~0.1.1"
372 | getpass "^0.1.1"
373 | jsbn "~0.1.0"
374 | safer-buffer "^2.0.2"
375 | tweetnacl "~0.14.0"
376 |
377 | strip-ansi@^3.0.0:
378 | version "3.0.1"
379 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
380 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
381 | dependencies:
382 | ansi-regex "^2.0.0"
383 |
384 | supports-color@^2.0.0:
385 | version "2.0.0"
386 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
387 | integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
388 |
389 | tough-cookie@~2.5.0:
390 | version "2.5.0"
391 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
392 | integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
393 | dependencies:
394 | psl "^1.1.28"
395 | punycode "^2.1.1"
396 |
397 | tunnel-agent@^0.6.0:
398 | version "0.6.0"
399 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
400 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
401 | dependencies:
402 | safe-buffer "^5.0.1"
403 |
404 | tweetnacl@^0.14.3, tweetnacl@~0.14.0:
405 | version "0.14.5"
406 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
407 | integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
408 |
409 | uri-js@^4.2.2:
410 | version "4.4.1"
411 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
412 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
413 | dependencies:
414 | punycode "^2.1.0"
415 |
416 | uuid@^3.3.2:
417 | version "3.4.0"
418 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
419 | integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
420 |
421 | verror@1.10.0:
422 | version "1.10.0"
423 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
424 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
425 | dependencies:
426 | assert-plus "^1.0.0"
427 | core-util-is "1.0.2"
428 | extsprintf "^1.2.0"
429 |
--------------------------------------------------------------------------------