刷leetcode力扣算法题目

// 从上到下打印二叉树 I  每一层都是从左到右
var levelOrder = function (root) {
    
    
  if (!root) return [];
  var queue = [root];
  var res = [];
  while (queue.length) {
    
    
    var len = queue.length;
    for (var i = 0; i < len; i++) {
    
    
      var node = queue.shift();
      if (node) {
    
    
        res.push(node.val);
        if (node.left) queue.push(node.left);
        if (node.right) queue.push(node.right);
      }
    }
  }
  return res;
};
// 从上到下打印二叉树 II  每一层都是从左到右,但是每一层打印到一行
var levelOrder = (root) => {
    
    
  if (!root) return [];
  const res = [];
  const queue = [root];
  while (queue.length) {
    
    
    let len = queue.length;
    res.push([]);
    for (var i = 0; i < len; i++) {
    
    
      var node = queue.shift();
      if (node) {
    
    
        res[res.length - 1].push(node.val);
        node.left && queue.push(node.left);
        node.right && queue.push(node.right);
      }
    }
  }
  return res;
};
// 从上到下打印二叉树 III  奇数层从左到右,偶数层从右到左,但是每一层打印到一行
var levelOrder = (root) => {
    
    
  if (!root) return [];
  const res = [];
  const queue = [root];
  var n = 2;
  while (queue.length) {
    
    
    let len = queue.length;
    res.push([]);
    for (var i = 0; i < len; i++) {
    
    
      var node = queue.shift();
      if (node) {
    
    
        res[res.length - 1].push(node.val);
        node.left && queue.push(node.left);
        node.right && queue.push(node.right);
      }
    }
    if (n % 2) {
    
    
      res[res.length - 1].reverse();
    }
    n++;
  }
  return res;
};
// 对称的二叉树
var isSymmetric = (root) => {
    
    
  if (!root) return true;
  const queue = [root.left, root.right];
  while (queue.length) {
    
    
    const len = queue.length;
    for (let i = 0; i < len; i += 2) {
    
    
      const left = queue.shift();
      const right = queue.shift();
      if ((left && !right) || (!left && right)) return false;
      if (left && right) {
    
    
        if (left.val !== right.val) return false;
        queue.push(left.left, right.right, left.right, right.left);
      }
    }
  }
  return true;
};

//二叉树的最近公共祖先
var lowestCommonAncestor = (root, p, q) => {
    
    
  if (!root) 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 && right) return root;
  if (left) return left;
  if (right) return right;
};
// 二叉搜索树的最近公共祖先
var lowestCommonAncestor = (root, p, q) => {
    
    
  if (!root) return null;
  if (root.val > p.val && root.val > q.val) {
    
    
    return lowestCommonAncestor(root.left, p, q);
  }
  if (root.val < p.val && root.val < q.val) {
    
    
    return lowestCommonAncestor(root.right, p, q);
  }
  return root;
};

// 二叉树的深度
const maxDepth = (root) => {
    
    
  if (!root) return 0;
  return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
};

// 平衡二叉树
// 输入一棵二叉树的根节点,判断该树是不是平衡二叉树。
// 如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
const isBalanced = (root) => {
    
    
  if (!root) return true;
  return (
    Math.abs(getH(root.left) - getH(root.right)) <= 1 &&
    isBalanced(root.left) &&
    isBalanced(root.right)
  );
  function getH(root) {
    
    
    if (!root) return 0;
    return Math.max(getH(root.left), getH(root.right)) + 1;
  }
};

// 二叉搜索树的第k大节点
const kthLargest = (root, k) => {
    
    
  const res = [];
  f(root);
  return res[k - 1];
  function f(node) {
    
    
    if (!node) return;
    f(node.right);
    res.push(node.val);
    f(node.left);
  }
};

// 已知二叉树,输出该二叉树的镜像
var mirrorTree = function (root) {
    
    
  return f(root);
  function f(node) {
    
    
    if (!node) return node;
    var mid = node.right;
    node.right = f(node.left);
    node.left = f(mid);
    return node;
  }
};

// 输入两棵二叉树A和B,判断B是不是A的子结构,(约定空树不是任意一个树的子结构)
var isSubStructure = function (A, B) {
    
    
  if (!A || !B) return false;
  return (
    isSame(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B)
  );
  function isSame(A, B) {
    
    
    if (!B) return true; // A和B都是一个叶节点,他们的左右子节点做比较,会走这里判断
    if (!A) return false; // B存在,A不存在
    if (A.val !== B.val) return false;
    return isSame(A.left, B.left) && isSame(A.right, B.right);
  }
};

