JS-LeetCode算法目录(持续更新)

358 阅读14分钟

是我刷过的算法题答案,持续更新

第一天

compare-version-numbers

js版本,就是不足的用0的补齐

function compare(a, b) {
  let n1 = parseInt(a, 10);
  let n2 = parseInt(b, 10);
  if (n1 > n2) {
    return 1;
  } else if (n1 < n2) {
    return -1;
  } else {
    return 0;
  }
}

var compareVersion = function(version1, version2) {
  let m = version1.split('.');
  let n = version2.split('.');
  let i = 0;
  let j = 0;
  while(i < m.length || j < n.length) {
     let a, b;
     a = i < m.length ? m[i] : '0';
     b = j < n.length ? n[j] : '0';
     let res = compare(a, b);
     if (res === 0) {
        i++;
        j++;
     } else {
        return res;
     }
     
  }
  return 0;
};

知道大于某个数的值的个数

提供一个有序数组,然后找到小于这个数的个数

[1, 2, 3, 4]
2
// 1

下面是我的代码,采用二分算法,但是需要计算之前的数字

function find(arr, val) {
  let sum = 0;
  let index = Math.floor(arr.length / 2);
  let center = arr[index];
  while(arr.length > 0) {
    if (center < val) {
      sum += index + 1;
      if (arr[index + 1] < val) {
        arr = arr.splice(index + 1)
        index = Math.floor(arr.length / 2);
        center = arr[index];
      } else {
        return sum;
      }
    } else {
      arr = arr.splice(0, index);
      index = Math.floor(arr.length  / 2);
      center = arr[index];
    }
  }
  return sum;
}

letter-combinations-of-a-phone-number

这道题有毒,我用执行代码就能通过,但是一提交就不行

  1. 先提供一个映射表
  2. 确定前面的可能,在和后面的组合
const map = {
  2: ['a', 'b', 'c'],
  3: ['d', 'e', 'f'],
  4: ['g', 'h', 'i'],
  5: ['j', 'k', 'l'],
  6: ['m', 'n', 'o'],
  7: ['p', 'q', 'r', 's'],
  8: ['t', 'u', 'v'],
  9: ['w', 'x', 'y', 'z']
}
var list = [];

function traceBack(front, letters) {
  if (letters.length == 0) {
    list.push(front);
    return false;
  }
  const firstStr = letters.substring(0, 1);
  const codeArr = map[firstStr];
  for (let i = 0; i < codeArr.length; i++) {
    traceBack(front + codeArr[i], letters.substring(1))
  }
}
var letterCombinations = function (digits) {
  if (digits.length > 0) {
    traceBack('', digits);
    return list;
  } else {
    return []
  }
};

happy-number

如果是快乐数,那么生成值不会重复

function auxiliary(num) {
  let last = 0;
  while (num > 0) {
    const current = num % 10;
    last += current ** 2;
    num = Math.floor(num / 10);
  }
  return last;
}
var isHappy = function(n) {
    let set = new Set();
    while (n !== 1) {
        n = auxiliary(n);
        if (!set.has(n)) {
            set.add(n);
        } else {
            return false;
        }
    }
    return true;
};

reverse-linked-list

翻转链表

