leetcode刷题记录(15)-简单

1.错误的集合

题目:

集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。

给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

思路:用一个set记录出现的数,出现过则是重复的数。遍历的同时累加,累加和与1-n的和的差就是丢失的数

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var findErrorNums = function(nums) {
  const l = nums.length;
  const set = new Set();
  let a = 0;
  let sum = 0;
  for (const n of nums) {
    if (set.has(n)) {
      a = n;
    } else {
      sum += n;
      set.add(n);
    }
  }
  return [a, ((1 + l) * l) / 2 - sum];
};

还可以用原地算法。用数组的下标记录出现的数。如果k出现,那么nums[k-1]就乘以-1.第二次循环时,某个数大于0,那么它的下标就是缺少的数

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var findErrorNums = function(nums) {
  let a = 0;
  for (const n of nums) {
    if (nums[Math.abs(n) - 1] < 0) {
      a = Math.abs(n);
    } else {
      nums[ Math.abs(n)- 1] *= -1;
    }
  }
  const l = nums.length;
  for (let i = 0; i < l; i++) {
    if (nums[i] > 0) {
      return [a, i + 1];
    }
  }
};

2.两数之和 IV——输入BST

题目:

给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。

思路:二叉搜索树的中序遍历是升序,所以是升序数组的搜索问题,用二分法。

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} k
 * @return {boolean}
 */
var findTarget = function(root, k) {
  const list = [];
  const search = (root) => {
    if (!root) return;
    search(root.left);
    list.push(root.val);
    search(root.right);
  };
  search(root);
  const l = list.length;
  let start = 0,
    end = l - 1;
  while (start < end) {
    const sum = list[start] + list[end];
    if (sum === k) return true;
    if (sum > k) {
      end--;
    } else {
      start++;
    }
  }
  return false;
};

3.机器人能否返回原点

题目:

在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。

移动顺序由字符串表示。字符 move[i] 表示其第 i 次移动。机器人的有效动作有 R(右),L(左),U(上)和 D(下)。如果机器人在完成所有动作后返回原点,则返回 true。否则,返回 false。

注意:机器人“面朝”的方向无关紧要。 “R” 将始终使机器人向右移动一次,“L” 将始终向左移动等。此外,假设每次移动机器人的移动幅度相同。

思路:维护一个二维坐标就行了,数组或者两个变量都可以

/**
 * @param {string} moves
 * @return {boolean}
 */
var judgeCircle = function(moves) {
  const res = [0, 0];
  for (const i of moves) {
    switch (i) {
      case "L":
        res[0]--;
        break;
      case "R":
        res[0]++;
        break;
      case "U":
        res[1]++;
        break;
      case "D":
        res[1]--;
        break;
    }
  }
  return !res[0] && !res[1];
};

4.图片平滑器

包含整数的二维矩阵 M 表示一个图片的灰度。你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽可能多的利用它们。

思路:遍历矩阵

/**
 * @param {number[][]} M
 * @return {number[][]}
 */
var imageSmoother = function(M) {
  const h = M.length;
  if (!h) return [];
  const w = M[0].length;
  const getEverage = (i, j) => {
    let sum = 0,
      count = 0;
    for (let m = i > 0 ? i - 1 : 0; m < i + 2 && m < h; m++) {
      for (let n = j > 0 ? j - 1 : 0; n < j + 2 && n < w; n++) {
        count++;
        sum += M[m][n];
      }
    }
    return ~~(sum / count);
  };
  const matrix = new Array(h).fill(null).map(() => new Array(w));
  for (let i = 0; i < h; i++) {
    for (let j = 0; j < w; j++) {
      matrix[i][j] = getEverage(i, j);
    }
  }
  return matrix;
};

5.非递减数列

题目:

给你一个长度为 n 的整数数组,请你判断在 最多 改变 1 个元素的情况下,该数组能否变成一个非递减数列。

我们是这样定义一个非递减数列的: 对于数组中所有的 i (0 <= i <= n-2),总满足 nums[i] <= nums[i + 1]。

思路:非递减数列,因为只能改变一个数,所以只需要找到两次递减情况即可。

递减情况分两种,一种是增大后前一个数,一种是减小前一个数。第一种情况,如果再前一个数仍然比当前数大,说明是非递减。第二种情况,如果后一个数必当前数小,也是非递减数列。

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var checkPossibility = function(nums) {
  const l = nums.length;
  if (l < 3) return true;
  let count = 0;
  for (let i = 1; i < l; i++) {
    if (count > 1) return false;
    if (nums[i] < nums[i - 1]) {
      nums[i] = nums[i - 1];
      count++;
    }
  }

  return count < 2;
};

 

你可能感兴趣的:(leetcode-简单难度)