持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
[面试题 17.25. 单词矩阵](leetcode.cn/problems/ma…)
给定一份单词的清单,设计一个算法,创建由字母组成的面积最大的矩形,其中每一行组成一个单词(自左向右),每一列也组成一个单词(自上而下)。不要求这些单词在清单里连续出现,但要求所有行等长,所有列等高。
如果有多个面积最大的矩形,输出任意一个均可。一个单词可以重复使用。
「示例1:」
输入: ["this", "real", "hard", "trh", "hea", "iar", "sld"]
输出:
[ "this", "real", "hard"]
「示例2:」
输入: ["aa"]
输出: ["aa","aa"]
「提示:」
words.length <= 1000
words[i].length <= 100
数据保证单词足够随机
解题思路
思路:
1.如何判断字符串是否能够组成矩形
2.如何保存能够组成矩形的字符串,并进行是否最大的判断
方法:
1.用字典树判断当前字符串的字符结点是否为字典树的结点
2.判断当前字符串所有结点是否都为字典树的叶子结点,如果是,则能组成矩形,并进行是否最大的判断
代码实现
class Trie {
constructor() {
this.isLeaf = false
this.childs = []
}
}
/**
* @param {string[]} words
* @return {string[]}
*/
var maxRectangle = function (words) {
// 构造字典树
const root = new Trie()
for (const str of words) {
let node = root
for (const c of str) {
const index = c.charCodeAt() - 'a'.charCodeAt()
if (!node.childs[index]) {
node.childs[index] = new Trie()
}
node = node.childs[index]
}
node.isLeaf = true
}
const map = new Map()
let ans = []
let maxArea = 0
let maxLength = 0
for (const w of words) {
const len = w.length
maxLength = Math.max(maxLength, len)
if (!map.has(len)) map.set(len, new Set())
map.get(len).add(w)
}
for (const [key, set] of map) {
backtracking(set, [], key)
}
return ans
// 回溯填入单词
function backtracking(set, path, len) {
if (len * maxLength <= maxArea) return
if (path.length > maxLength) return
for (const str of set) {
path.push(str)
const res = isValid(path)
if (res[0]) {
const area = path.length * path[0].length
if (res[1] && area > maxArea) {
maxArea = area
ans = path.slice()
}
backtracking(set, path, len)
}
path.pop()
}
}
// 校验填入的单词是否合法
function isValid(input) {
let allLeaf = true
const m = input.length
const n = input[0].length
// 横向的单词都是自己填的,只需要校验每列的单词就行了
for (let j = 0; j < n; j++) {
let node = root
for (let i = 0; i < m; i++) {
const index = input[i][j].charCodeAt() - 'a'.charCodeAt()
if (!node.childs[index]) return [false, false]
node = node.childs[index]
}
if (!node.isLeaf) allLeaf = false
}
return [true, allLeaf]
}
}
如果你对这道题目还有疑问的话,可以在评论区进行留言;