var reverseList = function(head) {
    let pre = null;
    let cur = head;
    while(cur) {
        let temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
};

是否是合法的IPv4,IPv6

ip4和ip6区分开,然后进行判断

function ipV4(ip) {
  const arr = ip.split('.');
  if(arr.length !== 4) {
    return false;
  }
  for (let i = 0; i < arr.length; i++) {
      const bool = arr[i] >= 0 && arr[i] <= 255;
      const firStr = arr[i].substring(0, 1);
      const second = arr[i].substring(1, 2);
      if (second && parseInt(firStr) === 0) {
          return false;
      }
      if (arr[i] == '') {
          return false;
      }
      if (!bool || /[^0-9]/gi.test(arr[i])) {
          return false;
      }
  }
  return true;
}

function ipV6(ip) {
  const arr = ip.split(':');
  if (arr.length !== 8) {
      return false;
  }
  for (let i = 0; i < arr.length; i++) {
      const bool2 = arr[i].length > 4;
      const bool1 = /[^a-f0-9]/gi.test(arr[i]);
      if (arr[i] === '') {
          return false;
      }
      if (bool2 || bool1) {
          return false;
      }
  }
  return true;
}

var validIPAddress = function(IP) {
  const IsIpV4 = IP.includes('.');
  if (IsIpV4) {
      return ipV4(IP) ? 'IPv4' : 'Neither'
  } else {
      return ipV6(IP) ? 'IPv6' : 'Neither'
  }
};

merge-two-sorted-lists

写了这道题让我走出了一个误区,就是给我一个链表我要是给next赋值,并不是放在最后面,是直接把这个链表的next值改了,如果是原来长度是5,现在给next赋值以后,他的长度就是2了,要走出这个误区

 var mergeTwoLists = function(l1, l2) {
  const list = new ListNode(0);
  let prev = list;
  while(l1 && l2) {
      let temp;
      if (l1.val > l2.val) {
        prev.next = l2;
        l2 = l2.next;
      } else {
        prev.next = l1;
        l1 = l1.next;
      }
      prev = prev.next;
  }

  if (l1) prev.next = l1;
  if (l2) prev.next = l2;
  return list.next;
};

validate-binary-search-tree

var isValidBST = function(root) {
    const stack = [{
        root,
        lower: -Infinity,
        upper: Infinity,
    }];
    while (stack.length > 0) {
        const params = stack.shift();
        root = params.root;
        lower = params.lower;
        upper = params.upper;
        if (!root) {
            continue;
        }
        const val = root.val;
        if (val <= lower || val >= upper) {
            return false;
        }
        stack.push({root: root.right, lower: val, upper: upper})
        stack.push({root: root.left, lower: lower, upper: val})
    }
    return true;
};

reverse-integer

如何取反

var reverse = function(x) {
  let res = 0;
  const max = Math.pow(2, 31) -1 ;
  const min = -Math.pow(2, 31)
  while (x !== 0) {
      res = res * 10 + x % 10;
      x = ~~(x / 10);
  }
  if (res > max) return 0;
  if (res < min) return 0;
  return res;
};

min-stack

就是用两个数组来存储,一个是构造的列表,另外一个降序的列表

var MinStack = function() {
    this.values = [];
    this.min = [];
};


/** 
 * @param {number} x
 * @return {void}
 */
MinStack.prototype.push = function(x) {
    const values = this.values;
    values.push(x);
    const min = this.min;
    if (min.length === 0 || x <= min[min.length - 1]) {
        min.push(x)
    }
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    const value = this.values.pop();
    const min = this.min;
    if (min[min.length - 1] === value) {
        min.pop();
    }
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    const values = this.values;
    return values[values.length - 1]
};

diameter-of-binary-tree

使用递归进行解决

var diameterOfBinaryTree = function(root) {
    let result = 0;
    function deep(root) {
        if (!root) return -1;
        let left = root.left ? deep(root.left) + 1 : 0;
        let right = root.right ? deep(root.right) + 1 : 0;

        result = Math.max(left + right, result);
        return Math.max(left, right);
    }
    deep(root);
    return result;
};

merge-sorted-array

var merge = function(nums1, m, nums2, n) {
    for (let i = 0; i < n; i++) {
        nums1[m] = nums2[i];
        m += 1;
    }
    nums1.sort((a, b) => {
        return a - b;
    })
};

best-time-to-buy-and-sell-stock

var maxProfit = function(prices) {
    if (prices.length < 2) {
        return 0;
    }
    let max = 0;
    let min = prices[0];
    for (let i = 0; i < prices.length; i++) {
        max = Math.max(max, prices[i] - min);
        min = Math.min(prices[i], min)
    }
    return max;
};

longest-substring-without-repeating-characters

主要思路就是用双指针

function lengthOfLongestSubstring(s) {
  let max = 0;
  let start = 0;
  let st = {};
  for (let end = 0; end < s.length; end++) {
    const key = s[end];
    if (st[key]) {
      start = Math.max(st[key], start)
    }
    max = Math.max(max, end - start + 1);
    st[key] = end + 1;
  }
  return max;
}

reverse-linked-list

翻转链表

var reverseList = function(head) {
    let pre = null;
    let cur = head;
    while(cur) {
        let temp = cur.next;
        cur.next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
};

第三天

delete-node-in-a-bst

var deleteNode = function(root, key) {
    let node;
    // 取出子树在进行排序
    if (root === null) {
        return root;
    }
    if (key === root.val) {
        if (root.left === null) {
            return root.right;
        } else if (root.right === null) {
            return root.left;
        } else {
            node = root.right;
            while (node.left !== null) {
                node = node.left;
            }
            node.left = root.left;
            return root.right;
        }
    } else if (key > root.val) {
        root.right = deleteNode(root.right, key);
    } else {
        root.left = deleteNode(root.left, key)
    }
    return root;
};

lowest-common-ancestor-of-a-binary-tree

如果当前结点root等于NULL,则直接返回NULL
如果root等于p或者q,那这棵树一定返回p或者q
然后看递归左右子树(因为是递归,使用函数后可以认为左右子树已经算出了结果,用left和right表示;
此时若left为空,那最终结果只要看right; 若right为空,那最终结果只要看left;
如果left和right都非空,因为只给了p和q两个结点,都非空,说明一边一个,因此root是他们的最近公共祖先;
如果left和right都为空,则返回空

感觉用文字不用容易理解可以用简单的例子来进行讲解

    1
   / \
  2   8
 / \   
3   4   

如果需要求导34和共同祖先,可以对比思考一下

var lowestCommonAncestor = function(root, p, q) {
    if (root === null) return null;
    if (root === p || root === q) {
        return root;
    }

    const left = lowestCommonAncestor(root.left, p, q);
    const right = lowestCommonAncestor(root.right, p, q);
    if (left !== null && right !== null) {
        return root;
    } else if (left !== null) {
        return left;
    } else if (right !== null) {
        return right;
    }
    return null;
};

kth-largest-element-in-an-array

这道题虽然简单,但好歹是自己实现的

var findKthLargest = function(nums, k) {
    const sortArr = nums.sort((a, b) => b - a);
    return sortArr[k - 1]
};

第四天

valid-parentheses

正则表达式

var isValid = function(s) {
    let bool = s.includes('{}') || s.includes('[]') || s.includes('()');
    while (bool) {
        s = s.replace('[]', '')
            .replace('{}', '')
            .replace('()', '')
        bool = s.includes('{}') || s.includes('[]') || s.includes('()');
    }
    return s === '';
};

辅助栈

var isValid = function(s) {
  const stack = [];
  for (let i = 0; i < s.length; i++) {
      let str = s[i];
      let len = stack.length - 1;
      if (stack[len] === str) {
          stack.pop();
          continue;
      } 
      if (str === '(') stack.push(')');
      else if (str === '[') stack.push(']')
      else if (str === '{') stack.push('}')
      else if (stack.length === 0 || stack[len] !== str) stack.push(str)
  }
  return stack.length === 0
};

climbing-stairs

这道题使用动态规划的思路,例如到第10层,有两种方法从8层跳动两格,或者从第9格跳到第十格,那么fn(10) = fn(8) + f(9),然后在采用自顶向下的方式:

var climbStairs = function(n) {
  if (n < 1) return 0;
  const result = [];
  let i = 1;
  while (i <= n) {
      if (i === 1) {
          result[i] = 1;
      } else if (i === 2) {
          result[i] = 2;
      } else {
          result[i] = result[i - 1] + result[i - 2] 
      }
      i++;
  }
  return result[n];
};

unique-paths

这里使用动态规划,在

在某个点的位置就等于(m-1, n)(m, n - 1)然后从下开始算,可以就可以算到结果

var uniquePaths = function(m, n) {
    let res = [];
    for (let i = 0; i < m; i++) {
        res[i] = [];
        res[i][0] = 1;
    }
    for (let j = 0; j < n; j++) {
        res[0][j] = 1;
    }
    for (let i = 1; i < m; i++) {
        for (let j = 1; j < n; j++) {
            res[i][j] = res[i - 1][j] + res[i][j - 1];
        }
    }
    return res[m - 1][n - 1];
};

last-stone-weight

var lastStoneWeight = function(stones) {
    let x, y;
 while (stones.length >= 2) {
     stones.sort((a, b) => b - a);
     y = stones.shift();
     x = stones.shift();
     if (x === y) {
         continue;
     } else {
         stones.push(y - x);
     }
 }
 return stones[0] || 0;
};

container-with-most-water

function maxArea(height) {
  let max = 0;
  let start = 0;
  let area = 0;
  let end = height.length - 1;
  while (start !== end) {
    if (height[start] > height[end]) {
      area = height[end] * Math.abs(end - start);
      max = Math.max(max, area);
      end--;
    } else {
      area = height[start] * Math.abs(end - start);
      max = Math.max(max, area);
      start++;
    }
  }
  return max;
}

maximum-depth-of-binary-tree

var maxDepth = function(root) {
  let left = 0;
  let right = 0;
  if (!root) return 0;
  left = maxDepth(root.left) + 1;
  right = maxDepth(root.right) + 1;
  return Math.max(left, right);
};

single-number

var singleNumber = function(nums) {
    nums = nums.sort((a, b) => a - b);
    let i = 0;
    while (i < nums.length) {
        if (nums[i] === nums[i + 1]) {
            i += 2;
            continue;
        } else {
            return nums[i];
        }
    }
}; 

find-pivot-index

var pivotIndex = function(nums) {
    let sum = 0, leftSum = 0;
    nums.forEach((val) => {
        sum += val;
    })
    for (let i = 0; i < nums.length; i++) {
        if (leftSum * 2 + nums[i] === sum) {
            return i;
        }
        leftSum += nums[i];
    }
    return -1;
};

maximum-subarray

/**
 * @param {number[]} nums
 * @return {number}
 */
var maxSubArray = function(nums) {
    let sum = nums[0];
    let max = nums[0];
    for (let i = 1; i < nums.length; i++) {
        if (sum > 0) {
            sum += nums[i];
        } else {
            sum = nums[i]
        }
        max = Math.max(sum, max);
    }
    return max;
};

n-ary-tree-postorder-traversal

var postorder = function(root) {
    const res = [];
    const stack = [];
    stack.push(root);
    while(stack.length > 0) {
      const node = stack.pop();
      if (!node) {
          continue;
      }
      res.push(node.val);
      for (let i = 0; i < node.children.length; i++) {
        child = node.children[i];
        console.log(child);
        stack.push(child)
      }
    }
    return res.reverse();
};

repeated-substring-pattern

var repeatedSubstringPattern = function(s) {
    let reg = /^(\w+)\1+$/
    return reg.test(s)
};

第五天

path-sum

迭代一

var hasPathSum = function(root, sum) {
    if (root === null) {
        return false;
    }
    sum -= root.val;
    if (root.left == null && root.right == null) {
        return sum == 0;
    }
    return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);
};

迭代二

var hasPathSum = function(root, sum) {
    if (!root) {
        return false;
    }
    const stacks = [];
    stacks.push({
        root: root,
        sum: sum - root.val,
    });
    while (stacks.length > 0) {
        let stack = stacks.pop();
        const node = stack.root;
        sum = stack.sum;
        console.log(sum);
        if (!node.left && !node.right && sum == 0) {
            return true;
        }
        if (node.left) {
            stacks.push({
                root: node.left,
                sum: sum - node.left.val,
            })
        }
        if (node.right) {
            stacks.push({
                root: node.right,
                sum: sum - node.right.val
            })
        }
    }
    return false;
};

count-primes

function countPrimes(n) {
  const primesArr = Array.from({length: n}).fill(true);
  for (let i = 2; i < n; i++) {
    if (primesArr[i]) {
      for (let j = i * i; j < n; j += i) {
        primesArr[j] = false;
      }
    }
  }
  let count = 0;
  for (let i = 2; i < n; i++) {
    if (primesArr[i]) count++
  }
  return count;
}

binary-tree-preorder-traversal

var preorderTraversal = function(root) {
    if (root === null) return [];
    const stacks = [];
    stacks.push(root);
    const res = [];
    while (stacks.length > 0) {
        const stack = stacks.pop();
        res.push(stack.val);
        if (stack.right) {
            stacks.push(stack.right)
        }
        if (stack.left) {
            stacks.push(stack.left)
        }
    }
    return res;
};

permutations

var permute = function (nums) {
    var len = nums.length;
    var output = [];
    function backtrack(first = 0) {
        if (first >= len) {
            output.push(nums.slice());
            return false;
        }
        for (let i = first; i < len; i++) {
            [nums[first], nums[i]] = [nums[i], nums[first]]
            backtrack(first + 1);
            [nums[first], nums[i]] = [nums[i], nums[first]]
        }
    }
    backtrack();
    return output;
};

shuffle-an-array

var Solution = function(nums) {
    this.values = nums;
};

/**
 * Resets the array to its original configuration and return it.
 * @return {number[]}
 */
Solution.prototype.reset = function() {
    return this.values;
};

/**
 * Returns a random shuffling of the array.
 * @return {number[]}
 */
Solution.prototype.shuffle = function() {
    const copyArr = this.values.slice();
    let len = copyArr.length;
    let len_1 = copyArr.length - 1;
    for (let i = 0; i < len_1; i++) {
        let index = Math.floor(Math.random() * (len - i));
        let temp = copyArr[index];
        copyArr[index] = copyArr[len_1 - i];
        copyArr[len_1 - i] = temp;
    }
    return copyArr;
};

increasing-subsequences

function dfs(result, nums, cur, index) {
    cur = cur.slice();
    if (index === nums.length && cur.length > 1) {
        result.push(cur)
    }

    if (index < nums.length) {
        if (cur.length === 0 || nums[index] >= cur[cur.length - 1]) {
            cur.push(nums[index]);
            dfs(result, nums, cur, index + 1);
            cur.pop();
        }
        if (cur.length === 0 || nums[index] != cur[cur.length - 1]) {
            dfs(result, nums, cur, index + 1)
        }
    }
}
var findSubsequences = function(nums) {
    let result = [];
    let cur = [];
    dfs(result, nums, cur, 0);
    return result;
};

longest-common-prefix

var longestCommonPrefix = function(strs) {
    if (strs)
    if (strs.length === 0) {
        return ''
    }
    let str = strs[0];
    for (let i = 1; i < strs.length; i++) {
        while (strs[i].indexOf(str) !== 0) {
            str = str.substring(0, str.length - 1)
        }
    }
    return str;
};

same-tree

var isSameTree = function(p, q) {
    if (p === null && q === null) return true;
    if (p === null || q === null) return false;
    if (p.val == q.val) {
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right)
    } else {
        return false;
    }
};

第六天

add-two-numbers

var addTwoNumbers = function(l1, l2) {
    const head = new ListNode(0);
    let pre = head;
    let curry = 0;
    while (l1 || l2 || curry != 0) {
        let l1Val = l1 !== null ? l1.val : 0;
        let l2Val = l2 !== null ? l2.val : 0;
        const value = l1Val + l2Val;
        pre.next = new ListNode((curry + value) % 10);
        curry = Math.floor((curry + value) / 10);
        pre = pre.next;
        if (l1 !== null) l1 = l1.next;
        if (l2 !== null) l2 = l2.next;
    }
    return head.next;
};

longest-palindrome

var longestPalindrome = function(s) {
    let set = new Set();
    let count = 0;
    for (let i = 0; i < s.length; i++) {
        if (set.has(s[i])) {
            count += 2;
            set.delete(s[i])
        } else {
            set.add(s[i])
        }
    }
    return set.size > 0 ? count+ 1 : count;
};

linked-list-cycle

var hasCycle = function(head) {
    let fast = head.next;
    let slow = head;
    while (fast != slow) {
        if (fast.next === null || fast.next.next === null) return false;
        fast = fast.next.next;
        slow = slow.next;
    }
    return true;
};

第七天

merge-intervals

var merge = function(intervals) {
    let res = [];
    if (intervals.length < 1) {
        return [];
    }
    intervals.sort((a, b) => {
        return a[0] - b[0]
    });
    res.push(intervals[0]);
    for (let i = 1; i < intervals.length; i++) {
        let last = res[res.length - 1];
        let temp = intervals[i];
        if (last[1] >= temp[0]) {
            last[1] = Math.max(temp[1], last[1])
        } else {
            res.push(temp)
        }
    }
    return res;
};

palindrome-number

var isPalindrome = function(x) {
    x = new String(x);
    y = x.split('').reverse().join('');
    return x == y;
};

remove-nth-node-from-end-of-list

var removeNthFromEnd = function(head, n) {
    let dummy = new ListNode(0);
    dummy.next = head;
    let first = dummy;
    let second = dummy;
    // 因为初始化的时候有一个初始节点
    // 所以这里需要设置为n+ 1
    for (let i = 0; i < n + 1; i++) {
        first = first.next;
    }
    while (first != null) {
        first = first.next;
        second = second.next;
    }
    second.next = second.next.next;
    return dummy.next;
};

binary-tree-level-order-traversal

var levelOrder = function(root) {
   let stack = [];
   function help(node, depth) {
       if (!node) return false;
        const current_stack = stack[depth] = stack[depth] || [];
        current_stack.push(node.val);
        help(node.left, depth + 1);
        help(node.right, depth + 1)
   }
   help(root, 0);
   return stack;
};

第八天

binary-tree-zigzag-level-order-traversal

var zigzagLevelOrder = function(root) {
    let stack = [];
    function help(root, depth, reverse) {
        if (!root) return false;
        const current_stack = stack[depth] = stack[depth] || [];
        if (reverse) {
            current_stack.unshift(root.val);
        } else {
            current_stack.push(root.val)
        }
        help(root.left, depth + 1, !reverse);
        help(root.right, depth + 1, !reverse)
    }
    help(root, 0, false)
    return stack;
};

intersection-of-two-linked-lists

var getIntersectionNode = function(headA, headB) {
    if (headA == null || headB == null) return null;
    let pA = headA, pB = headB;
    while (pA != pB) {
        pA = pA == null ? headB : pA.next;
        pB = pB == null ? headA : pB.next;
    }
    return pA;
};

binary-tree-inorder-traversal

function helper(root, res) {
    if (!root) return false;
    helper(root.left, res);
    res.push(root.val);
    helper(root.right, res);
}

var inorderTraversal = function(root) {
    let res = [];
    helper(root, res);
    return res;
};

第九天

binary-tree-right-side-view

var rightSideView = function(root) {
    const stack = [];
    function help(node, depth) {
        if (!node) return;
        const current = stack[depth] = stack[depth] || [];
        current.push(node.val)
        help(node.left, depth + 1);
        help(node.right, depth + 1);
    }
    help(root, 0);
    let res = [];
    for (let i = 0; i < stack.length; i++) {
        const cur = stack[i];
        res.push(cur[cur.length - 1])
    }
    return res;
};
var rightSideView = function(root) {
    const stack = [];
    function help(node, depth) {
        if (!node) return;
        stack[depth] = node.val;
        help(node.left, depth + 1);
        help(node.right, depth + 1);
    }
    help(root, 0);
    return stack;
};

symmetric-tree

var isSymmetric = function(root) {
    function check(node1, node2) {
        if (!node1 && !node2) {
            return true;
        }
        if (!node1 || !node2) {
            return false;
        }
        if (node1.val !== node2.val) {
            return false;
        }
        return check(node1.left, node2.right) && check(node1.right, node2.left)
    }
    return check(root, root);
};

第十天

house-robber

var rob = function(nums) {
    let nowRes = 0, lastRes = 0;
    for(let i = 0; i < nums.length; i++) {
        let temp = lastRes;
        lastRes = nowRes;
        nowRes = Math.max(temp + nums[i], nowRes);
    }
    return nowRes;
};

第十一天

generate-parentheses

分析上图可以得出下面结论:

  1. 当前左右括号都有大于 00 个可以使用的时候,才产生分支;
  2. 产生左分支的时候,只看当前是否还有左括号可以使用;
  3. 产生右分支的时候,还受到左分支的限制,右边剩余可以使用的括号数量一定得在严格大于左边剩余的数量的时候,才可以产生分支;
  4. 在左边和右边剩余的括号数都等于 00 的时候结算。
var generateParenthesis = function (n) {
    let res = [];
    function dfs(str, left, right) {
        if (left === 0 && right === 0) {
            res.push(str)
            return false;
        }
        if (right < left) {
            return false;
        }
        if (left > 0) {
            dfs(str + '(', left - 1, right)
        }
        if (right > 0) {
            dfs(str + ')', left, right - 1);
        }
    }
    dfs('', n, n)
    return res;
};

var reorderList = function(head) {
    let slow = fast = head;
    if (head == null || head.next === null) {
        return;
    }
    while (fast.next && fast.next.next) {
        slow = slow.next;
        fast = fast.next.next;
    }
    let needReverser = slow.next;
    slow.next = null;
    needReverser = reverse(needReverser);
    let cur = head;
    while (cur && needReverser) {
        let temp = cur.next;
        let first = needReverser;
        needReverser = needReverser.next;
        first.next = cur.next;
        cur.next = first;
        cur = temp;
    }
    return head;
};

// 翻转链表
function reverse(head) {
// 这里不能调用new ListNode
    let end = null;
    let cur = head;
    while (cur) {
        let temp = cur.next;
        cur.next = end;
        end = cur;
        cur = temp;
    }
    return end;
}

reverse-linked-list-i

var reverseBetween = function(head, m, n) {
    const dummy = new ListNode(0);
    dummy.next = head;
    let pre = dummy;
    for (let i = 1; i < m; i++) {
        pre = pre.next;
    }
    head = pre.next;
    for (let i = m; i < n; i++) {
        let nex = head.next;
        head.next = nex.next;
        nex.next = pre.next;
        pre.next = nex;
    }
    return dummy.next;
};

swap-nodes-in-pairs

var swapPairs = function(head) {
    if (!head || head.next == null) {
        return head;
    }
    let first = head;
    let second = head.next;
    first.next = swapPairs(second.next);
    second.next = first;
    return second;
};

best-time-to-buy-and-sell-stock-ii

var maxProfit = function(prices) {
    let ans = 0;
    for (let i = 1; i < prices.length; i++) {
        if (prices[i] > prices[i - 1]) {
            ans += prices[i] - prices[i - 1]
        }
    }
    return ans;
};

house-robber

var rob = function(nums) {
    let len = nums.length;
    let dp = new Array(len + 1);
    dp[0] = 0;
    dp[1] = nums[0];
    for (let i = 2; i <= nums.length; i++) {
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1])
    }
    return dp[len]
};