// 在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字
var missingNumber = function (nums) {
    
    
  if (nums.length === 1 && nums[0] === 1) {
    
    
    return 0;
  }
  if (nums.length === 1 && nums[0] === 0) {
    
    
    return 1;
  }
  var len = nums.length;
  for (var i = 0; i < len; i++) {
    
    
    if (nums[i + 1] && nums[i + 1] - nums[i] > 1) {
    
    
      return nums[i] + 1;
    }
  }
  if (nums[0] == 0) {
    
    
    return nums[len - 1] + 1;
  } else {
    
    
    return 0;
  }
};

// 构建乘积数组
var constructArr = function (a) {
    
    
  let n = a.length;
  if (!n) return [];
  let result = new Array(n).fill(1);
  let rightAccu = 1;
  for (let i = 1; i < n; i++) {
    
    
    result[i] = result[i - 1] * a[i - 1];
  }
  for (let i = n - 2; i >= 0; i--) {
    
    
    // 构建右边乘积,以a = [1, 2, 3, 4, 5]举例,这里的temp会分别等于5、20、60、120
    rightAccu *= a[i + 1];
    // 乘以左边的乘积
    result[i] *= rightAccu;
  }
  return result;
};
// constructArr([1, 2, 3, 4, 5])

// 入栈 出栈
var validateStackSequences = (pushed, popped) => {
    
    
  let stack = [];
  var index = 0;
  for (var i = 0; i < pushed.length; i++) {
    
    
    stack.push(pushed[i]);
    while (
      popped[index] !== undefined &&
      popped[index] === stack[stack.length - 1]
    ) {
    
    
      stack.pop();
      index++;
    }
  }
  return !stack.length;
};
// 滚动窗口
var maxSlidingWindow = (nums, k) => {
    
    
  const len = nums.length;
  if (!len) return [];
  const q = [];
  for (let i = 0; i < k; i++) {
    
    
    while (q.length && nums[i] >= nums[q[q.length - 1]]) {
    
    
      q.pop();
    }
    q.push(i);
  }
  const res = [nums[q[0]]];
  for (let i = k; i < len; i++) {
    
    
    while (q.length && nums[i] >= nums[q[q.length - 1]]) {
    
    
      q.pop();
    }
    q.push(i);
    while (q[0] <= i - k) {
    
    
      q.shift();
    }
    res.push(nums[q[0]]);
  }
  return res;
};
// maxSlidingWindow([1, 3, -1, -3, 5, 3, 6, 7], 3)

// 求两个数之和,不可用加法
var add = function (a, b) {
    
    
  let sum, carry;
  do {
    
    
    sum = a ^ b;
    carry = (a & b) << 1;
    a = sum;
    b = carry;
  } while (b != 0);
  return a;
};
//  和为target的两个数字,nums是递增数组
const twoSum = (nums, target) => {
    
    
  let [left, right] = [0, nums.length - 1];
  while (left < right) {
    
    
    sum = nums[left] + nums[right];
    if (sum > target) {
    
    
      right--;
    } else if (sum < target) {
    
    
      left++;
    } else {
    
    
      return [nums[left], nums[right]];
    }
  }
};
// 三个数字之和为0,[-1,0,1,2,-1,-1,-4],输出各种情况[[-1,-1,2],[-1,0,1]]
var threeSum = function (nums) {
    
    
  nums.sort((a, b) => a - b);
  var len = nums.length;
  var res = [];
  for (var i = 0; i < len; i++) {
    
    
    if (nums[i] == nums[i - 1]) continue;
    var left = i + 1;
    var right = len - 1;
    var value = nums[i];
    while (left < right) {
    
    
      if (value + nums[left] + nums[right] == 0) {
    
    
        res.push([value, nums[left], nums[right]]);
        while (nums[left] == nums[++left]);
        while (nums[right] == nums[--right]);
      } else if (value + nums[left] + nums[right] < 0) {
    
    
        left++;
      } else {
    
    
        right--;
      }
    }
  }
  return res;
};
// 求连续子数组和为target,输出各种情况的个数
var subarraySum = function (nums, k) {
    
    
  var len = nums.length;
  var n = 0;
  for (var i = 0; i < len; i++) {
    
    
    if (nums[i] === k) {
    
    
      n++;
    }
    var sum = nums[i];
    for (var j = i + 1; j < len; j++) {
    
    
      sum += nums[j];
      if (sum === k) {
    
    
        n++;
      }
    }
  }
  return n;
};
// 求最短连续子数组和大于target,返回它的长度
// 7 [2, 3, 1, 4, 2, 3]  得出长度为3 而不是2
var minSubArrayLen = function (target, nums) {
    
    
  var len = nums.length + 1;
  var i = 0;
  var sum = 0;
  for (var j = 0; j < nums.length; j++) {
    
    
    sum += nums[j];
    while (sum >= target) {
    
    
      if (j - i + 1 < len) {
    
    
        len = j - i + 1;
      }
      sum -= nums[i++];
    }
  }
  return len > nums.length ? 0 : len;
};
// 求连续子数组乘积小于target,所有可能情况的个数
var numSubarrayProductLessThanK = function (nums, t) {
    
    
  var len = nums.length;
  var n = 0;
  for (var i = 0; i < len; i++) {
    
    
    if (nums[i] >= t) continue;
    n++;
    var sum = nums[i];
    for (var j = i + 1; j < len; j++) {
    
    
      sum *= nums[j];
      if (sum >= t) break;
      n++;
    }
  }
  return n;
};

