自己搞下算法分类总结,以前大一还挺猛的,刷过三四百道,什么算法都会,现在不行了,只会些简单的,现在重新做人,把前端水平的算法题都写写,先把自己最不擅长的树总结下
- 树的遍历 以前序遍历为例,因为和前端都有个前字,含递归和迭代,中序和后序也就位置变下,前序根左右,中序左根右,后序左右根
//迭代
function pre(treeNode) {
if (!treeNode) {
return
}
let stack = [treeNode];
let res = [];
while (stack.length) {
let node = stack.pop()
if (node.right) { stack.push(node.right) }
if (node.left) { stack.push(node.left) }
res.push(node.val)
}
return res;
}
//递归
function pre(treeNode){
let arr=[]
if(!treeNode){
return arr;
}
arr.push(treeNode.val)
arr=arr.concat(pre(treeNode.left))
arr=arr.concat(pre(treeNode.right))
return arr;
}
- 重建二叉树 给个前序或后序加中序 把原本的树弄出来 因为前序是根左右,根就是第一个,中序是左根右,找到和根一样的就可以分出哪部分是左子树,哪边是右子树,然后递归
function resetTree(pre, mid) {
if (!pre.length) {
return null
}
let root = pre[0]
let index = mid.indexOf(root)
let node = new treeNode(root)
if (pre.length == 1) {
return node
}
let leftMid = mid.slice(0, index)
let rightMid = mid.slice(index + 1)
let leftPre = pre.slice(1, leftMid.length)
let rightPre = pre.slice(leftMid.length + 1, rightMid.length)
node.left = resetTree(leftPre, leftMid)
node.right = resetTree(rightPre, rightMid)
return node;
}
- 层次遍历 就是每层都从左到右记录下 也可能会问从上到下,从左到右打印二叉树,还顺带解决了二叉树深度
function levelOrder(tree) {
let res = [];
let queue = [tree];
let level = 0;
nodes[0] = tree;
if (queue.length) {
res[level] = []
let len = queue.length
while (len--) {
let node = queue.shift();
node.left && queue.push(node.left)
node.right && queue.push(node.right)
res[level].push(node.value)
}
level++;
}
return res;
}
- 二叉搜索树中第K小的元素 二叉搜索树是左<根<右,所以中序遍历的结果就是一个递增的数组,第k小就是第k个,当然也可以其他遍历,然后排序,然后直接找倒数第k个索引的值
var ksmall = function(root, k) {
let res;
function midOrder(root){
if(!root) return root;
midOrder(root.left);
if(k === 0) return res;
else{
res = root.val;
k--;
}
midOrder(root.right);
}
midOrder(root);
return res;
};
- 二叉树公共祖先 目前还没理解递归的方法,用map记录整个树的父子关系,然后记录p的整个父亲节点,用map检测q是否存在于p父亲节点中,没有就q=q的父亲节点
var lowestCommonAncestor = function(root, p, q) {
let map=new Map()
const search=(res)=>{
if(res.left){
map.set(res.left,res)
search(res.left)
}
if(res.right){
map.set(res.right,res)
search(res.right)
}
}
search(root)
let parent=new Map()
parent.set(p,p)
while(map.has(p)){
parent.set(map.get(p),map.get(p))
p=map.get(p)
}
while(!parent.has(q)){
q=map.get(q)
}
return q
};
- 翻转二叉树 就遍历一遍每个节点的左右子树都对换一下
var invertTree = function(root) {
if(root === null) return root;
[root.left,root.right] = [root.right,root.left];
invertTree(root.left);
invertTree(root.right);
return root;
};
- 合并二叉树 就都有节点就相加没有就返回有的那个
var mergeTrees = function(t1, t2) {
if(t1 && t2){
t1.val += t2.val;
t1.left = mergeTrees(t1.left,t2.left);
t1.right = mergeTrees(t1.right,t2.right);
}
return t1 || t2;
};
害 简单的树的题目大概就这些吧 难的俺也尽力了 脑子不够用