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

LeetCode 3446. 按对角线进行矩阵排序

LeetCode 3446. 按对角线进行矩阵排序 - 从复杂到简洁的优化思考

题目描述

给你一个大小为 n x n 的整数方阵 grid。返回一个经过如下调整的矩阵:

  • 左下角三角形(包括中间对角线)的对角线按 非递增顺序 排序
  • 右上角三角形 的对角线按 非递减顺序 排序

示例

示例 1:

输入: grid = [[1,7,3],[9,8,2],[4,5,6]]
输出: [[8,2,3],[9,6,7],[4,5,1]]

示例 2:

输入: grid = [[0,1],[1,2]]
输出: [[2,1],[1,0]]

解题思路的演进

第一版:收集-排序-放回

最初的想法是传统的排序方法:

def sortMatrix(self, grid: List[List[int]]) -> List[List[int]]:n = len(grid)if n <= 1:return grid# 处理左下角三角形 - 非递增排序for i in range(n):r, c = i, 0diagonal_length = min(n - i, n)# 收集当前对角线的元素diagonal = []for j in range(diagonal_length):diagonal.append(grid[r + j][c + j])# 对对角线元素进行非递增排序diagonal.sort(reverse=True)# 将排序后的元素放回原位置for j in range(diagonal_length):grid[r + j][c + j] = diagonal[j]# 处理右上角三角形 - 非递减排序for j in range(1, n):r, c = 0, jdiagonal_length = min(n, n - j)# 收集当前对角线的元素diagonal = []for l in range(diagonal_length):diagonal.append(grid[r + l][c + l])# 对对角线元素进行非递减排序diagonal.sort()# 将排序后的元素放回原位置for l in range(diagonal_length):grid[r + l][c + l] = diagonal[l]return grid

问题: 需要额外的内存空间存储对角线元素,时间复杂度 O(n² log n)

第二版:插入排序优化

为了减少内存分配,改用插入排序:

def sortMatrix(self, grid: List[List[int]]) -> List[List[int]]:n = len(grid)if n <= 1:return grid# 处理左下角三角形 - 非递增排序for i in range(n):r, c = i, 0diagonal_length = min(n - i, n)# 使用插入排序进行非递增排序(降序)for j in range(1, diagonal_length):key = grid[r + j][c + j]k = j - 1# 将大于key的元素向后移动while k >= 0 and grid[r + k][c + k] < key:grid[r + k + 1][c + k + 1] = grid[r + k][c + k]k -= 1grid[r + k + 1][c + k + 1] = key# 处理右上角三角形 - 非递减排序for j in range(1, n):r, c = 0, jdiagonal_length = min(n, n - j)# 使用插入排序进行非递减排序(升序)for l in range(1, diagonal_length):key = grid[r + l][c + l]k = l - 1# 将大于key的元素向后移动while k >= 0 and grid[r + k][c + k] > key:grid[r + k + 1][c + k + 1] = grid[r + k][c + k]k -= 1grid[r + k + 1][c + k + 1] = keyreturn grid

优化点: 空间复杂度降为 O(1),但时间复杂度变为 O(n³)

第三版:误解与纠正

在优化过程中,我产生了一个误解:

错误想法: 如果只需要"非递增"和"非递减",那么只需要一次交换就能破坏严格递增/递减性质

# 错误版本 - 只交换一次
for j in range(diagonal_length - 1):if grid[r + j][c + j] < grid[r + j + 1][c + j + 1]:grid[r + j][c + j], grid[r + j + 1][c + j + 1] = grid[r + j + 1][c + j + 1], grid[r + j][c + j]break  # 只需要交换一次

问题分析:

  • 对于 [1,8,6],交换一次变成 [8,1,6],虽然破坏了递增,但不是完全降序
  • 题目要求的是完整的排序,不是仅仅破坏递增/递减性质

最终版:简洁高效的实现

经过多次思考和验证,最终确定了正确的算法:

