├── README.md ├── 141-Linked-List-Cycle ├── 1.png ├── README.md └── index.js ├── 48-Rotate-Image ├── rotateImage.JPG ├── README.md └── index.js ├── 147-Insertion-Sort-List ├── README.md └── index.js ├── 344-Reverse-String ├── index.js └── README.md ├── .gitignore ├── 231-Power-of-Two ├── index.js └── README.md ├── 14-Longest-Common-Prefix ├── README.md └── index.js ├── 67-Add-Binary ├── README.md └── index.js ├── 136-Single-Number ├── index.js └── README.md ├── 151-Reverse-Words-in-a-String ├── index.js └── README.md ├── 191-Number-of-1-Bits ├── index.js └── README.md ├── 217-Contains-Duplicate ├── index.js └── README.md ├── 56-Merge-Intervals ├── README.md └── index.js ├── 392-Is-Subsequence ├── index.js └── README.md ├── 58-Length-of-Last-Word ├── index2.js ├── index.js └── README.md ├── 28-Implement-strStr() ├── README.md └── index.js ├── 342-Power-of-Four ├── index.js └── README.md ├── 108-Convert-Sorted-Array-to-Binary-Search-Tree ├── README.md └── index.js ├── 268-Missing-Number ├── index.js └── README.md ├── 371-Sum-of-Two-Integers ├── index.js └── README.md ├── 106-Construct-Binary-Tree-from-Inorder-and-Postorder-Traversal ├── README.md └── index.js ├── 104-Maximum-Depth-of-Binary-Tree ├── README.md └── index.js ├── 190-Reverse-Bits ├── index.js └── README.md ├── 201-Bitwise-AND-of-Numbers-Range ├── index.js └── README.md ├── 66-Plus-One ├── README.md └── index.js ├── 110-Balanced-Binary-Tree ├── README.md └── index.js ├── 219-Contains-Duplicate-II ├── README.md └── index.js ├── 105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal ├── README.md └── index.js ├── 137-Single-Number-II ├── index.js └── README.md ├── 389-Find-the-Difference ├── index.js └── README.md ├── 27-Remove-Element ├── index.js └── README.md ├── 100-Same-Tree ├── README.md └── index.js ├── 20-Valid-Parentheses ├── README.md └── index.js ├── 189-Rotate-Array ├── index.js └── README.md ├── 228-Summary-Ranges ├── README.md └── index.js ├── 118-Pascal's-Triangle ├── README.md └── index.js ├── 119-Pascal's-Triangle-II ├── index.js └── README.md ├── 345-Reverse-Vowels-of-a-String ├── README.md └── index.js ├── 55-Jump-Game ├── index2.js ├── README.md └── index.js ├── 35-Search-Insert-Position ├── README.md └── index.js ├── 179-Largest-Number ├── README.md └── index.js ├── 349-Intersection-of-Two-Arrays ├── README.md └── index.js ├── 7-Reverse-Integer ├── index2.js ├── index.js └── README.md ├── 111-Minimum-Depth-of-Binary-Tree ├── README.md ├── index2.js └── index.js ├── 405-Convert-a-Number-to-Hexadecimal ├── index.js └── README.md ├── 43-Multiply-Strings ├── README.md └── index.js ├── 75-Sort-Colors ├── index.js └── README.md ├── 144-Binary-Tree-Preorder-Traversal ├── README.md └── index.js ├── 49-Group-Anagrams ├── README.md └── index.js ├── 283-Move-Zeroes ├── index.js ├── index2.js └── README.md ├── 8-String-to-Integer(atoi) ├── index.js └── README.md ├── 80-Remove-Duplicates-from-Sorted-Array-II ├── README.md └── index.js ├── 34-Search-for-a-Range ├── README.md └── index.js ├── 94-Binary-Tree-Inorder-Traversal ├── README.md └── index.js ├── 205-Isomorphic-Strings ├── index.js └── README.md ├── 397-Integer-Replacement ├── index.js └── README.md ├── 71-Simplify-Path ├── index.js └── README.md ├── 128-Longest-Consecutive-Sequence ├── README.md └── index.js ├── 260-Single-Number-III ├── index.js └── README.md ├── 169-Majority-Element ├── README.md ├── index2.js └── index.js ├── 199-Binary-Tree-Right-Side-View ├── README.md └── index.js ├── 26-Remove-Duplicates-from-Sorted-Array ├── index.js └── README.md ├── 1-two-sum ├── index2.js ├── index.js └── README.md ├── 350-Intersection-of-Two-Arrays-II ├── index.js └── README.md ├── 145-Binary-Tree-Postorder-Traversal ├── README.md └── index.js ├── 242-Valid-Anagram ├── index2.js ├── README.md └── index.js ├── 107-Binary-Tree-Level-Order-Traversal-II ├── README.md └── index.js ├── 125-Valid-Palindrome ├── README.md └── index.js ├── 142-Linked-List-Cycle-II ├── README.md └── index.js ├── 383-Ransom-Note ├── index.js └── README.md ├── 112-Path-Sum ├── README.md └── index.js ├── 6-ZigZag-Conversion ├── index2.js ├── README.md └── index.js ├── 222-Count-Complete-Tree-Nodes ├── README.md └── index.js ├── 103-Binary-Tree-Zigzag-Level-Order-Traversal ├── README.md └── index.js ├── 113-Path-Sum-II ├── README.md └── index.js ├── 134-Gas-Station ├── index.js └── README.md ├── 129-Sum-Root-to-Leaf-Numbers ├── README.md └── index.js ├── 229-Majority-Element-II ├── README.md └── index.js ├── 102-Binary-Tree-Level-Order-Traversal ├── README.md └── index.js ├── 101-Symmetric-Tree ├── README.md ├── index.js └── index2.js ├── 2-Add-Two-Numbers ├── README.md └── index.js ├── 74-Search-a-2D-Matrix ├── README.md ├── index.js └── index2.js ├── 11-Container-With-Most-Water ├── index.js └── README.md ├── 3-Longest-Substring-Without-Repeating-Characters ├── index.js └── README.md ├── 230-Kth-Smallest-Element-in-a-BST ├── README.md └── index.js ├── 238-Product-of-Array-Except-Self ├── README.md └── index.js ├── 316-Remove-Duplicate-Letters ├── index.js └── README.md ├── 406-Queue-Reconstruction-by-Height ├── index.js └── README.md ├── 73-Set-Matrix-Zeroes ├── README.md ├── index2.js └── index.js ├── 226-Invert-Binary-Tree ├── README.md ├── index2.js └── index.js ├── 135-Candy ├── index.js └── README.md ├── 318-Maximum-Product-of-Word-Lengths ├── index.js └── README.md ├── 187-Repeated-DNA-Sequences ├── index.js └── README.md ├── 393-UTF-8-Validation ├── index.js └── README.md ├── 240-Search-a-2D-Matrix II ├── index2.js ├── README.md └── index.js ├── 287-Find-the-Duplicate-Number ├── index.js └── README.md ├── 57-Insert-Interval ├── README.md └── index.js ├── 164-Maximum-Gap ├── README.md └── index.js ├── 165-Compare-Version-Numbers ├── README.md └── index.js ├── 45-Jump-Game-II ├── README.md └── index.js ├── 435-Non-overlapping-Intervals ├── README.md └── index.js ├── 235-Lowest-Common-Ancestor-of-a-Binary-Search-Tree ├── README.md └── index.js └── 236-Lowest-Common-Ancestor-of-a-Binary-Tree ├── README.md └── index.js /README.md: -------------------------------------------------------------------------------- 1 | # leetcode算法(js) 2 | ----- 3 | 所有的题目都用了ES6语法,代码虽然不是写的很漂亮,如果你觉得哪道题看不懂解法,或者有更好的解法都可以提个issue。 -------------------------------------------------------------------------------- /141-Linked-List-Cycle/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fa-ge/leetcode/HEAD/141-Linked-List-Cycle/1.png -------------------------------------------------------------------------------- /48-Rotate-Image/rotateImage.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fa-ge/leetcode/HEAD/48-Rotate-Image/rotateImage.JPG -------------------------------------------------------------------------------- /147-Insertion-Sort-List/README.md: -------------------------------------------------------------------------------- 1 | ### 147\. Insertion Sort List 2 | 3 | Sort a linked list using insertion sort. 4 | 5 | -------------------------------------------------------------------------------- /344-Reverse-String/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {string} 4 | */ 5 | var reverseString = function(s) { 6 | return s.split('').reverse().join('') 7 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Example user template template 3 | ### Example user template 4 | 5 | # IntelliJ project files 6 | .idea 7 | *.iml 8 | out 9 | gen 10 | -------------------------------------------------------------------------------- /231-Power-of-Two/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} n 3 | * @return {boolean} 4 | */ 5 | var isPowerOfTwo = function(n) { 6 | return n > 0 ? !(n & (n - 1)) : false 7 | }; 8 | 9 | console.log(isPowerOfTwo(3)) -------------------------------------------------------------------------------- /14-Longest-Common-Prefix/README.md: -------------------------------------------------------------------------------- 1 | 1. ### 14\. Longest Common Prefix 2 | 3 | Write a function to find the longest common prefix string amongst an array of strings. 4 | 5 | ### 方法(一) 6 | 把数组中的第一个字符串进和其他字符串逐个比较。 7 | -------------------------------------------------------------------------------- /67-Add-Binary/README.md: -------------------------------------------------------------------------------- 1 | ### 67\. Add Binary 2 | 3 | Given two binary strings, return their sum (also a binary string). 4 | 5 | For example, 6 | a = `"11"` 7 | b = `"1"` 8 | Return `"100"`. 9 | 10 | ### 方法(一) 11 | 自己实现二进制加法 -------------------------------------------------------------------------------- /344-Reverse-String/README.md: -------------------------------------------------------------------------------- 1 | ### 344\. Reverse String 2 | 3 | Write a function that takes a string as input and returns the string reversed. 4 | 5 | Example: 6 | Given s = "hello", return "olleh". 7 | 8 | ### 方法(一) 9 | 10 | -------------------------------------------------------------------------------- /136-Single-Number/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var singleNumber = function(nums) { 6 | return nums.reduce((pre, cur) => pre ^ cur) 7 | }; 8 | 9 | console.log(singleNumber([1,2,3,3,2,1,4])) -------------------------------------------------------------------------------- /151-Reverse-Words-in-a-String/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} str 3 | * @returns {string} 4 | */ 5 | var reverseWords = function(str) { 6 | return str.trim().split(/ +/).reverse().join(' ') 7 | }; 8 | 9 | console.log(reverseWords("")) -------------------------------------------------------------------------------- /191-Number-of-1-Bits/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} n - a positive integer 3 | * @return {number} 4 | */ 5 | var hammingWeight = function(n) { 6 | return n.toString(2).replace(/0/g, '').length 7 | }; 8 | 9 | console.log(hammingWeight(4)) -------------------------------------------------------------------------------- /217-Contains-Duplicate/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {boolean} 4 | */ 5 | var containsDuplicate = function(nums) { 6 | return (new Set(nums)).size !== nums.length 7 | }; 8 | 9 | console.log(containsDuplicate([1,2,3,3])) -------------------------------------------------------------------------------- /231-Power-of-Two/README.md: -------------------------------------------------------------------------------- 1 | ### 231\. Power of Two 2 | 3 | Given an integer, write a function to determine if it is a power of two. 4 | 5 | ### 题意 6 | 判断一个整数是不是2的幂 7 | 8 | ### 方法(一) 9 | 32位的整数2的幂总共也就31(2^0-2^30)个,全部列出来都没关系。不过这里用啦其他的方法,根据如果n是2的幂那么n&(n-1)=0; -------------------------------------------------------------------------------- /56-Merge-Intervals/README.md: -------------------------------------------------------------------------------- 1 | ### 56\. Merge Intervals 2 | 3 | Given a collection of intervals, merge all overlapping intervals. 4 | 5 | For example, 6 | Given `[1,3],[2,6],[8,10],[15,18]`, 7 | return `[1,6],[8,10],[15,18]`. 8 | 9 | ### 方法(一) 10 | 先排序。其他和57题差不多。 -------------------------------------------------------------------------------- /392-Is-Subsequence/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {string} t 4 | * @return {boolean} 5 | */ 6 | var isSubsequence = function(s, t) { 7 | return new RegExp(s.split('').join('.*?')).test(t) 8 | }; 9 | 10 | console.log(isSubsequence('acb', 'ahbgdc')) -------------------------------------------------------------------------------- /58-Length-of-Last-Word/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | 6 | var lengthOfLastWord = function(s) { 7 | const sArr = s.trim().split(' ') 8 | return sArr[sArr.length - 1].length 9 | }; 10 | 11 | console.log(lengthOfLastWord(" ")) -------------------------------------------------------------------------------- /28-Implement-strStr()/README.md: -------------------------------------------------------------------------------- 1 | ### 28\. Implement strStr() 2 | 3 | Implement strStr(). 4 | 5 | Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. 6 | 7 | ### 题意 8 | 让你实现strStr函数,在一个字符串中找另一个字符串,能找到就返回第一个匹配的位置,不能就返回-1 9 | 10 | ### 方法(一) 11 | two pointer -------------------------------------------------------------------------------- /342-Power-of-Four/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | * @return {boolean} 4 | */ 5 | var isPowerOfFour = function(num) { 6 | if (num > 0 && ((num & (num - 1)) === 0) && ((num & 0x55555555) !== 0)) { 7 | return true 8 | } 9 | return false 10 | }; 11 | 12 | console.log(isPowerOfFour(16777216)) -------------------------------------------------------------------------------- /108-Convert-Sorted-Array-to-Binary-Search-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 108\. Convert Sorted Array to Binary Search Tree 2 | 3 | Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 4 | 5 | ### 题意 6 | 把一个有序递增的数组转换成平衡的二叉搜索树 7 | 8 | ### 方法(一) 9 | 因为是有序的数组,所以数组的中间的值就是树的跟节点,左边的值是树的左子树,右边的就是右子树。递归数组就好了 -------------------------------------------------------------------------------- /268-Missing-Number/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var missingNumber = function(nums) { 6 | for (let i = 0, len = nums.length; i <= len; i++) { 7 | nums.push(i) 8 | } 9 | return nums.reduce((pre, cur) => pre ^ cur) 10 | }; 11 | console.log(missingNumber([0,1])) -------------------------------------------------------------------------------- /371-Sum-of-Two-Integers/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} a 3 | * @param {number} b 4 | * @return {number} 5 | */ 6 | var getSum = function(a, b) { 7 | while (b !== 0) { 8 | let res = a ^ b 9 | b = (b & a) << 1 10 | a = res 11 | } 12 | return a 13 | }; 14 | 15 | console.log(getSum(5, 6)) -------------------------------------------------------------------------------- /106-Construct-Binary-Tree-from-Inorder-and-Postorder-Traversal/README.md: -------------------------------------------------------------------------------- 1 | ### 106\. Construct Binary Tree from Inorder and Postorder Traversal 2 | 3 | Given inorder and postorder traversal of a tree, construct the binary tree. 4 | 5 | Note: 6 | You may assume that duplicates do not exist in the tree. 7 | 8 | ### 题意 9 | 通过中序,后序遍历的结果生成二叉树。和105题几乎一样 -------------------------------------------------------------------------------- /104-Maximum-Depth-of-Binary-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 104\. Maximum Depth of Binary Tree 2 | 3 | Given a binary tree, find its maximum depth. 4 | 5 | The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 6 | 7 | ### 题意 8 | 求二叉树的最大深度 9 | 10 | ### 方法(一) 11 | 其实就是左子树和右子树中较大的深度。递归求左右子树深度取较大的值。 -------------------------------------------------------------------------------- /190-Reverse-Bits/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} n - a positive integer 3 | * @return {number} - a positive integer 4 | */ 5 | var reverseBits = function(n) { 6 | let res = 0 7 | for (let i = 0; i < 32; i++) { 8 | res = res << 1 | (n >> i & 1) 9 | } 10 | return res >>> 0 11 | }; 12 | 13 | console.log(reverseBits(1)) -------------------------------------------------------------------------------- /201-Bitwise-AND-of-Numbers-Range/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} m 3 | * @param {number} n 4 | * @return {number} 5 | */ 6 | var rangeBitwiseAnd = function(m, n) { 7 | let i = 0 8 | while (m !== n) { 9 | m >>= 1 10 | n >>= 1 11 | i++ 12 | } 13 | return m << i 14 | }; 15 | 16 | console.log(rangeBitwiseAnd(1, 2)) -------------------------------------------------------------------------------- /371-Sum-of-Two-Integers/README.md: -------------------------------------------------------------------------------- 1 | ### 371\. Sum of Two Integers 2 | 3 | Calculate the sum of two integers *a* and *b*, but you are not allowed to use the operator `+` and `-`. 4 | 5 | Example: 6 | Given *a* = 1 and *b* = 2, return 3. 7 | 8 | ### 题意 9 | 不用+,-符号算两个整数的加法 10 | 11 | ### 方法(一) 12 | 可以通过异或运算和与运算分别获得相加的值和进位。a,b两个整数相加,a&b<<1,其实就是获得每一位上的进位并且左移一位。 -------------------------------------------------------------------------------- /66-Plus-One/README.md: -------------------------------------------------------------------------------- 1 | ### 66\. Plus One 2 | 3 | Given a non-negative number represented as an array of digits, plus one to the number. 4 | 5 | The digits are stored such that the most significant digit is at the head of the list. 6 | 7 | ### 大意 8 | 给你一个非负的数字数组,然后加1,这个数组中的数字是由高位在前,低位在后,和正常的数字顺序一样,比如[1,5,7]就代表157 9 | ### 方法(一) 10 | 很简单,注意如果首位加进位变0的话,要在头部插入1 -------------------------------------------------------------------------------- /217-Contains-Duplicate/README.md: -------------------------------------------------------------------------------- 1 | ### 217\. Contains Duplicate 2 | 3 | Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct. 4 | 5 | ### 题意 6 | 给你一个数字数组,判断有没有重复元素,有就返回true,没有返回false 7 | ### 方法(一) 8 | 将数组转换成Set,看两者的长度是否一样。 -------------------------------------------------------------------------------- /110-Balanced-Binary-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 110\. Balanced Binary Tree 2 | 3 | Given a binary tree, determine if it is height-balanced. 4 | 5 | For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of *every* node never differ by more than 1. 6 | 7 | ### 题意 8 | 判断二叉树是否是平衡的 9 | 10 | ### 方法(一) 11 | 递归判断左右子树的最大深度是否相差一 -------------------------------------------------------------------------------- /219-Contains-Duplicate-II/README.md: -------------------------------------------------------------------------------- 1 | 1. ### 219\. Contains Duplicate II 2 | 3 | Given an array of integers and an integer *k*, find out whether there are two distinct indices *i* and *j* in the array such that nums[i] = nums[j]and the difference between *i* and *j* is at most *k*. 4 | 5 | ### 题意 6 | 给你一个整型数组nums和整数k,找出不同索引i,j使得nums[i] = nums[j]并且j-i<=k 7 | 8 | ### 方法(一) 9 | 比较简单,用hash表 -------------------------------------------------------------------------------- /105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/README.md: -------------------------------------------------------------------------------- 1 | ### 105\. Construct Binary Tree from Preorder and Inorder Traversal 2 | 3 | Given preorder and inorder traversal of a tree, construct the binary tree. 4 | 5 | Note: 6 | You may assume that duplicates do not exist in the tree. 7 | 8 | ### 题意 9 | 用中序,先序遍历的结果构造一个二叉树。 10 | 提示:树中的元素都不重复 11 | 12 | ### 方法(一) 13 | 14 | -------------------------------------------------------------------------------- /137-Single-Number-II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var singleNumber = function(nums) { 6 | const arr = [] 7 | for (let i = 0; i < 32; i++) { 8 | arr.unshift(nums.reduce((pre, cur) => pre + (cur >> i & 1), 0) % 3) 9 | } 10 | return parseInt(arr.join(''), 2) | 0 11 | }; 12 | 13 | console.log(singleNumber([-1,-1,-1,-2])) -------------------------------------------------------------------------------- /389-Find-the-Difference/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {string} t 4 | * @return {character} 5 | */ 6 | var findTheDifference = function(s, t) { 7 | const xorFun = (pre, cur) => (pre ^ cur.codePointAt(0)) 8 | return String.fromCodePoint([].reduce.call(s, xorFun, 0) ^ [].reduce.call(t, xorFun, 0)) 9 | }; 10 | 11 | console.log(findTheDifference('abcd', 'abcde')) -------------------------------------------------------------------------------- /136-Single-Number/README.md: -------------------------------------------------------------------------------- 1 | ### 136\. Single Number 2 | 3 | Given an array of integers, every element appears *twice* except for one. Find that single one. 4 | 5 | Note: 6 | Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 7 | 8 | ### 题意 9 | 一个整型数组中,所有的元素都出现两次,除了一个元素只出现一次,找出这个元素 10 | 11 | ### 方法(一) 12 | 根据位运算中的异或运算符的一个性质 13 | a^b^b=a -------------------------------------------------------------------------------- /27-Remove-Element/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} val 4 | * @return {number} 5 | */ 6 | var removeElement = function(nums, val) { 7 | for (let i = nums.length - 1; i >= 0; i--) { 8 | if (nums[i] === val) { 9 | nums.splice(i, 1) 10 | } 11 | } 12 | return nums.length 13 | }; 14 | 15 | 16 | 17 | console.log(removeElement([3,3], 3)) -------------------------------------------------------------------------------- /100-Same-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 100\. Same Tree 2 | 3 | Given two binary trees, write a function to check if they are equal or not. 4 | 5 | Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 6 | 7 | ### 题意 8 | 判断两棵树是否相等。这里的相等指的是结构相等并且各个节点的值相等 9 | 10 | ### 方法(一) 11 | 先序遍历两颗树,两颗树的节点不相同的情况有:一个为空,一个不为空或者两个节点的值不想等。当两个节点都为空时这两个节点自然相同了。但是当两个节点的值相同就比较他们的左子树和右子树 -------------------------------------------------------------------------------- /20-Valid-Parentheses/README.md: -------------------------------------------------------------------------------- 1 | 1. ### 20\. Valid Parentheses 2 | 3 | Given a string containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid. 4 | 5 | The brackets must close in the correct order, `"()"` and `"()[]{}"` are all valid but `"(]"` and `"([)]"` are not. 6 | 7 | ### 方法(一) 8 | 遍历字符串,碰到左括号入栈,右括号出栈,出栈的元素得是当前右括号的对应左括号。否则返回false。当遍历完后发现栈中仍有元素,返回false -------------------------------------------------------------------------------- /189-Rotate-Array/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by fage on 2016/10/22. 3 | */ 4 | /** 5 | * @param {number[]} nums 6 | * @param {number} k 7 | * @return {void} Do not return anything, modify nums in-place instead. 8 | */ 9 | var rotate = function(nums, k) { 10 | const length = nums.length 11 | k %= length 12 | nums.unshift(...nums.splice(length - k)) 13 | }; 14 | 15 | console.log(rotate([1,2,3,4,5,6,7],3)) -------------------------------------------------------------------------------- /228-Summary-Ranges/README.md: -------------------------------------------------------------------------------- 1 | ### 228\. Summary Ranges 2 | 3 | Given a sorted integer array without duplicates, return the summary of its ranges. 4 | 5 | For example, given `[0,1,2,4,5,7]`, return `["0->2","4->5","7"].` 6 | 7 | ### 题意 8 | 给你一个没有重复元素的,已经排序好的整型数组,返回它的简要写法 9 | 10 | ### 方法(一) 11 | 遍历数组,用begin记录每次起始的位置,当nums[end]-nums[end-1]!=1的时候保存此时的时候,也就出现begin->end-1 12 | 这里又一个小技巧,就是为数组push一个Infinity的值,这样就不用对数组末做特殊判断 -------------------------------------------------------------------------------- /118-Pascal's-Triangle/README.md: -------------------------------------------------------------------------------- 1 | ### 118\. Pascal's Triangle 2 | 3 | Given *numRows*, generate the first *numRows* of Pascal's triangle. 4 | 5 | For example, given *numRows* = 5, 6 | Return 7 | 8 | [ 9 | [1], 10 | [1,1], 11 | [1,2,1], 12 | [1,3,3,1], 13 | [1,4,6,4,1] 14 | ] 15 | 16 | ### 方法(一) 17 | 每一个数组中,除了第一个和最后一个元素外,每一个数都是肩上两个数相加的和。数组的左边和右边是完全一样的,所以内循环只需要遍历n/2次就可以了 -------------------------------------------------------------------------------- /119-Pascal's-Triangle-II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} rowIndex 3 | * @return {number[]} 4 | */ 5 | var getRow = function(rowIndex) { 6 | const res = new Array(rowIndex + 1).fill(0) 7 | res[0] = 1 8 | for (let i = 1; i <= rowIndex; i++) { 9 | for (let j = i; j >= 1; j--) { 10 | res[j] += res[j - 1] 11 | } 12 | } 13 | return res 14 | }; 15 | 16 | console.log(getRow(1)) -------------------------------------------------------------------------------- /345-Reverse-Vowels-of-a-String/README.md: -------------------------------------------------------------------------------- 1 | ### 345\. Reverse Vowels of a String 2 | 3 | Write a function that takes a string as input and reverse only the vowels of a string. 4 | 5 | Example 1: 6 | Given s = "hello", return "holle". 7 | 8 | Example 2: 9 | Given s = "leetcode", return "leotcede". 10 | 11 | Note: 12 | The vowels does not include the letter "y". 13 | 14 | ### 题意 15 | 只对元音字母反转 16 | 17 | ### 方法一 18 | two pointer -------------------------------------------------------------------------------- /55-Jump-Game/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {boolean} 4 | */ 5 | var canJump = function(nums) { 6 | const length = nums.length 7 | let lastIndex = length - 1 8 | for (let i = length - 2; i >= 0; i--) { 9 | if (nums[i] + i >= lastIndex) { 10 | lastIndex = i 11 | } 12 | } 13 | return lastIndex === 0 14 | }; 15 | 16 | console.log(canJump([3,2,1,0,5, 4])) -------------------------------------------------------------------------------- /58-Length-of-Last-Word/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | 6 | var lengthOfLastWord = function(s) { 7 | let curLen = 0 8 | for (let i = s.length - 1; i >= 0; i--) { 9 | if (s[i] !== ' ') { 10 | curLen++ 11 | } else if (curLen !== 0) { 12 | break 13 | } 14 | } 15 | return curLen 16 | }; 17 | 18 | console.log(lengthOfLastWord(" ")) -------------------------------------------------------------------------------- /35-Search-Insert-Position/README.md: -------------------------------------------------------------------------------- 1 | ### 35\. Search Insert Position 2 | 3 | Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. 4 | 5 | You may assume no duplicates in the array. 6 | 7 | Here are few examples. 8 | `[1,3,5,6]`, 5 → 2 9 | `[1,3,5,6]`, 2 → 1 10 | `[1,3,5,6]`, 7 → 4 11 | `[1,3,5,6]`, 0 → 0 12 | 13 | ### 方法(一) 14 | 二分查找直接实现 -------------------------------------------------------------------------------- /179-Largest-Number/README.md: -------------------------------------------------------------------------------- 1 | ### 179\. Largest Number 2 | 3 | Given a list of non negative integers, arrange them such that they form the largest number. 4 | 5 | For example, given `[3, 30, 34, 5, 9]`, the largest formed number is `9534330`. 6 | 7 | Note: The result may be very large, so you need to return a string instead of an integer. 8 | 9 | ### 方法(一) 10 | 其实就是一个排序,只不过这个排序不是简单的按照数字的大小来排序。在这里9>5>34>3>30.如果产生这样的排序。这里有个方法是如果a>b,那么ab一定大于ba。 -------------------------------------------------------------------------------- /349-Intersection-of-Two-Arrays/README.md: -------------------------------------------------------------------------------- 1 | ### 349\. Intersection of Two Arrays 2 | 3 | 4 | Given two arrays, write a function to compute their intersection. 5 | 6 | Example: 7 | Given *nums1* = `[1, 2, 2, 1]`, *nums2* = `[2, 2]`, return `[2]`. 8 | 9 | Note: 10 | 11 | * Each element in the result must be unique. 12 | * The result can be in any order. 13 | 14 | ### 题意 15 | 求两个数组的交集 16 | 17 | ### 方法(一) 18 | 特别简单,把一个数组放到map中,另一个数组中的元素一个个从map中找。 -------------------------------------------------------------------------------- /7-Reverse-Integer/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @return {number} 4 | */ 5 | var reverse = function(x) { 6 | const sign = Math.sign(x) 7 | x = Math.abs(x) 8 | let res = sign * (x + '').split('').reverse().join('') 9 | if (res > (Math.pow(2, 31) - 1)) { 10 | res = 0 11 | } else if (res < -Math.pow(2, 31)) { 12 | res = 0 13 | } 14 | return res 15 | }; 16 | 17 | console.log(reverse(12233)) -------------------------------------------------------------------------------- /111-Minimum-Depth-of-Binary-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 111\. Minimum Depth of Binary Tree 2 | 3 | Given a binary tree, find its minimum depth. 4 | 5 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 6 | 7 | ### 题意 8 | 求二叉树的最小深度 9 | 10 | ### 方法(一) 11 | BFS,只要第一次碰到左右节点都没有的节点就算是找到了 12 | 13 | ### 方法(二) 14 | DFS, 比BFS要差,空间复杂度虽然一样O(n),BFS需要用一个队列,DFS递归需要栈。但在时间上BFS第一次碰到叶子结点就退出循环了,DFS却需要遍历所有节点。 -------------------------------------------------------------------------------- /405-Convert-a-Number-to-Hexadecimal/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | * @return {string} 4 | */ 5 | var toHex = function(num) { 6 | const arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'] 7 | let res = '' 8 | for (let i = 0; i < 32; i+=4) { 9 | res = arr[(num >> i) & 0b1111] + res 10 | } 11 | return res.replace(/^0+/g, '') || '0' 12 | }; 13 | 14 | console.log(toHex(1000)) -------------------------------------------------------------------------------- /201-Bitwise-AND-of-Numbers-Range/README.md: -------------------------------------------------------------------------------- 1 | ### 201\. Bitwise AND of Numbers Range 2 | 3 | Given a range [m, n] where 0 \<= m \<= n \<= 2147483647, return the bitwise AND of all numbers in this range, inclusive. 4 | 5 | For example, given the range [5, 7], you should return 4. 6 | 7 | ### 题意 8 | 对一个范围内的所有整数做与运算 9 | ### 方法(一) 10 | 没想到什么好办法。网上看到有一个规律就是说,与运算的结果一定是第一个数和最后一个数最左边共同的部分。比如5-7 是 ...000101,...000111,左边共同部分是..000100,所以值是4.知道这个规律之后就号算了。对m,n两个数循环右移直到他们相等。 -------------------------------------------------------------------------------- /43-Multiply-Strings/README.md: -------------------------------------------------------------------------------- 1 | ### 43\. Multiply Strings 2 | 3 | Given two numbers represented as strings, return multiplication of the numbers as a string. 4 | 5 | Note: 6 | 7 | * The numbers can be arbitrarily large and are non-negative. 8 | * Converting the input string to integer is NOT allowed. 9 | * You should NOT use internal library such as BigInteger. 10 | 11 | ### 题意 12 | 给你两个字符串类型的数字,求他们的乘积 13 | 14 | ### 方法(一) 15 | 我首先把两个字符串转换成了两个倒序的数组,这样做乘法方便很多。 -------------------------------------------------------------------------------- /66-Plus-One/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} digits 3 | * @return {number[]} 4 | */ 5 | var plusOne = function(digits) { 6 | let carry = 1 7 | for (let i = digits.length - 1, sum; i >= 0; i--) { 8 | sum = carry + digits[i] 9 | carry = Math.floor(sum / 10) 10 | digits[i] = sum % 10 11 | } 12 | if (digits[0] === 0) { 13 | digits.unshift(1) 14 | } 15 | return digits 16 | }; 17 | 18 | console.log(plusOne([9,9,9])) -------------------------------------------------------------------------------- /75-Sort-Colors/index.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 | let res = ['', '', ''] 7 | nums.forEach(value => { 8 | res[value] += value 9 | }) 10 | res = res.join('').split('').map(value => +value) 11 | res.forEach((value, index) => { 12 | nums[index] = value 13 | }) 14 | }; 15 | 16 | console.log(sortColors([1,0])) -------------------------------------------------------------------------------- /342-Power-of-Four/README.md: -------------------------------------------------------------------------------- 1 | ### 342\. Power of Four 2 | 3 | Given an integer (signed 32 bits), write a function to check whether it is a power of 4. 4 | 5 | Example: 6 | Given num = 16, return true. Given num = 5, return false. 7 | 8 | Follow up: Could you solve it without loops/recursion? 9 | 10 | ### 题意 11 | 判断一个整数是不是4的幂 12 | ### 方法(一) 13 | 4的幂一定在从右往左数奇数位上是1,比如16的二进制是10000,在倒数第5位。先判断n是不是2的幂(231题),如果是说明该数符合000010000这样的格式。然后与上0x55555555(....01010101),如果不等于0,说明在奇数位上有1,那么就是4的幂啦 -------------------------------------------------------------------------------- /144-Binary-Tree-Preorder-Traversal/README.md: -------------------------------------------------------------------------------- 1 | ### 144\. Binary Tree Preorder Traversal 2 | 3 | Given a binary tree, return the *preorder* traversal of its nodes' values. 4 | 5 | For example: 6 | Given binary tree `{1,#,2,3}`, 7 | 8 | 1 9 | \ 10 | 2 11 | / 12 | 3 13 | 14 | return `[1,2,3]`. 15 | 16 | Note: Recursive solution is trivial, could you do it iteratively? 17 | 18 | ### 题意 19 | 先序遍历二叉树 20 | 21 | ### 方法(一) 22 | 真没什么好写的啦。不用递归需要用栈来存储节点 -------------------------------------------------------------------------------- /48-Rotate-Image/README.md: -------------------------------------------------------------------------------- 1 | ### 48\. Rotate Image 2 | 3 | You are given an *n* x *n* 2D matrix representing an image. 4 | 5 | Rotate the image by 90 degrees (clockwise). 6 | 7 | Follow up: 8 | Could you do this in-place? 9 | 10 | ### 方法(一) 11 | ![rotateImage](https://github.com/fa-ge/leetcodeAlgorithms/blob/master/48-Rotate-Image/rotateImage.JPG) 12 | 旋转90度就是先沿对角线翻转再沿y轴翻转。题目一定要求do this in-place,否者就可以直接转换。代码见index.js的注释部分。经过两次翻转的代码实现是见index.js 13 | 注视部分代码主要是根据矩阵线性变换后的结果,所列出的公式。 -------------------------------------------------------------------------------- /49-Group-Anagrams/README.md: -------------------------------------------------------------------------------- 1 | 1. ### 49\. Group Anagrams 2 | 3 | Given an array of strings, group anagrams together. 4 | 5 | For example, given: `["eat", "tea", "tan", "ate", "nat", "bat"]`, 6 | Return: 7 | 8 | [ 9 | ["ate", "eat","tea"], 10 | ["nat","tan"], 11 | ["bat"] 12 | ] 13 | 14 | Note: All inputs will be in lower-case. 15 | 16 | ### 方法(一) 17 | 要证明两个字符串是不是groupAnagrams,只要排序后是否相等就可以了。然后创建一个hash对象,key为排序后的字符串,value是返回结果数组的索引。 18 | 19 | -------------------------------------------------------------------------------- /283-Move-Zeroes/index.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 | const length = nums.length 7 | for (let i = length - 1; i >= 0; i--) { 8 | if (nums[i] === 0) { 9 | nums.splice(i, 1) 10 | } 11 | } 12 | nums.push(...new Array(length - nums.length).fill(0)) 13 | }; 14 | var arr = [0,2,1,5] 15 | moveZeroes(arr) 16 | console.log(arr) -------------------------------------------------------------------------------- /8-String-to-Integer(atoi)/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} str 3 | * @return {number} 4 | */ 5 | var myAtoi = function(str) { 6 | let num = parseInt(str) 7 | num = Number.isNaN(num) ? 0 : num 8 | const INT_MAX = Math.pow(2, 31) - 1 9 | const INT_MIN = -Math.pow(2, 31) 10 | if (num > INT_MAX) { 11 | num = INT_MAX 12 | } else if (num < INT_MIN) { 13 | num = INT_MIN 14 | } 15 | return num 16 | }; 17 | 18 | console.log(myAtoi("2147483648")) -------------------------------------------------------------------------------- /80-Remove-Duplicates-from-Sorted-Array-II/README.md: -------------------------------------------------------------------------------- 1 | ### 80\. Remove Duplicates from Sorted Array II 2 | 3 | Follow up for "Remove Duplicates": 4 | What if duplicates are allowed at most *twice*? 5 | 6 | For example, 7 | Given sorted array *nums* = `[1,1,1,2,2,3]`, 8 | 9 | Your function should return length = `5`, with the first five elements of *nums* being `1`, `1`, `2`, `2` and `3`. It doesn't matter what you leave beyond the new length. 10 | 11 | ### 方法(一) 12 | 没什么要说的,用splice方法 -------------------------------------------------------------------------------- /268-Missing-Number/README.md: -------------------------------------------------------------------------------- 1 | ### 268\. Missing Number 2 | 3 | Given an array containing *n* distinct numbers taken from `0, 1, 2, ..., n`, find the one that is missing from the array. 4 | 5 | For example, 6 | Given *nums* = `[0, 1, 3]` return `2`. 7 | 8 | Note: 9 | Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? 10 | 11 | ### 题意 12 | 一个整型数组包含0-n的整型数字,少了其中一个。找出那一个 13 | 14 | ### 方法(一) 15 | 建立一个0-n的整形数组,两个数组合在一起问题有转换成了找单独的数 -------------------------------------------------------------------------------- /34-Search-for-a-Range/README.md: -------------------------------------------------------------------------------- 1 | ### 34\. Search for a Range 2 | 3 | Given a sorted array of integers, find the starting and ending position of a given target value. 4 | 5 | Your algorithm's runtime complexity must be in the order of *O*(log *n*). 6 | 7 | If the target is not found in the array, return `[-1, -1]`. 8 | 9 | For example, 10 | Given `[5, 7, 7, 8, 8, 10]` and target value 8, 11 | return `[3, 4]`. 12 | 13 | ### 方法(一) 14 | 挺简单的,二分搜索到target在数组中的位置后然后再向两边搜索直到不是target为止。第二次搜索也能用二分法。不过我省了 -------------------------------------------------------------------------------- /94-Binary-Tree-Inorder-Traversal/README.md: -------------------------------------------------------------------------------- 1 | ### 94\. Binary Tree Inorder Traversal 2 | 3 | Given a binary tree, return the *inorder* traversal of its nodes' values. 4 | 5 | For example: 6 | Given binary tree `[1,null,2,3]`, 7 | 8 | 1 9 | \ 10 | 2 11 | / 12 | 3 13 | 14 | return `[1,3,2]`. 15 | 16 | Note: Recursive solution is trivial, could you do it iteratively? 17 | 18 | ### 题意 19 | 就是给你一个二叉树,让你以中序遍历的方式输出一个数组。提示中是不想你用递归来做 20 | 21 | ### 方法(一) 22 | 中序遍历非递归的话我用栈来写。 -------------------------------------------------------------------------------- /205-Isomorphic-Strings/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {string} t 4 | * @return {boolean} 5 | */ 6 | var isIsomorphic = function(s, t) { 7 | const hashS = {} 8 | const hashT = {} 9 | 10 | for (let i = 0, len = s.length; i < len; i++) { 11 | if (hashS[s[i]] !== hashT[t[i]]) { 12 | return false 13 | } 14 | 15 | hashS[s[i]] = i 16 | hashT[t[i]] = i 17 | } 18 | return true 19 | }; 20 | 21 | console.log(isIsomorphic('aba', 'baa')) -------------------------------------------------------------------------------- /349-Intersection-of-Two-Arrays/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums1 3 | * @param {number[]} nums2 4 | * @return {number[]} 5 | */ 6 | var intersection = function(nums1, nums2) { 7 | const map = {} 8 | const set = new Set() 9 | 10 | nums1.forEach(value => map[value] = true) 11 | nums2.forEach(value => { 12 | if (map[value]) { 13 | set.add(value) 14 | } 15 | }) 16 | 17 | return Array.from(set) 18 | }; 19 | 20 | console.log(intersection([1,2,3], [2,3,4])) -------------------------------------------------------------------------------- /397-Integer-Replacement/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} n 3 | * @return {number} 4 | */ 5 | var integerReplacement = function(n) { 6 | let step = 0 7 | while (n !== 1) { 8 | if (n % 2 === 0) { 9 | n /= 2 10 | } else if (n === 3) { 11 | n -= 1 12 | } else if ((n & 3) === 3){ 13 | n += 1 14 | } else { 15 | n -= 1 16 | } 17 | step++ 18 | } 19 | return step 20 | }; 21 | 22 | console.log(integerReplacement(7)) -------------------------------------------------------------------------------- /71-Simplify-Path/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} path 3 | * @return {string} 4 | */ 5 | var simplifyPath = function(path) { 6 | const pathArr = path.split('/') 7 | const stack = [] 8 | for (let path of pathArr) { 9 | if (path === '.' || path === '') { 10 | 11 | } else if(path === '..') { 12 | stack.pop() 13 | } else { 14 | stack.push(path) 15 | } 16 | } 17 | return '/' + stack.join('/') 18 | }; 19 | 20 | console.log(simplifyPath('/home/')) -------------------------------------------------------------------------------- /128-Longest-Consecutive-Sequence/README.md: -------------------------------------------------------------------------------- 1 | ### 128\. Longest Consecutive Sequence 2 | 3 | 4 | Given an unsorted array of integers, find the length of the longest consecutive elements sequence. 5 | 6 | For example, 7 | Given `[100, 4, 200, 1, 3, 2]`, 8 | The longest consecutive elements sequence is `[1, 2, 3, 4]`. Return its length: `4`. 9 | 10 | Your algorithm should run in O(*n*) complexity. 11 | 12 | ### 方法(一) 13 | 这题要求复杂度是O(*n*),所以先排序是不对的。这里将数组的元素都放到hash中,然后再迭代数组,如果在hash中存在num+1或者num-1这个key,那么继续找,找到就从数组中删除这个元素。每次中断后记录最长的长度。 -------------------------------------------------------------------------------- /260-Single-Number-III/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number[]} 4 | */ 5 | var singleNumber = function(nums) { 6 | const axorb = nums.reduce((pre, cur) => pre ^ cur) 7 | const last1 = axorb ^ ((axorb - 1) & axorb) 8 | let a = 0 9 | let b = 0 10 | for (let num of nums){ 11 | if ((last1 & num) === 0) { 12 | a ^= num 13 | } else { 14 | b ^= num 15 | } 16 | } 17 | return [a, b] 18 | }; 19 | 20 | console.log(singleNumber([88, 2, 88, 3, 2, 5])) -------------------------------------------------------------------------------- /7-Reverse-Integer/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @return {number} 4 | */ 5 | var reverse = function(x) { 6 | const sign = Math.sign(x) 7 | x = Math.abs(x) 8 | let ret = 0 9 | while (x !== 0) { 10 | ret = ret * 10 + x % 10 11 | x = Math.floor(x / 10) 12 | } 13 | let res = sign * ret 14 | if (res > (Math.pow(2, 31) - 1)) { 15 | res = 0 16 | } else if (res < -Math.pow(2, 31)) { 17 | res = 0 18 | } 19 | return res 20 | }; 21 | 22 | console.log(reverse(1534236469)) -------------------------------------------------------------------------------- /169-Majority-Element/README.md: -------------------------------------------------------------------------------- 1 | ### 169\. Majority Element 2 | 3 | 4 | Given an array of size *n*, find the majority element. The majority element is the element that appears more than `⌊ n/2 ⌋` times. 5 | 6 | You may assume that the array is non-empty and the majority element always exist in the array. 7 | 8 | ### 题意 9 | 找到n大小的数组中出现超过`⌊ n/2 ⌋`次的元素 10 | 11 | ### 方法(一) 12 | 把所有的元素都存到hashmap中,key为元素,value为元素出现的次数 13 | 14 | ### 方法(二) 15 | 因为元素出现的次数超过`⌊ n/2 ⌋`次。所以可以用抵消元素的方法来做。就是一开始假设第一个为的主元素,此时count为1。如果出现和它相同的元素,那么count加1.不同就减去1.当count为0的时候设置当前元素为主元素。 -------------------------------------------------------------------------------- /199-Binary-Tree-Right-Side-View/README.md: -------------------------------------------------------------------------------- 1 | ### 199\. Binary Tree Right Side View 2 | 3 | Given a binary tree, imagine yourself standing on the *right* side of it, return the values of the nodes you can see ordered from top to bottom. 4 | 5 | For example: 6 | Given the following binary tree, 7 | 8 | 1 <--- 9 | / \ 10 | 2 3 <--- 11 | \ \ 12 | 5 4 <--- 13 | 14 | You should return `[1, 3, 4]`. 15 | 16 | ### 题意 17 | 给定一个二叉树,想象自己站在*右侧,返回从顶部到底部可以看到的节点的值。 18 | 19 | ### 方法(一) 20 | 这里用BFS。没什么难度 -------------------------------------------------------------------------------- /26-Remove-Duplicates-from-Sorted-Array/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var removeDuplicates = function(nums) { 6 | const length = nums.length 7 | 8 | if (length < 2) { 9 | return length 10 | } 11 | 12 | let i = 1 13 | while (i < nums.length) { 14 | if (nums[i] === nums[i-1]) { 15 | nums.splice(i, 1) 16 | } else { 17 | i++ 18 | } 19 | } 20 | 21 | return nums.length 22 | }; 23 | 24 | console.log(removeDuplicates([1,1,1])) -------------------------------------------------------------------------------- /1-two-sum/index2.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @param {number[]} nums 4 | * @param {number} target 5 | * @return {number[]} 6 | * 把数组中的元素放到hash表中 7 | */ 8 | 9 | var twoSum = function(nums, target) { 10 | const numsHash = {} 11 | for (let i = 0, len = nums.length, tar; i < len; i++) { 12 | tar = target - nums[i] 13 | if (numsHash[tar] !== undefined) { 14 | return [numsHash[tar], i] 15 | } 16 | numsHash[nums[i]] = i 17 | } 18 | }; 19 | 20 | var nums = [3,2,4], target = 6 21 | console.log(twoSum(nums, target)) -------------------------------------------------------------------------------- /119-Pascal's-Triangle-II/README.md: -------------------------------------------------------------------------------- 1 | ### 119\. Pascal's Triangle II 2 | 3 | 4 | Given an index *k*, return the *k*th row of the Pascal's triangle. 5 | 6 | For example, given *k* = 3, 7 | Return `[1,3,3,1]`. 8 | 9 | Note: 10 | Could you optimize your algorithm to use only *O*(*k*) extra space? 11 | 12 | ### 题意 13 | 给你一个k,返回第k+1行的数组。空间复杂度是*O*(*k*) 14 | 15 | ### 方法(一) 16 | 这里给定了空间复杂度,这就要求我们只能用长度为k的数组。 17 | 1 0 0 0 0 18 | 1 1 0 0 0 19 | 1 2 1 0 0 20 | 1 3 3 1 0 21 | 1 4 6 4 1 22 | 从上面的排列中可以看出,假如此时我们数组中的元素是1 3 3 1,要计算下一行可以从后往前算,a[i]=a[i]+a[i-1]。这样就不会覆盖掉有用的元素了 -------------------------------------------------------------------------------- /169-Majority-Element/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var majorityElement = function(nums) { 6 | let majorCnt = 0 7 | let majorEle 8 | for (let num of nums) { 9 | if (majorCnt === 0) { 10 | majorEle = num 11 | majorCnt++ 12 | } else if (num === majorEle) { 13 | majorCnt++ 14 | } else { 15 | majorCnt-- 16 | } 17 | } 18 | return majorEle 19 | }; 20 | 21 | console.log(majorityElement([1,2,3,5,4,4,2,3,4,4,4,2,4])) -------------------------------------------------------------------------------- /58-Length-of-Last-Word/README.md: -------------------------------------------------------------------------------- 1 | ### 58\. Length of Last Word 2 | 3 | Given a string *s* consists of upper/lower-case alphabets and empty space characters `' '`, return the length of last word in the string. 4 | 5 | If the last word does not exist, return 0. 6 | 7 | Note: A word is defined as a character sequence consists of non-space characters only. 8 | 9 | For example, 10 | Given *s* = `"Hello World"`, 11 | return `5`. 12 | 13 | ### 方法(一) 14 | 从尾部遍历,当遇到空格的时候,如果此时遍历过的字符串的长度大于0,那么结束循环,如果等于0,继续遍历。 15 | 16 | ### 方法(二) 17 | 用trim方法去掉最后面的空格,然后再把字符串转成数组取出最后一个元素 -------------------------------------------------------------------------------- /350-Intersection-of-Two-Arrays-II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums1 3 | * @param {number[]} nums2 4 | * @return {number[]} 5 | */ 6 | var intersect = function(nums1, nums2) { 7 | const map = {} 8 | const arr = [] 9 | 10 | nums1.forEach(value => map[value] = map[value] === undefined ? 1 : ++map[value]) 11 | nums2.forEach((value) => { 12 | if (map[value]) { 13 | map[value]-- 14 | arr.push(value) 15 | } 16 | }) 17 | 18 | return arr 19 | }; 20 | 21 | console.log(intersect([1,2,2,4], [2,3,2,4])) -------------------------------------------------------------------------------- /145-Binary-Tree-Postorder-Traversal/README.md: -------------------------------------------------------------------------------- 1 | ### 145\. Binary Tree Postorder Traversal 2 | 3 | Given a binary tree, return the *postorder* traversal of its nodes' values. 4 | 5 | For example: 6 | Given binary tree `{1,#,2,3}`, 7 | 8 | 1 9 | \ 10 | 2 11 | / 12 | 3 13 | 14 | return `[3,2,1]`. 15 | 16 | Note: Recursive solution is trivial, could you do it iteratively? 17 | 18 | ### 题意 19 | 后序遍历二叉树 20 | 21 | ### 方法(一) 22 | 先序遍历是第一次访问节点的时候把值输出,中序遍历是第二次访问把值输出,后序遍历是第三次访问才把值输出。所以先序是把节点放入栈中的时候把值输出,中序是从栈中弹出节点的时候把值输出,所以后续遍历可以给节点加个标记属性。 -------------------------------------------------------------------------------- /242-Valid-Anagram/index2.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) { 8 | return false 9 | } 10 | 11 | return s.split('').sort().join() === t.split('').sort().join() 12 | }; 13 | 14 | let s = '' 15 | let n = 5000000 16 | let str = 'abcdefghijklmnopqrstuvwxyz' 17 | while (n--) { 18 | s += str[Math.floor(Math.random() * 26)] 19 | } 20 | 21 | let time1 = + new Date() 22 | console.log(isAnagram(s, s)) 23 | console.log(+new Date - time1) -------------------------------------------------------------------------------- /169-Majority-Element/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var majorityElement = function(nums) { 6 | const map = {} 7 | const cnt = Math.floor(nums.length / 2) 8 | 9 | if (cnt === 0) { 10 | return nums[0] 11 | } 12 | 13 | for (let i = 0, len = nums.length; i < len; i++) { 14 | if (map[nums[i]] === undefined) { 15 | map[nums[i]] = 1 16 | } else if (++map[nums[i]] > cnt) { 17 | return nums[i] 18 | } 19 | } 20 | }; 21 | 22 | console.log(majorityElement([1])) -------------------------------------------------------------------------------- /20-Valid-Parentheses/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {boolean} 4 | */ 5 | var isValid = function(s) { 6 | const sArr = s.split('') 7 | const map = { 8 | '{': '}', 9 | '[': ']', 10 | '(': ')', 11 | } 12 | const stack = [] 13 | for (let data of sArr) { 14 | if (map[data] !== undefined) { 15 | stack.push(data) 16 | } else if (map[stack.pop()] !== data) { 17 | return false 18 | } 19 | } 20 | return stack.length === 0 ? true : false 21 | }; 22 | console.log(isValid("({}")) -------------------------------------------------------------------------------- /80-Remove-Duplicates-from-Sorted-Array-II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var removeDuplicates = function(nums) { 6 | const length = nums.length 7 | 8 | if (length < 3) { 9 | return length 10 | } 11 | 12 | let i = 2 13 | while (i < nums.length) { 14 | if (nums[i] === nums[i-1] && nums[i] === nums[i-2]) { 15 | nums.splice(i, 1) 16 | } else { 17 | i++ 18 | } 19 | } 20 | 21 | return nums.length 22 | }; 23 | 24 | console.log(removeDuplicates([1,1,1,2])) -------------------------------------------------------------------------------- /107-Binary-Tree-Level-Order-Traversal-II/README.md: -------------------------------------------------------------------------------- 1 | ### 107\. Binary Tree Level Order Traversal II 2 | 3 | Given a binary tree, return the *bottom-up level order* traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). 4 | 5 | For example: 6 | Given binary tree `[3,9,20,null,null,15,7]`, 7 | 8 | 3 9 | / \ 10 | 9 20 11 | / \ 12 | 15 7 13 | 14 | return its bottom-up level order traversal as: 15 | 16 | [ 17 | [15,7], 18 | [9,20], 19 | [3] 20 | ] 21 | 22 | ### 题意 23 | 和第一题基本一样。把结果的二维数组反转一下就好了 -------------------------------------------------------------------------------- /191-Number-of-1-Bits/README.md: -------------------------------------------------------------------------------- 1 | ### 191\. Number of 1 Bits 2 | 3 | Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the [Hamming weight](http://en.wikipedia.org/wiki/Hamming_weight)). 4 | 5 | For example, the 32-bit integer ’11' has binary representation `00000000000000000000000000001011`, so the function should return 3. 6 | 7 | ### 题意 8 | 求一个32位无符号整数的位中1的个数 9 | 10 | ### 方法(一) 11 | 这道题最容易想到的方法是遍历32位,可行,简单,但是js没有无符号整数的概念,所以对最后一位要单独考虑,比较麻烦。第二种就是把它转成2进制的字符串,把所有的0替换成空字符串后剩下的就是1啦。第三种方法比较难理解,[链接](http://www.matrix67.com/blog/archives/264). -------------------------------------------------------------------------------- /49-Group-Anagrams/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} strs 3 | * @return {string[][]} 4 | */ 5 | var groupAnagrams = function(strs) { 6 | const res = [] 7 | const hash = {} 8 | let key 9 | for (let str of strs) { 10 | key = str.split('').sort().join() 11 | if (hash[key] === undefined) { 12 | hash[key] = res.length 13 | res.push([str]) 14 | } else { 15 | res[hash[key]].push(str) 16 | } 17 | } 18 | return res 19 | }; 20 | 21 | console.log(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"])) -------------------------------------------------------------------------------- /125-Valid-Palindrome/README.md: -------------------------------------------------------------------------------- 1 | ### 125\. Valid Palindrome 2 | 3 | Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 4 | 5 | For example, 6 | `"A man, a plan, a canal: Panama"` is a palindrome. 7 | `"race a car"` is *not* a palindrome. 8 | 9 | Note: 10 | Have you consider that the string might be empty? This is a good question to ask during an interview. 11 | 12 | For the purpose of this problem, we define empty string as valid palindrome. 13 | 14 | ### 题意 15 | 判断是否是回文字符串,但是只要考虑数字字母字符就可以了,而且不用考略大小写。 16 | ### 方法(一) 17 | 简单题。two pointer -------------------------------------------------------------------------------- /142-Linked-List-Cycle-II/README.md: -------------------------------------------------------------------------------- 1 | ### 142\. Linked List Cycle II 2 | 3 | Given a linked list, return the node where the cycle begins. If there is no cycle, return `null`. 4 | 5 | Note: Do not modify the linked list. 6 | 7 | Follow up: 8 | Can you solve it without using extra space? 9 | 10 | ### 题意 11 | 找闭合环路的起点 12 | 13 | ### 方法(一) 14 | 假设A的速度是1,B的速度是2,这个环的长度是n,环之前的长度是k,假设走了x次后能相遇,相遇的时候A绕了e圈,B绕了f圈,其实n肯定是0,A,B第一次相遇与p,可以得出 15 | x = k+en+p 16 | 2x= k+fn+p 17 | 可以得出(f-e)n=k+p 18 | 那么也就是说当他们第一次相遇在p点后,再走k的距离,就能回到闭合环路的起点来。怎么求k呢?当他们第一次相遇后把A或B的指针指向head初始的位置,然后第一次都以1的速度前进,第一次相遇就是环路的起点。 19 | 20 | -------------------------------------------------------------------------------- /118-Pascal's-Triangle/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} numRows 3 | * @return {number[][]} 4 | */ 5 | var generate = function(numRows) { 6 | const res = [] 7 | for (let i = 0, mid; i < numRows; i++) { 8 | mid = Math.floor(i / 2) 9 | for (let j = 0; j <= mid; j++) { 10 | if (j === 0) { 11 | res[i] = [1] 12 | res[i][i] = 1 13 | } else { 14 | res[i][j] = res[i][i - j] = res[i - 1][j - 1] + res[i - 1][j] 15 | } 16 | } 17 | } 18 | return res 19 | }; 20 | 21 | console.log(generate(6)) -------------------------------------------------------------------------------- /179-Largest-Number/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {string} 4 | */ 5 | var largestNumber = function(nums) { 6 | return nums.sort((a, b) => { 7 | return ('' + b + a) - ('' + a + b) 8 | }).join('') .replace(/^0+/, '') || '0' 9 | }; 10 | 11 | console.log(largestNumber([41,23,87,55,50,53,18,9,39,63,35,33,54,25,26,49,74,61,32,81,97,99,38,96,22,95,35,57,80,80,16,22,17,13,89,11,75,98,57,81,69,8,10,85,13,49,66,94,80,25,13,85,55,12,87,50,28,96,80,43,10,24,88,52,16,92,61,28,26,78,28,28,16,1,56,31,47,85,27,30,85,2,30,51,84,50,3,14,97,9,91,90,63,90,92,89,76,76,67,55])) 12 | -------------------------------------------------------------------------------- /219-Contains-Duplicate-II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} k 4 | * @return {boolean} 5 | */ 6 | var containsNearbyDuplicate = function(nums, k) { 7 | const hash = {} 8 | for (let i = 0, len = nums.length; i < len; i++) { 9 | if (hash[nums[i]] === undefined) { 10 | hash[nums[i]] = i 11 | } else { 12 | if (i - hash[nums[i]] <= k) { 13 | return true 14 | } 15 | hash[nums[i]] = i 16 | } 17 | } 18 | return false 19 | }; 20 | 21 | console.log(containsNearbyDuplicate([1,2,3,4,5,2], 6)) -------------------------------------------------------------------------------- /26-Remove-Duplicates-from-Sorted-Array/README.md: -------------------------------------------------------------------------------- 1 | ### 26\. Remove Duplicates from Sorted Array 2 | 3 | Given a sorted array, remove the duplicates in place such that each element appear only *once* and return the new length. 4 | 5 | Do not allocate extra space for another array, you must do this in place with constant memory. 6 | 7 | For example, 8 | Given input array *nums* = `[1,1,2]`, 9 | 10 | Your function should return length = `2`, with the first two elements of *nums* being `1` and `2` respectively. It doesn't matter what you leave beyond the new length. 11 | 12 | ### 方法(一) 13 | 没什么要说的,用splice方法 -------------------------------------------------------------------------------- /137-Single-Number-II/README.md: -------------------------------------------------------------------------------- 1 | ### 137\. Single Number II 2 | 3 | Given an array of integers, every element appears *three* times except for one. Find that single one. 4 | 5 | Note: 6 | Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 7 | 8 | ### 题意 9 | 一个整型数组中,所有的元素都出现三次,除了一个元素只出现一次,找出这个元素 10 | 11 | ### 方法(一) 12 | 把所有数的二进制位对应相加 13 | 1110 14 | 15 | 1110 16 | 17 | 1110 18 | 19 | 1001 20 | 21 | \_\_\_\_\_ 22 | 23 | 4331 对每一位进行求和 24 | 25 | 1001 对每一位的和做%3运算,来消去所有重复3次的数 26 | 这里要注意的是js存储整型用了8个字节,但是能取到最大的数是Math.pow(2,53)-1;但是能参与位运算的只有32。记得最后要转成32位的数字 27 | 28 | -------------------------------------------------------------------------------- /14-Longest-Common-Prefix/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} strs 3 | * @return {string} 4 | */ 5 | var longestCommonPrefix = function(strs) { 6 | if (strs.length === 0) { 7 | return '' 8 | } 9 | let res = '' 10 | for (let i = 0, len = strs[0].length, tmp; i < len; i++) { 11 | tmp = strs[0][i] 12 | for (let j = 1, length = strs.length; j < length; j++) { 13 | if (strs[j][i] !== tmp) { 14 | return res 15 | } 16 | } 17 | res += tmp 18 | } 19 | return res 20 | }; 21 | 22 | console.log(longestCommonPrefix(['abc','ab','abd'])) -------------------------------------------------------------------------------- /383-Ransom-Note/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} ransomNote 3 | * @param {string} magazine 4 | * @return {boolean} 5 | */ 6 | var canConstruct = function(ransomNote, magazine) { 7 | const hash = {} 8 | for (let mag of magazine) { 9 | if (hash[mag]) { 10 | hash[mag]++ 11 | } else { 12 | hash[mag] = 1 13 | } 14 | } 15 | for (let ran of ransomNote) { 16 | if (hash[ran]) { 17 | hash[ran]-- 18 | } else { 19 | return false 20 | } 21 | } 22 | return true 23 | }; 24 | 25 | console.log(canConstruct('a', 'b')) -------------------------------------------------------------------------------- /112-Path-Sum/README.md: -------------------------------------------------------------------------------- 1 | ### 112\. Path Sum 2 | 3 | 4 | Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. 5 | 6 | For example: 7 | Given the below binary tree and `sum = 22`, 8 | 9 | 5 10 | / \ 11 | 4 8 12 | / / \ 13 | 11 13 4 14 | / \ \ 15 | 7 2 1 16 | 17 | return true, as there exist a root-to-leaf path `5->4->11->2` which sum is 22. 18 | 19 | ### 题意 20 | 从二叉树的根到叶子节点找到一条路的和为22. 21 | 22 | ### 方法(一) 23 | DFS -------------------------------------------------------------------------------- /397-Integer-Replacement/README.md: -------------------------------------------------------------------------------- 1 | ### 397\. Integer Replacement 2 | 3 | Given a positive integer *n* and you can do operations as follow: 4 | 5 | 1. If *n* is even, replace *n* with `*n*/2`. 6 | 2. If *n* is odd, you can replace *n* with either `*n* + 1` or `*n* - 1`. 7 | 8 | What is the minimum number of replacements needed for *n* to become 1? 9 | 10 | ### 题意 11 | 给你一个整数n,如果这个整数是偶数,那么可以除以2,如果整数是奇数,那么可以加一或者减一。这样最快多少次后可以变成1 12 | 13 | ### 方法(一) 14 | 从一个数的二进制比如7,...000111去看,要让它变成1,就是要减少1的个数。如8,...0001000,要让他变1就是让他的1右移。归根结底我们就是要减少1的个数和右移1.右移1就是除以2,减少1的个数可以是加1也可以是减去1。看谁减少1的个数多。当末尾有连续两个1以及以上的时候,加1合算。只有末尾一个1的时候减去1更合算。但这个情况要对3特殊考虑。 -------------------------------------------------------------------------------- /389-Find-the-Difference/README.md: -------------------------------------------------------------------------------- 1 | ### 389\. Find the Difference 2 | 3 | Given two strings *s* and *t* which consist of only lowercase letters. 4 | 5 | String *t* is generated by random shuffling string *s* and then add one more letter at a random position. 6 | 7 | Find the letter that was added in *t*. 8 | 9 | Example: 10 | 11 | Input: 12 | s = "abcd" 13 | t = "abcde" 14 | 15 | Output: 16 | e 17 | 18 | Explanation: 19 | 'e' is the letter that was added. 20 | 21 | ### 题意 22 | 字符串s,打乱顺序后再随机插入一个字符组成t。找出插入的那个字符 23 | 24 | ### 方法(一) 25 | 只要把两个字符串连在一起看就能看出来,除了新插入的字符只出现一次,其他字符都出现两次。可以用异或运算来找出单独的一个。解法和136类似 -------------------------------------------------------------------------------- /6-ZigZag-Conversion/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {number} numRows 4 | * @return {string} 5 | */ 6 | var convert = function(s, numRows) { 7 | const resArr = new Array(numRows).fill('') 8 | const loop = numRows * 2 - 2 9 | 10 | if(loop === 0 || s.length <= numRows) { 11 | return s 12 | } 13 | 14 | for (let i = 0, len = s.length, line = 0; i < len; i++) { 15 | line = i % loop 16 | line = (line > numRows - 1) ? (loop - line) : line 17 | resArr[line] += s[i] 18 | } 19 | return resArr.join('') 20 | }; 21 | 22 | console.log(convert("PAYPALISHIRING", 3)) -------------------------------------------------------------------------------- /222-Count-Complete-Tree-Nodes/README.md: -------------------------------------------------------------------------------- 1 | ### 222\. Count Complete Tree Nodes 2 | 3 | 4 | Given a complete binary tree, count the number of nodes. 5 | 6 | Definition of a complete binary tree from [Wikipedia](http://en.wikipedia.org/wiki/Binary_tree#Types_of_binary_trees): 7 | In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. 8 | 9 | ### 题意 10 | 求完全二叉树的节点个数 11 | 12 | ### 方法(一) 13 | 如果当前子树的“极左节点”(从根节点出发一路向左)与“极右节点”(从根节点出发一路向右)的高度h相同,则当前子树为满二叉树,返回2^h - 1 14 | 15 | 否则,递归计算左子树与右子树的节点个数。 -------------------------------------------------------------------------------- /228-Summary-Ranges/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {string[]} 4 | */ 5 | var summaryRanges = function(nums) { 6 | const res = [] 7 | nums.push(Infinity) 8 | for (let begin = 0, end = 1, len = nums.length; end < len; end++) { 9 | if (nums[end] - nums[end - 1] !== 1) { 10 | if (end - begin === 1) { 11 | res.push('' + nums[begin]) 12 | } else { 13 | res.push(nums[begin] + '->' + nums[end - 1]) 14 | } 15 | begin = end 16 | } 17 | } 18 | return res 19 | }; 20 | 21 | console.log(summaryRanges([1,2,3,5,6,9,10])) -------------------------------------------------------------------------------- /103-Binary-Tree-Zigzag-Level-Order-Traversal/README.md: -------------------------------------------------------------------------------- 1 | ### 103\. Binary Tree Zigzag Level Order Traversal 2 | 3 | Given a binary tree, return the *zigzag level order* traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). 4 | 5 | For example: 6 | Given binary tree `[3,9,20,null,null,15,7]`, 7 | 8 | 3 9 | / \ 10 | 9 20 11 | / \ 12 | 15 7 13 | 14 | return its zigzag level order traversal as: 15 | 16 | [ 17 | [3], 18 | [20,9], 19 | [15,7] 20 | ] 21 | 22 | ### 方法(一) 23 | 这道题投机取巧了一把,把102道题加了一个判断如果第n层是奇数就反转该数组 24 | 25 | -------------------------------------------------------------------------------- /113-Path-Sum-II/README.md: -------------------------------------------------------------------------------- 1 | ### 113\. Path Sum II 2 | 3 | Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. 4 | 5 | For example: 6 | Given the below binary tree and `sum = 22`, 7 | 8 | 5 9 | / \ 10 | 4 8 11 | / / \ 12 | 11 13 4 13 | / \ / \ 14 | 7 2 5 1 15 | 16 | return 17 | 18 | [ 19 | [5,4,11,2], 20 | [5,8,4,5] 21 | ] 22 | 23 | ### 题意 24 | 和112不一样的是这题还需要列出具体的路径 25 | 26 | ### 方法(一) 27 | 做法和112基本一样。只不过要多记录每次的路径。这里一个注意点是,用数组记录路径的时候每次递归传参,传的都是同一个数组,必须复制一份再传 -------------------------------------------------------------------------------- /189-Rotate-Array/README.md: -------------------------------------------------------------------------------- 1 | ### 189\. Rotate Array 2 | 3 | Rotate an array of *n* elements to the right by *k* steps. 4 | 5 | For example, with *n* = 7 and *k* = 3, the array `[1,2,3,4,5,6,7]` is rotated to `[5,6,7,1,2,3,4]`. 6 | 7 | Note: 8 | Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. 9 | 10 | [[show hint]](https://leetcode.com/problems/rotate-array/#) 11 | 12 | Related problem: [Reverse Words in a String II](https://leetcode.com/problems/reverse-words-in-a-string-ii/) 13 | 14 | ### 题意 15 | 向右旋转数组,其实一开始我没看懂这个意思。原来就是把最后的元素往开头插 16 | 17 | ### 方法(一) 18 | 把要插的元素先截取下来,然后再插到最前面 -------------------------------------------------------------------------------- /242-Valid-Anagram/README.md: -------------------------------------------------------------------------------- 1 | ### 242\. Valid Anagram 2 | 3 | Given two strings *s* and *t*, write a function to determine if *t* is an anagram of *s*. 4 | 5 | For example, 6 | *s* = "anagram", *t* = "nagaram", return true. 7 | *s* = "rat", *t* = "car", return false. 8 | 9 | Note: 10 | You may assume the string contains only lowercase alphabets. 11 | 12 | Follow up: 13 | What if the inputs contain unicode characters? How would you adapt your solution to such case? 14 | 15 | ### 方法(一) 16 | 因为元素只可能是26中情况,所以可以采用桶排序。时间复杂度是O(n).代码见index.js。在index2.js采用的是系统的sort方法。很奇怪的是在leetcode上竟然还是第二个方法跑的快。sort方法时间复杂度肯定不可能超过O(nlogn)的。所以我对当字符串很大的情况做里测试,确实还是桶排序跑的快。我就放心了。 -------------------------------------------------------------------------------- /134-Gas-Station/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} gas 3 | * @param {number[]} cost 4 | * @return {number} 5 | */ 6 | var canCompleteCircuit = function(gas, cost) { 7 | let sum = 0 8 | for (let i = 0; i < gas.length; i++) { 9 | sum += gas[i] - cost[i] 10 | } 11 | if (sum < 0) { 12 | return -1 13 | } 14 | sum = 0 15 | let res = 0 16 | for (let i = 0; i < gas.length; i++) { 17 | sum += gas[i] - cost[i] 18 | if (sum < 0) { 19 | res = i + 1 20 | sum = 0 21 | } 22 | } 23 | return res 24 | }; 25 | 26 | console.log(canCompleteCircuit([3,4,5], [3,4,5])) -------------------------------------------------------------------------------- /283-Move-Zeroes/index2.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 | let left = 0 7 | let right = 1 8 | 9 | while (right < nums.length) { 10 | if (nums[left] == 0 && nums[right] !== 0) { 11 | [nums[left], nums[right]] = [nums[right], nums[left]] 12 | } else if(nums[left] == 0 && nums[right] === 0) { 13 | right++ 14 | } else { 15 | left++ 16 | right++ 17 | } 18 | } 19 | }; 20 | 21 | var arr = [0,2,1,5] 22 | moveZeroes(arr) 23 | console.log(arr) -------------------------------------------------------------------------------- /129-Sum-Root-to-Leaf-Numbers/README.md: -------------------------------------------------------------------------------- 1 | ### 129\. Sum Root to Leaf Numbers 2 | 3 | Given a binary tree containing digits from `0-9` only, each root-to-leaf path could represent a number. 4 | 5 | An example is the root-to-leaf path `1->2->3` which represents the number `123`. 6 | 7 | Find the total sum of all root-to-leaf numbers. 8 | 9 | For example, 10 | 11 | 1 12 | / \ 13 | 2 3 14 | 15 | The root-to-leaf path `1->2` represents the number `12`. 16 | The root-to-leaf path `1->3` represents the number `13`. 17 | 18 | Return the sum = 12 + 13 = `25`. 19 | 20 | ### 题意 21 | 计算二叉树所欲从根到叶子组成的树的和 22 | 23 | ### 方法(一) 24 | 一个套路。DFS把所有的值都求出来 -------------------------------------------------------------------------------- /229-Majority-Element-II/README.md: -------------------------------------------------------------------------------- 1 | ### 229\. Majority Element II 2 | 3 | Given an integer array of size *n*, find all elements that appear more than `⌊ n/3 ⌋` times. The algorithm should run in linear time and in O(1) space. 4 | 5 | Hint: 6 | 7 | 1. How many majority elements could it possibly have? 8 | 2. Do you have a better hint? [Suggest it](mailto:admin@leetcode.com?subject=Hints%20for%20Majority%20Element%20II)! 9 | 10 | ### 题意 11 | 从一个长度为n的数组中找到超过`⌊ n/3 ⌋`次的元素,可能没有。要求时间复杂度是O(n),空间复杂度是O(1);照理来说空间复杂度是常量的话,那么hash表的解决方法应该是不能用了。但是看到discuss中有人用hash表解决也是挺奇怪的。 12 | 13 | ### 方法(一) 14 | 因为元素出现的次数要超过`⌊ n/3 ⌋`次,所以这样的元素最多两个。原理和169中的方法(二)一样。只不过这里要设置两个候选主元素,两个count。 -------------------------------------------------------------------------------- /102-Binary-Tree-Level-Order-Traversal/README.md: -------------------------------------------------------------------------------- 1 | ### 102\. Binary Tree Level Order Traversal 2 | 3 | Given a binary tree, return the *level order* traversal of its nodes' values. (ie, from left to right, level by level). 4 | 5 | For example: 6 | Given binary tree `[3,9,20,null,null,15,7]`, 7 | 8 | 3 9 | / \ 10 | 9 20 11 | / \ 12 | 15 7 13 | 14 | return its level order traversal as: 15 | 16 | [ 17 | [3], 18 | [9,20], 19 | [15,7] 20 | ] 21 | 22 | ### 题意 23 | 按层遍历二叉树并返回二维数组中的结构 24 | 25 | ### 方法(一) 26 | 首先想到的就是BFS啊。麻烦一点的就是要记录第几层。这里用了两个队列。queue1如果有9,20两个节点。那么循环出队queue1.把出队节点的左右子节点放到queue2中。也就是15,7 -------------------------------------------------------------------------------- /101-Symmetric-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 101\. Symmetric Tree 2 | 3 | 4 | Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). 5 | 6 | For example, this binary tree `[1,2,2,3,4,4,3]` is symmetric: 7 | 8 | 1 9 | / \ 10 | 2 2 11 | / \ / \ 12 | 3 4 4 3 13 | 14 | But the following `[1,2,2,null,3,null,3]` is not: 15 | 16 | 1 17 | / \ 18 | 2 2 19 | \ \ 20 | 3 3 21 | 22 | Note: 23 | Bonus points if you could solve it both recursively and iteratively. 24 | 25 | ### 题意 26 | 判断一颗树是否对称(照镜子后是否一样),要求用递归和迭代都实现 27 | 28 | ### 方法(一) 29 | 递归实现。和100题基本一样 30 | ### 方法(二) 31 | 迭代实现 -------------------------------------------------------------------------------- /2-Add-Two-Numbers/README.md: -------------------------------------------------------------------------------- 1 | ### 2\. Add Two Numbers 2 | 3 | You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. 4 | 5 | Input: (2 -\> 4 -\> 3) + (5 -\> 6 -\> 4) 6 | Output: 7 -\> 0 -\> 8 7 | 8 | ### 方法(一) 9 | 题目意思就是两个链表代表了两个整数做加法,第一个是最低位个位,第二个是十位。。。依次,和正常的数字刚好相反,因为正常数字第一个数是最高位。再注意一下进制就可以了 10 | 3 4 5 11 | 3 1 4 12 | 13 | res = new node(6) 14 | head = res 15 | tail = res 16 | 17 | res = new node(5) 18 | tail.next = res 19 | tail = res 20 | 21 | 22 | res = new node(9) 23 | tail.next = res 24 | tail = res 25 | 26 | -------------------------------------------------------------------------------- /6-ZigZag-Conversion/README.md: -------------------------------------------------------------------------------- 1 | ### 6\. ZigZag Conversion 2 | 3 | The string `"PAYPALISHIRING"` is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) 4 | 5 | P A H N 6 | A P L S I I G 7 | Y I R 8 | 9 | And then read line by line: `"PAHNAPLSIIGYIR"` 10 | 11 | Write the code that will take a string and make this conversion given a number of rows: 12 | 13 | string convert(string text, int nRows); 14 | 15 | `convert("PAYPALISHIRING", 3)` should return `"PAHNAPLSIIGYIR"`. 16 | 17 | ### 方法(一) 18 | 建立一个二维数组,然后一个往里写数据,但是Memory Limit Exceeded了。 19 | 20 | ### 方法(二) 21 | 找规律。 -------------------------------------------------------------------------------- /74-Search-a-2D-Matrix/README.md: -------------------------------------------------------------------------------- 1 | ### 74\. Search a 2D Matrix 2 | 3 | Write an efficient algorithm that searches for a value in an *m* x *n* matrix. This matrix has the following properties: 4 | 5 | * Integers in each row are sorted from left to right. 6 | * The first integer of each row is greater than the last integer of the previous row. 7 | 8 | For example, 9 | 10 | Consider the following matrix: 11 | 12 | [ 13 | [1, 3, 5, 7], 14 | [10, 11, 16, 20], 15 | [23, 30, 34, 50] 16 | ] 17 | 18 | Given target = `3`, return `true`. 19 | 20 | ### 方法(一) 21 | 把二维数组转换成一维的再用二分法找,代码见index.js 22 | 23 | ### 方法(二) 24 | 先对第一列二分查找,找到target在那一行后再对那一行二分查找,代码见index2.js -------------------------------------------------------------------------------- /11-Container-With-Most-Water/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} height 3 | * @return {number} 4 | */ 5 | var maxArea = function(height) { 6 | let left = 0 7 | let right = height.length - 1 8 | let maxArea = 0 9 | 10 | while (left < right) { 11 | maxArea = Math.max(maxArea, (right - left) * Math.min(height[left], height[right])) 12 | 13 | if (height[left] > height[right]) { 14 | right-- 15 | } else if (height[left] < height[right]) { 16 | left++ 17 | } else { 18 | left++ 19 | right-- 20 | } 21 | } 22 | return maxArea 23 | 24 | }; 25 | 26 | 27 | console.log(maxArea([1,1])) -------------------------------------------------------------------------------- /3-Longest-Substring-Without-Repeating-Characters/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | var lengthOfLongestSubstring = function(s) { 6 | let left = 0 7 | let maxLen = 0 8 | const hash = {} 9 | 10 | for (let right = 0, len = s.length, tmpHashVal; right < len; right++) { 11 | tmpHashVal = hash[s[right]] 12 | if (tmpHashVal === undefined || tmpHashVal < left) { 13 | maxLen = Math.max(maxLen, right - left + 1) 14 | } else { 15 | left = tmpHashVal + 1 16 | } 17 | hash[s[right]] = right 18 | } 19 | return maxLen 20 | }; 21 | 22 | console.log(lengthOfLongestSubstring('abbca')) -------------------------------------------------------------------------------- /35-Search-Insert-Position/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} target 4 | * @return {number} 5 | */ 6 | function bSearchRange(arr, target) { 7 | let low = 0 8 | let high = arr.length - 1 9 | while (low <= high) { 10 | let mid = Math.floor((low + high) / 2) 11 | if (target > arr[mid]) { 12 | low = mid + 1 13 | } else if (target < arr[mid]) { 14 | high = mid - 1 15 | } else { 16 | return mid 17 | } 18 | } 19 | return low 20 | } 21 | var searchInsert = function(nums, target) { 22 | return bSearchRange(nums, target) 23 | }; 24 | 25 | console.log(searchInsert([1,3,5,6], 2)) -------------------------------------------------------------------------------- /67-Add-Binary/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} a 3 | * @param {string} b 4 | * @return {string} 5 | */ 6 | /** 7 | var addBinary = function(a, b) { 8 | const aInt = parseInt(a, 2) 9 | const bInt = parseInt(b, 2) 10 | return (aInt + bInt).toString(2) 11 | }; 12 | */ 13 | 14 | var addBinary = function(a, b) { 15 | let carry = 0 16 | let sum 17 | let res = [] 18 | for (let i = a.length - 1, j = b.length - 1; a[i] || b[j] || carry; i--, j--) { 19 | sum = carry + +(a[i] || 0) + +(b[j] || 0) 20 | carry = Math.floor(sum / 2) 21 | res.unshift(sum % 2) 22 | } 23 | 24 | return res.join('') 25 | }; 26 | 27 | console.log(addBinary('11', '1')) -------------------------------------------------------------------------------- /11-Container-With-Most-Water/README.md: -------------------------------------------------------------------------------- 1 | ### 11\. Container With Most Water 2 | 3 | Given *n* non-negative integers *a1*, *a2*, ..., *an*, where each represents a point at coordinate (*i*, *ai*). *n* vertical lines are drawn such that the two endpoints of line *i* is at (*i*, *ai*) and (*i*, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. 4 | 5 | Note: You may not slant the container. 6 | 7 | ### 方法(一) 8 | 题意是x轴上在1,2,...,n点上有许多垂直的线段,长度依次是a1, a2, ..., an。找出两条线段能围成的最大面积。这是一个矩形,就像往其中灌水,能最多灌到高短的一边。公式是S(i,j) = min(ai, aj) * (j-i) 9 | 这里采用的算法是,双指针头尾扫描,如果a[left] 1, `nums`, return an array `output` such that `output[i]` is equal to the product of all the elements of `nums` except `nums[i]`. 4 | 5 | Solve it without division and in O(*n*). 6 | 7 | For example, given `[1,2,3,4]`, return `[24,12,8,6]`. 8 | 9 | Follow up: 10 | Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.) 11 | 12 | ### 题意 13 | 求一个整型数组的中每个元素除自身外其他所有数的乘积。 14 | 15 | ### 方法(一) 16 | 很容易想到的方法是,把所有数相乘然后除以当前数就可以了。这里比较麻烦的是0的情况,所以我对0分情况讨论了。总共三种情况 17 | 1. 没有0 18 | 2. 有且只有一个0 19 | 3. 有两个0 -------------------------------------------------------------------------------- /316-Remove-Duplicate-Letters/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {string} 4 | */ 5 | var removeDuplicateLetters = function(s) { 6 | const map = {} 7 | for (let i of s) { 8 | map[i] = map[i] ? map[i] + 1 : 1 9 | } 10 | 11 | const stack = [] 12 | for (let i of s) { 13 | if (!stack.includes(i)) { 14 | let top = stack[stack.length - 1] 15 | while (top > i && map[top] > 0) { 16 | stack.pop() 17 | top = stack[stack.length - 1] 18 | } 19 | stack.push(i) 20 | } 21 | map[i]-- 22 | } 23 | return stack.join('') 24 | }; 25 | 26 | console.log(removeDuplicateLetters('cbacdcbc')) -------------------------------------------------------------------------------- /3-Longest-Substring-Without-Repeating-Characters/README.md: -------------------------------------------------------------------------------- 1 | 1. ### 3\. Longest Substring Without Repeating Characters 2 | 3 | Given a string, find the length of the longest substring without repeating characters. 4 | 5 | Examples: 6 | 7 | Given `"abcabcbb"`, the answer is `"abc"`, which the length is 3. 8 | 9 | Given `"bbbbb"`, the answer is `"b"`, with the length of 1. 10 | 11 | Given `"pwwkew"`, the answer is `"wke"`, with the length of 3\. Note that the answer must be a substring, `"pwke"` is a *subsequence* and not a substring. 12 | 13 | ### 方法(一) 14 | 在遍历字符串的时候,用left记录最长字长字符串的首字符位置,len记录长度。hash的key记录出现过的字符,value记录字符的位置。 15 | 有两种情况len的值可能会发生变化,一种是遍历的时候当前字符在hash中没找到,第二种时找到了但是hash的value要小于left。 16 | 其余情况改变left到合适的位置 -------------------------------------------------------------------------------- /406-Queue-Reconstruction-by-Height/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} people 3 | * @return {number[][]} 4 | */ 5 | var reconstructQueue = function(people) { 6 | people.sort((a, b) => { 7 | if (a[0] > b[0]) { 8 | return -1 9 | } else if (a[0] < b[0]) { 10 | return 1 11 | } 12 | if (a[1] > b[1]) { 13 | return 1 14 | } else if (a[1] < b[1]) { 15 | return -1 16 | } 17 | return 0 18 | }) 19 | 20 | const res = [] 21 | people.forEach(value => { 22 | res.splice(value[1], 0, value) 23 | }) 24 | 25 | return res 26 | }; 27 | 28 | console.log(reconstructQueue([[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]])) -------------------------------------------------------------------------------- /128-Longest-Consecutive-Sequence/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var longestConsecutive = function(nums) { 6 | const hash = {} 7 | nums.forEach((value) => hash[value] = true) 8 | let i = 0 9 | let j = 0 10 | let maxLen = 0 11 | for (let num of nums) { 12 | i = j = num 13 | while (hash[j + 1] || hash[i - 1]) { 14 | if (hash[j + 1]) { 15 | nums.splice(++j, 1) 16 | } 17 | if (hash[i - 1]) { 18 | nums.splice(--i, 1) 19 | } 20 | } 21 | maxLen = Math.max(maxLen, j - i + 1) 22 | } 23 | return maxLen 24 | }; 25 | 26 | console.log(longestConsecutive([0])) 27 | -------------------------------------------------------------------------------- /73-Set-Matrix-Zeroes/README.md: -------------------------------------------------------------------------------- 1 | ### 73\. Set Matrix Zeroes 2 | 3 | Given a *m* x *n* matrix, if an element is 0, set its entire row and column to 0\. Do it in place. 4 | 5 | 6 | Follow up: 7 | 8 | Did you use extra space? 9 | A straight forward solution using O(*m**n*) space is probably a bad idea. 10 | A simple improvement uses O(*m* + *n*) space, but still not the best solution. 11 | Could you devise a constant space solution? 12 | 13 | ### 方法(一) 14 | 1. 先确定第一行和第一列是否需要清零 15 | 2. 扫描剩下的矩阵元素,如果遇到了0,就将对应的第一行和第一列上的元素赋值为0 16 | 3. 根据第一行和第一列的信息,已经可以讲剩下的矩阵元素赋值为结果所需的值了 17 | 4. 根据1中确定的状态,处理第一行和第一列。 18 | 19 | ### 方法(二) 20 | 这个方法比较有趣,应该是js的专利。js中0和-0是有区别的,虽然0 === -0但是1/0=Infinity,而1/-0=-Infinity,根据这个区别,我们只要把等于0的那一行列都赋值成-0就可以了。相当简单见代码index2.js -------------------------------------------------------------------------------- /190-Reverse-Bits/README.md: -------------------------------------------------------------------------------- 1 | ### 190\. Reverse Bits 2 | 3 | Reverse bits of a given 32 bits unsigned integer. 4 | 5 | For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000). 6 | 7 | Follow up: 8 | If this function is called many times, how would you optimize it? 9 | 10 | Related problem: [Reverse Integer](https://leetcode.com/problems/reverse-integer/) 11 | 12 | ### 题意 13 | 反转无符号整数的位 14 | 15 | ### 方法(一) 16 | 这道题如果你有c,c++,java这样的语言来写是很简单的一道题目,因为这些语言都有无符号整数的类型。但是js没有。所以说我当时写出来后数字大于Math.pow(2,31)后就会出错。因为js的整数是有符号的。首位是符号位。看到一些答案的方法转成二进制字符串后再反转补0.确实可以这么做。完全没有问题。不过我看到一个答案很机智,他循环右移了31位,最后一位特殊判断。 17 | 好吧。根本不机智。对一个有符号数做 >>> 0运算就成无符号数了 -------------------------------------------------------------------------------- /283-Move-Zeroes/README.md: -------------------------------------------------------------------------------- 1 | ### 283\. Move Zeroes 2 | 3 | Given an array `nums`, write a function to move all `0`'s to the end of it while maintaining the relative order of the non-zero elements. 4 | 5 | For example, given `nums = [0, 1, 0, 3, 12]`, after calling your function, `nums` should be `[1, 3, 12, 0, 0]`. 6 | 7 | Note: 8 | 9 | 1. You must do this in-place without making a copy of the array. 10 | 2. Minimize the total number of operations. 11 | 12 | 13 | ### 题意 14 | 把数组中的所有0移到最后 15 | 16 | ### 方法(一) 17 | 记录数组的长度,把数组中的0全部删掉,然后再往后补0。代码见index.js 18 | 19 | ### 方法(二) 20 | 双指针扫描,left=0,right=1 21 | 三种情况 22 | 1. nums[left]=0,nums[right]!=0,交换两个数 23 | 2. nums[left]=0,nums[right]=0,right++ 24 | 3. 其他都right++ left++ 25 | 26 | 27 | -------------------------------------------------------------------------------- /226-Invert-Binary-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 226\. Invert Binary Tree 2 | 3 | Invert a binary tree. 4 | 5 | 4 6 | / \ 7 | 2 7 8 | / \ / \ 9 | 1 3 6 9 10 | 11 | to 12 | 13 | 4 14 | / \ 15 | 7 2 16 | / \ / \ 17 | 9 6 3 1 18 | 19 | Trivia: 20 | This problem was inspired by [this original tweet](https://twitter.com/mxcl/status/608682016205344768) by [Max Howell](https://twitter.com/mxcl): 21 | 22 | > Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off. 23 | 24 | ### 题意 25 | 反转一下二叉树。 26 | 27 | ### 方法(一) 28 | 首先看完题直接能写出A过的都应该骄傲一下。因为Homebrew的作者竟然没写出来。刚开始我是用BFS来写,比较复杂。 29 | 30 | ### 方法(二) 31 | 递归的方式 -------------------------------------------------------------------------------- /28-Implement-strStr()/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} haystack 3 | * @param {string} needle 4 | * @return {number} 5 | */ 6 | var strStr = function(haystack, needle) { 7 | if (needle === '') { 8 | return 0 9 | } 10 | let pos = -1 11 | for (let i = 0, j = 0, len = haystack.length; i < len; i++) { 12 | if (haystack[i] === needle[j]) { 13 | if (j++ === 0) { 14 | pos = i 15 | } 16 | } else { 17 | if (j !== 0) { 18 | i = pos 19 | j = 0 20 | } 21 | } 22 | if (j === needle.length) { 23 | return pos 24 | } 25 | } 26 | return -1 27 | }; 28 | 29 | console.log(strStr('a', 'a')) -------------------------------------------------------------------------------- /316-Remove-Duplicate-Letters/README.md: -------------------------------------------------------------------------------- 1 | ### 316\. Remove Duplicate Letters 2 | 3 | Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results. 4 | 5 | Example: 6 | 7 | Given `"bcabc"` 8 | Return `"abc"` 9 | 10 | Given `"cbacdcbc"` 11 | Return `"acdb"` 12 | 13 | ### 题意 14 | 给定一个仅包含小写字母的字符串,删除重复的字母,以便每个字母只出现一次。 您必须确保您的结果是所有可能结果中最小的词典顺序。 15 | 16 | 例: 17 | 给定“bcabc” 18 | 返回“abc” 19 | 20 | 给定“cbacdcbc” 21 | 返回“acdb” 22 | 23 | ### 方法(一) 24 | 首先对字符串出现的个数进行统计。 25 | 26 | 然后对字符串扫描,每遇到一个字符串,判断其是否在栈中,如果在则跳过。(计数 – 1) 27 | 28 | 如果不在栈中,和栈顶的元素判断,要是当前栈顶的元素比较大而且cnt不为0(也就是说之后还有这个元素),就把栈顶弹出。然后把当前的元素入栈。 -------------------------------------------------------------------------------- /135-Candy/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} ratings 3 | * @return {number} 4 | */ 5 | var candy = function(ratings) { 6 | const length = ratings.length 7 | const resArr = new Array(length) 8 | resArr[0] = 1 9 | 10 | for (let i = 0; i < length - 1; i++) { 11 | if (ratings[i] < ratings[i + 1]) { 12 | resArr[i + 1] = resArr[i] + 1 13 | } else { 14 | resArr[i + 1] = 1 15 | } 16 | } 17 | 18 | for (let i = length - 1; i > 0; i--) { 19 | if (ratings[i] < ratings[i - 1]) { 20 | resArr[i - 1] = Math.max(resArr[i] + 1, resArr[i - 1]) 21 | } 22 | } 23 | 24 | return resArr.reduce((pre, cur) => pre + cur, 0) 25 | }; 26 | 27 | console.log(candy([1,2,2,3,3,4])) -------------------------------------------------------------------------------- /55-Jump-Game/README.md: -------------------------------------------------------------------------------- 1 | ### 55\. Jump Game 2 | 3 | Given an array of non-negative integers, you are initially positioned at the first index of the array. 4 | 5 | Each element in the array represents your maximum jump length at that position. 6 | 7 | Determine if you are able to reach the last index. 8 | 9 | For example: 10 | A = `[2,3,1,1,4]`, return `true`. 11 | 12 | A = `[3,2,1,0,4]`, return `false`. 13 | 14 | ### 题意 15 | 给定一个非负整数数组,你最初被定位在数组的第一个索引。 16 | 17 | 数组中的每个元素表示在该位置的最大跳跃长度。 18 | 19 | 确定是否能够达到最后一个索引。 20 | 21 | 例如: 22 | 23 | A = `[2,3,1,1,4]`,return `true`。 24 | 25 | A = `[3,2,1,0,4]`,return `false`。 26 | 27 | ### 方法(一) 28 | 贪心题目。每次跳的时候都应该选择最优的。最优就是你在这点起跳能跳最远的。方法一就是很普通的解法 29 | ### 方法(二) 30 | 讨论里看到的,倒着遍历,但跳的方向不变,记录能跳的最近距离,如果最近距离为0,那说明所有的位置都能到。 -------------------------------------------------------------------------------- /318-Maximum-Product-of-Word-Lengths/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} words 3 | * @return {number} 4 | */ 5 | var maxProduct = function(words) { 6 | const bitArr = words.map((value) => { 7 | let bit = 0 8 | for (let val of value) { 9 | bit |= 1 << (val.codePointAt() - 97) 10 | } 11 | return bit 12 | }) 13 | 14 | let max = 0 15 | for (let i = 0, len = bitArr.length; i < len - 1; i++) { 16 | for (let j = i + 1; j < len; j++) { 17 | if ((bitArr[i] & bitArr[j]) === 0) { 18 | max = Math.max(max, words[i].length * words[j].length) 19 | } 20 | } 21 | } 22 | return max 23 | }; 24 | console.log(maxProduct(["abcw", "baz", "foo", "bar", "xtfn", "abcdef"])) -------------------------------------------------------------------------------- /125-Valid-Palindrome/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {boolean} 4 | */ 5 | var isPalindrome = function(s) { 6 | let flag = true 7 | let left = 0 8 | let right = s.length - 1 9 | while (left < right) { 10 | if (!s[left].match(/[a-zA-Z0-9]/)) { 11 | left++ 12 | continue 13 | } 14 | if (!s[right].match(/[a-zA-Z0-9]/)) { 15 | right-- 16 | continue 17 | } 18 | if (s[left].toLowerCase() !== s[right].toLowerCase()) { 19 | flag = false 20 | break 21 | } else { 22 | right-- 23 | left++ 24 | } 25 | } 26 | return flag 27 | }; 28 | 29 | console.log(isPalindrome("A man, a plan, a canal: Panama")) -------------------------------------------------------------------------------- /141-Linked-List-Cycle/README.md: -------------------------------------------------------------------------------- 1 | ### 141\. Linked List Cycle 2 | 3 | Given a linked list, determine if it has a cycle in it. 4 | 5 | Follow up: 6 | Can you solve it without using extra space? 7 | 8 | ### 题意 9 | 判断一个链表是否有一个闭合环路。 10 | 11 | ### 方法(一) 12 | 声明两个指针,一个指针的速度是1,一个指针的速度是2,如果是闭合的那么第二个指针一定会在一段时间后和第一个重合。如果不是闭合的,那么第二个一定先到达终点 13 | 其实大家不显麻烦还能证明一下为什么有一个闭合环路就一定能相遇。 14 | ![1](https://github.com/fa-ge/leetcodeAlgorithms/blob/master/141-Linked-List-Cycle/1.png) 15 | 假设假设A的速度是1,B的速度是2,这个环的长度是n,环之前的长度是k,假设走了x次后能相遇 16 | 图一中,A,B同时从同一个点出发,那么当第一次相遇的时候B一定比A多走n的距离。因为B要超上A一圈才能相遇吧,所以肯定多走了一圈。 17 | 图二中,A,B同时从不同位置出发,那么B一定比A要走B离A的距离 18 | 图三中,A,B同时从同一个点出发,但这个点不在圆上,也就是说当A到达O点的位置的时候,B已经多走了K的距离。此时A和B相差就是n-k%n;此时B要比A多走这点距离才能第一次赶上A。当B赶上A的时候,A总共走了,当赶上的时候A其实总共走了k+n-k%n=x。因为k,n都是已知的数,所以x一定能得出来 -------------------------------------------------------------------------------- /71-Simplify-Path/README.md: -------------------------------------------------------------------------------- 1 | ### 71\. Simplify Path 2 | 3 | Given an absolute path for a file (Unix-style), simplify it. 4 | 5 | For example, 6 | path = `"/home/"`, =\> `"/home"` 7 | path = `"/a/./b/../../c/"`, =\> `"/c"` 8 | 9 | [click to show corner cases.](https://leetcode.com/problems/simplify-path/#) 10 | 11 | Corner Cases: 12 | 13 | * Did you consider the case where path = `"/../"`? 14 | In this case, you should return `"/"`. 15 | * Another corner case is the path might contain multiple slashes `'/'` together, such as `"/home//foo/"`. 16 | In this case, you should ignore redundant slashes and return `"/home/foo"`. 17 | 18 | ### 题意 19 | 给你一个绝对路径,简化它。 20 | 21 | ### 方法(一) 22 | 把路径字符串分割成数组,四种情况 23 | 1. '', 不管 24 | 2. '..', 出栈 25 | 3. '.', 不管 26 | 4. 其他入栈 27 | 最后注意再开头加上'/' -------------------------------------------------------------------------------- /187-Repeated-DNA-Sequences/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {string[]} 4 | */ 5 | var findRepeatedDnaSequences = function(s) { 6 | const map = new Set() 7 | const set = new Set() 8 | const wordToBit = { 9 | A: '00', 10 | C: '01', 11 | G: '10', 12 | T: '11', 13 | } 14 | const bitStr = s.replace(/A|C|G|T/g, a => wordToBit[a]) 15 | for (let i = 0, len = bitStr.length, tmpKey; i <= len - 20; i += 2) { 16 | tmpKey = +('0b' + bitStr.substr(i, 20)) 17 | if (map.has(tmpKey)) { 18 | set.add(s.substr(i / 2, 10)) 19 | } else { 20 | map.add(tmpKey) 21 | } 22 | } 23 | return Array.from(set) 24 | }; 25 | 26 | console.log(findRepeatedDnaSequences("AAAAAAAAAA")) -------------------------------------------------------------------------------- /27-Remove-Element/README.md: -------------------------------------------------------------------------------- 1 | ### 27\. Remove Element 2 | 3 | 4 | Given an array and a value, remove all instances of that value in place and return the new length. 5 | 6 | Do not allocate extra space for another array, you must do this in place with constant memory. 7 | 8 | The order of elements can be changed. It doesn't matter what you leave beyond the new length. 9 | 10 | Example: 11 | Given input array *nums* = `[3,2,2,3]`, *val* = `3` 12 | 13 | Your function should return length = 2, with the first two elements of *nums* being 2. 14 | 15 | Hint: 16 | 17 | 1. Try two pointers. 18 | 2. Did you use the property of "the order of elements can be changed"? 19 | 3. What happens when the elements to remove are rare? 20 | 21 | ### 方法(一) 22 | 遍历删除元素,js没有java那样的迭代器可以在迭代中删除元素,不过可以倒着遍历数组 -------------------------------------------------------------------------------- /350-Intersection-of-Two-Arrays-II/README.md: -------------------------------------------------------------------------------- 1 | ### 350\. Intersection of Two Arrays II 2 | 3 | Given two arrays, write a function to compute their intersection. 4 | 5 | Example: 6 | Given *nums1* = `[1, 2, 2, 1]`, *nums2* = `[2, 2]`, return `[2, 2]`. 7 | 8 | Note: 9 | 10 | * Each element in the result should appear as many times as it shows in both arrays. 11 | * The result can be in any order. 12 | 13 | Follow up: 14 | 15 | * What if the given array is already sorted? How would you optimize your algorithm? 16 | * What if *nums1*'s size is small compared to *nums2*'s size? Which algorithm is better? 17 | * What if elements of *nums2* are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once? 18 | 19 | ### 方法(一) 20 | 和349基本一样。扩展久没写了 -------------------------------------------------------------------------------- /393-UTF-8-Validation/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} data 3 | * @return {boolean} 4 | */ 5 | var validUtf8 = function(data) { 6 | let cnt = 0 7 | for (let val of data) { 8 | if (cnt === 0) { 9 | if ((val >> 3) === 0b11110) { 10 | cnt = 3 11 | } else if ((val >> 4) === 0b1110) { 12 | cnt = 2 13 | } else if ((val >> 5) === 0b110) { 14 | cnt = 1 15 | } else if ((val >> 7) !== 0) { 16 | return false 17 | } 18 | } else { 19 | if ((val >> 6) !== 0b10) { 20 | return false 21 | } 22 | cnt-- 23 | } 24 | } 25 | return cnt === 0 26 | }; 27 | 28 | console.log(validUtf8([237])) -------------------------------------------------------------------------------- /55-Jump-Game/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {boolean} 4 | */ 5 | var canJump = function(nums) { 6 | function getBestIndex(nums, start, end) { 7 | let bestIndex = start 8 | for (let i = start + 1, best = nums[start] + start; i <= end && i < nums.length; i++) { 9 | if (nums[i] + i >= best) { 10 | bestIndex = i 11 | best = nums[i] + i 12 | } 13 | } 14 | return bestIndex 15 | } 16 | 17 | let n = 0 18 | while (n + nums[n] < nums.length - 1) { 19 | n = getBestIndex(nums, n, n + nums[n]) 20 | if (nums[n] === 0) { 21 | return false 22 | } 23 | } 24 | 25 | return true 26 | }; 27 | 28 | console.log(canJump([3,2,1,0,4])) -------------------------------------------------------------------------------- /240-Search-a-2D-Matrix II/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @param {number} target 4 | * @return {boolean} 5 | */ 6 | var searchMatrix = function(matrix, target) { 7 | let rowLen = matrix.length 8 | let colLen = matrix[0].length 9 | let row = rowLen - 1 10 | let col = 0 11 | while (row >= 0 && col < colLen) { 12 | if (target > matrix[row][col]) { 13 | col++ 14 | } else if (target < matrix[row][col]) { 15 | row-- 16 | } else { 17 | return true 18 | } 19 | } 20 | return false 21 | }; 22 | 23 | console.log(searchMatrix([ 24 | [1, 4, 7, 11, 15], 25 | [2, 5, 8, 12, 19], 26 | [3, 6, 9, 16, 22], 27 | [10, 13, 14, 17, 24], 28 | [18, 21, 23, 26, 30] 29 | ], 5)) -------------------------------------------------------------------------------- /242-Valid-Anagram/index.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) { 8 | return false 9 | } 10 | 11 | const sArr = new Array(26).fill('') 12 | const tArr = new Array(26).fill('') 13 | 14 | for (let i = 0; i < s.length; i++) { 15 | sArr[s[i].charCodeAt() - 97] += s[i] 16 | tArr[t[i].charCodeAt() - 97] += t[i] 17 | } 18 | 19 | return sArr.join() === tArr.join() 20 | }; 21 | 22 | let s = '' 23 | let n = 5000000 24 | let str = 'abcdefghijklmnopqrstuvwxyz' 25 | while (n--) { 26 | s += str[Math.floor(Math.random() * 26)] 27 | } 28 | 29 | let time1 = + new Date() 30 | console.log(isAnagram(s, s)) 31 | console.log(+new Date - time1) -------------------------------------------------------------------------------- /287-Find-the-Duplicate-Number/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var findDuplicate = function(nums) { 6 | let oneSpeedPointer = 0 7 | let twoSpeedPointer = 0 8 | while (nums[twoSpeedPointer] !== undefined) { 9 | oneSpeedPointer = nums[oneSpeedPointer] 10 | twoSpeedPointer = nums[nums[twoSpeedPointer]] 11 | if (oneSpeedPointer === twoSpeedPointer) { 12 | oneSpeedPointer = 0 13 | break 14 | } 15 | } 16 | 17 | while (nums[oneSpeedPointer] !== nums[twoSpeedPointer]) { 18 | oneSpeedPointer = nums[oneSpeedPointer] 19 | twoSpeedPointer = nums[twoSpeedPointer] 20 | } 21 | return nums[oneSpeedPointer] 22 | }; 23 | 24 | console.log(findDuplicate([1,3,5,4,6,3,5])) -------------------------------------------------------------------------------- /187-Repeated-DNA-Sequences/README.md: -------------------------------------------------------------------------------- 1 | ### 187\. Repeated DNA Sequences 2 | 3 | All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA. 4 | 5 | Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. 6 | 7 | For example, 8 | 9 | Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT", 10 | 11 | Return: 12 | ["AAAAACCCCC", "CCCCCAAAAA"]. 13 | 14 | ### 题意 15 | 给你一个由A,C,G,T组成的字符串,找出连续出现两次以及以上的子串,子串的长度是10. 16 | ### 方法(一) 17 | 这道题太容易Memory Limit Exceeded。首先先说下我的方法,我把这里的A,C,G,T用二进制00,01,10,11来替代。然后遍历子串把出现过的长度位10对子串保存到set中。如果再次出现,那么说明重复了。一开始我没用set保存。我用了js的对象来保存。毕竟方便啊。没想到就Memory Limit Exceeded了。提交了好多次才找到错误,蓝瘦,香菇。 -------------------------------------------------------------------------------- /205-Isomorphic-Strings/README.md: -------------------------------------------------------------------------------- 1 | ### 205\. Isomorphic Strings 2 | 3 | Given two strings *s* and *t*, determine if they are isomorphic. 4 | 5 | Two strings are isomorphic if the characters in *s* can be replaced to get *t*. 6 | 7 | All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself. 8 | 9 | For example, 10 | Given `"egg"`, `"add"`, return true. 11 | 12 | Given `"foo"`, `"bar"`, return false. 13 | 14 | Given `"paper"`, `"title"`, return true. 15 | 16 | Note: 17 | You may assume both *s* and *t* have the same length. 18 | 19 | ### 方法(一) 20 | 分别对s,t建立两个hash表,再遍历字符串的时候,分别从各自的hash表中找值,如果值相等,那么将值设为i,如果不相等,返回false。为什么要设置成i呢?i其实是对这个当前字符的标记。当两个字符的标记不同的时候也就意味着它们对不上号了。 -------------------------------------------------------------------------------- /57-Insert-Interval/README.md: -------------------------------------------------------------------------------- 1 | ### 57\. Insert Interval 2 | 3 | Given a set of *non-overlapping* intervals, insert a new interval into the intervals (merge if necessary). 4 | 5 | You may assume that the intervals were initially sorted according to their start times. 6 | 7 | Example 1: 8 | Given intervals `[1,3],[6,9]`, insert and merge `[2,5]` in as `[1,5],[6,9]`. 9 | 10 | Example 2: 11 | Given `[1,2],[3,5],[6,7],[8,10],[12,16]`, insert and merge `[4,9]` in as `[1,2],[3,10],[12,16]`. 12 | 13 | This is because the new interval `[4,9]` overlaps with `[3,5],[6,7],[8,10]`. 14 | 15 | ### 方法(一) 16 | 两个集合[a1,b1],[a2,b2]有重合的情况比较多,所以看两个集合无重合的情况有两种: 17 | 1. a2>b1 18 | 2. a1>b2 19 | 在遍历intervals的时候判断两个集合是否有重合,如果有,那就从intervals中删除这个集合,并把newinterval这个集合合[Math.min(a1,a2), Math.max(b1,b2)]. 20 | 最后再遍历intervals一次把newinterval插入到适当位置即可 -------------------------------------------------------------------------------- /1-two-sum/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @param {number[]} nums 4 | * @param {number} target 5 | * @return {number[]} 6 | * 双指针扫描 7 | */ 8 | 9 | var twoSum = function(nums, target) { 10 | const numsBak = nums.slice(0) 11 | numsBak.sort((a, b) => a - b) 12 | 13 | const len = numsBak.length 14 | let left = 0 15 | let right = len - 1 16 | let tar = numsBak[left] + numsBak[right] 17 | 18 | while (tar !== target || left >= right) { 19 | tar > target ? right-- : left++ 20 | tar = numsBak[left] + numsBak[right] 21 | } 22 | 23 | const index1 = nums.indexOf(numsBak[left]) 24 | const index2 = nums.lastIndexOf(numsBak[right]) 25 | 26 | return [Math.min(index1, index2), Math.max(index1, index2)] 27 | }; 28 | 29 | var nums = [0,4,3,0], target = 0 30 | console.log(twoSum(nums, target)) -------------------------------------------------------------------------------- /135-Candy/README.md: -------------------------------------------------------------------------------- 1 | ### 135\. Candy 2 | 3 | There are *N* children standing in a line. Each child is assigned a rating value. 4 | 5 | You are giving candies to these children subjected to the following requirements: 6 | 7 | * Each child must have at least one candy. 8 | * Children with a higher rating get more candies than their neighbors. 9 | 10 | What is the minimum candies you must give? 11 | 12 | ### 题意 13 | 有N个孩子站在一排。 每个孩子被分配一个评分值。 14 | 15 | 你给这些孩子糖果满足以下要求: 16 | 17 | 每个孩子必须有至少一个糖果。 18 | 评分较高的孩子比他们的邻居获得更多的糖果。 19 | 你必须给的最少糖果是多少? 20 | 21 | ### 方法(一) 22 | 有两种情况,一种是递增到最大值,一种是递减到最小值。还有以下几个特性 23 | * 在递增的时候,后一个数一定比前一个数大1,最高点列外。 24 | * 极小值一定是1(比左边右边都要小的值) 25 | 由以上两个特性可以推出下面的解法 26 | 先从左往右遍历,确保每个孩子根他左边的孩子相比,如果分高,则糖要多1个,如果分比左边低,就只给一颗。然后我们再从右往左遍历,确保每个孩子跟他右边的孩子相比,如果分高则糖至少多1个(这里至少多1个的意思是,我们要取当前孩子手里糖的数量,和其右边孩子糖的数量加1,两者的较大值)。 27 | 28 | 29 | -------------------------------------------------------------------------------- /383-Ransom-Note/README.md: -------------------------------------------------------------------------------- 1 | ### 383\. Ransom Note 2 | 3 | Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false. 4 | 5 | Each letter in the magazine string can only be used once in your ransom note. 6 | 7 | Note: 8 | You may assume that both strings contain only lowercase letters. 9 | 10 | canConstruct("a", "b") -> false 11 | canConstruct("aa", "ab") -> false 12 | canConstruct("aa", "aab") -> true 13 | 14 | ### 题意 15 | 从magazine中找ransomNote,如果ransomNote的每一个字符都能在magazine中找到,如果ransomNote中有两个a,那么magazine也至少需要两个啊,能找到的话返回true,否则返回false 16 | 17 | ### 方法(一) 18 | 用hash表,把magazine的每一个字符作为key放入hash中,value是这个key出现的次数。在遍历ransomNote的时候,当字符在hash表中找不到的时候,活着value是0的时候返回false -------------------------------------------------------------------------------- /164-Maximum-Gap/README.md: -------------------------------------------------------------------------------- 1 | ### 164\. Maximum Gap 2 | 3 | Given an unsorted array, find the maximum difference between the successive elements in its sorted form. 4 | 5 | Try to solve it in linear time/space. 6 | 7 | Return 0 if the array contains less than 2 elements. 8 | 9 | You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range. 10 | 11 | ### 题意 12 | 求一个未排序数组中排序后两个相邻元素的最大间隔 13 | 14 | ### 方法(一) 15 | 要求在时间复杂度是线性的,所以基于比较的排序肯定是不可取的。下面列出官方答案: 16 | 假设有N个元素(有N-1个间隙),它们的范围从A到B. 17 | 18 | 那么最大间隙将不小于ceiling [(B-A)/(N-1)] 19 | 20 | 令桶的长度为len = ceiling [(B-A)/(N-1)],那么我们将最多具有num =(B-A)/ len + 1个桶,我反倒是觉得应该是(B-A+1)/ len更好理解。 21 | 对于数组中的任何数K,我们可以通过计算loc =(K-A)/ len容易地找出它属于哪个桶,并且因此保持每个桶中的最大和最小元素。 22 | 由于相同桶中的元素之间的最大差异将最多为len-1,因此最终答案不会取自相同桶中的两个元素。 23 | 24 | 对于每个非空桶p,找到下一个非空桶q,然后q.min - p.max可能是问题的潜在答案。 返回所有这些值的最大值。 -------------------------------------------------------------------------------- /151-Reverse-Words-in-a-String/README.md: -------------------------------------------------------------------------------- 1 | ### 151\. Reverse Words in a String 2 | 3 | Given an input string, reverse the string word by word. 4 | 5 | For example, 6 | Given s = "`the sky is blue`", 7 | return "`blue is sky the`". 8 | 9 | Update (2015-02-12): 10 | For C programmers: Try to solve it *in-place* in *O*(1) space. 11 | 12 | [click to show clarification.](https://leetcode.com/problems/reverse-words-in-a-string/#) 13 | 14 | Clarification: 15 | 16 | * What constitutes a word? 17 | A sequence of non-space characters constitutes a word. 18 | * Could the input string contain leading or trailing spaces? 19 | Yes. However, your reversed string should not contain leading or trailing spaces. 20 | * How about multiple spaces between two words? 21 | Reduce them to a single space in the reversed string. 22 | 23 | ### 题意 24 | 以单词为最小单位反转字符串 25 | ### 方法(一) 26 | 一行代码,真没想到能过。 -------------------------------------------------------------------------------- /406-Queue-Reconstruction-by-Height/README.md: -------------------------------------------------------------------------------- 1 | ### 406\. Queue Reconstruction by Height 2 | 3 | Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers `(h, k)`, where `h` is the height of the person and `k` is the number of people in front of this person who have a height greater than or equal to `h`. Write an algorithm to reconstruct the queue. 4 | 5 | Note: 6 | The number of people is less than 1,100. 7 | 8 | Example 9 | 10 | Input: 11 | [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] 12 | 13 | Output: 14 | [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] 15 | 16 | ### 题意 17 | 假设你有一个随机列表的人站在队列中。 每个人都用一对整数(h,k)来描述,其中`h`是人的身高,`k`是这个人前面的身高大于或等于的人数 `h`。 编写一个算法来重建队列。 18 | 19 | 注意: 20 | 人数不足1100人。 21 | 22 | ### 方法(一) 23 | 首先我们给队列先排个序,按照身高高的排前面,如果身高相同,则第二个数小的排前面。然后我们新建一个空的数组,遍历之前排好序的数组,然后根据每个元素的第二个数字,将其插入到res数组中对应的位置 -------------------------------------------------------------------------------- /43-Multiply-Strings/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} num1 3 | * @param {string} num2 4 | * @return {string} 5 | */ 6 | var multiply = function(num1, num2) { 7 | let res = [] 8 | const num1RevArr = num1.split('').reverse() 9 | const num2RevArr = num2.split('').reverse() 10 | for (let i = 0, len1 = num1RevArr.length, mul, carry = 0; i < len1; i++) { 11 | for (let j = 0, len2 = num2RevArr.length; j < len2; j++) { 12 | mul = num1RevArr[i] * num2RevArr[j] 13 | res[i + j] = (res[i + j] || 0) + mul 14 | carry = Math.floor(res[i + j] / 10) 15 | res[i + j] %= 10 16 | res[i + j + 1] = (res[i + j + 1] || 0) + carry 17 | } 18 | } 19 | const resStr = res.reverse().join('').replace(/^0+/, '') 20 | return resStr === '' ? '0' : resStr 21 | }; 22 | 23 | console.log(multiply('9999', '0')) -------------------------------------------------------------------------------- /165-Compare-Version-Numbers/README.md: -------------------------------------------------------------------------------- 1 | ### 165\. Compare Version Numbers 2 | 3 | Compare two version numbers *version1* and *version2*. 4 | If *version1* \> *version2* return 1, if *version1* \< *version2* return -1, otherwise return 0. 5 | 6 | You may assume that the version strings are non-empty and contain only digits and the `.` character. 7 | The `.` character does not represent a decimal point and is used to separate number sequences. 8 | For instance, `2.5` is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. 9 | 10 | Here is an example of version numbers ordering: 11 | 12 | 0.1 < 1.1 < 1.2 < 13.37 13 | 14 | ### 题意 15 | 比较两个版本号 16 | 17 | ### 方法(一) 18 | 先把版本转换成整型数组,然后逐个比较两个数组。在遍历的时候以下的情况事第一个版本较大,当前版本一中的数字大于0,版本二中的数字比一中的小或者是undi]efined.只有这一种情况。如果版本一遇到0或者undefined的同时,版本二也是0或者undefined,那么继续遍历。 -------------------------------------------------------------------------------- /7-Reverse-Integer/README.md: -------------------------------------------------------------------------------- 1 | ### 7\. Reverse Integer 2 | 3 | Reverse digits of an integer. 4 | 5 | Example1: x = 123, return 321 6 | Example2: x = -123, return -321 7 | 8 | Have you thought about this? 9 | 10 | Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! 11 | 12 | If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. 13 | 14 | Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases? 15 | 16 | For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. 17 | 18 | ### 方法(一) 19 | 一个再普通不过的方法,循环x除以10取整,知道x等于0。就是对看代码index.js,但是写出来效率只打败了16.61%的 20 | 21 | ### 方法(二) 22 | 这个方法是把数字转成字符串,然后再把字符串数组,反转数组再转成字符串。打败了72.9%.代码见index2.js -------------------------------------------------------------------------------- /75-Sort-Colors/README.md: -------------------------------------------------------------------------------- 1 | ### 75\. Sort Colors 2 | 3 | Given an array with *n* objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. 4 | 5 | Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. 6 | 7 | Note: 8 | You are not suppose to use the library's sort function for this problem. 9 | 10 | [click to show follow up.](https://leetcode.com/problems/sort-colors/#) 11 | 12 | Follow up: 13 | A rather straight forward solution is a two-pass algorithm using counting sort. 14 | First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. 15 | 16 | Could you come up with an one-pass algorithm using only constant space? 17 | 18 | ### 方法(一) 19 | 做这道题相当简单,我用的是桶排序,但是需要O(n)的空间。 -------------------------------------------------------------------------------- /287-Find-the-Duplicate-Number/README.md: -------------------------------------------------------------------------------- 1 | ### 287\. Find the Duplicate Number 2 | 3 | Given an array *nums* containing *n* + 1 integers where each integer is between 1 and *n* (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. 4 | 5 | Note: 6 | 7 | 1. You must not modify the array (assume the array is read only). 8 | 2. You must use only constant, *O*(1) extra space. 9 | 3. Your runtime complexity should be less than `O(n2)`. 10 | 4. There is only one duplicate number in the array, but it could be repeated more than once. 11 | 12 | ### 题意 13 | 给定一个数组* nums *包含* n * + 1个整数,其中每个整数在1和* n *(含)之间,证明至少有一个重复的数字必须存在。 假设只有一个重复的数字,找到重复的一个。 14 | 15 | ### 方法(一) 16 | 之前做项目有碰到过类似的需求,那时候用了一个正则解决啦。代码见index2.js.不过在n上万的时候正则处理的数独特别慢。所以超时啦!但是代码超级简单 17 | ### 方法(二) 18 | 和题目Linked List Cycle II想法是一模一样的。代码见index.js 19 | 20 | -------------------------------------------------------------------------------- /345-Reverse-Vowels-of-a-String/index.js: -------------------------------------------------------------------------------- 1 | 2 | function isVowels(ch) { 3 | return /^[aeiou]$/i.test(ch) 4 | } 5 | 6 | /** 7 | * @param {string} s 8 | * @return {string} 9 | */ 10 | var reverseVowels = function(s) { 11 | let left = 0 12 | let right = s.length - 1 13 | let res = s.split('') 14 | 15 | while (left < right) { 16 | if (isVowels(res[left]) && isVowels(res[right])) { 17 | [res[left], res[right]] = [res[right], res[left]] 18 | left++ 19 | right-- 20 | } else if (isVowels(res[left]) && !isVowels(res[right])) { 21 | right-- 22 | } else if(!isVowels(res[left]) && isVowels(res[right])) { 23 | left++ 24 | } else { 25 | left++ 26 | right-- 27 | } 28 | } 29 | return res.join('') 30 | }; 31 | 32 | 33 | console.log(reverseVowels('aA')) -------------------------------------------------------------------------------- /45-Jump-Game-II/README.md: -------------------------------------------------------------------------------- 1 | ### 45\. Jump Game II 2 | 3 | Given an array of non-negative integers, you are initially positioned at the first index of the array. 4 | 5 | Each element in the array represents your maximum jump length at that position. 6 | 7 | Your goal is to reach the last index in the minimum number of jumps. 8 | 9 | For example: 10 | Given array A = `[2,3,1,1,4]` 11 | 12 | The minimum number of jumps to reach the last index is `2`. (Jump `1` step from index 0 to 1, then `3` steps to the last index.) 13 | 14 | Note: 15 | You can assume that you can always reach the last index. 16 | 17 | ### 题意 18 | 给定一个非负整数数组,你最初被定位在数组的第一个索引。 19 | 20 | 数组中的每个元素表示在该位置的最大跳跃长度。 21 | 22 | 你的目标是达到最小跳跃数的最后一个索引。 23 | 24 | ## 例如: 25 | 26 | 给定数组A = [2,3,1,1,4] 27 | 28 | 到达最后一个索引的跳转的最小数量为2.(从索引0跳到1,然后跳到最后一个索引的3个步骤。) 29 | 30 | ## 注意: 31 | 您可以假设您可以始终达到最后一个索引。 32 | 33 | ### 方法(一) 34 | 和55题的解法一一样 -------------------------------------------------------------------------------- /45-Jump-Game-II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var jump = function(nums) { 6 | function getBestIndex(nums, start, end) { 7 | let bestIndex = start 8 | for (let i = start + 1, best = nums[start] + start; i <= end && i < nums.length; i++) { 9 | if (nums[i] + i >= best) { 10 | bestIndex = i 11 | best = nums[i] + i 12 | } 13 | } 14 | return bestIndex 15 | } 16 | 17 | if (nums.length === 1) { 18 | return 0 19 | } 20 | 21 | let res = 1 22 | let n = 0 23 | while (n + nums[n] < nums.length - 1) { 24 | n = getBestIndex(nums, n, n + nums[n]) 25 | if (nums[n] === 0) { 26 | return -1 27 | } 28 | res++ 29 | } 30 | 31 | return res 32 | }; 33 | 34 | console.log(jump([2,3,1,1,1,4])) -------------------------------------------------------------------------------- /165-Compare-Version-Numbers/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} version1 3 | * @param {string} version2 4 | * @return {number} 5 | */ 6 | var compareVersion = function(version1, version2) { 7 | const version1Arr = version1.split('.').map(val => +val) 8 | const version2Arr = version2.split('.').map(val => +val) 9 | const maxLen = Math.max(version1Arr.length, version2Arr.length) 10 | 11 | for (let i = 0; i < maxLen; i++) { 12 | if (version1Arr[i] && !version2Arr[i]) { 13 | return 1 14 | } 15 | if (!version1Arr[i] && version2Arr[i]) { 16 | return -1 17 | } 18 | if (version1Arr[i] > version2Arr[i]) { 19 | return 1 20 | } 21 | if (version1Arr[i] < version2Arr[i]) { 22 | return -1 23 | } 24 | } 25 | return 0 26 | }; 27 | 28 | console.log(compareVersion('1', '0')) -------------------------------------------------------------------------------- /101-Symmetric-Tree/index.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 | * @return {boolean} 11 | */ 12 | var isSymmetric = function(root) { 13 | function isEqualLR(left, right) { 14 | if (!left && !right) return true 15 | if(!left || !right || left.val !== right.val) return false 16 | return isEqualLR(left.left, right.right) && isEqualLR(left.right, right.left) 17 | } 18 | if (root) { 19 | return isEqualLR(root.left, root.right) 20 | } 21 | return true 22 | }; 23 | 24 | function TreeNode(val) { 25 | this.val = val; 26 | this.left = this.right = null; 27 | } 28 | const p = new TreeNode(1) 29 | p.left = new TreeNode(2) 30 | p.right = new TreeNode(3) 31 | 32 | console.log(isSymmetric(p)) -------------------------------------------------------------------------------- /104-Maximum-Depth-of-Binary-Tree/index.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 | * @return {number} 11 | */ 12 | var maxDepth = function(root) { 13 | let lDep 14 | let rDep 15 | if (root) { 16 | lDep = maxDepth(root.left) 17 | rDep = maxDepth(root.right) 18 | return Math.max(lDep, rDep) + 1 19 | } 20 | 21 | return 0 22 | }; 23 | 24 | function TreeNode(val) { 25 | this.val = val; 26 | this.left = this.right = null; 27 | } 28 | const root = new TreeNode(1) 29 | root.left = new TreeNode(2) 30 | root.right = new TreeNode(3) 31 | root.left.left = new TreeNode(4) 32 | root.left.right = new TreeNode(5) 33 | root.right.left = new TreeNode(6) 34 | root.right.right = new TreeNode(7) 35 | 36 | console.log(maxDepth(root)) -------------------------------------------------------------------------------- /226-Invert-Binary-Tree/index2.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 | * @return {TreeNode} 11 | */ 12 | var invertTree = function(root) { 13 | if (!root) { 14 | return null 15 | } 16 | const rl = root.left 17 | const rr = root.right 18 | root.left = invertTree(rr) 19 | root.right = invertTree(rl) 20 | 21 | return root 22 | }; 23 | 24 | function TreeNode(val) { 25 | this.val = val; 26 | this.left = this.right = null; 27 | } 28 | const root = new TreeNode(1) 29 | root.left = new TreeNode(2) 30 | root.right = new TreeNode(3) 31 | root.left.left = new TreeNode(4) 32 | root.left.right = new TreeNode(5) 33 | root.right.left = new TreeNode(6) 34 | root.right.right = new TreeNode(7) 35 | 36 | console.log(invertTree(root)) -------------------------------------------------------------------------------- /240-Search-a-2D-Matrix II/README.md: -------------------------------------------------------------------------------- 1 | ### 240\. Search a 2D Matrix II 2 | 3 | Write an efficient algorithm that searches for a value in an *m* x *n* matrix. This matrix has the following properties: 4 | 5 | * Integers in each row are sorted in ascending from left to right. 6 | * Integers in each column are sorted in ascending from top to bottom. 7 | 8 | For example, 9 | 10 | Consider the following matrix: 11 | 12 | [ 13 | [1, 4, 7, 11, 15], 14 | [2, 5, 8, 12, 19], 15 | [3, 6, 9, 16, 22], 16 | [10, 13, 14, 17, 24], 17 | [18, 21, 23, 26, 30] 18 | ] 19 | 20 | Given target = `5`, return `true`. 21 | 22 | Given target = `20`, return `false`. 23 | 24 | ### 题意 25 | 从一个二维数组中找一个数 26 | * 每一行的整数从左向右递增 27 | * 每一列的整数从上往下递增 28 | 29 | ### 方法(一) 30 | 因为每一行都已经排序,那么对每一行二分搜索。时间复杂度是O(mlogn)。其实随便想想也知道这肯定不是最佳算法。第二个条件都没用 31 | 32 | ### 方法(二) 33 | 从左下角那个数字开始,如果比这个数大就往右边搜索,如果比这个数小就往上边搜索,时间复杂度是O(m+n) -------------------------------------------------------------------------------- /1-two-sum/README.md: -------------------------------------------------------------------------------- 1 | ### 1\. Two Sum 2 | 3 | Given an array of integers, return indices of the two numbers such that they add up to a specific target. 4 | 5 | You may assume that each input would have *exactly* one solution. 6 | 7 | Example: 8 | 9 | Given nums = [2, 7, 11, 15], target = 9, 10 | 11 | Because nums[0] + nums[1] = 2 + 7 = 9, 12 | return [0, 1]. 13 | 14 | UPDATE (2016/2/13): 15 | The return format had been changed to zero-based indices. Please read the above updated description carefully. 16 | 17 | ### 方法(一) 18 | 对数组排序,然后用指针分别指向排序好的数组的头部和尾部的值,将两个值相加,如果大于target就向左移动尾部指针,如果小于target就向右移动首部指针,等于则结束循环。当首部指针的index大于等于尾部指针的index的时候就没找到相应的位置,也结束循环。代码看index.js 19 | 20 | ### 方法(二) 21 | 这一种方法更简单了,但是有一个坑。原来是把数组复制一份到hash表中。其实我们就是要找target-nums[i]的值再hash表中能不能找到,这里要注意两点。一个就是不能nums[i]和hash表中找到的不能是同一个数,比如[3,4] target: 6;你要排除nums[i]是3,找到hash表中的也是3。第二个点是再创建hash表的时候,因为hash的key必须是唯一的,如果[3,3,4]这样的数组再hash表只能对应两个key。代码看index2.js 22 | 23 | -------------------------------------------------------------------------------- /100-Same-Tree/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by fage on 2016/10/31. 3 | */ 4 | /** 5 | * Definition for a binary tree node. 6 | * function TreeNode(val) { 7 | * this.val = val; 8 | * this.left = this.right = null; 9 | * } 10 | */ 11 | /** 12 | * @param {TreeNode} p 13 | * @param {TreeNode} q 14 | * @return {boolean} 15 | */ 16 | var isSameTree = function(p, q) { 17 | if (!p && !q) return true 18 | if(!p || !q || p.val !== q.val) return false 19 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right) 20 | }; 21 | function TreeNode(val) { 22 | this.val = val; 23 | this.left = this.right = null; 24 | } 25 | const p = new TreeNode(1) 26 | p.left = null 27 | const node1 = p.right = new TreeNode(2) 28 | node1.left = new TreeNode(3) 29 | 30 | const q = new TreeNode(1) 31 | q.left = null 32 | const node2 = q.right = new TreeNode(2) 33 | node2.left = new TreeNode(3) 34 | 35 | console.log(isSameTree(p, q)) -------------------------------------------------------------------------------- /318-Maximum-Product-of-Word-Lengths/README.md: -------------------------------------------------------------------------------- 1 | ### 318\. Maximum Product of Word Lengths 2 | 3 | Given a string array `words`, find the maximum value of `length(word[i]) * length(word[j])` where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. 4 | 5 | Example 1: 6 | 7 | Given `["abcw", "baz", "foo", "bar", "xtfn", "abcdef"]` 8 | Return `16` 9 | The two words can be `"abcw", "xtfn"`. 10 | 11 | Example 2: 12 | 13 | Given `["a", "ab", "abc", "d", "cd", "bcd", "abcd"]` 14 | Return `4` 15 | The two words can be `"ab", "cd"`. 16 | 17 | Example 3: 18 | 19 | Given `["a", "aa", "aaa", "aaaa"]` 20 | Return `0` 21 | No such pair of words. 22 | 23 | ### 题意 24 | 给你一个小写的字符串数组,求出这个数组中两个字符串长度乘积最大的值。并且这两个字符串不能有公共字符。 25 | 26 | ### 方法(一) 27 | 想到了就很简单。因为都是小写字母。所以所有的字符也就26个。可以用32位来表示。a如果表示的是第一位(最低位),那么z表示第26位。abcd字符串表示..0001111.要判断两个字符串有没有共同字符串,则只要这两个数做与运算就可以了。 -------------------------------------------------------------------------------- /94-Binary-Tree-Inorder-Traversal/index.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 | * @return {number[]} 11 | */ 12 | var inorderTraversal = function(root) { 13 | const stack = [] 14 | const res = [] 15 | 16 | while (root || stack.length !== 0) { 17 | while (root) { 18 | stack.push(root) 19 | root = root.left 20 | } 21 | 22 | let tmp = stack.pop() 23 | res.push(tmp.val) 24 | root = tmp.right 25 | } 26 | return res 27 | }; 28 | function TreeNode(val) { 29 | this.val = val; 30 | this.left = this.right = null; 31 | } 32 | const root = new TreeNode(1) 33 | root.left = null 34 | const node1 = root.right = new TreeNode(2) 35 | node1.left = new TreeNode(3) 36 | 37 | console.log(inorderTraversal(root)) -------------------------------------------------------------------------------- /6-ZigZag-Conversion/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @param {number} numRows 4 | * @return {string} 5 | */ 6 | // Memory Limit Exceeded 7 | var convert = function(s, numRows) { 8 | const length = s.length 9 | let i = 0 10 | const resArr = Array.from(new Array(numRows)).map((val) => []) 11 | 12 | let col = 0 13 | while (i < length) { 14 | for (let n = 0; n < numRows; n++) { 15 | resArr[n][col] = s[i++] 16 | } 17 | for (let n = numRows - 2; n > 0; n--) { 18 | resArr[n][++col] = s[i++] 19 | } 20 | col++ 21 | } 22 | return resArr.reduce((pre, cur) => pre + cur.join(''), '') 23 | }; 24 | 25 | console.log(convert("twckwuyvbihajbmhmodminftgpdcbquupwflqfiunpuwtigfwjtgzzcfofjpydjnzqysvgmiyifrrlwpwpyvqadefmvfshsrxsltbxbziiqbvosufqpwsucyjyfbhauesgzvfdwnloojejdkzugsrksakzbrzxwudxpjaoyocpxhycrxwzrpllpwlsnkqlevjwejkfxmuwvsyopxpjmbuexfwksoywkhsqqevqtpoohpd", 4)) -------------------------------------------------------------------------------- /110-Balanced-Binary-Tree/index.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 | * @return {boolean} 11 | */ 12 | var isBalanced = function(root) { 13 | function DepthDiff(root) { 14 | if (!root) return 0 15 | 16 | let lDep = DepthDiff(root.left) 17 | if (lDep === -1) return -1 18 | 19 | let rDep = DepthDiff(root.right) 20 | if (rDep === -1) return -1 21 | 22 | if (Math.abs(lDep - rDep) > 1) return -1 23 | 24 | return Math.max(lDep, rDep) + 1 25 | } 26 | 27 | return DepthDiff(root) === -1 ? false : true 28 | }; 29 | 30 | 31 | function TreeNode(val) { 32 | this.val = val; 33 | this.left = this.right = null; 34 | } 35 | const root = new TreeNode(1) 36 | root.right = new TreeNode(2) 37 | 38 | 39 | console.log(isBalanced(root)) -------------------------------------------------------------------------------- /108-Convert-Sorted-Array-to-Binary-Search-Tree/index.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 {number[]} nums 10 | * @return {TreeNode} 11 | */ 12 | var sortedArrayToBST = function(nums) { 13 | function sortedArrayToBSTRec(nums, start, end) { 14 | if (start > end) { 15 | return null 16 | } 17 | let mid = Math.floor((end + start) / 2) 18 | let root = new TreeNode(nums[mid]) 19 | root.left = sortedArrayToBSTRec(nums, start, mid - 1) 20 | root.right = sortedArrayToBSTRec(nums, mid + 1, end) 21 | return root 22 | } 23 | return sortedArrayToBSTRec(nums, 0, nums.length - 1) 24 | }; 25 | 26 | function TreeNode(val) { 27 | this.val = val; 28 | this.left = this.right = null; 29 | } 30 | 31 | console.log(sortedArrayToBST([1,2,3,4,5,6,7])) -------------------------------------------------------------------------------- /111-Minimum-Depth-of-Binary-Tree/index2.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 | * @return {number} 11 | */ 12 | var minDepth = function(root) { 13 | if (!root) { 14 | return 0 15 | } 16 | let lDep = minDepth(root.left) 17 | let rDep = minDepth(root.right) 18 | if (lDep === 0 && rDep === 0) { 19 | return 1 20 | } 21 | if (lDep === 0) { 22 | lDep = Infinity 23 | } 24 | if (rDep === 0) { 25 | rDep = Infinity 26 | } 27 | return Math.min(lDep, rDep) + 1 28 | }; 29 | 30 | function TreeNode(val) { 31 | this.val = val; 32 | this.left = this.right = null; 33 | } 34 | const root = new TreeNode(1) 35 | root.left = new TreeNode(2) 36 | root.right = new TreeNode(2) 37 | root.right = new TreeNode(2) 38 | 39 | 40 | console.log(minDepth(root)) -------------------------------------------------------------------------------- /73-Set-Matrix-Zeroes/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @return {void} Do not return anything, modify matrix in-place instead. 4 | */ 5 | var setZeroes = function(matrix) { 6 | const row = matrix.length 7 | const col = matrix[0].length 8 | 9 | for (let m = 0; m < row; m++) { 10 | for (let n = 0; n < col; n++) { 11 | if (matrix[m][n] === 0 && 1 / matrix[m][n] === Infinity) { 12 | for (let i = 0; i < row; i++) { 13 | if (matrix[i][n] !== 0) { 14 | matrix[i][n] = -0 15 | } 16 | } 17 | for (let i = 0; i < col; i++) { 18 | if (matrix[m][i] !== 0) { 19 | matrix[m][i] = -0 20 | } 21 | } 22 | } 23 | } 24 | } 25 | 26 | }; 27 | var matrix = [[0,1,1,0],[1,0,1,1],[1,1,1,1],[0,1,1,1]] 28 | setZeroes(matrix) 29 | console.log(matrix) -------------------------------------------------------------------------------- /34-Search-for-a-Range/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} target 4 | * @return {number[]} 5 | */ 6 | 7 | function bSearch(arr, low, high, target) { 8 | if (low > high) { 9 | return -1 10 | } 11 | let mid = Math.floor((high + low) / 2) 12 | if (arr[mid] > target) { 13 | return bSearch(arr, low, mid - 1, target) 14 | } else if (arr[mid] < target) { 15 | return bSearch(arr, mid + 1, high, target) 16 | } 17 | return mid 18 | } 19 | var searchRange = function(nums, target) { 20 | const position = bSearch(nums, 0, nums.length - 1, target) 21 | 22 | if (position === -1) { 23 | return [-1, -1] 24 | } 25 | 26 | let i = position - 1 27 | let j = position + 1 28 | while (nums[i] === target || nums[j] === target) { 29 | nums[i] === target && i-- 30 | nums[j] === target && j++ 31 | } 32 | return [i + 1, j - 1] 33 | }; 34 | 35 | console.log(searchRange([2,2], 3)) -------------------------------------------------------------------------------- /435-Non-overlapping-Intervals/README.md: -------------------------------------------------------------------------------- 1 | ### 435\. Non-overlapping Intervals 2 | 3 | Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. 4 | 5 | Note: 6 | 7 | 1. You may assume the interval's end point is always bigger than its start point. 8 | 2. Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. 9 | 10 | ### 题意 11 | 给定间隔集合,找到需要删除的间隔的最小数量,以使其余间隔不重叠。 12 | 13 | 注意: 14 | 您可以假定间隔的终点总是大于其起点。 15 | 像[1,2]和[2,3]之类的边界具有“接触”边界,但它们彼此不重叠。 16 | 实施例1: 17 | 输入:[[1,2],[2,3],[3,4],[1,3] 18 | 19 | 输出:1 20 | 21 | 说明:[1,3]可以删除,其余的间隔是不重叠的。 22 | 实施例2: 23 | 输入:[[1,2],[1,2],[1,2]] 24 | 25 | 输出:2 26 | 27 | 说明:您需要删除两个[1,2],使其余的时间间隔不重叠。 28 | 实施例3: 29 | 输入:[[1,2],[2,3]] 30 | 31 | 输出:0 32 | 33 | 说明:您不需要删除任何间隔,因为它们已经不重叠。 34 | 35 | ### 方法(一) 36 | 按照end从小到大排序,从第二个元素开始遍历排序后的数组。再定义一个指针a指向第一个元素。如果两个元素重合结果加一,如果不重合a指向当前元素。。 37 | 不知道为什么好慢,discuss中也没有js solution。我的思想应该是没错的。有人知道为什么我的代码这么慢请告诉我一下。 -------------------------------------------------------------------------------- /141-Linked-List-Cycle/index.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 {boolean} 12 | */ 13 | var hasCycle = function(head) { 14 | let oneSpeedPointer = head 15 | let twoSpeedPointer = head 16 | 17 | while (twoSpeedPointer !== null) { 18 | oneSpeedPointer = oneSpeedPointer.next 19 | twoSpeedPointer = twoSpeedPointer.next 20 | if (twoSpeedPointer === null) { 21 | return false 22 | } 23 | twoSpeedPointer = twoSpeedPointer.next 24 | if (twoSpeedPointer === oneSpeedPointer) { 25 | return true 26 | } 27 | } 28 | return false 29 | }; 30 | function ListNode(val) { 31 | this.val = val; 32 | this.next = null; 33 | } 34 | var head = new ListNode(1) 35 | head.next = new ListNode(2) 36 | head.next.next = head 37 | console.log(hasCycle(head)) -------------------------------------------------------------------------------- /435-Non-overlapping-Intervals/index.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 {number} 11 | */ 12 | var eraseOverlapIntervals = function(intervals) { 13 | intervals.sort((a, b) => { 14 | if (a.end > b.end) { 15 | return 1 16 | } else if(a.end < b.end) { 17 | return -1 18 | } 19 | 20 | return 0 21 | }) 22 | 23 | let res = 0 24 | for (let i = 1, j = 0; i < intervals.length; i++) { 25 | if (intervals[i].start < intervals[j].end) { 26 | res++ 27 | } else { 28 | j = i 29 | } 30 | } 31 | return res 32 | }; 33 | 34 | function Interval(start, end) { 35 | this.start = start; 36 | this.end = end; 37 | } 38 | 39 | console.log(eraseOverlapIntervals( [new Interval(1,2),new Interval(1,2),new Interval(1,2)])) -------------------------------------------------------------------------------- /238-Product-of-Array-Except-Self/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number[]} 4 | */ 5 | var productExceptSelf = function(nums) { 6 | const firstZeroIndex = nums.indexOf(0) 7 | const lastZeroIndex = nums.lastIndexOf(0) 8 | let product = 0 9 | if (firstZeroIndex !== -1 && lastZeroIndex !== -1 && firstZeroIndex !== lastZeroIndex) { 10 | return nums.fill(0) 11 | } 12 | if (firstZeroIndex === -1 && lastZeroIndex === -1) { 13 | product = nums.reduce((pre, cur) => pre * cur) 14 | return nums.map(val => product/val) 15 | } 16 | if (firstZeroIndex !== -1 && lastZeroIndex !== -1 && firstZeroIndex === lastZeroIndex) { 17 | product = nums.reduce((pre, cur) => { 18 | return cur === 0 ? pre : pre * cur 19 | }, 1) 20 | nums[firstZeroIndex] = product 21 | return nums.fill(0, 0 , firstZeroIndex).fill(0, firstZeroIndex + 1, nums.length) 22 | } 23 | }; 24 | 25 | console.log(productExceptSelf([0,1])) -------------------------------------------------------------------------------- /147-Insertion-Sort-List/index.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 insertionSortList = function(head) { 13 | const res = new TreeNode(-Infinity) 14 | res.next = null 15 | 16 | while (head !== null) { 17 | let pre = res 18 | 19 | while (pre.next && head.val > pre.next.val) { 20 | pre = pre.next 21 | } 22 | 23 | let tmpHead = head.next 24 | head.next = pre.next 25 | pre.next = head 26 | head = tmpHead 27 | } 28 | 29 | return res.next 30 | }; 31 | 32 | function TreeNode(val) { 33 | this.val = val; 34 | this.next = null; 35 | } 36 | 37 | let root = new TreeNode(3) 38 | root.next = new TreeNode(2) 39 | root.next.next = new TreeNode(4) 40 | root.next.next.next = new TreeNode(1) 41 | 42 | console.log(insertionSortList(root)) -------------------------------------------------------------------------------- /235-Lowest-Common-Ancestor-of-a-Binary-Search-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 235\. Lowest Common Ancestor of a Binary Search Tree 2 | 3 | Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. 4 | 5 | According to the [definition of LCA on Wikipedia](https://en.wikipedia.org/wiki/Lowest_common_ancestor): “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” 6 | 7 | _______6______ 8 | / \ 9 | ___2__ ___8__ 10 | / \ / \ 11 | 0 _4 7 9 12 | / \ 13 | 3 5 14 | 15 | For example, the lowest common ancestor (LCA) of nodes `2` and `8` is `6`. Another example is LCA of nodes `2` and `4` is `2`, since a node can be a descendant of itself according to the LCA definition. 16 | 17 | ### 方法(一) 18 | 其实就是BFS第一个找到满足以下要求的节点 19 | 节点的值等于v或者w的值,节点的值在v,w之间 -------------------------------------------------------------------------------- /129-Sum-Root-to-Leaf-Numbers/index.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 | * @return {number} 11 | */ 12 | var sumNumbers = function(root) { 13 | let res = 0 14 | function dfs(root, sum) { 15 | if (!root) { 16 | return 17 | } 18 | sum += root.val 19 | if (root.left || root.right) { 20 | dfs(root.left, sum) 21 | dfs(root.right, sum) 22 | return 23 | } 24 | res += +sum 25 | 26 | return 0 27 | } 28 | dfs(root, '') 29 | return res 30 | }; 31 | 32 | function TreeNode(val) { 33 | this.val = val; 34 | this.left = this.right = null; 35 | } 36 | const root = new TreeNode(1) 37 | root.left = new TreeNode(2) 38 | root.right = new TreeNode(3) 39 | root.right.right = new TreeNode(3) 40 | 41 | 42 | console.log(sumNumbers(root)) 43 | 44 | -------------------------------------------------------------------------------- /405-Convert-a-Number-to-Hexadecimal/README.md: -------------------------------------------------------------------------------- 1 | ### 405\. Convert a Number to Hexadecimal 2 | 3 | Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, [two’s complement](https://en.wikipedia.org/wiki/Two%27s_complement) method is used. 4 | 5 | Note: 6 | 7 | 1. All letters in hexadecimal (`a-f`) must be in lowercase. 8 | 2. The hexadecimal string must not contain extra leading `0`s. If the number is zero, it is represented by a single zero character `'0'`; otherwise, the first character in the hexadecimal string will not be the zero character. 9 | 3. The given number is guaranteed to fit within the range of a 32-bit signed integer. 10 | 4. You must not use *any* method provided by the library which converts/formats the number to hex directly. 11 | 12 | Example 1: 13 | 14 | Input: 15 | 26 16 | 17 | Output: 18 | "1a" 19 | 20 | Example 2: 21 | 22 | Input: 23 | -1 24 | 25 | Output: 26 | "ffffffff" 27 | 28 | ### 题意 29 | 把一个数字转换成16进制的数 30 | ### 方法(一) 31 | 每右移动四位和0b1111做与运算得到的值换算成16进制 -------------------------------------------------------------------------------- /144-Binary-Tree-Preorder-Traversal/index.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 | * @return {number[]} 11 | */ 12 | var preorderTraversal = function(root) { 13 | const stack = [] 14 | const res = [] 15 | while (root || stack.length !== 0) { 16 | while (root) { 17 | stack.push(root) 18 | res.push(root.val) 19 | root = root.left 20 | } 21 | root = stack.pop().right 22 | } 23 | return res 24 | }; 25 | 26 | 27 | function TreeNode(val) { 28 | this.val = val; 29 | this.left = this.right = null; 30 | } 31 | const root = new TreeNode(1) 32 | root.left = new TreeNode(2) 33 | root.right = new TreeNode(3) 34 | root.left.left = new TreeNode(4) 35 | root.left.right = new TreeNode(5) 36 | root.right.left = new TreeNode(6) 37 | root.right.right = new TreeNode(7) 38 | 39 | 40 | console.log(preorderTraversal(root)) -------------------------------------------------------------------------------- /240-Search-a-2D-Matrix II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @param {number} target 4 | * @return {boolean} 5 | */ 6 | var searchMatrix = function(matrix, target) { 7 | function bSearch(arr, target) { 8 | let low = 0 9 | let high = arr.length - 1 10 | while (low <= high) { 11 | let mid = Math.floor((low + high) / 2) 12 | if (target > arr[mid]) { 13 | low = mid + 1 14 | } else if (target < arr[mid]) { 15 | high = mid - 1 16 | } else { 17 | return true 18 | } 19 | } 20 | return false 21 | } 22 | 23 | for (let i = 0, len = matrix.length; i < len; i++) { 24 | if (bSearch(matrix[i], target)) { 25 | return true 26 | } 27 | } 28 | 29 | return false 30 | }; 31 | 32 | console.log(searchMatrix([ 33 | [1, 4, 7, 11, 15], 34 | [2, 5, 8, 12, 19], 35 | [3, 6, 9, 16, 22], 36 | [10, 13, 14, 17, 24], 37 | [18, 21, 23, 26, 30] 38 | ], 5)) -------------------------------------------------------------------------------- /164-Maximum-Gap/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var maximumGap = function(nums) { 6 | const numsLen = nums.length 7 | if (numsLen < 2) { 8 | return 0 9 | } 10 | 11 | const maxNum = Math.max(...nums) 12 | const minNum = Math.min(...nums) 13 | const bucketLen = Math.ceil((maxNum - minNum) / (numsLen - 1)) 14 | if (bucketLen === 0) { 15 | return 0 16 | } 17 | 18 | const bucketCount = Math.ceil((maxNum - minNum + 1) / bucketLen) 19 | const bucket = Array.from(new Array(bucketCount)).map(() => []) 20 | for (let num of nums) { 21 | bucket[Math.floor((num - minNum) / bucketLen)].push(num) 22 | } 23 | 24 | const bucketFilter = bucket.filter(value => value.length !== 0) 25 | let maxGap = 0 26 | for (let i = 0; i < bucketFilter.length - 1; i++) { 27 | maxGap = Math.max(maxGap, (Math.min(...bucketFilter[i + 1]) || 0) - Math.max(...bucketFilter[i])) 28 | } 29 | 30 | return maxGap 31 | }; 32 | 33 | console.log(maximumGap([1,3,7,8])) -------------------------------------------------------------------------------- /112-Path-Sum/index.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 | function hasPath(root, sum, tmpSum) { 15 | if (!root) { 16 | return false 17 | } 18 | tmpSum += root.val 19 | 20 | if (root.left || root.right) { 21 | let hasLeftPath = hasPath(root.left, sum, tmpSum) 22 | let hasRightPath = hasPath(root.right, sum, tmpSum) 23 | return hasLeftPath || hasRightPath 24 | } 25 | 26 | return sum === tmpSum 27 | } 28 | return hasPath(root, sum, 0) 29 | }; 30 | 31 | function TreeNode(val) { 32 | this.val = val; 33 | this.left = this.right = null; 34 | } 35 | const root = new TreeNode(1) 36 | root.left = new TreeNode(3) 37 | root.right = new TreeNode(4) 38 | 39 | 40 | console.log(hasPathSum(root, 3)) -------------------------------------------------------------------------------- /230-Kth-Smallest-Element-in-a-BST/index.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} k 11 | * @return {number} 12 | */ 13 | var kthSmallest = function(root, k) { 14 | let n = 0 15 | let res 16 | function inOrder(root) { 17 | if (root) { 18 | inOrder(root.left) 19 | if (++n === k) { 20 | res = root.val 21 | } 22 | inOrder(root.right) 23 | } 24 | } 25 | inOrder(root) 26 | return res 27 | }; 28 | 29 | function TreeNode(val) { 30 | this.val = val; 31 | this.left = this.right = null; 32 | } 33 | const root = new TreeNode(4) 34 | root.left = new TreeNode(2) 35 | root.right = new TreeNode(6) 36 | root.left.left = new TreeNode(1) 37 | root.left.right = new TreeNode(3) 38 | root.right.left = new TreeNode(5) 39 | root.right.right = new TreeNode(7) 40 | 41 | console.log(kthSmallest(root, 2)) -------------------------------------------------------------------------------- /260-Single-Number-III/README.md: -------------------------------------------------------------------------------- 1 | ### 260\. Single Number III 2 | 3 | Given an array of numbers `nums`, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once. 4 | 5 | For example: 6 | 7 | Given `nums = [1, 2, 1, 3, 2, 5]`, return `[3, 5]`. 8 | 9 | Note: 10 | 11 | 1. The order of the result is not important. So in the above example, `[5, 3]` is also correct. 12 | 2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity? 13 | 14 | ### 题意 15 | 一个整型数组中有两个数只出现一次,其他的数都出现两次,返回那两个数 16 | 17 | ### 方法(一) 18 | 题 Single Number 的 follow up, 不妨设最后两个只出现一次的数分别为 x1, x2. 那么遍历数组时根据两两异或的方法可得最后的结果为 x1 ^ x2, 如果我们要分别求得 x1 和 x2, 我们可以根据 x1 ^ x2 ^ x1 = x2 求得 x2, 同理可得 x_1. 那么问题来了,如何得到x1和x2呢?看起来似乎是个死循环。大多数人一般也就能想到这一步(比如我...)。 19 | 20 | 这道题的巧妙之处在于利用x1 ^ x2的结果对原数组进行了分组,进而将x1和x2分开了。具体方法则是利用了x1 ^ x2不为0的特性,如果x1 ^ x2不为0,那么x1 ^ x2的结果必然存在某一二进制位不为0(即为1),我们不妨将最低位的1提取出来,由于在这一二进制位上x1和x2必然相异,即x1, x2中相应位一个为0,另一个为1,所以我们可以利用这个最低位的1将x1和x2分开。又由于除了x1和x2之外其他数都是成对出现,故与最低位的1异或时一定会抵消,十分之精妙! -------------------------------------------------------------------------------- /113-Path-Sum-II/index.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 {number[][]} 12 | */ 13 | var pathSum = function(root, sum) { 14 | const res = [] 15 | function pathRe(root, tmpSum, eles) { 16 | if (!root) { 17 | return 18 | } 19 | tmpSum += root.val 20 | eles.push(root.val) 21 | 22 | if (root.left || root.right) { 23 | pathRe(root.left, tmpSum, eles.slice()) 24 | pathRe(root.right, tmpSum, eles.slice()) 25 | return 26 | } 27 | 28 | if (tmpSum === sum) { 29 | res.push(eles) 30 | } 31 | } 32 | pathRe(root, 0, []) 33 | return res 34 | }; 35 | 36 | function TreeNode(val) { 37 | this.val = val; 38 | this.left = this.right = null; 39 | } 40 | const root = new TreeNode(1) 41 | root.left = new TreeNode(2) 42 | 43 | 44 | console.log(pathSum(root, 3)) -------------------------------------------------------------------------------- /111-Minimum-Depth-of-Binary-Tree/index.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 | * @return {number} 11 | */ 12 | var minDepth = function(root) { 13 | if (!root) { 14 | return 0 15 | } 16 | let queue = [root] 17 | let n = 0 18 | while (queue.length !== 0) { 19 | let tmpQueue = [] 20 | while (root = queue.pop()) { 21 | if (root.left || root.right) { 22 | root.left && tmpQueue.push(root.left) 23 | root.right && tmpQueue.push(root.right) 24 | } else { 25 | return n + 1 26 | } 27 | } 28 | queue = tmpQueue 29 | n++ 30 | } 31 | return n 32 | }; 33 | 34 | function TreeNode(val) { 35 | this.val = val; 36 | this.left = this.right = null; 37 | } 38 | const root = new TreeNode(1) 39 | root.right = new TreeNode(2) 40 | root.right.right = new TreeNode(2) 41 | 42 | 43 | console.log(minDepth(root)) -------------------------------------------------------------------------------- /48-Rotate-Image/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @return {void} Do not return anything, modify matrix in-place instead. 4 | */ 5 | // var rotate = function(matrix) { 6 | // const length = matrix.length 7 | // const arr = [] 8 | // const len = length - 1 9 | // for (let m = 0; m < length; m++) { 10 | // arr[m] = [] 11 | // for (let n = 0; n < length; n++) { 12 | // arr[m][n] = matrix[len-n][m] 13 | // } 14 | // } 15 | // }; 16 | var rotate = function(matrix) { 17 | const length = matrix.length 18 | for (let n = 0; n < length - 1; n++) { 19 | for (let m = n; m < length; m++) { 20 | [matrix[m][n], matrix[n][m]] = [matrix[n][m], matrix[m][n]] 21 | } 22 | } 23 | for (let m = 0; m < length; m++) { 24 | for (let n = 0; n < length / 2; n++) { 25 | [matrix[m][length - n - 1], matrix[m][n]] = [matrix[m][n], matrix[m][length - n - 1]] 26 | } 27 | } 28 | }; 29 | 30 | var data = [[1,3,6],[7,9,5],[8,4,2]] 31 | rotate(data) 32 | console.log(data) -------------------------------------------------------------------------------- /102-Binary-Tree-Level-Order-Traversal/index.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 | * @return {number[][]} 11 | */ 12 | var levelOrder = function(root) { 13 | if (!root) { 14 | return [] 15 | } 16 | 17 | let queue = [root] 18 | const res = [] 19 | let n = 0 20 | while (queue.length !== 0) { 21 | let tmpQueue = [] 22 | res[n] = [] 23 | while (root = queue.shift()) { 24 | res[n].push(root.val) 25 | root.left && tmpQueue.push(root.left) 26 | root.right && tmpQueue.push(root.right) 27 | } 28 | queue = tmpQueue 29 | n++ 30 | } 31 | return res 32 | }; 33 | 34 | function TreeNode(val) { 35 | this.val = val; 36 | this.left = this.right = null; 37 | } 38 | const root = new TreeNode(1) 39 | root.left = new TreeNode(2) 40 | const node1 = root.right = new TreeNode(2) 41 | node1.left = new TreeNode(3) 42 | 43 | console.log(levelOrder(root)) -------------------------------------------------------------------------------- /236-Lowest-Common-Ancestor-of-a-Binary-Tree/README.md: -------------------------------------------------------------------------------- 1 | ### 236\. Lowest Common Ancestor of a Binary Tree 2 | 3 | Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. 4 | 5 | According to the [definition of LCA on Wikipedia](https://en.wikipedia.org/wiki/Lowest_common_ancestor): “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” 6 | 7 | _______3______ 8 | / \ 9 | ___5__ ___1__ 10 | / \ / \ 11 | 6 _2 0 8 12 | / \ 13 | 7 4 14 | 15 | For example, the lowest common ancestor (LCA) of nodes `5` and `1` is `3`. Another example is LCA of nodes `5` and `4` is `5`, since a node can be a descendant of itself according to the LCA definition. 16 | 17 | ### 方法(一) 18 | 二种情况。 19 | 1. v和w有直系关系,就像5和6或者6和3 20 | 2. v和w没有直系关系 21 | 第二种情况一定分别在T节点的左右子树上,而且也仅有T节点的左右子树分别有这两个节点。这里用递归找左右子树中是否有这两个节点。如果左右子树中都有,那祖先节点就是当前节点,如果只有左或者只有右子树上找到节点,说明是第一种情况返回找到的节点就可以了。 22 | 23 | -------------------------------------------------------------------------------- /107-Binary-Tree-Level-Order-Traversal-II/index.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 | * @return {number[][]} 11 | */ 12 | var levelOrderBottom = function(root) { 13 | if (!root) { 14 | return [] 15 | } 16 | const res = [] 17 | let queue = [root] 18 | 19 | let n = 0 20 | while (queue.length !== 0) { 21 | let tmpQueue = [] 22 | res[n] = [] 23 | while (root = queue.shift()) { 24 | res[n].push(root.val) 25 | root.left && tmpQueue.push(root.left) 26 | root.right && tmpQueue.push(root.right) 27 | } 28 | queue = tmpQueue 29 | n++ 30 | } 31 | return res.reverse() 32 | }; 33 | 34 | function TreeNode(val) { 35 | this.val = val; 36 | this.left = this.right = null; 37 | } 38 | const root = new TreeNode(1) 39 | root.left = new TreeNode(2) 40 | const node1 = root.right = new TreeNode(4) 41 | node1.left = new TreeNode(3) 42 | 43 | console.log(levelOrderBottom(root)) -------------------------------------------------------------------------------- /222-Count-Complete-Tree-Nodes/index.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 | * @return {number} 11 | */ 12 | var countNodes = function(root) { 13 | let leftRoot = root 14 | let leftHeight = 0 15 | let rightRoot = root 16 | let rightHeight = 0 17 | 18 | while (leftRoot) { 19 | leftRoot = leftRoot.left 20 | leftHeight++ 21 | } 22 | while (rightRoot) { 23 | rightRoot = rightRoot.right 24 | rightHeight++ 25 | } 26 | if (leftHeight === rightHeight) { 27 | return 2 ** leftHeight - 1 28 | } 29 | return 1 + countNodes(root.left) + countNodes(root.right) 30 | }; 31 | 32 | 33 | function TreeNode(val) { 34 | this.val = val; 35 | this.left = this.right = null; 36 | } 37 | const root = new TreeNode(1) 38 | root.left = new TreeNode(2) 39 | root.right = new TreeNode(3) 40 | root.left.left = new TreeNode(4) 41 | root.left.right = new TreeNode(5) 42 | root.right.left = new TreeNode(6) 43 | root.right.right = new TreeNode(7) 44 | 45 | console.log(countNodes(root)) -------------------------------------------------------------------------------- /229-Majority-Element-II/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number[]} 4 | */ 5 | 6 | var majorityElement = function(nums) { 7 | let major1 8 | let major2 9 | let major1Cnt = 0 10 | let major2Cnt = 0 11 | for (let num of nums) { 12 | if (num === major1) { 13 | major1Cnt++ 14 | } else if (num === major2) { 15 | major2Cnt++ 16 | } else if (major1Cnt === 0) { 17 | major1 = num 18 | major1Cnt++ 19 | } else if (major2Cnt === 0) { 20 | major2 = num 21 | major2Cnt++ 22 | } else { 23 | major1Cnt-- 24 | major2Cnt-- 25 | } 26 | } 27 | 28 | major1Cnt = 0 29 | major2Cnt = 0 30 | for (let num of nums) { 31 | if (num === major1) { 32 | major1Cnt++ 33 | } else if (num === major2) { 34 | major2Cnt++ 35 | } 36 | } 37 | 38 | const res = [] 39 | const cnt = Math.floor(nums.length / 3) 40 | if (major1Cnt > cnt) { 41 | res.push(major1) 42 | } 43 | if (major2Cnt > cnt) { 44 | res.push(major2) 45 | } 46 | return res 47 | }; 48 | 49 | console.log(majorityElement([1,2])) -------------------------------------------------------------------------------- /2-Add-Two-Numbers/index.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} l1 10 | * @param {ListNode} l2 11 | * @return {ListNode} 12 | */ 13 | 14 | /** 15 | 分析 16 | 3 4 5 17 | 3 1 4 18 | 19 | sum = new node(6) 20 | head = sum 21 | tail = sum 22 | 23 | sum = new node(5) 24 | tail.next = sum 25 | tail = tail.next 26 | 27 | 28 | sum = new node(9) 29 | tail.next = sum 30 | tail = tail.next 31 | */ 32 | 33 | function ListNode(val) { 34 | this.val = val; 35 | this.next = null; 36 | } 37 | 38 | var addTwoNumbers = function(l1, l2) { 39 | let tail 40 | let head 41 | let carry = 0 42 | while (l1 || l2 || carry) { 43 | let sum = carry + (l1 ? l1.val : 0) + (l2 ? l2.val : 0) 44 | carry = Math.floor(sum / 10) 45 | let res = new ListNode(sum % 10) 46 | if (!head) { 47 | head = res 48 | tail = res 49 | } else { 50 | tail.next = res 51 | tail = tail.next 52 | } 53 | 54 | l1 = l1 && l1.next 55 | l2 = l2 && l2.next 56 | } 57 | 58 | return head 59 | }; 60 | 61 | -------------------------------------------------------------------------------- /236-Lowest-Common-Ancestor-of-a-Binary-Tree/index.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 {TreeNode} p 11 | * @param {TreeNode} q 12 | * @return {TreeNode} 13 | */ 14 | var lowestCommonAncestor = function(root, p, q) { 15 | if (root == p || root == q || !root) { 16 | return root 17 | } 18 | let left = lowestCommonAncestor(root.left, p, q) 19 | let right = lowestCommonAncestor(root.right, p, q) 20 | 21 | if (left && right) { 22 | return root 23 | } else if (left) { 24 | return left 25 | } else if (right) { 26 | return right 27 | } else { 28 | return null 29 | } 30 | }; 31 | function TreeNode(val) { 32 | this.val = val; 33 | this.left = this.right = null; 34 | } 35 | const root = new TreeNode(4) 36 | root.left = new TreeNode(2) 37 | root.right = new TreeNode(6) 38 | root.left.left = new TreeNode(1) 39 | root.left.right = new TreeNode(3) 40 | root.right.left = new TreeNode(5) 41 | root.right.right = new TreeNode(7) 42 | 43 | console.log(lowestCommonAncestor(root, root.right.left, root.right)) -------------------------------------------------------------------------------- /74-Search-a-2D-Matrix/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @param {number} target 4 | * @return {boolean} 5 | */ 6 | 7 | // function bSearch(arr, low, high, target) { 8 | // if (low > high) { 9 | // return false 10 | // } 11 | // 12 | // let mid = Math.floor((low + high) / 2) 13 | // 14 | // if (arr[mid] < target) { 15 | // return bSearch(arr, mid + 1, high, target) 16 | // } else if (arr[mid] > target) { 17 | // return bSearch(arr, 0, mid - 1, target) 18 | // } 19 | // return true 20 | // } 21 | 22 | function bSearch(arr, target) { 23 | let low = 0 24 | let high = arr.length - 1 25 | while (low <= high) { 26 | let mid = Math.floor((low + high) / 2) 27 | if (target > arr[mid]) { 28 | low = mid + 1 29 | } else if (target < arr[mid]) { 30 | high = mid - 1 31 | } else { 32 | return true 33 | } 34 | } 35 | return false 36 | } 37 | 38 | var searchMatrix = function(matrix, target) { 39 | const arr = [].concat(...matrix) 40 | return bSearch(arr, target) 41 | }; 42 | 43 | console.log(searchMatrix([ 44 | [1, 3, 5, 7], 45 | [10, 11, 16, 20], 46 | [23, 30, 34, 50] 47 | ], 0)) -------------------------------------------------------------------------------- /235-Lowest-Common-Ancestor-of-a-Binary-Search-Tree/index.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 {TreeNode} p 11 | * @param {TreeNode} q 12 | * @return {TreeNode} 13 | */ 14 | var lowestCommonAncestor = function(root, p, q) { 15 | if (!root) { 16 | return null 17 | } 18 | const queue = [root] 19 | while (root = queue.shift()) { 20 | if (root.val === p.val || root.val === q.val || (root.val > p.val && root.val < q.val) || (root.val < p.val && root.val > q.val)) { 21 | return root 22 | } else { 23 | root.left && queue.push(root.left) 24 | root.right && queue.push(root.right) 25 | } 26 | } 27 | return null 28 | }; 29 | 30 | function TreeNode(val) { 31 | this.val = val; 32 | this.left = this.right = null; 33 | } 34 | const root = new TreeNode(4) 35 | root.left = new TreeNode(2) 36 | root.right = new TreeNode(6) 37 | root.left.left = new TreeNode(1) 38 | root.left.right = new TreeNode(3) 39 | root.right.left = new TreeNode(5) 40 | root.right.right = new TreeNode(7) 41 | 42 | console.log(lowestCommonAncestor(root, root.left, root.right)) -------------------------------------------------------------------------------- /74-Search-a-2D-Matrix/index2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @param {number} target 4 | * @return {boolean} 5 | */ 6 | 7 | function bSearchRange(arr, target) { 8 | let low = 0 9 | let high = arr.length - 1 10 | while (low <= high) { 11 | let mid = Math.floor((low + high) / 2) 12 | if (target > arr[mid]) { 13 | low = mid + 1 14 | } else if (target < arr[mid]) { 15 | high = mid - 1 16 | } else { 17 | return mid 18 | } 19 | } 20 | return low - 1 21 | } 22 | 23 | function bSearch(arr, target) { 24 | let low = 0 25 | let high = arr.length - 1 26 | while (low <= high) { 27 | let mid = Math.floor((low + high) / 2) 28 | if (target > arr[mid]) { 29 | low = mid + 1 30 | } else if (target < arr[mid]) { 31 | high = mid - 1 32 | } else { 33 | return true 34 | } 35 | } 36 | return false 37 | } 38 | 39 | var searchMatrix = function(matrix, target) { 40 | const firstColArr = matrix.map(val => val[0]) 41 | const row = bSearchRange(firstColArr, target) 42 | if (row === -1) { 43 | return false 44 | } 45 | return bSearch(matrix[row], target) 46 | }; 47 | 48 | console.log(searchMatrix([[1]],0)) -------------------------------------------------------------------------------- /199-Binary-Tree-Right-Side-View/index.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 | * @return {number[]} 11 | */ 12 | var rightSideView = function(root) { 13 | const res = [] 14 | 15 | if (!root) { 16 | return [] 17 | } 18 | 19 | let queue = [root] 20 | while (queue.length !== 0) { 21 | let tmpQueue = [] 22 | for (let i = 0, len = queue.length; i < len; i++) { 23 | root = queue.shift() 24 | if (i === 0) { 25 | res.push(root.val) 26 | } 27 | root.right && tmpQueue.push(root.right) 28 | root.left && tmpQueue.push(root.left) 29 | } 30 | queue = tmpQueue 31 | } 32 | return res 33 | }; 34 | 35 | function TreeNode(val) { 36 | this.val = val; 37 | this.left = this.right = null; 38 | } 39 | const root = new TreeNode(1) 40 | root.left = new TreeNode(2) 41 | root.right = new TreeNode(3) 42 | root.left.left = new TreeNode(4) 43 | root.left.left.right = new TreeNode(8) 44 | root.left.right = new TreeNode(5) 45 | root.right.left = new TreeNode(6) 46 | root.right.right = new TreeNode(7) 47 | 48 | console.log(rightSideView(root)) -------------------------------------------------------------------------------- /101-Symmetric-Tree/index2.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 | * @return {boolean} 11 | */ 12 | var isSymmetric = function(root) { 13 | if (root) { 14 | let left = root.left 15 | let right = root.right 16 | const leftStack = [] 17 | const rightStack = [] 18 | while (left || (leftStack.length !== 0) || right || (rightStack.length !== 0)) { 19 | while (left || right) { 20 | if (!left || !right || left.val !== right.val) { 21 | return false 22 | } 23 | leftStack.push(left) 24 | left = left.left 25 | rightStack.push(right) 26 | right = right.right 27 | } 28 | 29 | left = leftStack.pop() 30 | left = left.right 31 | right = rightStack.pop() 32 | right = right.left 33 | } 34 | } 35 | return true 36 | }; 37 | 38 | function TreeNode(val) { 39 | this.val = val; 40 | this.left = this.right = null; 41 | } 42 | const p = new TreeNode(1) 43 | p.left = new TreeNode(2) 44 | p.right = new TreeNode(3) 45 | 46 | console.log(isSymmetric(p)) -------------------------------------------------------------------------------- /56-Merge-Intervals/index.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 {Interval[]} 11 | */ 12 | var merge = function(intervals) { 13 | intervals.sort((a, b) => { 14 | if (a.start > b.start) { 15 | return -1 16 | } else if (a.start < b.start) { 17 | return 1 18 | } 19 | return 0 20 | }) 21 | for (let i = intervals.length - 1; i > 0; i--) { 22 | if (!(intervals[i].start > intervals[i - 1].end || intervals[i - 1].start > intervals[i].end)) { 23 | intervals[i - 1].start = Math.min(intervals[i - 1].start, intervals[i].start) 24 | intervals[i - 1].end = Math.max(intervals[i - 1].end, intervals[i].end) 25 | intervals.splice(i, 1) 26 | } 27 | } 28 | return intervals.reverse() 29 | }; 30 | 31 | 32 | function Interval(start, end) { 33 | this.start = start; 34 | this.end = end; 35 | } 36 | 37 | let intervals = [new Interval(2,3), new Interval(0,1), new Interval(5,7), new Interval(4,6), new Interval(5,5), new Interval(4,6), new Interval(5,6), new Interval(1,3), new Interval(4,4), new Interval(0,0), new Interval(3,5), new Interval(2,2)] 38 | console.log(merge(intervals)) -------------------------------------------------------------------------------- /105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/index.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 {number[]} preorder 10 | * @param {number[]} inorder 11 | * @return {TreeNode} 12 | */ 13 | var buildTree = function(preorder, inorder) { 14 | const map = {} 15 | inorder.forEach((val, index) => map[val] = index) 16 | 17 | function buildTreeByOrder(preorder, start1, end1, inorder, start2, end2) { 18 | if (start1 > end1 || start2 > end2) { 19 | return null 20 | } 21 | let rootVal = preorder[start1] 22 | let rootValIndex = map[rootVal] 23 | let lLen = rootValIndex - start2 24 | let root = new TreeNode(rootVal) 25 | 26 | root.left = buildTreeByOrder(preorder, start1 + 1, start1 + lLen, inorder, start2, rootValIndex - 1) 27 | root.right = buildTreeByOrder(preorder, start1 + lLen + 1, end1, inorder, rootValIndex + 1, end2) 28 | 29 | return root 30 | } 31 | return buildTreeByOrder(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1) 32 | }; 33 | 34 | function TreeNode(val) { 35 | this.val = val; 36 | this.left = this.right = null; 37 | } 38 | 39 | console.log(buildTree([1,2,4,5,3,6,7], [4,2,5,1,6,3,7])) -------------------------------------------------------------------------------- /106-Construct-Binary-Tree-from-Inorder-and-Postorder-Traversal/index.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 {number[]} inorder 10 | * @param {number[]} postorder 11 | * @return {TreeNode} 12 | */ 13 | var buildTree = function(inorder, postorder) { 14 | const map = {} 15 | inorder.forEach((val, index) => map[val] = index) 16 | 17 | function buildTreeByOrder(inorder, start1, end1, postorder, start2, end2) { 18 | if (start1 > end1 || start2 > end2) { 19 | return null 20 | } 21 | let rootVal = postorder[end2] 22 | let rootValIndex = map[rootVal] 23 | let lLen = rootValIndex - start1 24 | let root = new TreeNode(rootVal) 25 | 26 | root.left = buildTreeByOrder(inorder, start1, rootValIndex - 1, postorder, start2, start2 + lLen - 1) 27 | root.right = buildTreeByOrder(inorder, rootValIndex + 1, end1, postorder, start2 + lLen, end2 - 1) 28 | 29 | return root 30 | } 31 | return buildTreeByOrder(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1) 32 | }; 33 | 34 | function TreeNode(val) { 35 | this.val = val; 36 | this.left = this.right = null; 37 | } 38 | 39 | console.log(buildTree([4,2,5,1,6,3,7], [4,5,2,6,7,3,1])) -------------------------------------------------------------------------------- /145-Binary-Tree-Postorder-Traversal/index.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 | * @return {number[]} 11 | */ 12 | var postorderTraversal = function(root) { 13 | const stack = [] 14 | const res = [] 15 | 16 | while (stack.length !== 0 || root) { 17 | while (root && !root.isVisited) { 18 | stack.push(root) 19 | root = root.left 20 | } 21 | let stackTop = stack[stack.length - 1] 22 | if (!stackTop) { 23 | break 24 | } 25 | if (stackTop.isVisited) { 26 | res.push(stackTop.val) 27 | root = stack.pop() 28 | } else { 29 | stackTop.isVisited = true 30 | root = stackTop.right 31 | } 32 | } 33 | return res 34 | }; 35 | 36 | 37 | function TreeNode(val) { 38 | this.val = val; 39 | this.left = this.right = null; 40 | } 41 | const root = new TreeNode(1) 42 | root.left = new TreeNode(2) 43 | root.right = new TreeNode(3) 44 | root.left.left = new TreeNode(4) 45 | root.left.left.right = new TreeNode(8) 46 | root.left.right = new TreeNode(5) 47 | root.right.left = new TreeNode(6) 48 | root.right.right = new TreeNode(7) 49 | 50 | 51 | console.log(postorderTraversal(root)) -------------------------------------------------------------------------------- /392-Is-Subsequence/README.md: -------------------------------------------------------------------------------- 1 | ### 392\. Is Subsequence 2 | 3 | Given a string s and a string t, check if s is subsequence of t. 4 | 5 | You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (\<=100). 6 | 7 | A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, `"ace"` is a subsequence of `"abcde"` while `"aec"` is not). 8 | 9 | Example 1: 10 | s = `"abc"`, t = `"ahbgdc"` 11 | 12 | Return `true`. 13 | 14 | Example 2: 15 | s = `"axc"`, t = `"ahbgdc"` 16 | 17 | Return `false`. 18 | 19 | Follow up: 20 | If there are lots of incoming S, say S1, S2, ... , Sk where k \>= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code? 21 | 22 | ### 题意 23 | 给定一个字符串s和一个字符串t,检查s是否是t的子序列。 24 | 25 | 您可以假设在s和t中只有小写英文字母。 t可能是非常长(长度〜= 500,000)字符串,并且s是短字符串(<= 100)。 26 | 27 | 字符串的子序列是一个新字符串,它通过删除一些(可以是无)字符而不干扰剩余字符的相对位置从原始字符串形成。 (即,“ace”是“abcde”的子序列,而“aec”不是)。 28 | 29 | 实施例1: 30 | s =“abc”,t =“ahbgdc” 31 | 32 | 返回true。 33 | 34 | 实施例2: 35 | s =“axc”,t =“ahbgdc” 36 | 37 | 返回false。 38 | 39 | 跟进: 40 | 如果有很多输入S,比如S1,S2,...,Sk,其中k> = 1B,并且你想逐个检查T是否有它的子序列。 在这种情况下,您将如何更改代码? 41 | 42 | ### 方法(一) 43 | 懂一点正则的人都能非常快的写出来吧 -------------------------------------------------------------------------------- /226-Invert-Binary-Tree/index.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 | * @return {TreeNode} 11 | */ 12 | var invertTree = function(root) { 13 | if (!root) { 14 | return root 15 | } 16 | let queue = [root] 17 | let invertRoot = new TreeNode(root.val) 18 | const res = invertRoot 19 | let invertQueue = [invertRoot] 20 | while (root = queue.shift()) { 21 | invertRoot = invertQueue.shift() 22 | if (root.left) { 23 | queue.push(root.left) 24 | invertRoot.right = new TreeNode(root.left.val) 25 | invertQueue.push(invertRoot.right) 26 | } 27 | if (root.right) { 28 | queue.push(root.right) 29 | invertRoot.left = new TreeNode(root.right.val) 30 | invertQueue.push(invertRoot.left) 31 | } 32 | } 33 | return res 34 | }; 35 | 36 | function TreeNode(val) { 37 | this.val = val; 38 | this.left = this.right = null; 39 | } 40 | const root = new TreeNode(1) 41 | root.left = new TreeNode(2) 42 | root.right = new TreeNode(3) 43 | root.left.left = new TreeNode(4) 44 | root.left.right = new TreeNode(5) 45 | root.right.left = new TreeNode(6) 46 | root.right.right = new TreeNode(7) 47 | 48 | console.log(invertTree(root)) -------------------------------------------------------------------------------- /57-Insert-Interval/index.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 | * @param {Interval} newInterval 11 | * @return {Interval[]} 12 | */ 13 | var insert = function(intervals, newInterval) { 14 | for (let i = intervals.length - 1; i >= 0; i--) { 15 | if (!(intervals[i].start > newInterval.end || newInterval.start > intervals[i].end)) { 16 | newInterval.start = Math.min(newInterval.start, intervals[i].start) 17 | newInterval.end = Math.max(newInterval.end, intervals[i].end) 18 | intervals.splice(i, 1) 19 | } 20 | } 21 | intervals.push(new Interval(Infinity, Infinity)) 22 | for (let i = 0; i < intervals.length; i++) { 23 | if (newInterval.start < intervals[i].start) { 24 | intervals.splice(i, 0, newInterval) 25 | break 26 | } 27 | } 28 | intervals.pop() 29 | return intervals 30 | }; 31 | 32 | function Interval(start, end) { 33 | this.start = start; 34 | this.end = end; 35 | } 36 | new Interval(1,3) 37 | // const intervals = [new Interval(1,2), new Interval(3,5), new Interval(6,7), new Interval(8,10), new Interval(12,16)] 38 | const intervals = [new Interval(1,5)] 39 | const newInterval = new Interval(6,8) 40 | console.log(insert(intervals, newInterval)) -------------------------------------------------------------------------------- /103-Binary-Tree-Zigzag-Level-Order-Traversal/index.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 | * @return {number[][]} 11 | */ 12 | var zigzagLevelOrder = function(root) { 13 | if (!root) { 14 | return [] 15 | } 16 | 17 | let queue = [root] 18 | const res = [] 19 | let n = 0 20 | while (queue.length !== 0) { 21 | let tmpQueue = [] 22 | res[n] = [] 23 | while (queue.length !== 0) { 24 | root = queue.shift() 25 | res[n].push(root.val) 26 | root.left && tmpQueue.push(root.left) 27 | root.right && tmpQueue.push(root.right) 28 | } 29 | queue = tmpQueue 30 | if (n % 2 !== 0) { 31 | res[n].reverse() 32 | } 33 | n++ 34 | } 35 | return res 36 | }; 37 | 38 | function TreeNode(val) { 39 | this.val = val; 40 | this.left = this.right = null; 41 | } 42 | // const root = new TreeNode(1) 43 | // root.left = new TreeNode(9) 44 | // const node1 = root.right = new TreeNode(20) 45 | // node1.left = new TreeNode(15) 46 | // node1.right = new TreeNode(7) 47 | 48 | const root = new TreeNode(1) 49 | root.left = new TreeNode(2) 50 | root.right = new TreeNode(3) 51 | root.left.left = new TreeNode(4) 52 | root.left.right = new TreeNode(5) 53 | root.right.left = new TreeNode(6) 54 | root.right.right = new TreeNode(7) 55 | 56 | console.log(zigzagLevelOrder(root)) -------------------------------------------------------------------------------- /142-Linked-List-Cycle-II/index.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 | let oneSpeedPointer = head 15 | let twoSpeedPointer = head 16 | 17 | while (twoSpeedPointer !== null) { 18 | oneSpeedPointer = oneSpeedPointer.next 19 | twoSpeedPointer = twoSpeedPointer.next 20 | if (twoSpeedPointer === null) { 21 | return null 22 | } 23 | twoSpeedPointer = twoSpeedPointer.next 24 | if (twoSpeedPointer === oneSpeedPointer) { 25 | oneSpeedPointer = head 26 | break 27 | } 28 | } 29 | if (twoSpeedPointer === null || twoSpeedPointer.next === null) { 30 | return null 31 | } 32 | while (oneSpeedPointer !== twoSpeedPointer) { 33 | oneSpeedPointer = oneSpeedPointer.next 34 | twoSpeedPointer = twoSpeedPointer.next 35 | } 36 | return oneSpeedPointer 37 | }; 38 | 39 | function ListNode(val) { 40 | this.val = val; 41 | this.next = null; 42 | } 43 | var head = new ListNode(1) 44 | var second = new ListNode(2) 45 | head.next = second 46 | var thrid = new ListNode(3) 47 | second.next = thrid 48 | var four = new ListNode(4) 49 | thrid.next = four 50 | var five = new ListNode(5) 51 | four.next = five 52 | var six = new ListNode(6) 53 | five.next = six 54 | six.next = second 55 | console.log(detectCycle(head)) -------------------------------------------------------------------------------- /73-Set-Matrix-Zeroes/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @return {void} Do not return anything, modify matrix in-place instead. 4 | */ 5 | var setZeroes = function(matrix) { 6 | const row = matrix.length 7 | const col = matrix[0].length 8 | let cleanFirstRowFlag = false 9 | let cleanFirstColFlag = false 10 | 11 | for (let m = 0; m < row; m++) { 12 | if (matrix[m][0] === 0) { 13 | cleanFirstColFlag = true 14 | break 15 | } 16 | } 17 | 18 | for (let m = 0; m < col; m++) { 19 | if (matrix[0][m] === 0) { 20 | cleanFirstRowFlag = true 21 | break 22 | } 23 | } 24 | 25 | for (let m = 1; m < row; m++) { 26 | for (let n = 1; n < col; n++) { 27 | if (matrix[m][n] === 0) { 28 | matrix[0][n] = matrix[m][0] = 0 29 | } 30 | } 31 | } 32 | 33 | for (let m = 1; m < row; m++) { 34 | if (matrix[m][0] === 0) { 35 | for (let i = 0; i < col; i++) { 36 | matrix[m][i] = 0 37 | } 38 | } 39 | } 40 | for (let m = 1; m < col; m++) { 41 | if (matrix[0][m] === 0) { 42 | for (let i = 0; i < row; i++) { 43 | matrix[i][m] = 0 44 | } 45 | } 46 | } 47 | 48 | if (cleanFirstRowFlag) { 49 | for (let m = 0; m < col; m++) { 50 | matrix[0][m] = 0 51 | } 52 | } 53 | 54 | if (cleanFirstColFlag) { 55 | for (let m = 0; m < row; m++) { 56 | matrix[m][0] = 0 57 | } 58 | } 59 | }; 60 | var matrix = [[0,1,1,0],[1,0,1,1],[1,1,1,1],[0,1,1,1]] 61 | setZeroes(matrix) 62 | console.log(matrix) -------------------------------------------------------------------------------- /134-Gas-Station/README.md: -------------------------------------------------------------------------------- 1 | ### 134\. Gas Station 2 | 3 | There are *N* gas stations along a circular route, where the amount of gas at station *i* is `gas[i]`. 4 | 5 | You have a car with an unlimited gas tank and it costs `cost[i]` of gas to travel from station *i* to its next station (*i*+1). You begin the journey with an empty tank at one of the gas stations. 6 | 7 | Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. 8 | 9 | Note: 10 | The solution is guaranteed to be unique. 11 | 12 | ### 题意 13 | 沿着圆形路线有N个加油站,其中站i处的气体量是气体[i]。 14 | 15 | 你有一辆带有无限气罐的汽车,并且它花费从站i到其下一站(i + 1)的气体的成本[i]。 你从一个加油站开着一辆没油的坦克开始旅程。 16 | 17 | 如果您可以绕回路运行一次,返回起始加油站的索引,否则返回-1。 18 | 19 | 注意: 20 | 解决方案保证是唯一的。 21 | 22 | ### 方法(一) 23 | 复制别人的解法 24 | [leetcode-gas-station](http://bangbingsyb.blogspot.jp/2014/11/leetcode-gas-station.html) 25 | 这题要想清楚不容易,尽管想清楚后代码写起来很简单。 26 | 27 | I. 显然当gas[i]\i-\>i的路径,而这个路径会覆盖j-\>j一周的路径。那么j也将是一个符合条件的起点。与唯一解的限制条件矛盾。 38 | 39 | 性质3\. 假如i是最后的解,则由1可知,从0 ~ i-1出发无法达到i。而从i出发可以到达i+1 ~ n-1。 40 | 41 | 结合以上三条性质,得出解决的思路: 42 | 43 | 0\. 如果对所有加油站的sum(gas[i] - cost[i])\<0,则无解。否则进入1。 44 | 45 | 1\. 从0开始计算sum(gas[i] - cost[i]),当遇到i1使sum\<0时,说明从0出发无法到达i1。根据性质1,0不是起始点。而由于从0出发已经到达了1 ~ i1-1。根据性质2,1 ~ i1-1一定不是正确的起始点。此时i1为起始点的候选。 46 | 47 | 2\. 将sum清0,并从i1出发,假如又遇到i2使sum(gas[i] - cost[i]) \< 0 时,说明i1出发无法绕一圈,更具性质1,排除i1。又因为i1+1 ~ i2-1都能从i1出发到达,。根据性质2,它们也必然不是起始点。此时i2为起始点的候选。 48 | 49 | 3\. 以此类推,直到遇到ik,使从ik出发可以到达ik+1 ~ n-1。 50 | 51 | 其中步骤0可以合并到1~3的扫描中,一个pass来得到解。 52 | 53 | -------------------------------------------------------------------------------- /393-UTF-8-Validation/README.md: -------------------------------------------------------------------------------- 1 | ### 393\. UTF-8 Validation 2 | 3 | A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules: 4 | 5 | 1. For 1-byte character, the first bit is a 0, followed by its unicode code. 6 | 2. For n-bytes character, the first n-bits are all one's, the n+1 bit is 0, followed by n-1 bytes with most significant 2 bits being 10. 7 | 8 | This is how the UTF-8 encoding would work: 9 | 10 | ``` 11 | Char. number range | UTF-8 octet sequence 12 | (hexadecimal) | (binary) 13 | --------------------+--------------------------------------------- 14 | 0000 0000-0000 007F | 0xxxxxxx 15 | 0000 0080-0000 07FF | 110xxxxx 10xxxxxx 16 | 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 17 | 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 18 | 19 | ``` 20 | 21 | Given an array of integers representing the data, return whether it is a valid utf-8 encoding. 22 | 23 | Note: 24 | The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data. 25 | 26 | Example 1: 27 | 28 | data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001. 29 | 30 | Return true. 31 | It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character. 32 | 33 | Example 2: 34 | 35 | data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100. 36 | 37 | Return false. 38 | The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character. 39 | The next byte is a continuation byte which starts with 10 and that's correct. 40 | But the second continuation byte does not start with 10, so it is invalid. 41 | 42 | ### 方法(一) 43 | 想不好写什么,还是看代码吧 -------------------------------------------------------------------------------- /8-String-to-Integer(atoi)/README.md: -------------------------------------------------------------------------------- 1 | ### 8\. String to Integer (atoi) 2 | 3 | QuestionEditorial Solution 4 | 5 | [My Submissions](https://leetcode.com/problems/string-to-integer-atoi/submissions/) 6 | 7 | * Total Accepted: 130038 8 | * Total Submissions: 944237 9 | * Difficulty: Easy 10 | * Contributors: Admin 11 | 12 | Implement atoi to convert a string to an integer. 13 | 14 | Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. 15 | 16 | Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. 17 | 18 | Update (2015-02-10): 19 | The signature of the `C++` function had been updated. If you still see your function signature accepts a `const char *` argument, please click the reload button to reset your code definition. 20 | 21 | [spoilers alert... click to show requirements for atoi.](https://leetcode.com/problems/string-to-integer-atoi/#) 22 | 23 | Requirements for atoi: 24 | 25 | The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. 26 | 27 | The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. 28 | 29 | If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. 30 | 31 | If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT\_MAX (2147483647) or INT\_MIN (-2147483648) is returned. 32 | 33 | ### 方法(一) 34 | 这题不能说这出来,借助了parseInt这个方法,这个方法和atoi很类似。有空再来实现一下parseInt吧 --------------------------------------------------------------------------------