jump-game

function canJump (nums) {
    let max = 0;
    for (let i = 0; i < nums.length; i++) {
        if (i > max) return false;
        max = Math.max(max, nums[i] + i)
    }
    return true;
}

第十二天

add-two-numbers-ii

var addTwoNumbers = function(l1, l2) {
    l1 = reverse(l1);
    l2 = reverse(l2);
    let curry = 0;
    let cur = null;
    while (l1 || l2 || curry) {
        const value1 = l1 ? l1.val : 0;
        const value2 = l2 ? l2.val : 0;
        console.log(l1 ? l1.val : 0, l2 ? l2.val : 0);
        const temp = new ListNode(Math.floor((value1 + value2 + curry) % 10))
        curry = Math.floor((value1 + value2 + curry) / 10);
        temp.next = cur;
        cur = temp;
        l1 = l1 && l1.next;
        l2 = l2 && l2.next;
    }
    return cur;
}

function reverse(head) {
    let temp = head;
    let cur = null;
    while (temp) {
        let node = temp;
        temp = temp.next;
        node.next = cur;
        cur = node;
    }
    return cur;
}

construct-binary-tree-from-preorder-and-inorder-traversal

var buildTree = function(preorder, inorder) {
  if(!preorder.length && !inorder.length)
    return null;
  var head = preorder[0];
  var pos = inorder.indexOf(head);
  var midLeft = inorder.slice(0, pos), midRight = inorder.slice(pos+1);
  var preLeft = preorder.slice(1, pos+1), preRight = preorder.slice(pos+1);

  var tree = new TreeNode(head);
  tree.left = buildTree(preLeft, midLeft);
  tree.right = buildTree(preRight, midRight);
  return tree;
};

