当前位置: 首页 > news >正文

【LeetCode hot100|Week3】数组,矩阵

笔记用于个人复习和巩固,题解非原创,参考LeetCode官方题解以及各个大佬的解法,希望给大家带来帮助,同时笔记也能督促我学习进步

这周主要把数组和矩阵的题目刷了一遍

文章目录

  • Week3
    • D1
      • 189. 轮转数组
    • D2
      • 238. 除自身以外数组的乘积
    • D3
      • 41. 缺失的第一个正数
    • D4
      • 73. 矩阵置零
    • D5
      • 54. 螺旋矩阵
    • D6
      • 48. 旋转图像
    • D7
      • 240. 搜索二维矩阵 II

Week3

D1

189. 轮转数组

189. 轮转数组

在这里插入图片描述

把A + B变成B + A:

  • 先反转整个数组
  • 再分别反转A和B
class Solution {public void rotate(int[] nums, int k) {int n = nums.length;k %= n; // 轮转 k 次等于轮转 k % n 次reverse(nums, 0, n - 1);reverse(nums, 0, k - 1);reverse(nums, k, n - 1);}private void reverse(int[] nums, int i, int j) {while (i < j) {int temp = nums[i];nums[i++] = nums[j];nums[j--] = temp;}}
}

D2

238. 除自身以外数组的乘积

238. 除自身以外数组的乘积

前缀积和后缀积

class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] answer = new int[n];int[] pre = new int[n];int[] suf = new int[n];pre[0] = nums[0];suf[0] = nums[n - 1];for(int i = 1;i < n;i++){pre[i] = pre[i - 1] * nums[i];suf[i] = suf[i - 1] * nums[n - 1 -i];}answer[0] = suf[n - 2];answer[n - 1] = pre[n - 2];for(int i = 1;i < n - 1;i++){answer[i] = pre[i - 1]*suf[n - 1 - 1 - i];}return answer;}
}

照灵茶山的优化一下索引

灵茶山版本的 suf[i] 直接表示“从 i+1n-1 的积”,索引清晰,无需转换

//灵茶山版
class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] pre = new int[n];pre[0] = 1; //初始化为1for (int i = 1; i < n; i++) {pre[i] = pre[i - 1] * nums[i - 1];}int[] suf = new int[n];suf[n - 1] = 1;for (int i = n - 2; i >= 0; i--) {suf[i] = suf[i + 1] * nums[i + 1];}int[] ans = new int[n];for (int i = 0; i < n; i++) {ans[i] = pre[i] * suf[i];}return ans;}
}
//个人改进版
class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] answer = new int[n];int[] pre = new int[n];int[] suf = new int[n];pre[0] = nums[0];suf[n - 1] = nums[n - 1];for(int i = 1;i < n;i++){pre[i] = pre[i - 1] * nums[i];}for(int i = n - 2;i >= 0;i--){suf[i] = suf[i + 1] * nums[i];}answer[0] = suf[1];answer[n - 1] = pre[n - 2];for(int i = 1;i < n - 1;i++){answer[i] = pre[i - 1]*suf[i + 1];}return answer;}
}

D3

41. 缺失的第一个正数

41. 缺失的第一个正数

原地哈希:将原来的数组视为哈希表

  • 要找的数一定是在[1,N+1]里的整数
  • 把1放在下标为0的位置上,把2放在下标为1的位置上…
class Solution {public int firstMissingPositive(int[] nums) {int n = nums.length;for (int i = 0; i < n; i++) {// 如果当前学生的学号在 [1,n] 中,但(真身)没有坐在正确的座位上while (1 <= nums[i] && nums[i] <= n && nums[i] != nums[nums[i] - 1]) {// 那么就交换 nums[i] 和 nums[j],其中 j 是 i 的学号int j = nums[i] - 1; // 减一是因为数组下标从 0 开始int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}}// 找第一个学号与座位编号不匹配的学生for (int i = 0; i < n; i++) {if (nums[i] != i + 1) {return i + 1;}}// 所有学生都坐在正确的座位上return n + 1;}
}//作者:灵茶山艾府

如果空间复杂度没要求 就用哈希表

class Solution {public int firstMissingPositive(int[] nums) {int n = nums.length;Set<Integer>hashSet = new HashSet<>();for(int num : nums){hashSet.add(num);}for(int i = 1;i < n;i++){if(!hashSet.contains(i)){return i;}}return n + 1;}
}

D4

73. 矩阵置零

73. 矩阵置零

用两个标记数组分别记录每一行和每一列是否有零出现。

  • 首先遍历该数组一次,如果某个元素为 0,那么就将该元素所在的行和列所对应标记数组的位置置为 true
  • 最后再次遍历该数组,用标记数组更新原数组
class Solution {public void setZeroes(int[][] matrix) {int m = matrix.length, n = matrix[0].length;boolean[] row = new boolean[m];boolean[] col = new boolean[n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (matrix[i][j] == 0) {row[i] = col[j] = true;}}}for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (row[i] || col[j]) {matrix[i][j] = 0;}}}}
}

D5

54. 螺旋矩阵

54. 螺旋矩阵

示例 2 这 12 个数字,可以分为以下 5 组:

  • 1→2→3→4
  • 8→12
  • 11→10→9
  • 5
  • 6→7

其中第 1,3,5 组都是向右或者向左走的,长度依次为 4,3,2,这是一个从 n=4 开始的逐渐递减的序列。

