leetcode刷题记录(23)-简单

这篇博客详细解析了LeetCode中的五个问题:山羊拉丁文、较大分组的位置、翻转图像、矩形重叠以及矩阵中的幻方。针对每个问题,给出了思路和时间复杂度分析,包括使用双指针法、位运算等技巧解决编程挑战。
摘要由CSDN通过智能技术生成

1.山羊拉丁文

题目:

给定一个由空格分割单词的句子 S。每个单词只包含大写或小写字母。

我们要将句子转换为 “Goat Latin”(一种类似于 猪拉丁文 - Pig Latin 的虚构语言)。

山羊拉丁文的规则如下:

如果单词以元音开头(a, e, i, o, u),在单词后添加"ma"。
例如,单词"apple"变为"applema"。

如果单词以辅音字母开头(即非元音字母),移除第一个字符并将它放到末尾,之后再添加"ma"。
例如,单词"goat"变为"oatgma"。

根据单词在句子中的索引,在单词最后添加与索引相同数量的字母'a',索引从1开始。
例如,在第一个单词后添加"a",在第二个单词后添加"aa",以此类推。
返回将 S 转换为山羊拉丁文后的句子。

思路:遍历就行,先将句子分割成数组,然后拼接

时间复杂度O(n),空间复杂度O(n)

/**
 * @param {string} S
 * @return {string}
 */
var toGoatLatin = function(S) {
  const s = ["a", "e", "i", "o", "u"];
  const words = S.split(" ");
  const temp = "a";
  words.forEach((item, index) => {
    if (s.includes(item[0].toLowerCase())) {
      words[index] = `${item}ma${temp.repeat(index + 1)}`;
    } else {
      words[index] = `${item.slice(1)}${item[0]}ma${temp.repeat(index + 1)}`;
    }
  });
  return words.join(" ");
};

2.较大分组的位置

题目:

在一个由小写字母构成的字符串 S 中,包含由一些连续的相同字符所构成的分组。

例如,在字符串 S = "abbxxxxzyy" 中,就含有 "a", "bb", "xxxx", "z" 和 "yy" 这样的一些分组。

我们称所有包含大于或等于三个连续字符的分组为较大分组。找到每一个较大分组的起始和终止位置。

最终结果按照字典顺序输出。

思路:用双指针法,记录重复字符串的开始和结束下标,下标差大于等于2就符合条件

时间复杂度O(n),空间复杂度O(n)

/**
 * @param {string} S
 * @return {number[][]}
 */
var largeGroupPositions = function(S) {
  let s = S[0];
  let start = 0,
    end = 0;
  const l = S.length;
  const res = [];
  if (l < 3) return res;
  for (let i = 0; i < l; ) {
    while (S[i] === s) {
      end = i;
      i++
    }
    if (end - start >= 2) {
      res.push([start, end]);
    }
    start = end = i;
    s=S[i]
    i++
  }
  if (end - start >= 2) {
    res.push([start, end]);
  }
  return res;
};

3.翻转图像

题目:

给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果。

水平翻转图片就是将图片的每一行都进行翻转,即逆序。例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]。

反转图片的意思是图片中的 0 全部被 1 替换, 1 全部被 0 替换。例如,反转 [0, 1, 1] 的结果是 [1, 0, 0]。

思路:可以在水平翻转的同时将0和1反转,借助位运算异或^,将1和0反转

时间复杂度O(n²),空间复杂度O(1),原地算法,不需要额外的空间

/**
 * @param {number[][]} A
 * @return {number[][]}
 */
var flipAndInvertImage = function(A) {
  const h = A.length;
  if (!h) return A;
  const w = A[0].length;
  for (let i = 0; i < h; i++) {
    for (let j = 0; j < w / 2; j++) {
      [A[i][j], A[i][w - j - 1]] = [A[i][w - j - 1] ^ 1, A[i][j] ^ 1];
    }
  }
  return A;
};

4.矩形重叠

题目:

矩形以列表 [x1, y1, x2, y2] 的形式表示,其中 (x1, y1) 为左下角的坐标,(x2, y2) 是右上角的坐标。

如果相交的面积为正,则称两矩形重叠。需要明确的是,只在角或边接触的两个矩形不构成重叠。

给出两个矩形,判断它们是否重叠并返回结果。

思路:两个矩形判断是否重叠,有两种办法,第一个方法,固定一个矩形,判断另一个矩形的四个点是否在第一个矩形内,只要有一个点在第一矩形内,就重叠。第二个方法就是判断两个矩形中心点的距离,两个中心点x/y轴的距离都小于对应方向长度和的一半就行

这里用第二种方法

/**
 * @param {number[]} rec1
 * @param {number[]} rec2
 * @return {boolean}
 */
const inRange = (value, min, max) => {
  return value > min && value < max;
};
var isRectangleOverlap = function (rec1, rec2) {
  const ax = (rec1[0] + rec1[2]) / 2;
  const ay = (rec1[1] + rec1[3]) / 2;
  const bx = (rec2[0] + rec2[2]) / 2;
  const by = (rec2[1] + rec2[3]) / 2;
  const h1 = rec1[3] - rec1[1];
  const h2 = rec2[3] - rec2[1];
  const w1 = rec1[2] - rec1[0];
  const w2 = rec2[2] - rec2[0];
  return (
    inRange(Math.abs(bx - ax), -1, (w1 + w2) / 2) &&
    inRange(Math.abs(by - ay), -1, (h1 + h2) / 2)
  );
};

5.矩阵中的幻方

题目:

3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。

给定一个由整数组成的 grid,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。

思路:遍历所有的3×3矩阵,记录第一行的和,然后就是计算每一行和每一列的差,可以在同一轮遍历同时计算出行和列的和,调换x/y的值就行。

时间复杂度,是O(3n),也就是O(n),空间复杂度O(1)

/**
 * @param {number[][]} grid
 * @return {number}
 */
var numMagicSquaresInside = function(grid) {
  const h = grid.length;
  let count = 0;
  if (!h) return count;
  const w = grid[0].length;
  if (h < 3 || w < 3) return count;
  for (let i = 0; i < h - 2; i++) {
    for (let j = 0; j < w - 2; j++) {
      if (checkGrid(i, j)) count++;
    }
  }
  function checkGrid(i, j) {
    const set = new Set();
    let rowSum;
    for (let row = 0; row < 3; row++) {
      let sum = 0;
      let cSum = 0;
      for (let col = 0; col < 3; col++) {
          if(grid[i + row][j + col]>9||grid[i + row][j + col]<1)return false
        if (set.has(grid[i + row][j + col])) return false;
        set.add(grid[i + row][j + col]);
        sum += grid[i + row][j + col];
        cSum += grid[i + col][j + row];
      }
      rowSum = rowSum || sum;
      if (sum !== rowSum) return false;
      if (rowSum !== cSum) return false;
    }
    if (grid[i][j] + grid[i + 2][j + 2] !== grid[i][j + 2] + grid[i + 2][j])
      return false;
    return true;
  }
  return count;
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值