第十三天

combination-sum

var combinationSum = function(candidates, target) {
    candidates.sort((a, b) => a - b);
    let res = [];
    function helper(curry, index, list) {
        for (; index < candidates.length; index++ ) {
            let cur = curry - candidates[index];
            if (cur === 0) {
                res.push([...list, candidates[index]])
            } else if (cur > 0) {
                helper(cur, index, [...list, candidates[index]])
            } else {
                break;
            }
        }
    }
    helper(target, 0, []);
    return res;
};

max-area-of-island

function bfs(grid, i, j) {
    if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] === 0) {
        return 0;
    }
    grid[i][j] = 0;
    let sum = 1;
    sum += bfs(grid, i - 1, j);
    sum += bfs(grid, i + 1, j);
    sum += bfs(grid, i, j - 1);
    sum += bfs(grid, i, j + 1);
    return sum;
}

var maxAreaOfIsland = function(grid) {
    if (grid == null || grid.length == 0) {
        return 0;
    }
    let max = 0;
    for (let i = 0; i < grid.length; i++) {
        for (let j = 0; j < grid[0].length; j++) {
            if (grid[i][j] === 1) {
                max = Math.max(max, bfs(grid, i, j));
            }
        }
    }
    return max;
};

palindrome-linked-list

var isPalindrome = function(head) {
    if (!head || !head.next) {
        return true;
    }
    let fast = slow = head;
    while (fast) {
        fast = fast.next ? fast.next.next : fast.next;
        slow = slow.next;
    }
    slow = reverse(slow);
    while (slow) {
        if (slow.val !== head.val) {
            return false;
        }
        slow = slow.next;
        head = head.next;
    }
    return true;
};

