LeetCode 1861. 旋转盒子|Go 双指针解法

题目链接

1861. 旋转盒子 - 力扣(LeetCode)

题意简述

给你一个 m * n 的字符矩阵 boxGrid,包含三种字符:

  • #:石头,受重力影响向下(本题先向右)掉落
  • *:障碍物,石头不能穿过
  • .:空位

规则:

  1. 重力方向:盒子向右倾倒,石头会落到每一段的最右侧,障碍物隔开独立区间;
  2. 处理完石头掉落之后,将整个盒子顺时针旋转 90°,返回最终矩阵。

注意:旋转之后重力方向才变成向下,我们先在原矩阵模拟石头往右侧下沉,再做坐标旋转。

思路分析

核心:双指针(读指针 j + 写指针 right)

不需要提前计算石头移动多少步!

  • j:遍历指针,从右向左扫描一行 ,负责寻找石头 #
  • right:写指针,记录当前分段内最靠右可以放置石头的空位

每行处理逻辑:

  1. 初始化 right = n - 1(本行最右侧位置)
  2. j 从右往左遍历:
    • 遇到 * 障碍物:石头无法穿过,right = j - 1,障碍物左边作为新的落位起点
    • 遇到 # 石头:把石头放到 right 空位,原位置置空,right--
    • 遇到 . 空位:什么都不做,right 保持不动,留给后续石头

一句话记忆:j 找石头,right 放石头;遇墙重置,放完右位左移。

第二步:顺时针 90° 坐标转换

原矩阵:m行 n列 旋转后矩阵:n行 m列 映射公式:

复制代码
res[j][m-1-i] = boxGrid[i][j]
  • 原坐标 (i,j):i = 原行,j = 原列
  • 新行 = j(原来的列号直接变成新行号)
  • 新列 = m-1-i(原行号上下反转,上面的行转到右边,下面的行转到左边)

原理:顺时针 90° = 转置 + 原行上下翻转

完整 Go 代码

Go 复制代码
func rotateTheBox(boxGrid [][]byte) [][]byte {
	// 用一个指针right记录本分段里当前最靠右的空位,从右往左扫,自动放石头
	m := len(boxGrid)
	if m == 0 {
		return nil
	}
	n := len(boxGrid[0])

	// 第一步:双指针,模拟石头向右侧掉落
	for i := 0; i < m; i++ {
		right := n - 1
		for j := n - 1; j >= 0; j-- { // 注意边界 j >= 0,不要写成 j>0
			if boxGrid[i][j] == '*' {
				// 障碍物,重置可放石头的位置到障碍物左边
				right = j - 1
			} else if boxGrid[i][j] == '#' {
				// 抓到石头,放到right空位
				boxGrid[i][j] = '.'
				boxGrid[i][right] = '#'
				right--
			}
			// 遇到 . 空位:不操作,right不动
		}
	}

	// 第二步:顺时针旋转90度
	res := make([][]byte, n)
	for idx := range res {
		res[idx] = make([]byte, m)
	}
	for i := 0; i < m; i++ {
		for j := 0; j < n; j++ {
			res[j][m-1-i] = boxGrid[i][j]
		}
	}
	return res
}

易错点总结(刷题踩坑清单)

  1. 循环边界:j >= 0,如果写成 j>0,会漏掉第 0 列,最左侧石头处理失败
  2. 旋转矩阵行列互换:原 m 行 n 列 → 结果 n 行 m 列,make 数组长度不要写反
  3. 旋转公式 m-1-i:是原总行数 m ,不是 n!很容易写成 n-1-i
  4. 区分:本题和轮转数组(189)分组循环不一样!
    • 189:所有元素固定移动 k 步,需要 gcd 分组
    • 1861:障碍物分割成多个独立段,石头向段末尾挤,用双指针更合适

复杂度分析

  • 时间复杂度:\(O(m*n)\),每个格子最多遍历两次(一次掉落、一次旋转)
  • 空间复杂度:\(O(m*n)\),存储答案矩阵(不计输出矩阵则为 O (1) 原地修改原数组)
相关推荐
软件派2 小时前
生产动态数据智能风控:阈值判别、趋势预测、异常识别算法工程落地实战
前端·数据库·算法
ZhengEnCi10 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
吞下星星的少年·-·13 小时前
Div.3 CF 1131A题(排序,模拟)
算法·模拟·排序
aichitang202414 小时前
代数拓扑学与现代前沿视角
考研·算法·数学建模·ai·拓扑学·高考
二本咕咕-机械转码14 小时前
FreeRTOS深入解析(一)_链表与并发保护——哨兵循环链表、排序键游标、临界区与关调度
单片机·算法·链表
-银雾鸢尾-14 小时前
两数之和-C++实现
c++·算法
j7~14 小时前
【动态规划算法专题】动态规划五部曲实战:泰波那契数、三步问题、最小花费爬楼梯
c++·算法·动态规划·数据结构与算法
倍利福猎头公司官方账号15 小时前
大企业HR如何向猎头公司清晰传达AI岗位的技术需求?
人工智能·算法·机器人·求职招聘·业界资讯