// 求最长连续子数组,返回它的长度,满足0和1的个数相等
var findMaxLength = function (nums) {
    
    
  var len = nums.length;
  var map = new Map();
  var key = 0;
  map.set(key, -1);
  var maxlen = 0;
  for (var i = 0; i < len; i++) {
    
    
    if (nums[i] == 1) {
    
    
      key++;
    } else {
    
    
      key--;
    }
    if (map.has(key)) {
    
    
      var k = map.get(key);
      maxlen = Math.max(maxlen, i - k);
    } else {
    
    
      map.set(key, i);
    }
  }
  return maxlen;
};
// 找寻中心轴元素下标,左右两边子数组的和相等
var pivotIndex = function (nums) {
    
    
  var add = nums.reduce(function (acc, item) {
    
    
    return (acc += item);
  }, 0);
  var sum = 0;
  for (var i = 0; i < nums.length; i++) {
    
    
    if (add == nums[i] + 2 * sum) return i;
    sum += nums[i];
  }
  return -1;
};
// 二进制加法
var addBinary = function (a, b) {
    
    
  var count = 0;
  var sum = "";
  var i, j;
  var temp;
  for (i = a.length - 1, j = b.length - 1; i > -1 && j > -1; i--, j--) {
    
    
    temp = count + parseInt(a[i]) + parseInt(b[j]);
    sum += temp > 1 ? String(temp - 2) : String(temp);
    count = temp > 1 ? 1 : 0;
  }
  var k = i > j ? i : j;
  var arr = i > j ? a : b;
  while (k > -1) {
    
    
    temp = count + parseInt(arr[k]);
    sum += temp > 1 ? String(temp - 2) : String(temp);
    count = temp > 1 ? 1 : 0;
    k--;
  }
  if (count === 1) {
    
    
    sum += "1";
  }
  return sum.split("").reverse().join("");
};
// 整数除法
var divide = function (a, b) {
    
    
  const {
    
     abs, pow } = Math;
  const MAX = pow(2, 31) - 1;
  var MIN = -pow(2, 31);
  if (a == MIN && b == -1) return MAX;
  if (a == MIN && b == 1) return MIN;
  const sign = (a > 0) ^ (b > 0);
  a = abs(a);
  b = abs(b);
  let n = 0;
  while (a >= b) {
    
    
    a -= b;
    n++;
  }
  return sign ? -n : n;
};

// 整数转二进制后,含有1的个数
function f(i) {
    
    
  var j = 0;
  while (i > 0) {
    
    
    i = i & (i - 1);
    j++;
  }
  return j;
}

// 股票最大利润
var maxProfit = function (prices) {
    
    
  var min = prices[0];
  var maxValue = 0;
  for (var i = 1; i < prices.length; i++) {
    
    
    if (prices[i] < min) {
    
    
      min = prices[i];
    } else {
    
    
      maxValue = Math.max(maxValue, prices[i] - min);
    }
  }
  return maxValue;
};

// 圆圈中最后剩下的数字
const lastRemaining = (n, m) => {
    
    
  let res = 0;
  for (let i = 2; i <= n; i++) {
    
    
    res = (res + m) % i;
  }
  return res;
};

// 扑克牌中的顺子
const isStraight = (nums) => {
    
    
  const set = new Set();
  let [max, min] = [0, 14];
  for (const num of nums) {
    
    
    if (num === 0) continue;
    max = Math.max(max, num);
    min = Math.min(min, num);
    if (set.has(num)) return false;
    set.add(num);
  }
  return max - min < 5;
};