from typing import Listclass Solution:def sortMatrix(self, grid: List[List[int]]) -> List[List[int]]:n = len(grid)if n <= 1:return grid# 左下角三角形 - 非递增排序(降序)for i in range(n):r, c = i, 0l = min(n - i, n)# 收集对角线元素d = []for j in range(l):d.append(grid[r + j][c + j])# 降序排序d.sort(reverse=True)# 放回for j in range(l):grid[r + j][c + j] = d[j]# 右上角三角形 - 非递减排序(升序)for j in range(1, n):r, c = 0, jl = min(n, n - j)# 收集对角线元素d = []for k in range(l):d.append(grid[r + k][c + k])# 升序排序d.sort()# 放回for k in range(l):grid[r + k][c + k] = d[k]return grid

关键理解点

1. "非递增"和"非递减"的真正含义

  • 非递增顺序 = 降序排列,可以包含相等元素
  • 非递减顺序 = 升序排列,可以包含相等元素

2. 为什么不能只用一次交换?

错误理解: 一次交换就能破坏严格递增/递减性质

正确理解: 需要完整的排序才能满足题目要求

举例说明:

  • 输入:[1,8,6]
  • 错误做法:交换一次 → [8,1,6] ❌
  • 正确做法:完整排序 → [8,6,1] ✅

3. 算法复杂度分析

版本时间复杂度空间复杂度特点
第一版O(n² log n)O(n)传统方法,内存开销大
第二版O(n³)O(1)插入排序,原地操作
最终版O(n² log n)O(n)平衡了效率和简洁性

总结

这道题目教会了我几个重要的编程思维:

  1. 仔细理解题目要求:不能想当然地简化问题
  2. 验证算法正确性:通过具体例子验证思路
  3. 权衡效率与简洁:在时间复杂度和代码可读性之间找到平衡
  4. 持续优化:从复杂到简单,不断改进算法

最终,虽然我回到了"收集-排序-放回"的基本思路,但通过这个过程,我更深刻地理解了算法的本质和优化的边界。


标签: #LeetCode #算法优化 #矩阵排序 #对角线排序 #Python

更新日期2025年8月28日

http://www.dtcms.com/a/355570.html

相关文章:

  • Linux部分底层机制
  • 【每天一个知识点】云存储(Cloud Storage)
  • 从混沌到有序:工作流设计的创作迷思与破局之道
  • AI智能农业监测系统深度解读:从大田作物管理到病虫害预警,破解传统农业增产难题
  • 大模型私有化部署
  • RAG概念被误用:AI应用落地需回归上下文工程本质
  • leetcode算法day22
  • kotlin中关于协程的使用
  • 陕西风味马卡龙:家常自制,特色甜趣共享
  • 传输层协议介绍
  • 结构化提示词革命:JSON Prompting如何让AI输出精准如激光
  • 数字化生产管理系统 (MES)
  • 服务器核心组件:CPU 与 GPU 的核心区别、应用场景、协同工作
  • 揭开.NET Core 中 ToList () 与 ToArray () 的面纱:从原理到抉择
  • ansible常用命令的简单练习
  • Linux系统 -- 多线程的控制(互斥与同步)
  • 数学思维好题(冯哈伯公式)-平方根下取整求和
  • 个人博客运行3个月记录
  • 了解ADS中信号和电源完整性的S参数因果关系
  • Typora 教程:从零开始掌握 Markdown 高效写作
  • MySQL事务ACID特性
  • JavaScript中的BOM,DOM和事件
  • 英语单词:ad-hoc
  • BugKu Web渗透之成绩查询
  • 白杨SEO:网站优化怎么做?应用举例和适合哪些企业做?参考
  • 速成Javascript(二)
  • 新书速览|SQL Server运维之道
  • 【第三方网站运行环境测试:服务器配置(如Nginx/Apache)的WEB安全测试重点】
  • 激活函数篇(3):Softmax
  • maven scope 详解