leetcode刷题记录(16)-简单

1.修剪二叉搜索树

题目:

给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。

思路:递归处理即可。对每一课树,判断节点的值是否在边界内。如果在边界内,则返回对这个根节点,且左右子树分别递归修剪。如果小于L,则返回左子树的修剪结果,因为此时右子树的所有值肯定不满足。如果大于R,则返回右子树的修剪结果

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} L
 * @param {number} R
 * @return {TreeNode}
 */
var trimBST = function(root, L, R) {
  if (!root) return root;
  if (root.val < L) return trimBST(root.right, L, R);
  if (root.val > R) return trimBST(root.left, L, R);
  root.left = trimBST(root.left, L, R);
  root.right = trimBST(root.right, L, R);
  return root;
};

2.二叉树中第二小的节点

题目:

给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,那么该节点的值等于两个子节点中较小的一个。

思路:递归处理树。首先,记录根节点的值。我们要先明确一点:如果某个节点的子节点不等于根节点的值,那么这课子节点的树的所有节点的最小值就是这个子节点的值,且这个值肯定比根节点的值更大。所以这个值要作为可能的结果比较。

如果等于根节点的值,那么就先判断是否有子节点,没有子节点返回undefined,有子节点再递归处理。

我们的目标就是找到子树中不等于根节点的最小值

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var findSecondMinimumValue = function(root) {
  if (!root) return -1;
  const search = (root, val) => {
    if (!root) return;
    if (root.val === val) {
      if (!root.left) return;
      const left = search(root.left, val);
      const right = search(root.right, val);
      if (!left || !right) {
        return left || right;
      } else {
        return Math.min(left, right);
      }
    } else {
      return root.val;
    }
  };
  const left = search(root.left, root.val);
  const right = search(root.right, root.val);
  if (!left || !right) {
    return left || right || -1;
  } else {
    return Math.min(left, right);
  }
};

3.最长连续递增数列

题目:

给定一个未经排序的整数数组,找到最长且连续的的递增序列,并返回该序列的长度。

思路:遍历,记录上一次递归数列开始的数字的下标,每次遇到降序时计算下标差,注意在遍历结束之后也要做一次计算

/**
 * @param {number[]} nums
 * @return {number}
 */
var findLengthOfLCIS = function(nums) {
  let length = 0;
  let index = 1;
  nums.unshift(-Infinity)
  const l = nums.length;
  for (let i = 1; i < l; i++) {
    if (nums[i] <= (nums[i - 1])) {
      length = Math.max(i - index, length);
      index = i;
    }
  }
  return Math.max(l - index, length);
};

4.验证回文字符串 II

题目:给定一个非空字符串 s最多删除一个字符。判断是否能成为回文字符串。

思路:删除字符,可能删除左字符也可能删除右字符,所以做个分支处理。为了复用逻辑,可以记录删除的次数,用双指针实现

/**
 * @param {string} s
 * @return {boolean}
 */
var validPalindrome = function(s) {
  const valdate = (s, count) => {
    let left = 0;
    let right = s.length - 1;
    while (left < right) {
      if (count > 1) return false;
      if (s[left] === s[right]) {
        left++;
        right--;
      } else {
        if (!count) {
          return (
            valdate(s.slice(left + 1, right + 1), 1) ||
            valdate(s.slice(left, right), 1)
          );
        } else {
          return false;
        }
      }
    }
    return true;
  };
  return valdate(s, 0);
};

5.棒球比赛

题目:

你现在是棒球比赛记录员。
给定一个字符串列表,每个字符串可以是以下四种类型之一:
1.整数(一轮的得分):直接表示您在本轮中获得的积分数。
2. "+"(一轮的得分):表示本轮获得的得分是前两轮有效 回合得分的总和。
3. "D"(一轮的得分):表示本轮获得的得分是前一轮有效 回合得分的两倍。
4. "C"(一个操作,这不是一个回合的分数):表示您获得的最后一个有效 回合的分数是无效的,应该被移除。

每一轮的操作都是永久性的,可能会对前一轮和后一轮产生影响。
你需要返回你在所有回合中得分的总和。

示例 1:

输入: ["5","2","C","D","+"]
输出: 30
解释: 
第1轮:你可以得到5分。总和是:5。
第2轮:你可以得到2分。总和是:7。
操作1:第2轮的数据无效。总和是:5。
第3轮:你可以得到10分(第2轮的数据已被删除)。总数是:15。
第4轮:你可以得到5 + 10 = 15分。总数是:30。
示例 2:

输入: ["5","-2","4","C","D","9","+","+"]
输出: 27
解释: 
第1轮:你可以得到5分。总和是:5。
第2轮:你可以得到-2分。总数是:3。
第3轮:你可以得到4分。总和是:7。
操作1:第3轮的数据无效。总数是:3。
第4轮:你可以得到-4分(第三轮的数据已被删除)。总和是:-1。
第5轮:你可以得到9分。总数是:8。
第6轮:你可以得到-4 + 9 = 5分。总数是13。
第7轮:你可以得到9 + 5 = 14分。总数是27。
注意:

输入列表的大小将介于1和1000之间。
列表中的每个整数都将介于-30000和30000之间。

思路:创建一个数组,存储每一次有效回合的得分,最后对数组进行累加即可

/**
 * @param {string[]} ops
 * @return {number}
 */
var calPoints = function(ops) {
  const scores = [];
  for (const s of ops) {
    switch (s) {
      case "+":
        scores.push(
          (scores[scores.length - 1] || 0) + (scores[scores.length - 2] || 0)
        );
        break;
      case "D":
        scores.push((scores[scores.length - 1] || 0) * 2);
        break;
      case "C":
        scores.pop();
        break;
      default:
        scores.push(+s);
    }
  }
  return scores.reduce((res, i) => res + i, 0);
};

 

你可能感兴趣的:(leetcode-简单难度,修剪二叉搜索树,二叉说中第二小的节点,最长连续递增数列,验证回文字符串II,棒球比赛)