// 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。
var singleNumbers = function (nums) {
    
    
  var obj = {
    
    };
  var len = nums.length;
  for (var i = 0; i < len; i++) {
    
    
    if (obj[nums[i]] !== undefined) {
    
    
      delete obj[nums[i]];
    } else {
    
    
      obj[nums[i]] = i;
    }
  }
  return Object.keys(obj);
};
// 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
var singleNumber = function (nums) {
    
    
  var obj = {
    
    };
  for (var i = 0; i < nums.length; i++) {
    
    
    if (obj[nums[i]] === undefined) {
    
    
      obj[nums[i]] = 1;
    } else if (obj[nums[i]] === 1) {
    
    
      obj[nums[i]]++;
    } else {
    
    
      delete obj[nums[i]];
    }
  }
  return Object.keys(obj);
};

// 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
var findContinuousSequence = function (target) {
    
    
  var mid = target >> 1;
  var res = [];
  for (var i = 1; i < mid; i++) {
    
    
    var j = i;
    var sum = i;
    var arr = [];
    while (sum < target) {
    
    
      arr.push(j);
      j++;
      sum += j;
      if (sum == target) {
    
    
        arr.push(j);
        res.push(arr);
        continue;
      }
    }
  }
  if (target % 2 !== 0) {
    
    
    res.push([mid, mid + 1]);
  }
  return res;
};

// 输入两个链表,找出它们的第一个公共节点。
const getIntersectionNode = (a, b) => {
    
    
  let x = a,
    y = b;
  while (x !== y) {
    
    
    if (x === null) {
    
    
      x = b;
    } else {
    
    
      x = x.next;
    }
    if (y === null) {
    
    
      y = a;
    } else {
    
    
      y = y.next;
    }
  }
  return x;
};
// 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
// 方法一
const lengthOfLongestSubstring1 = (s) => {
    
    
  const arr = [];
  let max = 0;
  const len = s.length;
  for (let i = 0; i < len; i++) {
    
    
    const index = arr.indexOf(s[i]);
    if (index !== -1) {
    
    
      arr.splice(0, index + 1);
    }
    arr.push(s[i]);
    if (max < arr.length) max = arr.length;
  }
  return max;
};
// 方法二
var lengthOfLongestSubstring2 = function (s) {
    
    
  var arr = s.split("");
  var maxlen = 0;
  for (var i = 0; i < arr.length; i++) {
    
    
    var brr = [];
    var j = i;
    while (arr[j] && !brr.includes(arr[j])) {
    
    
      brr.push(arr[j]);
      j++;
    }
    maxlen = Math.max(maxlen, brr.length);
  }
  return maxlen;
};

// 礼物的最大价值
const maxValue = (dArr) => {
    
    
  const [m, n] = [dArr.length, dArr[0].length];
  const dp = new Array(m).fill(0).map(() => new Array(n).fill(0));
  dp[0][0] = dArr[0][0];
  // 补充第一列初始化
  for (let i = 1; i < m; i++) {
    
    
    dp[i][0] = dp[i - 1][0] + dArr[i][0];
  }
  // 补充第一行初始化
  for (let j = 1; j < n; j++) {
    
    
    dp[0][j] = dp[0][j - 1] + dArr[0][j];
  }
  // 遍历,完善dp数组
  for (let i = 1; i < m; i++) {
    
    
    for (let j = 1; j < n; j++) {
    
    
      dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + dArr[i][j];
    }
  }
  return dp[m - 1][n - 1];
};

// 顺时针打印二维数组
var spiralOrder = function (arr) {
    
    
  if (!arr.length || !arr[0].length) return [];
  let left = 0,
    right = arr[0].length - 1,
    top = 0,
    bottom = arr.length - 1,
    result = [];
  while (true) {
    
    
    for (let i = left; i <= right; i++) result.push(arr[top][i]);
    if (++top > bottom) break;

    for (let i = top; i <= bottom; i++) result.push(arr[i][right]);
    if (--right < left) break;

    for (let i = right; i >= left; i--) result.push(arr[bottom][i]);
    if (--bottom < top) break;

    for (let i = bottom; i >= top; i--) result.push(arr[i][left]);
    if (++left > right) break;
  }
  return result;
};

// 把数组排成最小的数
var minNumber = function (nums) {
    
    
  var len = nums.length;
  for (var i = 0; i < len; i++) {
    
    
    for (var j = i + 1; j < len; j++) {
    
    
      swap(i, j, nums);
    }
  }
  return nums.join("");
  function swap(i, j, nums) {
    
    
    var ij = Number(String(nums[i]) + String(nums[j]));
    var ji = Number(String(nums[j]) + String(nums[i]));
    if (ij > ji) {
    
    
      var mid = nums[i];
      nums[i] = nums[j];
      nums[j] = mid;
    }
  }
};

