|
| 1 | +# [2624. 蜗牛排序](https://leetcode.com/problems/snail-traversal) |
| 2 | + |
| 3 | +🟠 <font color=#ffb800>Medium</font>  🔗 [`LeetCode`](https://leetcode.com/problems/snail-traversal) |
| 4 | + |
| 5 | +## 题目 |
| 6 | + |
| 7 | +Write code that enhances all arrays such that you can call the |
| 8 | +`snail(rowsCount, colsCount)` method that transforms the 1D array into a 2D |
| 9 | +array organised in the pattern known as **snail traversal order**. Invalid |
| 10 | +input values should output an empty array. If `rowsCount * colsCount !== nums.length`, the input is considered invalid. |
| 11 | + |
| 12 | +**Snail traversal order** starts at the top left cell with the first value |
| 13 | +of the current array. It then moves through the entire first column from top |
| 14 | +to bottom, followed by moving to the next column on the right and traversing |
| 15 | +it from bottom to top. This pattern continues, alternating the direction of |
| 16 | +traversal with each column, until the entire current array is covered. For |
| 17 | +example, when given the input array `[19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, |
| 18 | +12, 18, 6, 13, 11, 20, 4, 15]` with `rowsCount = 5` and `colsCount = 4`, the |
| 19 | +desired output matrix is shown below. Note that iterating the matrix following |
| 20 | +the arrows corresponds to the order of numbers in the original array. |
| 21 | + |
| 22 | + |
| 24 | + |
| 25 | +**Example 1:** |
| 26 | + |
| 27 | +> Input: |
| 28 | +> |
| 29 | +> nums = [19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15] |
| 30 | +> |
| 31 | +> rowsCount = 5 |
| 32 | +> |
| 33 | +> colsCount = 4 |
| 34 | +> |
| 35 | +> Output: |
| 36 | +> |
| 37 | +> [ |
| 38 | +> |
| 39 | +> [19,17,16,15], |
| 40 | +> |
| 41 | +> [10,1,14,4], |
| 42 | +> |
| 43 | +> [3,2,12,20], |
| 44 | +> |
| 45 | +> [7,5,18,11], |
| 46 | +> |
| 47 | +> [9,8,6,13] |
| 48 | +> |
| 49 | +> ] |
| 50 | +
|
| 51 | +**Example 2:** |
| 52 | + |
| 53 | +> Input: |
| 54 | +> |
| 55 | +> nums = [1,2,3,4] |
| 56 | +> |
| 57 | +> rowsCount = 1 |
| 58 | +> |
| 59 | +> colsCount = 4 |
| 60 | +> |
| 61 | +> Output: [[1, 2, 3, 4]] |
| 62 | +
|
| 63 | +**Example 3:** |
| 64 | + |
| 65 | +> Input: |
| 66 | +> |
| 67 | +> nums = [1,3] |
| 68 | +> |
| 69 | +> rowsCount = 2 |
| 70 | +> |
| 71 | +> colsCount = 2 |
| 72 | +> |
| 73 | +> Output: [] |
| 74 | +> |
| 75 | +> Explanation: 2 multiplied by 2 is 4, and the original array [1,3] has a length of 2; therefore, the input is invalid. |
| 76 | +
|
| 77 | +**Constraints:** |
| 78 | + |
| 79 | +- `0 <= nums.length <= 250` |
| 80 | +- `1 <= nums[i] <= 1000` |
| 81 | +- `1 <= rowsCount <= 250` |
| 82 | +- `1 <= colsCount <= 250` |
| 83 | + |
| 84 | +## 题目大意 |
| 85 | + |
| 86 | +请你编写一段代码为所有数组实现 `snail(rowsCount,colsCount)` 方法,该方法将 1D 数组转换为以蜗牛排序的模式的 2D |
| 87 | +数组。无效的输入值应该输出一个空数组。当 ` rowsCount * colsCount !==``nums.length ` 时。这个输入被认为是无效的。 |
| 88 | + |
| 89 | +蜗牛排序从左上角的单元格开始,从当前数组的第一个值开始。然后,它从上到下遍历第一列,接着移动到右边的下一列,并从下到上遍历它。将这种模式持续下去,每列交替变换遍历方向,直到覆盖整个数组。例如,当给定输入数组 |
| 90 | +`[19, 10, 3, 7, 9, 8, 5, 2, 1, 17, 16, 14, 12, 18, 6, 13, 11, 20, 4, 15]` ,当 |
| 91 | +`rowsCount = 5` 且 `colsCount = 4` 时,需要输出矩阵如下图所示。注意,矩阵沿箭头方向对应于原数组中数字的顺序 |
| 92 | + |
| 93 | + |
| 95 | + |
| 96 | +**提示:** |
| 97 | + |
| 98 | +- `0 <= nums.length <= 250` |
| 99 | +- `1 <= nums[i] <= 1000` |
| 100 | +- `1 <= rowsCount <= 250` |
| 101 | +- `1 <= colsCount <= 250` |
| 102 | + |
| 103 | +## 解题思路 |
| 104 | + |
| 105 | +### 思路一 |
| 106 | + |
| 107 | +1. **输入验证**: |
| 108 | + - 首先检查 `rowsCount * colsCount` 是否等于 `nums.length`,如果不相等,则返回空数组,因为此时无法将 `nums` 重组成指定行列数的二维数组。 |
| 109 | +2. **初始化二维数组**: |
| 110 | + - 创建一个大小为 `rowsCount` x `colsCount` 的空二维数组 `res`,用于存储最终的结果。 |
| 111 | +3. **填充数组**: |
| 112 | + - 使用一个索引 `index`,从 0 开始依次取出 `nums` 中的元素并填充到 `res` 中。 |
| 113 | + - 遍历 `col` 列,对于每一列 `col`,需要判断当前列是自上而下填充还是自下而上填充。 |
| 114 | + - 如果 `col` 是偶数列,则自上而下填充。 |
| 115 | + - 如果 `col` 是奇数列,则自下而上填充。 |
| 116 | +4. **返回结果**: |
| 117 | + - 当所有元素填充完毕后,返回 `res`,即按蜗牛遍历顺序填充的二维数组。 |
| 118 | + |
| 119 | +#### 复杂度分析 |
| 120 | + |
| 121 | +- **时间复杂度**:`O(n)`,其中 `n = rowsCount * colsCount`,由于遍历了 `nums` 数组的所有元素。 |
| 122 | +- **空间复杂度**:`O(1)`,不包含结果数组的存储空间。 |
| 123 | + |
| 124 | +### 思路二 |
| 125 | + |
| 126 | +填充数组的时候,还可以遍历 `nums` 中的元素,然后根据元素下标 `i` 来动态计算行和列: |
| 127 | + |
| 128 | +1. 计算当前元素所在的列数:`col = (i / rowsCount) | 0`; |
| 129 | +2. 先计算当前元素所在列的奇偶:`dirction = col % 2 == 0`; |
| 130 | +3. 计算当前元素所在的行数: |
| 131 | + - 若列数是奇数(`dirction == true`),从上往下填充,行数为:`row = i % rowsCount`; |
| 132 | + - 若列数是偶数(`dirction == false`),从下往上填充,行数为:`row = rowsCount - 1 - (i % rowsCount)`; |
| 133 | +4. 将 `nums[i]` 填充到 `res[row][col]`; |
| 134 | + |
| 135 | +#### 复杂度分析 |
| 136 | + |
| 137 | +- **时间复杂度**:`O(n)`,其中 `n = rowsCount * colsCount`,由于遍历了 `nums` 数组的所有元素。 |
| 138 | +- **空间复杂度**:`O(1)`,不包含结果数组的存储空间。 |
| 139 | + |
| 140 | +## 代码 |
| 141 | + |
| 142 | +:::code-tabs |
| 143 | +@tab 思路一 |
| 144 | + |
| 145 | +```javascript |
| 146 | +/** |
| 147 | + * @param {number} rowsCount |
| 148 | + * @param {number} colsCount |
| 149 | + * @return {Array<Array<number>>} |
| 150 | + */ |
| 151 | +Array.prototype.snail = function (rowsCount, colsCount) { |
| 152 | + if (rowsCount * colsCount !== this.length) return []; |
| 153 | + |
| 154 | + let res = new Array(rowsCount).fill(0).map((i) => new Array(colsCount)); |
| 155 | + let index = 0; |
| 156 | + |
| 157 | + for (let col = 0; col < colsCount; col++) { |
| 158 | + if (col % 2 === 0) { |
| 159 | + // 从上到下填充这一列 |
| 160 | + for (let row = 0; row < rowsCount; row++) { |
| 161 | + res[row][col] = this[index++]; |
| 162 | + } |
| 163 | + } else { |
| 164 | + // 从下到上填充这一列 |
| 165 | + for (let row = rowsCount - 1; row >= 0; row--) { |
| 166 | + res[row][col] = this[index++]; |
| 167 | + } |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + return res; |
| 172 | +}; |
| 173 | + |
| 174 | +/** |
| 175 | + * const arr = [1,2,3,4]; |
| 176 | + * arr.snail(1,4); // [[1,2,3,4]] |
| 177 | + */ |
| 178 | +``` |
| 179 | + |
| 180 | +@tab 思路二 |
| 181 | + |
| 182 | +```javascript |
| 183 | +/** |
| 184 | + * @param {number} rowsCount |
| 185 | + * @param {number} colsCount |
| 186 | + * @return {Array<Array<number>>} |
| 187 | + */ |
| 188 | +Array.prototype.snail = function (rowsCount, colsCount) { |
| 189 | + if (rowsCount * colsCount !== this.length) return []; |
| 190 | + let res = new Array(rowsCount).fill(0).map((i) => new Array(colsCount)); |
| 191 | + for (let i = 0; i < rowsCount * colsCount; i++) { |
| 192 | + const col = (i / rowsCount) | 0; |
| 193 | + const dirction = col % 2 == 0; |
| 194 | + const row = dirction ? i % rowsCount : rowsCount - 1 - (i % rowsCount); |
| 195 | + res[row][col] = this[i]; |
| 196 | + } |
| 197 | + return res; |
| 198 | +}; |
| 199 | + |
| 200 | +/** |
| 201 | + * const arr = [1,2,3,4]; |
| 202 | + * arr.snail(1,4); // [[1,2,3,4]] |
| 203 | + */ |
| 204 | +``` |
| 205 | + |
| 206 | +::: |
| 207 | + |
| 208 | +## 相关题目 |
| 209 | + |
| 210 | +<!-- prettier-ignore --> |
| 211 | +| 题号 | 标题 | 题解 | 标签 | 难度 | |
| 212 | +| :------: | :------ | :------: | :------ | :------ | |
| 213 | +| 2619 | [数组原型对象的最后一个元素](https://leetcode.com/problems/array-prototype-last) | [[✓]](/problem/2619.md) | | <font color=#15bd66>Easy</font> | |
| 214 | +| 2631 | [分组](https://leetcode.com/problems/group-by) | [[✓]](/problem/2631.md) | | <font color=#ffb800>Medium</font> | |
| 215 | +| 2774 | [数组的上界](https://leetcode.com/problems/array-upper-bound) | | | <font color=#15bd66>Easy</font> | |
0 commit comments