其中第 2,4 组都是向下或者向上走的,长度依次为 2,1,这是一个从 m−1=2 开始的逐渐递减的序列。

由于走的步数是有规律的,我们可以精确地控制在每个方向上要走多少步,无需判断是否出界、是否重复访问:

  • 从 (0,−1) 开始。

  • 一开始,向右走 n 步,每次先走一步,再把数字加入答案。走 n 步即 1→2→3→4,矩阵第一排的数都加入了答案。

  • 然后向下走 m−1 步,即 8→12。

  • 然后向左走 n−1 步,即 11→10→9。

  • 然后向上走 m−2 步,即 5。

  • 然后向右走 n−2 步,即 6→7。

  • 重复上述过程,直到答案的长度等于 mn。

代码实现时,可以这样简化代码:

  • 一开始走 n 步。

  • 把 n,m 分别更新为 m−1,n,这样下一轮循环又可以走 n 步(相当于走了 m−1 步),无需修改其他逻辑。

  • 把 n,m 分别更新为 m−1,n,这样下一轮循环又可以走 n 步(相当于走了 n−1 步)。

  • 把 n,m 分别更新为 m−1,n,这样下一轮循环又可以走 n 步(相当于走了 m−2 步)。

  • 依此类推,每次只需把 n,m 分别更新为 m−1,n 即可。

class Solution {private static final int[][] DIRS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 右下左上public List<Integer> spiralOrder(int[][] matrix) {int m = matrix.length;int n = matrix[0].length;int size = m * n;List<Integer> ans = new ArrayList<>(m * n); // 预分配空间int i = 0;int j = -1; // 从 (0, -1) 开始for (int di = 0; ans.size() < size; di = (di + 1) % 4) {for (int k = 0; k < n; k++) { // 走 n 步(注意 n 会减少)i += DIRS[di][0];j += DIRS[di][1]; // 先走一步ans.add(matrix[i][j]); // 再加入答案}int tmp = n;n = m - 1; // 减少后面的循环次数(步数)m = tmp;}return ans;}
}

D6

48. 旋转图像

48. 旋转图像

class Solution {public void rotate(int[][] matrix) {int n = matrix.length;int[][] matrix_new = new int[n][n];for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {matrix_new[j][n - i - 1] = matrix[i][j];}}for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {matrix[i][j] = matrix_new[i][j];}}}
}

matrix_new[col][n−row−1]=matrix[row][col]

matrix[n−row−1][n−col−1]=matrix[col][n−row−1]

D7

240. 搜索二维矩阵 II

240. 搜索二维矩阵 II

排除法
在这里插入图片描述

class Solution {public boolean searchMatrix(int[][] matrix, int target) {int i = 0;int j = matrix[0].length - 1;while(i < matrix.length && j >= 0){if(matrix[i][j] == target){return true;}else if(matrix[i][j] < target){i++;}else{j--;}}return false;}
}
http://www.dtcms.com/a/393722.html

相关文章:

  • linux-环境配置-指令-记录
  • 自学嵌入式第四十四天:汇编
  • RTX 4090助力深度学习:从PyTorch到生产环境的完整实践指南——模型部署与性能优化
  • PythonOCC 在二维平面上实现圆角(Fillet)
  • Unity 性能优化 之 实战场景简化(LOD策略 | 遮挡剔除 | 光影剔除 | 渲染流程的精简与优化 | Terrain地形优化 | 主光源级联阴影优化)
  • [GXYCTF2019]禁止套娃1
  • 【论文阅读】-《Triangle Attack: A Query-efficient Decision-based Adversarial Attack》
  • 云微短剧小程序系统开发:赋能短剧生态,打造全链路数字化解决方案
  • 《从延迟300ms到80ms:GitHub Copilot X+Snyk重构手游跨服社交系统实录》
  • 力扣2132. 用邮票贴满网格图
  • Halcon学习--视觉深度学习
  • LeetCode:40.二叉树的直径
  • dplyr 是 R 语言中一个革命性的数据操作包,它的名字是 “data plier“ 的缩写,意为“数据折叠器“或“数据操作器“
  • 使用Node.js和PostgreSQL构建数据库应用
  • 设计模式(C++)详解—享元模式(1)
  • C++线程池学习 Day08
  • VALUER倾角传感器坐标系的选择
  • 解决 win+R 运行处以及文件资源管理器处无法使用 wt、wsl 命令打开终端
  • R语言 生物分析 CEL 文件是 **Affymetrix 基因芯片的原始扫描文件**,全称 **Cell Intensity File**。
  • Apache Spark Shuffle 文件丢失问题排查与解决方案实践指南
  • xtuoj 0x05-C 项链
  • STM32F429I-DISC1【读取板载运动传感器数据】
  • 【Kafka面试精讲 Day 21】Kafka Connect数据集成
  • 2025数据资产管理平台深度分析:技术特性、与选型逻辑
  • RabbitMQ Java 解决消息丢失、重复和积压问题
  • 深入解析 Spring AI 系列:解析请求参数处理
  • OpenLayers地图交互 -- 章节五:捕捉交互详解
  • 阿瓦隆1566HA-448T矿机深度解析:性能、效率与冷却技术
  • 平替confluence,推荐一款国产开源免费的知识管理工具 - sward
  • 【开源】基于STM32的智能垃圾桶