// 连续子数组的最大和
// nums = [-2,1,-3,4,-1,2,1,-5,4]
var maxSubArray = (nums) => {
    
    
  if (nums.length === 1) return nums[0];
  let max = nums[0];
  for (let i = 1; i < nums.length; i++) {
    
    
    if (nums[i - 1] > 0) {
    
    
      nums[i] += nums[i - 1];
    }
    max = max > nums[i] ? max : nums[i];
  }
  return max;
};
var maxSubArray = (nums) => {
    
    
  let curSum = nums[0];
  let maxSum = nums[0];
  for (let i = 1; i < nums.length; i++) {
    
    
    curSum = Math.max(nums[i], nums[i] + curSum);
    maxSum = Math.max(curSum, maxSum);
  }
  return maxSum;
};

// [3,2,2,1] 3  输出[1,2,2]
var getLeastNumbers = function (arr, k) {
    
    
  if (k == 0) return [];
  for (var i = 0; i < arr.length; i++) {
    
    
    for (var j = i; j < arr.length; j++) {
    
    
      if (arr[i] > arr[j]) {
    
    
        var mid = arr[i];
        arr[i] = arr[j];
        arr[j] = mid;
      }
    }
    if (i + 1 == k) return arr.slice(0, k);
  }
};

// 可能有重复的字符串,自由组合的种类
var permutation = function (s) {
    
    
  var arr = s.split("");
  var len = arr.length;
  var res = [];
  fn(0);
  function swap(i, j, arr) {
    
    
    if (i == j) return;
    var mid = arr[i];
    arr[i] = arr[j];
    arr[j] = mid;
  }
  function fn(i) {
    
    
    if (i == len - 1) return res.push(arr.join(""));
    var set = new Set();
    for (var j = i; j < len; j++) {
    
    
      if (set.has(arr[j])) continue;
      set.add(arr[j]);
      swap(i, j, arr);
      fn(i + 1);
      swap(j, i, arr);
    }
  }
  return res;
};

// 复制一个复杂的链表,random指向随机
// head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
function Node(val, next, random) {
    
    
  this.val = val;
  this.next = next;
  this.random = random;
}
var copyRandomList = function (head) {
    
    
  if (!head) return head;
  var map = new Map();
  var node = head;
  while (node) {
    
    
    map.set(node, new Node(node.val));
    node = node.next;
  }
  node = head;
  while (node) {
    
    
    var item = map.get(node);
    item.next = map.get(node.next) ? map.get(node.next) : null;
    item.random = map.get(node.random) ? map.get(node.random) : null;
    node = node.next;
  }
  return map.get(head);
};

// 反转每对括号间的子串
var reverseParentheses = function (s) {
    
    
  var stock = [];
  var arr = s.split("");
  var len = arr.length;
  for (var i = 0; i < len; i++) {
    
    
    if (arr[i] == "(") {
    
    
      stock.push(i);
    }
    if (arr[i] == ")") {
    
    
      var index = stock[stock.length - 1];
      var str = s
        .slice(index, i + 1)
        .split("")
        .reverse()
        .join("");
      s = s.slice(0, index) + str + s.slice(i + 1);
      stock.pop();
    }
  }
  s = s.replace(/[\(\)]/g, "");
  return s;
};

// s = "11111222223", k = 3
// 3465 = 346 + 5
// 13 + 5
// 135  返回135
var digitSum = function (s, k) {
    
    
  return f(s, k);
  function f(s, k) {
    
    
    if (s.length <= k) return s;
    var arr = [];
    for (var i = 0; i < s.length; i += k) {
    
    
      if (i > s.length) break;
      arr.push(sum(s.slice(i, i + k)));
    }
    var str = arr.join("");
    return f(str, k);
  }
  function sum(str) {
    
    
    return str.split("").reduce(function (acc, item) {
    
    
      acc = acc + Number(item);
      return acc;
    }, 0);
  }
};

// 判断arr 是否是 二叉搜索数后续遍历
const verifyPostorder = (arr) => {
    
    
  const len = arr.length;
  if (len <= 1) return true;
  const root = arr[len - 1];
  let i = 0;
  while (arr[i] < root) i++;
  const res = arr.slice(i, len - 1).every((x) => x > root);
  return res
    ? verifyPostorder(arr.slice(0, i)) && verifyPostorder(arr.slice(i, len - 1))
    : false;
};

