刷题顺序很重要吗?重要
发布时间:2025-06-24 19:31:00 作者:北方职教升学中心 阅读量:759
首先要知道数组在内存中的存储方式,这样才能真正理解数组相关的面试题
数组是存放在连续内存空间上的相同类型数据的集合。448、495、但现在在网上随便搜一下就能搜到许多关于计算机语言的教程。273 提示: 示例 2: 示例 1: 示例 2: 提示: 详解:这个就是我们在遍历的时候增加一个num++,放到数组里面 题解: 题目: 在 MATLAB 中,有一个非常有用的函数 示例 2: 刷题顺序很重要吗? 提示: 题目: 代码 测试用例 测试结果 测试结果 628. 三个数的最大乘积 已解答 简单 相关标签 相关企业 给你一个整型数组 你必须设计并实现一个时间复杂度为 题解: 题目: 给定一个非空且只包含非负数的整数数组 示例 1: 示例 2: 详解:其实这个就是左边和右边为1 第一行也是为1,然后下一行是上一行两个相邻元素之和 题解: 题目: 给定一个非负索引 示例 3: 题解: 题目: 给你一个整数数组 你的任务是在 题解: 题目: 给你一个长度为 示例 1: 示例 2: 示例 3: 提示: 详解:同样的这里也是可以用一个哈希表来记录值和出现的次数,然后遍历哈希表,取出出现2次的值即可 题解: 题目: 给你一个未排序的整数数组 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。 示例 1: 示例 2: 提示: 详解:我们可以把非零的元素移到前面,然后把其他位置的元素置零 题解: 题目: 给定一个非负整数 正是因为数组在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。 示例 1: 示例 2: 示例 3: 提示: 题解: 题目: 集合 题解: 题目: 给你一个长度为 我们是这样定义一个非递减数列的: 对于数组中任意的 题目: 给你一个长度为 给你一个由二维数组 示例 1: 示例 2: 提示: 详解:因为不能使用复制矩阵,所以只能在原矩阵上操作,细细观察,变换的矩阵就是把原来的矩阵翻转,然后再沿着列翻转 题解: 题目: 给定一个 示例 2: 给你一个 非递减 的整数数组 下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。 示例 1: 示例 2: 提示: 详解:声明二个Boolean的数组,用于记录每一个为0的元素的横纵坐标,然后再次遍历二维数组,把有横纵坐标的那一行或那一列变为0 题解: 题目: 根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。 重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。2、艾希在第 1、41、 题目数据 保证 数组 例如删除下标为3的元素,需要对下标为3的元素后面的所有元素都要做移动操作,如图所示: 然后二维数组其实和一维数组其实是一样的概念,只不过由X Y来组成数组元素,如图: 注意: 题目:给定一个二进制数组 举一个字符数组的例子,如图所示: 有亮点需要注意: 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 示例 2: 提示: 详解:这里也是利用第 k 个元素的 k - 1前面的乘积和 k + 1 后面的乘积 题解: 示例 1: 示例 2: 提示: 详解:这里有一种解法就是先翻转所有的元素,然后再次翻转前 k 个元素,再翻转[k, length - 1]个元素。请使用 原地 算法。当然,最好还是上一下正规的课程。 示例 1: 示例 2: 提示: 详解:每次操作让n - 1个元素加1,我们可以逆向思考,每次操作都使得1个元素 -1,然后返回最少操作让所有元素的值都一样。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 题解: 题目: 给定一个长度为 请 不要使用除法,且在 示例 2: 示例 1: 示例 2: 示例 3: 题解: 请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。此例中存在两个值为 2 的数,它们都排第二。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。艾希在第 1、先计算好,然后利用索引可以直接求出。 示例 1: 示例 2: 提示: 详解:不管给什么矩阵,改造后长宽的乘积一定要一样,也就是元素个数之和一定要一样。包含了小编刷题的心得与解法(主要使用JAVA语言来解题),此后小编会继续分享后续的刷题的一些详解和如何进行有效的刷题。我么可以先把矩阵放进一个数组里然后再遍历新的二维矩阵,把数组里的数据放到新的矩阵里面。 示例 1: 示例 1: 示例 2: 提示: 详解: 题解: 题目: 给定一个整数数组 实现 示例 1: 提示: 详解:前缀和数组是一种预处理技术,可以在常数时间内计算任意子数组的和。 示例 2: 题解: 题目: 给定一个 n × n 的二维矩阵 示例 1: 示例 2: 提示: 提示: 详解:这一题需要先判断第 i 个元素和 i - 1 个元素之间的差值是否大于duration,如果差值比duration大,直接加上duration、304、 示例 1: 示例 2: 提示: 示例 1: 示例 2: 详解:我们只需要遍历数组,对数组中的元素进行判断、给你 数组是非常基础的数据结构,在面试中,考察数组的题目一般在思维上都不难,主要是考察对代码的掌控能力 也就是说,想法很简单,但实现起来 可能就不是那么回事了。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。按照题目类别结构化地刷题的速度不仅更快,而且可以在刷完一类题之后进行总结。 题解: 题目: 给你一个含 给定一个数组 返回艾希处于中毒状态的 总 秒数。请你找出所有出现 两次 的整数,并以数组形式返回。如果没有那么就要加上的是元素之间的差值,图解 题解: 题目:给你一个非空数组,返回此数组中 第三大的数 。 生成的测试用例让答案符合 32 位 整数。 题解: 题目: 给你一个 完全零基础可以刷题吗? 如果具有给定参数的 题目: 给定一个整数数组 当提莫攻击艾希,艾希的中毒状态正好持续 提示: 详解:暂无 题解: 题目: 给定一个数组 正式地讲,提莫在 示例 1: 示例 2: 提示: 详解: 根据以下公式计算 是不是有许多小伙伴在刷力扣的时候感觉无从下手?从头按顺序开始刷的童鞋们可能会比较有感触,为什么才第四题就感觉很难了?没关系,本文将对力扣的 1-500 题中不需要会员的数据结构与算法题目(数据库与 shell 除外)进行分类,并推荐一个刷题的顺序。 此篇文章是小编整理和学习的过程和心得、 示例 1: 示例 2: 示例 3: 详解:这个是返回第几行的数组元素,就是简化版本的杨辉三角, 题解:这里的话就是每一行插入当前的元素。 示例 1: 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 示例 2: 提示: 详解: 首先:top = 0 bottom = left= 0 right= 题解: 题目: 给你一个正整数 示例 1: 给定一个包含 请你实现时间复杂度为 例如:数组 题解: 提示: 题目: 在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。 数组可以方便的通过下标索引的方式获取到下标对应的数据。 示例 3: 假设 返回 详解:要找频率出现的最大的度,并且还要输出最短连续数组的长度。 示例 1: 详解:需要找出最小的正整数,我们可以这样想,把大于0的数每个数都放与之对应的索引上去,然后再次遍历数组,如果哪个数与其索引并不对应,那么索引 i+1 就是缺失的最小正数 题解: 题目: 将非负整数 示例 1:数组的改变移动 453、289 前缀和数组 303、 nums.length
在 1
到 50,000
范围内。输入:nums = [4,2,1]输出:false解释:你不能在只改变一个元素的情况下将其变为非递减数列。
输入:n = 3输出:[[1,2,3],[8,9,4],[7,6,5]]
输入:n = 1输出:[[1]]
1 <= n <= 20
class Solution { public int[][] generateMatrix(int n) { int[][] matrix = new int[n][n]; int num = 1; int top = 0; int bottom = n - 1; int left = 0; int right = n - 1; while (num <= n * n) { // 从上左往右走 for (int i = left; i <= right; i++) { matrix[top][i] = num++; } top++; // 从右边往下走 for (int i = top; i <= bottom; i++) { matrix[i][right] = num++; } right--; // 从下边界往左走 if (top <= bottom) { for (int i = right; i >= left; i--) { matrix[bottom][i] = num++; } bottom--; } // 从左边界往上走 if (left <= right) { for (int i = bottom; i >= top; i--) { matrix[i][left] = num++; } left++; } } return matrix; }}
2.9 二维数组变换
2.9.1 重塑举证(566)
reshape
,它可以将一个 m x n
矩阵重塑为另一个大小不同(r x c
)的新矩阵,但保留其原始数据。输入:timeSeries = [1,2], duration = 2输出:3解释:提莫攻击对艾希的影响如下:- 第 1 秒,提莫攻击艾希并使其立即中毒。
重要。396特定顺序遍历二维数组 54、在所有不同数字中排第三大的数为 1 1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
详解;我们可以使用JAVA里的一种数据结构TreeSet(自然排序集合),遍历数组,只保留三个元素在Treeset集合了,超过三个就剔除最小那个,最后只需要输出TreeSet最小的元素就是第三大元素
题解:;
class Solution { public int thirdMax(int[] nums) { TreeSet<Integer> set = new TreeSet<>(); for(int num : nums) { set.add(num); if(set.size() > 3){ set.pollFirst(); // 移除最小的元素以保持集合的大小为3 } } return set.size() == 3 ? set.first() : set.last(); //第三大数不存在 返回最大的数 }}
2.3.4 三个数最大乘积 (628)
nums
,在数组中找出由三个数组成的最大乘积,并输出这个乘积。O(n)
且仅使用常量额外空间的算法解决此问题。如果提莫在中毒影响结束 前 再次攻击,中毒状态计时器将会 重置 ,在新的攻击之后,中毒影响将会在 duration
秒后结束。3 秒处于中毒状态,所以总中毒秒数是 3 。连续子数组里面拥有相同度的有如下所示:[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]最短连续子数组 [2, 2] 的长度为 2 ,所以返回 2 。对于缺失的元素,我们可以用一个boolean数组来遍历,给[1,n]的数组每个位置都标记为True,然后再次遍历原数组,如果booelan[i]=false,i就是那个丢失的元素class Solution { public int[] findErrorNums(int[] nums) { int repeat = 0; int lost = 0; Arrays.sort(nums); for (int i = 1; i < nums.length; i++) { if (nums[i] == nums[i - 1]) { repeat = nums[i]; } // 检查从1到n的每一个数字 boolean[] seen = new boolean[nums.length + 1]; for (int num : nums) { seen[num] = true; } for (int j = 1; j <= nums.length; j++) { if (!seen[j]) { lost = j; break; } } } return new int[] { repeat, lost }; }}
2.4.2 数组的度(697)
nums
,数组的 度 的定义是指数组里任一元素出现频数的最大值。输入:numRows = 5输出:[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
输入:numRows = 1输出:[[1]]
class Solution { public List<List<Integer>> generate(int numRows) { List<List<Integer>> triangle = new ArrayList<>(); if (numRows == 0) { return triangle; } // 第一行固定为 [1] List<Integer> firstRow = new ArrayList<>(); firstRow.add(1); triangle.add(firstRow); // 生成每一行 for (int i = 1; i < numRows; i++) { List<Integer> prevRow = triangle.get(i - 1); List<Integer> currentRow = new ArrayList<>(); // 每行的第一个元素为 1 currentRow.add(1); // 中间的元素等于上一行的两个相邻元素之和 for (int j = 1; j < i; j++) { currentRow.add(prevRow.get(j - 1) + prevRow.get(j)); } // 每行的最后一个元素为 1 currentRow.add(1); triangle.add(currentRow); } return triangle; }}
2.6.2 杨辉三角II(119)
rowIndex
,返回「杨辉三角」的第 rowIndex
行。2 刷题顺序
2.1 数组篇
题目分类 题目编号 数组遍历 485、 输入:[2, 2, 3, 1]输出:1解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。
class NumArray {private int[] prefixSum; public NumArray(int[] nums) { int n = nums.length; prefixSum = new int[n + 1]; for (int i = 0; i < n; i++) { prefixSum[i + 1] = prefixSum[i] + nums[i]; } } public int sumRange(int left, int right) { return prefixSum[right + 1] - prefixSum[left]; }}/** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * int param_1 = obj.sumRange(left,right); */
2.10.2 除自身以外数组的乘积(238)
nums
,返回 数组 answer
,其中 answer[i]
等于 nums
中除 nums[i]
之外其余各元素的乘积 。所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6 。[4, 3, 2, 1]
,结果为 [1, 2, 3, 4]
。nums
中找到与 nums
拥有相同大小的度的最短连续子数组,返回其长度。5 秒处于中毒状态,所以总中毒秒数是 4 。665、697、59二维数组变换 566、 class Solution { public List<Integer> findDisappearedNumbers(int[] nums) { int length = nums.length; //用来标记不存在的数字 boolean[] bool = new boolean[length + 1]; List<Integer> result = new ArrayList<>(); for(int num : nums){ bool[num]=true; } for(int i = 1; i <= length; i++){ if(!bool[i]) { result.add(i); } } return result; }}
2.4.4数组中重复的数据(442)
n
的整数数组 nums
,其中 nums
的所有整数都在范围 [1, n]
内,且每个整数出现 一次 或 两次 。输入:nums = [4,3,2,7,8,2,3,1]输出:[2,3]
输入:nums = [1,1,2]输出:[1]
输入:nums = [1]输出:[]
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
nums
中的每个元素出现 一次 或 两次class Solution { public List<Integer> findDuplicates(int[] nums) { Map<Integer, Integer> twice = new HashMap<>(); List<Integer> result = new ArrayList<>(); int count = 0; // 记录出现两次的数组值 for (int num : nums) { twice.put(num, twice.getOrDefault(num, 0) + 1); } // 找出出现两次的数字 for (Map.Entry<Integer, Integer> entry : twice.entrySet()) { if (entry.getValue() == 2) { result.add(entry.getKey()); } } return result; }}
2.4.5 缺失的第一个正数(41)
nums
,请你找出其中没有出现的最小的正整数。输入:nums =
[0,1,0,3,12]
输出:[1,3,12,0,0]
输入:nums =
[0]
输出:[0]
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
class Solution { public void moveZeroes(int[] nums) { int nonZeroIndex = 0; // 用于记录非零元素应该存放的位置 // 遍历数组,将非零元素移动到数组前部 for (int i = 0; i < nums.length; i++) { if (nums[i] != 0) { nums[nonZeroIndex++] = nums[i]; } } // 将剩余的位置全部填充为0 for (int i = nonZeroIndex; i < nums.length; i++) { nums[i] = 0; } }}
2.6 二维数组及滚动数组
2.6.1 杨辉三角(118)
numRows
,生成「杨辉三角」的前 numRows
行。输入:nums = [1,2,3]输出:6
输入:nums = [1,2,3,4]输出:24
输入:nums = [-1,-2,-3]输出:-6
3 <= nums.length <= 104
-1000 <= nums[i] <= 1000
详解:首先要求三个数的最大乘积,我们要先给数组排序(JAVA里面的 Arrays.sort方法就可以排序 O(n)=nlog2n),这样才能更好找出最大的数来,然后是有两种情况
三个最大的正数
两个最小负数和一个最大正数
最后比较两个数 看一看是哪个最大就是最大的三个数乘积(Math.max)(a,b))
class Solution { public int maximumProduct(int[] nums) { // 利用Arrays给数组做自然排序 Arrays.sort(nums); int n = nums.length; //情况一 两个最小负数和最大数 int multiplyMax1 = nums[0] * nums[1] * nums[n - 1] ; //情况二 最大三个正数 int multiplyMax2 = nums[n - 1] * nums[n - 2] * nums[n - 3]; return Math.max(multiplyMax1, multiplyMax2); }}
2.4 统计数组的元素
2.4.1 错误的集合 (645)
s
包含从 1
到 n
的整数。我们可以用一个哈希表记录元素的key和出现的count次数,然后用两个哈希表记录下每个元素第一次出现时间和最后一次出现的时间,最后遍历第一个哈希表(也就是记录了所有值的哈希表),用得到的度去判断两个哈希表中元素位置,再相减就能求出来了。class Solution { public int minMoves(int[] nums) { int count = 0; Arrays.sort(nums); for(int i = 1; i < nums.length; i++) { //让没每个元素都减去最小的元素然后再累加 count = count + nums[i] - nums[0]; } return count; }}
2.5.2 非递减数列(665)
n
的整数数组 nums
,请你判断在 最多 改变 1
个元素的情况下,该数组能否变成一个非递减数列。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合 丢失了一个数字 并且 有一个数字重复 。请你将图像顺时针旋转 90 度。请你找出所有在 [1, n]
范围内但没有出现在 nums
中的数字,并以数组的形式返回结果。i
(0 <= i <= n-2)
,总满足 nums[i] <= nums[i + 1]
。414、亿及其英文表示 private static final String[] THOUSANDS = { "", "Thousand", "Million", "Billion" }; public String numberToWords(int num) { if (num == 0) return "Zero"; int i = 0; String words = ""; while (num > 0) { if (num % 1000 != 0) { words = helper(num % 1000) + THOUSANDS[i] + " " + words; } num /= 1000; i++; } return words.trim(); } private String helper(int num) { if (num == 0) return ""; else if (num < 20) return LESS_THAN_20[num] + " "; else if (num < 100) return TENS[num / 10] + " " + helper(num % 10); else return LESS_THAN_20[num / 100] + " Hundred " + helper(num % 100); }}2.5 数组的移动改变
2.5.1 最小操作使数组元素相等(453)
n
的整数数组,每次操作将会使 n - 1
个元素增加 1
。mat
表示的 m x n
矩阵,以及两个正整数 r
和 c
,分别表示想要的重构的矩阵的行数和列数。如果不存在,则返回数组中最大的数。输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]输出:[[7,4,1],[8,5,2],[9,6,3]]
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
n == matrix.length == matrix[i].length
1 <= n <= 20
-1000 <= matrix[i][j] <= 1000
class Solution { public void rotate(int[][] matrix) { int n = matrix.length; for(int i = 0; i < n; i++) { for(int j = i; j < n; j++ ) { //二维数组翻转 int temp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = temp; } } for(int i = 0; i < n; i++) { for(int j = 0; j < n /2 ; j++ ) { //将翻转后的数组列翻转 int temp = matrix[i][j]; matrix[i][j] = matrix[i][n - 1 - j]; matrix[i][n - 1 - j] = temp; } } }}
2.9.3 矩阵置零(73)
mx n
的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。输入:nums = [3,4,-1,1]输出:2解释:1 在数组中,但 2 没有。
timeSeries
,其中 timeSeries[i]
表示提莫在 timeSeries[i]
秒时对艾希发起攻击,以及一个表示中毒持续时间的整数 duration
。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]输出:[[1,0,1],[0,0,0],[1,0,1]]
输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]
m == matrix.length
n == matrix[0].length
1 <= m, n <= 200
-231 <= matrix[i][j] <= 231 - 1
class Solution { public void setZeroes(int[][] matrix) { int m = matrix.length; int n = matrix[0].length; // 创建标记数组 记录为零元素的行和列 boolean[] rows = new boolean[m]; boolean[] cols = new boolean[n]; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(matrix[i][j] == 0){ rows[i] = true; cols[j] = true; } } } //根据标记将行置零 for(int i = 0; i < m; i++){ if(rows[i] == true){ for(int j = 0; j < n; j++){ matrix[i][j] =0; } } } //根据标记将列置零 for(int j = 0; j < n; j++){ if(cols[j] == true){ for(int i = 0; i < m; i++){ matrix[i][j] = 0; } } } }}
2.9.4 生命游戏(289)
nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。2.3 数组遍历
2.3.1 最大连续1的个数(485)
nums
, 计算其中最大连续 1
的个数。输入:nums =
[1,2,3,4]
输出:[24,12,8,6]
输入:nums = [-1,1,0,-3,3]输出:[0,0,9,0,0]
2 <= nums.length <= 105
-30 <= nums[i] <= 30
nums
之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内
48、class Solution { public int[] productExceptSelf(int[] nums) { int n = nums.length; int[] answer = new int[n]; int[] prefix = new int[n]; int[] suffix = new int[n]; // 初始化 prefix 和 suffix 数组 prefix[0] = 1; suffix[n - 1] = 1; // 计算 prefix 数组 for (int i = 1; i < n; i++) { prefix[i] = prefix[i - 1] * nums[i - 1]; } // 计算 suffix 数组 for (int i = n - 2; i >= 0; i--) { suffix[i] = suffix[i + 1] * nums[i + 1]; } // 计算最终结果 for (int i = 0; i < n; i++) { answer[i] = prefix[i] * suffix[i]; } return answer; }}
输入:nums = [1,2,3,4,5,6,7], k = 3输出:
[5,6,7,1,2,3,4]
解释:向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
输入:nums = [-1,-100,3,99], k = 2输出:[3,99,-1,-100]解释:向右轮转 1 步: [99,-1,-100,3]向右轮转 2 步: [3,99,-1,-100]
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
输入:nums = [1,2,3]输出:3解释:只需要3次操作(注意每次操作会增加两个元素的值):[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
输入:nums = [1,1,1]输出:0
n == nums.length
1 <= nums.length <= 105
-109 <= nums[i] <= 109
class Solution { public void rotate(int[] nums, int k) { k = k % nums.length; // 处理 k 大于数组长度的情况 reverse(nums, 0, nums.length - 1); // 反转前k个元素 reverse(nums, 0, k - 1); // 反转剩余元素 reverse(nums, k, nums.length - 1); } // 辅助方法:反转数组中指定范围的元素 private void reverse(int[] nums, int start, int end) { while(start < end) { int temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; start++; end--; } }}
2.7.2 旋转函数(396)
n
的整数数组 nums
。O(n)
时间复杂度内完成此题。返回让数组所有元素相等的最小操作次数。输入:nums = [1,2,2,3,1,4,2]输出:6解释:数组的度是 3 ,因为元素 2 重复出现 3 次。对于萌新们来说,按照推荐顺序刷,能更好地掌握数据结构与算法基础。
输入:num = 123输出:"One Hundred Twenty Three"
输入:num = 12345输出:"Twelve Thousand Three Hundred Forty Five"
输入:num = 1234567输出:"One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
class Solution { // 低于 20 的数字及其英文表示 private static final String[] LESS_THAN_20 = { "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }; // 十位数及其英文表示 private static final String[] TENS = { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; // 千、
k
个元素,使这些元素恢复到它们在旋转后的正确位置。输入:mat = [[1,2],[3,4]], r = 1, c = 4输出:[[1,2,3,4]]
输入:mat = [[1,2],[3,4]], r = 2, c = 4输出:[[1,2],[3,4]]
m == mat.length
n == mat[i].length
1 <= m, n <= 100
-1000 <= mat[i][j] <= 1000
1 <= r, c <= 300
输入:timeSeries = [1,4], duration = 2输出:4解释:提莫攻击对艾希的影响如下:- 第 1 秒,提莫攻击艾希并使其立即中毒。
输入:board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]
输入:board = [[1,1],[1,0]]输出:[[1,1],[1,1]]
m == board.length
n == board[i].length
1 <= m, n <= 25
board[i][j]
为 0
或 1
class Solution { public void gameOfLife(int[][] board) { int m = board.length; int n = board[0].length; // 遍历每个细胞并计算其下一状态 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { int liveNeighbors = countLiveNeighbors(board, i, j); // 根据规则更新状态 if (board[i][j] == 1 && (liveNeighbors < 2 || liveNeighbors > 3)) { // 规则1或规则3:活细胞死亡 board[i][j] = 2; // 10 in binary } if (board[i][j] == 0 && liveNeighbors == 3) { // 规则4:死细胞复活 board[i][j] = 3; // 11 in binary } } } // 更新细胞状态 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { board[i][j] %= 2; } } } private int countLiveNeighbors(int[][] board, int i, int j) { int count = 0; int m = board.length; int n = board[0].length; // 方向数组,表示相邻的8个位置 int[] directions = {-1, 0, 1}; for (int x : directions) { for (int y : directions) { if (x == 0 && y == 0) { continue; } int newX = i + x; int newY = j + y; if (newX >= 0 && newX < m && newY >= 0 && newY < n) { if (board[newX][newY] == 1 || board[newX][newY] == 2) { count++; } } } } return count; }}
2.10 前缀和数组
2.10.1 区域和检索-数组不可变(303)
nums
,处理以下类型的多个查询:left
和 right
(包含 left
和 right
)之间的 nums
元素的 和 ,其中 left <= right
NumArray
类:NumArray(int[] nums)
使用数组 nums
初始化对象int sumRange(int i, int j)
返回数组 nums
中索引 left
和 right
之间的元素的 总和 ,包含 left
和 right
两点(也就是 nums[left] + nums[left + 1] + ... + nums[right]
)输入:["NumArray", "sumRange", "sumRange", "sumRange"][[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]输出:[null, 1, -1, -3]解释:NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3)numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1))
1 <= nums.length <= 104
-105 <= nums[i] <= 105
0 <= i <= j < nums.length
104
次 sumRange
方法输入:[1, 2]输出:2解释:第三大的数不存在, 所以返回最大的数 2 。每个细胞都具有一个初始状态:
1
即为 活细胞 (live),或 0
即为 死细胞 (dead)。class Solution { public int[][] matrixReshape(int[][] mat, int r, int c) { int m = mat.length; int n = mat[0].length; int[] fresh = new int[m * n]; if(m*n != r*c) return mat; int index = 0; for(int i = 0; i < m; i++ ){ for(int j = 0; j < n; j++){ fresh[index++] = mat[i][j]; } } int[][] reshaped = new int[r][c]; index = 0; for(int i = 0; i < r; i++ ){ for(int j = 0; j < c; j++){ reshaped[i][j] = fresh[index++]; } } return reshaped; }}
2.9.2 旋转图像 (48)
matrix
表示一个图像。4、输入:nums = [1,2,2,4]输出:[2,3]
输入:nums = [1,1]输出:[1,2]
2 <= nums.length <= 104
1 <= nums[i] <= 104
详解:因为数组是[1,n]的数组,要找出重复的数字和缺失的数,首先重复的数好找,我们先给数组进行排序(Arrays.srot()),然后遍历找出重复的那个元素。
1 <= timeSeries.length <= 104
0 <= timeSeries[i], duration <= 107
timeSeries
按 非递减 顺序排列 输入:nums = [4,3,2,7,8,2,3,1]输出:[5,6]
输入:nums = [1,1]输出:[2]
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
详解:先对数组进行排序,然后使用一个boolean数组来进行标记为True,遍历数组,对boolean[i]进行判断,为false的就是缺失的数据。
输入:nums = [1,1,0,1,1,1]输出:3解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
输入:nums = [1,0,1,1,0,1]输出:2
m x n
网格面板 board
的当前状态,返回下一个状态。2382.2 数组的理论基础
class Solution { public int findShortestSubArray(int[] nums) { // 哈希表记录每个元素的出现频数 Map<Integer, Integer> countMap = new HashMap<>(); // 哈希表记录每个元素首次出现的位置 Map<Integer, Integer> firstOccurrenceMap = new HashMap<>(); // 哈希表记录每个元素最后出现的位置 Map<Integer, Integer> lastOccurrenceMap = new HashMap<>(); int degree = 0; // 数组的度 int minLength = nums.length; // 初始化最短子数组长度为数组的长度 // 遍历数组 for (int i = 0; i < nums.length; i++) { int num = nums[i]; // 更新出现次数 countMap.put(num, countMap.getOrDefault(num, 0) + 1); // 记录首次出现的位置 if (!firstOccurrenceMap.containsKey(num)) { firstOccurrenceMap.put(num, i); } // 更新最后出现的位置 lastOccurrenceMap.put(num, i); } // 查找最大频数(数组的度) for (int count : countMap.values()) { degree = Math.max(degree, count); } // 查找具有最大频数的元素的最短子数组长度 for (int num : countMap.keySet()) { if (countMap.get(num) == degree) { int length = lastOccurrenceMap.get(num) - firstOccurrenceMap.get(num) + 1; minLength = Math.min(minLength, length); } } return minLength; }}
2.4.3 找到数组中消失的数字(448)
n
个整数的数组 nums
,其中 nums[i]
在区间 [1, n]
内。nums
代表了集合 S
发生错误后的结果。class Solution { public int findPoisonedDuration(int[] timeSeries, int duration) { int totalDuration = 0; for (int i = 1; i < timeSeries.length; i++) { int interval = timeSeries[i] - timeSeries[i - 1]; if (interval >= duration) { totalDuration += duration; } else { totalDuration += interval; } } // 加上最后一次攻击的持续时间 totalDuration += duration; return totalDuration; }}
2.3.3 第三大的数(414)
class Solution { public int maxRotateFunction(int[] nums) { int sum = 0; int F = 0; // 计算数组元素的总和和初始的 F(0) for (int i = 0; i < n; i++) { sum += nums[i]; F += i * nums[i]; } int maxF = F; // 计算其他 F(k) for (int k = 1; k < n; k++) { F = F + sum - n * nums[n - k]; maxF = Math.max(maxF, F); } return maxF; }}
2.8 特定顺序遍历二维数组
2.8.1 螺旋矩阵(54)
m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。2、
不能,至少要基本掌握一门计算机语言的语法。reshape
操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。class Solution { public List<Integer> getRow(int rowIndex) { List<Integer> row = new ArrayList<>(); // 初始化第 0 行 for (int i = 0; i <= rowIndex; i++) { row.add(0, 1); for (int j = 1; j < row.size() - 1; j++) { row.set(j, row.get(j) + row.get(j + 1)); } } return row; }}
2.7 数组的轮转
2.7.1 轮转数组(189)
nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。[7, 6, 5]
,结果为 [5, 6, 7]
。283二维数组及滚动数组 118、 duration
秒。n == nums.length
1 <= n <= 104
-105 <= nums[i] <= 105
class Solution { public boolean checkPossibility(int[] nums) { int count = 0; for (int i = 1; i < nums.length && count <= 1; i++) { if (nums[i] < nums[i - 1]) { count++; // 如果当前元素小于前一个元素,尝试调整当前或前一个元素 if (i - 2 < 0 || nums[i - 2] <= nums[i]) { nums[i - 1] = nums[i]; // 调整前一个元素 } else { nums[i] = nums[i - 1]; // 调整当前元素 } } } return count <= 1; }}
2.5.3 移动零(283)
nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。t
发起攻击意味着艾希在时间区间 [t, t + duration - 1]
(含 t
和 t + duration - 1
)处于中毒状态。输入:nums = [4,3,2,6]输出:26解释:F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26所以 F(0), F(1), F(2), F(3) 中的最大值是 F(3) = 26 。
输入:nums = [100]输出:0
n == nums.length
1 <= n <= 105
-100 <= nums[i] <= 100
F(k)
: F(k)=F(k−1)+sum−n⋅nums[n−k] 其中,nums[n-k]
是旋转到第 k
位的元素。设置一个标记为、1 简介
输入:rowIndex = 3输出:[1,3,3,1]
输入:rowIndex = 0输出:[1]
输入:rowIndex = 1输出:[1,1]
输入:nums = [4,2,3]输出:true解释:你可以通过把第一个 4 变成 1 来使得它成为一个非递减数列。
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]输出:[1,2,3,4,8,12,11,10,9,5,6,7]
m == matrix.length
n == matrix[i].length
1 <= m, n <= 10
-100 <= matrix[i][j] <= 100
matrix
.length - 1matrix
[0].length - 1class Solution { public List<Integer> spiralOrder(int[][] matrix) { List<Integer> result = new ArrayList<>(); if (matrix == null || matrix.length == 0) { return result; } int top = 0; int bottom = matrix.length - 1; int left = 0; int right = matrix[0].length - 1; while (top <= bottom && left <= right) { // 从左往右走 for (int i = left; i <= right; i++) { result.add(matrix[top][i]); } top++; // 从右边上往下走 for (int i = top; i <= bottom; i++) { result.add(matrix[i][right]); } right--; // 从右往左走下边界 if (top <= bottom) { for (int i = right; i >= left; i--) { result.add(matrix[bottom][i]); } bottom--; } // 从左边往上走 if (left <= right) { for (int i = bottom; i >= top; i--) { result.add(matrix[i][left]); } left++; } } return result; }}
2.8.2 螺旋矩阵II(59)
n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。628统计数组的元素 645、对于水平较高的小伙伴们来说,按照推荐的顺序刷,可以在 200 小时内刷完 500 多题。- 第 4 秒,提莫再次攻击艾希,艾希中毒状态又持续 2 秒,即第 4 秒和第 5 秒。119 数组的旋转 189、 输入:[3, 2, 1]输出:1解释:第三大的数是 1 。
m × n
个格子的面板,每一个格子都可以看成是一个细胞。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。百万、O(n)
并且只使用常数级别额外空间的解决方案。[1, 2, 3, 4, 5, 6, 7]
变为 [7, 6, 5, 4, 3, 2, 1]
。73、请不要 使用另一个矩阵来旋转图像。只要等于1就要标志位+1,最后输出最大连续数class Solution { public int findMaxConsecutiveOnes(int[] nums) { int maxCount = 0; int count = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == 1) { count++; if (count > maxCount) { maxCount = count; } } else { count = 0; } } return maxCount; }}
1 <= nums.length <= 105
nums[i]
不是 0
就是 1
.2.3.2 提莫攻击 (495)
输入:nums = [7,8,9,11,12]输出:1解释:最小的正数 1 没有出现。
k
个位置到末尾的元素,使这些元素恢复到它们在旋转后的正确位置。arrk
是数组 nums
顺时针旋转 k
个位置后的数组,我们定义 nums
的 旋转函数 F
为:F(k) = 0 * arrk[0] + 1 * arrk[1] + ... + (n - 1) * arrk[n - 1]
F(0), F(1), ..., F(n-1)
中的最大值 。输入:nums = [1,2,2,3,1]输出:2解释:输入数组的度是 2 ,因为元素 1 和 2 的出现频数最大,均为 2 。
class Solution { public int firstMissingPositive(int[] nums) { int n = nums.length; // Step 1: 将每个数字放到正确的位置上 for (int i = 0; i < n; i++) { while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) { swap(nums, i, nums[i] - 1); } } // Step 2: 找到第一个不符合位置的索引 for (int i = 0; i < n; i++) { if (nums[i] != i + 1) { return i + 1; } } // 如果所有位置都正确,返回 n + 1 return n + 1; } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; }}
2.4.6 整数转英文的表示(273)
num
转换为其对应的英文表示。输入:nums = [1,2,0]输出:3解释:范围 [1,2] 中的数字都在数组中。- 第 2 秒,提莫再次攻击艾希,并重置中毒计时器,艾希中毒状态需要持续 2 秒,即第 2 秒和第 3 秒。
nums[i]
是一个在 0
到 49,999
范围内的整数。442、