leetcode刷题记录(29)-简单

1.重新排列日志文件

题目:

你有一个日志数组 logs。每条日志都是以空格分隔的字串。

对于每条日志,其第一个字为字母与数字混合的 标识符 ,除标识符之外的所有字为这一条日志的 内容 。

除标识符之外,所有字均由小写字母组成的,称为 字母日志
除标识符之外,所有字均由数字组成的,称为 数字日志
题目所用数据保证每个日志在其标识符后面至少有一个字。

请按下述规则将日志重新排序:

所有 字母日志 都排在 数字日志 之前。
字母日志 在内容不同时,忽略标识符后,按内容字母顺序排序;在内容相同时,按标识符排序;
数字日志 应该按原来的顺序排列。
返回日志的最终顺序。

思路:先区分字母日志和数字日志,然后在字母日志之间排序

/**
 * @param {string[]} logs
 * @return {string[]}
 */
var reorderLogFiles = function(logs) {
  const l1 = [];
  const l2 = [];
  for (const s of logs) {
    if (s.split(" ")[1][0].charCodeAt() > 96) {
      l1.push(s);
    } else {
      l2.push(s);
    }
  }
  l1.sort((cNum, nNum) => {
    let cNumIndex = cNum.indexOf(" ");
    let nNumIndex = nNum.indexOf(" ");
    let cSplit1 = cNum.substring(0, cNumIndex);
    let cSplit2 = cNum.substring(cNumIndex, cNum.length);
    let nSplit1 = nNum.substring(0, nNumIndex);
    let nSplit2 = nNum.substring(nNumIndex, nNum.length);
    if (cSplit2 === nSplit2) {
      return cSplit1 < nSplit1 ? -1 : 1;
    } else {
      return cSplit2 < nSplit2 ? -1 : 1;
    }
  });
  return l1.concat(l2);
};

2.二叉搜索树的范围和

题目:

给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和。

二叉搜索树保证具有唯一的值。

思路:中序遍历的方式,如果在范围内,加上当前节点的值,并且遍历左右子节点;如果当前节点比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 {number}
 */
var rangeSumBST = function(root, L, R) {
  const search = (root) => {
    if (!root) return 0;
    if (root.val < L) {
      return search(root.right);
    } else if (root.val > R) {
      return search(root.left);
    } else {
      return root.val + search(root.left) + search(root.right);
    }
  };
  return search(root);
};

迭代:


/**
 * 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 {number}
 */
var rangeSumBST = function(root, L, R) {
  let sum = 0;
  const stack = [root];
  while (stack.length) {
    const item = stack.pop();
    if(!item)continue
    if (item.val < L) {
      stack.push(item.right);
    } else if (item.val > R) {
      stack.push(item.left);
    } else {
      sum += item.val;
      stack.push(item.left, item.right);
    }
  }
  return sum;
};

非尾递归的递归

/**
 * 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 {number}
 */
var rangeSumBST = function(root, L, R) {
  let sum = 0;
  const search = (root) => {
    if (!root) return 0;
    if (root.val < L) {
      search(root.right);
    } else if (root.val > R) {
      search(root.left);
    } else {
      sum += root.val;
      search(root.left);
      search(root.right);
    }
  };
  search(root);
  return sum;
};

3.有效的山脉数组

题目:

给定一个整数数组 A,如果它是有效的山脉数组就返回 true,否则返回 false。

让我们回顾一下,如果 A 满足下述条件,那么它是一个山脉数组:

A.length >= 3
在 0 < i < A.length - 1 条件下,存在 i 使得:
A[0] < A[1] < ... A[i-1] < A[i]
A[i] > A[i+1] > ... > A[A.length - 1]

思路:首先,排除相邻两个数相等的情况。然后,开始肯定是升序的,最后肯定是降序的,用一个变量记录当前是升序还是降序,如果是降序,又碰到升序,则不符合条件。如果是单调递增,也不符合条件

/**
 * @param {number[]} A
 * @return {boolean}
 */
var validMountainArray = function(A) {
  const l = A.length;
  if (l < 3) return false;
  let flag = true;
  if (A[0] >= A[1]) return false;
  for (let i = 0; i < l - 1; i++) {
    if (A[i] == A[i + 1]) return false;
    if (flag && A[i] > A[i + 1]) {
      flag = false;
    } else if (!flag && A[i] < A[i + 1]) {
      return false;
    }
  }
  return !flag;
};

4.增减字符串匹配

题目:

给定只含 "I"(增大)或 "D"(减小)的字符串 S ,令 N = S.length。

返回 [0, 1, ..., N] 的任意排列 A 使得对于所有 i = 0, ..., N-1,都有:

如果 S[i] == "I",那么 A[i] < A[i+1]
如果 S[i] == "D",那么 A[i] > A[i+1]

思路:对于任意位置的数字而言,它只需要和它的下一个字符比较,所以我们将所有可选的数字放在一个数组里,如果当前字符是I,那么取最小的数,当前数字是D,那么取最大的数

/**
 * @param {string} S
 * @return {number[]}
 */
var diStringMatch = function(S) {
  const l = S.length;
  const list = new Array(l + 1);
  for (let i = 0; i <= l; i++) {
    list[i] = i;
  }
  const res = [];
  for (const i of S) {
    if (i == "I") {
      res.push(list.shift());
    } else {
      res.push(list.pop());
    }
  }
  return res.concat(list);
};

5.删列造序

题目:

给定由 N 个小写字母字符串组成的数组 A,其中每个字符串长度相等。

你需要选出一组要删掉的列 D,对 A 执行删除操作,使 A 中剩余的每一列都是 非降序 排列的,然后请你返回 D.length 的最小可能值。

删除 操作的定义是:选出一组要删掉的列,删去 A 中对应列中的所有字符,形式上,第 n 列为 [A[0][n], A[1][n], ..., A[A.length-1][n]])。(可以参见 删除操作范例)

思路:遍历每个字符的同一个位置,如果出现降序,那么+1

/**
 * @param {string[]} A
 * @return {number}
 */
var minDeletionSize = function(A) {
  const l = A.length;
  const s = A[0].length;
  let res = 0;
  for (let i = 0; i < s; i++) {
    for (let j = 0; j < l-1; j++) {
      if (A[j][i] > A[j + 1][i]) {
          res++
          break
      };
    }
  }
  return res;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值