function reverse(head) {
    let cur = null;
    while(head) {
        let temp = head;
        head = head.next;
        temp.next = cur;
        cur = temp;
    }
    return cur;
}

majority-element

var majorityElement = function(nums) {
    if (nums.length < 2) {
        return nums[0]
    }
    let temp = {};
    let res = [];
    for (let i = 0; i < nums.length; i++) {
        let cur = nums[i];
        if (temp[cur]) {
            temp[cur]++;
            if (temp[cur] > (nums.length / 2)) {
                res.push(cur)
            }
        } else {
            temp[cur] = 1;
        }
    }
    return [...new Set(res)];
};

reverse-string

var reverseString = function(s) {
    let start = 0;
    let end = s.length - 1;
    while (end > start) {
        let temp = s[start];
        s[start] = s[end];
        s[end] = temp;
        end--;
        start++;
    }
    return s;
};

第十四天

multiply-strings

var multiply = function(num1, num2) {
  if(num1 == '0' || num2 == '0') return '0';
  num1 = num1 + '';
  num2 = num2 + '';
  let l1 = num1.length,l2 = num2.length, 
      store = new Array(l1 + l2 - 1).fill(0), t = 0, r = '';
  for( let i = 0; i < l2; i++ ){
    for( let j = 0; j < l1; j++ ){
      store[i + j] += (+num2[i] * + num1[j])
    }
  }
  let k = store.length;
  while(k--){
    t += store[k];
    r = t % 10 + r;
    t = t / 10 | 0;
  }
  return t > 0 ? (t + r) : r;
}