// 二维矩阵中
var exist = function (arr, str) {
    
    
  if (!arr) return false;
  var m = arr.length;
  var n = arr[0].length;
  for (var i = 0; i < m; i++) {
    
    
    for (var j = 0; j < n; j++) {
    
    
      if (dfs(i, j, 0)) return true;
    }
  }
  function dfs(i, j, x) {
    
    
    if (i < 0 || j < 0 || i >= m || j >= n || arr[i][j] != str[x]) return false;
    if (x == str.length - 1) return true;
    var mid = arr[i][j];
    arr[i][j] = "";
    var res =
      dfs(i + 1, j, x + 1) ||
      dfs(i, j + 1, x + 1) ||
      dfs(i - 1, j, x + 1) ||
      dfs(i, j - 1, x + 1);
    arr[i][j] = mid;
    return res;
  }
  return false;
};
// 二维矩阵,求子矩阵的各项和
var NumMatrix = function (matrix) {
    
    
  var [m, n] = [matrix.length, matrix[0].length];
  var dp = Array.from({
    
     length: m }, () => new Array(n + 1).fill(0));
  for (var i = 0; i < m; i++) {
    
    
    for (var j = 0; j < n; j++) {
    
    
      dp[i][j + 1] = dp[i][j] + matrix[i][j];
    }
  }
  this.dp = dp;
};
NumMatrix.prototype.sumRegion = function (row1, col1, row2, col2) {
    
    
  var dp = this.dp;
  var sum = 0;
  for (var i = row1; i <= row2; i++) {
    
    
    sum += dp[i][col2 + 1] - dp[i][col1];
  }
  return sum;
};
// 重建二叉树,arr前序遍历 brr为中序遍历,且数组没有重复的值
/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
var buildTree = function (arr, brr) {
    
    
  return f(arr, brr);
  function f(arr, brr) {
    
    
    if (!arr.length) return null;
    var value = arr[0];
    var root = new TreeNode(value);
    if (arr.length === 1) return root;
    var index = brr.indexOf(value);
    var leftTree2 = brr.slice(0, index);
    var rightTree2 = brr.slice(index + 1);
    var leftTree1 = arr.slice(1, index + 1);
    var rightTree1 = arr.slice(index + 1);
    root.left = f(leftTree1, leftTree2);
    root.right = f(rightTree1, rightTree2);
    return root;
  }
};
// 两个递增链表合并
const mergeTwoLists = (l1, l2) => {
    
    
  const res = new ListNode(0);
  let p = res;
  while (l1 && l2) {
    
    
    if (l1.val < l2.val) {
    
    
      p.next = l1;
      l1 = l1.next;
    } else {
    
    
      p.next = l2;
      l2 = l2.next;
    }
    p = p.next;
  }
  p.next = l1 ? l1 : l2;
  return res.next;
};
// 链表反转
var reverseList = function (head) {
    
    
  // 1 -> 2 -> 3 -> 4 -> 5 -> NULL
  // NULL <- 1 <- 2 <- 3 <- 4 <- 5
  var pre = null;
  var cur = head;
  while (cur) {
    
    
    var next = cur.next;
    cur.next = pre;
    pre = cur;
    cur = next;
  }
  return pre;
};

// 两个递增数组合并
function f(arr, brr) {
    
    
  var res = [];
  while (arr.length && brr.length) {
    
    
    if (arr[0] > brr[0]) {
    
    
      res.push(brr[0]);
      brr.shift();
    } else {
    
    
      res.push(arr[0]);
      arr.shift();
    }
  }
  return arr.length ? res.concat(arr) : res.concat(brr);
}
// 链表中倒数第k个节点
var getKthFromEnd = function (head, k) {
    
    
  // 1->2->3->4->5, 和 k = 2
  var quick = head;
  while (k--) {
    
    
    quick = quick.next;
  }
  var node = head;
  while (quick) {
    
    
    node = node.next;
    quick = quick.next;
  }
  return node;
};
// 实现 pow(x, n)
var myPow = function (x, n) {
    
    
  if (n == 0) return 1;
  if (n < 0) return 1 / myPow(x, -n);
  if (n % 2 == 1) return x * myPow(x, n - 1);
  return myPow(x * x, n / 2);
};

