问:
- 给一个字符串类型的数组arr,譬如arr=['b\cst','d','a\d\e','a\b\c']。每个字符串都是一个路径。把这些路径中蕴含的目录结构打印出来。子目录在父目录下面,并且后移两个空格。同级目录按字符升序。如下所示:
a
b
c
d
e
b
cst
d
- 给定一个搜索二叉树的头结点head,请转化为一条有序的双向链表。并返回链表头结点
- 找到一颗二叉树中,最大的搜索二叉子树。返回其节点个数
- 给定一个整型矩阵,返回子矩阵的最大累加和
解:
- 生成前缀树。深度优先遍历前缀树即可。
function printCatalogue(arr) {
class DiyNode {
constructor(val, level) {
this.value = val
this.level = level
this.childrenMap = new Map()
}
}
for (let i = 0; i < arr.length;i++) {
arr[i] = arr[i].split('\\')
}
const orNode = new DiyNode()
// 遍历字符串数组。形成前缀树
for (let i = 0; i < arr.length; i++) {
let curNode = orNode
for (let j = 0; j <arr[i].length;j++) {
if (!arr[i][j]) continue
if (curNode.childrenMap.has(arr[i][j])) {
curNode = curNode.childrenMap.get(arr[i][j])
} else {
const temp = new DiyNode(arr[i][j], curNode.level + 1)
curNode.childrenMap.set(arr[i][j], temp)
curNode = temp
}
}
}
// 打印前缀树
print(orNode.childrenMap)
// 给前缀树的每一层按key排序
function sortMap(map) {
const keys = []
for (let i of map.keys()) {
keys.push(i)
}
keys.sort((a, b) => a.localeCompare(b))
const sp = new Map()
keys.forEach((item) => {
sp.set(item, map.get(item))
})
return sp
}
// 深度优先打印
function print(map) {
if (!map) return
map = sortMap(map)
for (let i of map.entries()) {
console.log(' '.repeat((i[1].level - 1) * 2) + i[0]);
print(i[1].childrenMap)
}
}
}
function treeToList(head) {
function getRes(node) {
if (!node) return {min: null, max: null}
const leftInfo = getRes(node.left)
const rightInfo = getRes(node.right)
if (leftInfo.max) leftInfo.max.next = node
node.next = rightInfo?.min
if (rightInfo.min) rightInfo.min.pre = node.next
node.pre = leftInfo?.max
return {
min: leftInfo.min ?? node,
max: rightInfo.max ?? node
}
}
return getRes(head).min
}
function findMaxBs(head) {
let max = 1
function getRes(node) {
if (!node) return {
nums: 0,
isBST: true,
max: -Infinity,
min: Infinity
}
const leftInfo = getRes(node.left)
const rightInfo = getRes(node.right)
// 如果左右子树都是bst
if (leftInfo.isBST && rightInfo.isBST) {
// 若当前节点也符合bst
if (node.val > leftInfo.max && node.val < rightInfo.min) {
const nums = leftInfo.nums + rightInfo.nums + 1
max = Math.max(max, nums)
return {
nums,
isBST: true,
min: leftInfo.min === Infinity ? node.val : leftInfo.min,
max: rightInfo.max === -Infinity ? node.val : rightInfo.max
}
}
}
// 否则不是bst
return {
isBST: false
}
}
getRes(head)
return max
}
function getMaxSum(Matrix) {
let maxSum = -Infinity
// 矩阵的最大子矩阵和。可以分解为若干矩阵累加成一个数组的最大子序和问题
// 也就是说像
// matrix=[[1,2,3,4]
// [2,3,4,5]
// [-1,-2,3,-4]]
// 这种矩阵。可以分解为
// 只看第i行。求第i行子序和问题。
// 只看第i~n行。求第i~n行子矩阵问题
// 第i~n行,可以用矩阵累加方式转换成数组。也就等同于数组子序和问题
// 譬如第0~1行矩阵 同列相加,转换成数组[3,5,7,9]
for (let i = 0; i < Matrix.length; i++) {
let preArrSum = []
for (let j = i; j < Matrix.length; j++) {
for (let k = 0; k < Matrix[i].length; k++) {
preArrSum[k] = (preArrSum[k] ?? 0) + Matrix[j][k]
}
const tempMax = getArrSum(preArrSum)
maxSum = Math.max(maxSum, tempMax)
}
}
// 最大子序和
function getArrSum(arr) {
let sum = 0
let max = -Infinity
for (let i of arr) {
sum += i
max = Math.max(max, sum)
if (sum < 0) sum = 0
}
return max
}
return maxSum
}