LeetCode 422 - 有效的单词方块


文章目录
- 摘要
- 描述
- 题解答案
- 题解代码分析
- 示例测试及结果
- 时间复杂度
- 空间复杂度
- 总结
摘要
这道题《LeetCode 422. 有效的单词方块(Valid Word Square)》看起来挺像是脑筋急转弯题。它考验的是我们对二维字符结构的理解。简单说就是:给你一组单词,把它们竖着横着排好后,判断是不是上下读、左右读都一样。
这类题其实挺有趣的,也挺常见于字符串矩阵处理的业务场景中,比如:文本对称性检查、纵横字谜验证、或类似的游戏逻辑系统。

描述
题目给出一个字符串数组 words,它代表一个“单词方块”。
要求:
如果 k 行的第 j 个字符等于 k 列的第 j 个字符(即 words[i][j] == words[j][i]),那它就是一个“有效的单词方块”。
举个例子:
["ball","area","lead","lady"
]
横着看:
b a l l
a r e a
l e a d
l a d y
竖着看也一模一样,说明它就是一个有效的单词方块。
反例:
["abcd","bnrt","crm","dt"
]
第三行“crm”只有3个字符,但第三列有4个字符,结果不匹配,所以不是有效的方块。
题解答案
这题的核心在于 双向一致性校验。
我们需要同时确保两个方向的字符矩阵是一致的。
思路其实挺直白:
- 遍历每个单词的每个字符;
- 如果当前字符
words[i][j]存在,就看看竖着的那个words[j][i]是否存在、是否相等; - 如果越界或者不相等,就返回 false;
- 遍历完所有元素都没问题,就返回 true。
这题其实不需要复杂的数据结构,也不用构造完整矩阵。只要保证索引安全、字符对称就行。

题解代码分析
下面是可运行的 Swift 代码版本:
import Foundationclass Solution {func validWordSquare(_ words: [String]) -> Bool {for i in 0..<words.count {let charsI = Array(words[i])for j in 0..<charsI.count {// 判断纵向越界if j >= words.count { return false }let charsJ = Array(words[j])// 判断横向越界或字符不匹配if i >= charsJ.count || charsI[j] != charsJ[i] {return false}}}return true}
}// Demo 测试
let s = Solution()
let words1 = ["ball", "area", "lead", "lady"]
print("示例1结果:", s.validWordSquare(words1)) // truelet words2 = ["abcd", "bnrt", "crm", "dt"]
print("示例2结果:", s.validWordSquare(words2)) // truelet words3 = ["abcd", "bnrt", "crm", "da"]
print("示例3结果:", s.validWordSquare(words3)) // false
代码解析:
Array(words[i]):将字符串转为字符数组,方便按下标取字符。- 双重循环中,外层是横向,内层是纵向。
if j >= words.count检查纵向越界(列超过行数)。if i >= charsJ.count检查横向越界(当前列字符串太短)。- 两个字符不匹配则立即返回 false。
Swift 的字符串在索引操作上不像 Python 或 C++ 那样简单,转成 Array 是为了能直接下标访问,性能上也足够快。
示例测试及结果
测试1:
输入: ["ball", "area", "lead", "lady"]
输出: true
解释: 横竖都对称。
测试2:
输入: ["abcd", "bnrt", "crm", "dt"]
输出: true
解释: 看似不齐,其实每个对应位置的字符都匹配。
测试3:
输入: ["abcd", "bnrt", "crm", "da"]
输出: false
解释: 最后一行和最后一列不一致。
执行结果:
示例1结果: true
示例2结果: true
示例3结果: false
时间复杂度
O(N²)
原因是我们最多要遍历整个字符方块的每个元素一次。
N 是单词数量,平均单词长度也大概是 N,所以是平方级。
不过在一般测试数据中,这个复杂度完全没问题。
空间复杂度
O(1)
除了在局部转换字符串成 Array 外,不需要额外的存储结构。
总结
这道题虽然不难,但非常锻炼我们对二维字符关系的观察力。
在实际开发中,这类逻辑经常出现,比如:
- 多语言字符矩阵是否一致(横读/竖读)
- 游戏中的文字谜题逻辑
- 文本对齐和矩阵一致性校验
从实现角度看,最容易错的地方其实是 越界检查。只要保证行列索引都在范围内,再比字符即可。
而 Swift 的字符串索引操作稍显复杂,转成数组是一种实用的技巧。
如果换成 Python,代码可能只有几行,但 Swift 的这种写法更严谨,也更贴近真实开发中字符串处理的写法。