// 机器人的运动范围
var movingCount = function (m, n, k) {
    
    
  var arr = Array.from({
    
     length: m }, () => Array(n).fill(false));
  return dfs(0, 0, arr);
  function dfs(i, j, arr) {
    
    
    if (i >= m || j >= n) return 0;
    if (k < sum(i, j)) return 0;
    if (arr[i][j]) return 0;
    arr[i][j] = true;
    return 1 + dfs(i + 1, j, arr) + dfs(i, j + 1, arr);
  }
  function sum(i, j) {
    
    
    var sum = 0;
    while (i) {
    
    
      sum += i % 10;
      i = (i / 10) >> 0;
    }
    while (j) {
    
    
      sum += j % 10;
      j = (j / 10) >> 0;
    }
    return sum;
  }
};
// 从尾到头打印链表 ,用数组返回
var reversePrint = function (head) {
    
    
  var node = head;
  var res = [];
  while (node) {
    
    
    res.push(node.val);
    node = node.next;
  }
  res.reverse();
  return res;
};

// 前n个丑数,1是丑数,其余的都是 2,3,5乘的
/**
    输入: n = 10
    输出: 12
    解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
   */
var nthUglyNumber = function (n) {
    
    
  var nums = new Array(n).fill(0);
  nums[0] = 1;
  var index2 = 0;
  var index3 = 0;
  var index5 = 0;
  /**
        1, 2, 3, 4, 5, 6, 8, 9, 10, 12
        0 0 0
        1 0 0
        1 1 0
        2 1 0
        2 1 1
        3 2 1
     */
  for (var i = 1; i < n; i++) {
    
    
    nums[i] = Math.min(nums[index2] * 2, nums[index3] * 3, nums[index5] * 5);
    if (nums[i] == nums[index2] * 2) {
    
    
      index2++;
    }
    if (nums[i] == nums[index3] * 3) {
    
    
      index3++;
    }
    if (nums[i] == nums[index5] * 5) {
    
    
      index5++;
    }
  }
  return nums[n - 1];
};

// ["a","ab","abc","d","cd","bcd","abcd"] 两个串没有重叠部分,最长乘积
var maxProduct = function (words) {
    
    
  var max = 0;
  for (var i = 0; i < words.length; i++) {
    
    
    for (var j = i + 1; j < words.length; j++) {
    
    
      var value = f(words[i], words[j]);
      max = Math.max(max, value);
    }
  }
  return max;
  function f(s1, s2) {
    
    
    var set = Array.from([...s2]).join("");
    var reg = new RegExp(`[${
      
      set}]`);
    var flag = reg.test(s1);
    if (flag) return 0;
    return s1.length * s2.length;
  }
};

// 检测两个字符串是否相同的字符
function f(s1, s2) {
    
    
  var str1;
  for (var i = 0; i < s1.length; i++) {
    
    
    str1 |= 1 << (s1[i].charCodeAt() - "a".charCodeAt());
  }
  var str2;
  for (var i = 0; i < s2.length; i++) {
    
    
    str2 |= 1 << (s2[i].charCodeAt() - "a".charCodeAt());
  }
  return !!(str1 & str2);
}
// s1 = 'ab' s1的变位词为 "ab"或者"ba"
// s2 = "cbad" s2的子串中"ba"刚好是s1的变位词之一,找到一个就返回true
var checkInclusion = function (s1, s2) {
    
    
  var m = s1.length;
  var n = s2.length;
  if (m > n) return false;
  var arr = new Array(26).fill(0);
  var brr = new Array(26).fill(0);
  for (var i = 0; i < m; i++) {
    
    
    arr[s1[i].charCodeAt() - "a".charCodeAt()]++;
    brr[s2[i].charCodeAt() - "a".charCodeAt()]++;
  }
  if (arr.toString() === brr.toString()) return true;
  for (var i = m; i < n; i++) {
    
    
    brr[s2[i].charCodeAt() - "a".charCodeAt()]++;
    brr[s2[i - m].charCodeAt() - "a".charCodeAt()]--;
    if (arr.toString() === brr.toString()) return true;
  }
  return false;
};
// 找出 字符串s2中存在的所有 s1的变位词,并返回起始下标
var findAnagrams = function (s2, s1) {
    
    
  var m = s1.length;
  var n = s2.length;
  if (m > n) return [];
  var arr = new Array(26).fill(0);
  var brr = new Array(26).fill(0);
  var res = [];
  for (var i = 0; i < m; i++) {
    
    
    arr[s1[i].charCodeAt(0) - "a".charCodeAt(0)]++;
    brr[s2[i].charCodeAt(0) - "a".charCodeAt(0)]++;
  }
  if (arr.toString() == brr.toString()) res.push(0);
  for (var j = m; j < n; j++) {
    
    
    brr[s2[j].charCodeAt(0) - "a".charCodeAt(0)]++;
    brr[s2[j - m].charCodeAt(0) - "a".charCodeAt(0)]--;
    if (arr.toString() == brr.toString()) res.push(j - m + 1);
  }
  return res;
};