第十五天

decode-string

function decodeString(s) {
    let stack = [],
    res = '',
    multi = 0;
    for (let i = 0; i < s.length; i++) {
        let str = s[i];
        if (str === '[') {
            stack.push({
                multi,
                res,
            });
            res = '';
            multi = 0;
        } else if (str === ']') {
            const pop = stack.pop();
            let cur_mult = pop.multi;
            let last_res = pop.res;
            res = last_res + res.repeat(cur_mult);
        } else if ('0' <= str && str <= '9') {
            multi = multi * 10 + parseInt(str)
        } else {
            res += str;
        }
    }
    return res;
}

spiral-matrix

[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]
var spiralOrder = function(matrix) {
    let result = [];
    if (matrix.length === 0) {
        return [];
    }
    let row = matrix.length;
    let column = matrix[0].length;
    let x1 = 0;
    let y1 = 0;
    let x2 = column - 1;
    let y2 = row - 1;
    while (x1 <= x2 && y1 <= y2) {
        for (let i = x1; i < x2 +1; i++) {
            result.push(matrix[y1][i])
        }
        for(let j = y1 + 1; j < y2 + 1; j++) {
            result.push(matrix[j][x2])
        }
        if(x1 < x2 && y1 < y2) {
            for (let i = x2 - 1; i > x1; i--) {
                result.push(matrix[y2][i])
            }
            for (let j = y2; j > y1; j--) {
                result.push(matrix[j][x1])
            }
        }
        x1 += 1;
        y1 += 1;
        x2 -= 1;
        y2 -= 1;
    } 
    return result;
};

spiral-matrix-ii

var generateMatrix = function(n) {
    var left = 0, right = n - 1, top = 0, bottom = n - 1;
    var res = [];
    for(var m=0;m<n;m++) res[m] = [];
    var step = 1;
    var end = n**2;
    while(step<=end){
        //left->right
        for(var i=left;i<=right;i++) res[top][i] = step++;
        top++;
        //top->bottom
        for(var i=top;i<=bottom;i++) res[i][right] = step++;
        right--;
        //right->left
        for(var i=right;i>=left;i--) res[bottom][i] = step++;
        bottom--;
        //bottom->top
        for(var i=bottom;i>=top;i--) res[i][left] = step++;
        left++;
    }
    return res;
};

第十五天

subsets

var subsets = function(nums) {
    let res = [[]];
    for (let i = 0; i < nums.length; i++) {
        res.forEach((item) => {
            res.push(item.concat(nums[i]))
        })
    }
    return res;
};