// 有效的回文
// "A man, a plan, a canal: Panama"
// "amanaplanacanalpanama"
var isPalindrome = function (s) {
    
    
  var len = s.length;
  var arr = [];
  for (var i = 0; i < len; i++) {
    
    
    if (/[A-Za-z0-9]/.test(s[i])) {
    
    
      arr.push(s[i].toLowerCase());
    }
  }
  return arr.join("") === arr.reverse().join("");
};

// 字符串删除一个字符后,是否形成回文字符串
var validPalindrome = function (s) {
    
    
  var left = 0;
  var right = s.length - 1;
  while (left < right) {
    
    
    if (s[left] == s[right]) {
    
    
      ++left;
      --right;
    } else {
    
    
      return (
        checkPalindrome(s, left, right - 1) ||
        checkPalindrome(s, left + 1, right)
      );
    }
  }
  return true;
  function checkPalindrome(s, i, j) {
    
    
    while (i < j) {
    
    
      if (s[i] != s[j]) return false;
      i++;
      j--;
    }
    return true;
  }
};

// 字符串的子串,是回文字符串的个数
var countSubstrings = function (s) {
    
    
  var len = s.length;
  var count = 0;
  for (var i = 0; i < len; i++) {
    
    
    for (var j = i + 1; j < len + 1; j++) {
    
    
      if (checkPalindrome(s.slice(i, j))) {
    
    
        count++;
      }
    }
  }
  return count;
  function checkPalindrome(s) {
    
    
    var i = 0;
    var j = s.length - 1;
    while (i < j) {
    
    
      if (s[i] != s[j]) return false;
      i++;
      j--;
    }
    return true;
  }
};
// 链表中如果有环,则输出环的入口节点
var detectCycle = function (head) {
    
    
  var node = head;
  var map = new Map();
  while (node) {
    
    
    map.set(node, true);
    node = node.next;
    if (map.has(node)) return node;
  }
  return null;
};

// 两个链表,返回第一个重合的地方
var getIntersectionNode1 = function (headA, headB) {
    
    
  var set = new Set();
  while (headA || headB) {
    
    
    if (headA) {
    
    
      if (set.has(headA)) {
    
    
        return headA;
      } else {
    
    
        set.add(headA);
        headA = headA.next;
      }
    }
    if (headB) {
    
    
      if (set.has(headB)) {
    
    
        return headB;
      } else {
    
    
        set.add(headB);
        headB = headB.next;
      }
    }
  }
  return null;
};
var getIntersectionNode2 = function (headA, headB) {
    
    
  var node1 = headA;
  var node2 = headB;
  var n = 0;
  while (node1 !== node2) {
    
    
    node1 = node1.next;
    node2 = node2.next;
    if (node1 == null) {
    
    
      node1 = headB;
      n++;
      if (n == 2) return null;
    }
    if (node2 == null) {
    
    
      node2 = headA;
    }
  }
  return node1;
};
// 链表反转
var reverseList = function (head) {
    
    
  var pre = null;
  var cur = head;
  while (cur) {
    
    
    var next = cur.next;
    cur.next = pre;
    pre = cur;
    cur = next;
  }
  return pre;
};
// 两链表,对应的数相加,生成新的链表
var addTwoNumbers = function (l1, l2) {
    
    
  var arr1 = []; // [3,4,2,7]
  var arr2 = []; //[4,6,5]
  var p1 = l1;
  var p2 = l2;
  while (p1 || p2) {
    
    
    if (p1) {
    
    
      arr1.unshift(p1.val);
      p1 = p1.next;
    }
    if (p2) {
    
    
      arr2.unshift(p2.val);
      p2 = p2.next;
    }
  }
  var brr = [];
  var car = 0; // 前一个数加的进位数 1|0
  while (arr1.length || arr2.length) {
    
    
    if (arr1.length && arr2.length) {
    
    
      var sum = arr1.shift() + arr2.shift() + car;
    } else if (arr1.length) {
    
    
      var sum = arr1.shift() + car;
    } else {
    
    
      var sum = arr2.shift() + car;
    }
    brr.push(sum % 10);
    car = sum >= 10 ? 1 : 0;
  }
  brr.reverse(); // [7,0,8,7] ==> [7,8,0,7]
  if (car == 1) brr.unshift(1);
  var head = new ListNode();
  var node = head;
  for (var val of brr) {
    
    
    node = node.next = new ListNode(val);
  }
  return head.next;
};

猜你喜欢

转载自blog.csdn.net/formylovetm/article/details/126340991
今日推荐