前言🌧️
算法,对前端人来说陌生又熟悉,很多时候我们都不会像后端工程师一样重视这项能力。但事实上,算法对每一个程序员来说,都有着不可撼动的地位。
因为开发的过程就是把实际问题转换成计算机可识别的指令,也就是《数据结构》里说的,「设计出数据结构,在施加以算法就行了」。
当然,学习也是有侧重点的,作为前端我们不需要像后端开发一样对算法全盘掌握,有些比较偏、不实用的类型和解法,只要稍做了解即可。
题目🦀
难度中等
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
**注意:**本题与主站 426 题相同:leetcode-cn.com/problems/co…
**注意:**此题对比原题有改动。
解题思路🌵
- 此题可以利用树的中序遍历这样从小到大访问到每个节点
- 退出条件:当前阶段为空则推出
- 递推公式:dfs(左子树),这里访问当前节点,做链表构建的逻辑,dfs(右子树)
- 使用pre来保存上一个节点,当pre为null时则是head指针
- 最后dfs完毕 记得将头节点和尾节点进行双向绑定
解法🔥
/** * // Definition for a Node. * function Node(val,left,right) { * this.val = val; * this.left = left; * this.right = right; * }; */ /** * @param {Node} root * @return {Node} */ var treeToDoublyList = function(root) { let pre, head; if(!root){return} const dfs=(cur)=>{ if(!cur){return} dfs(cur.left)//左 //根 if(!pre){ head=cur } else{ cur.left=pre pre.right=cur } pre=cur dfs(cur.right)//右 } dfs(root); // 首尾相连 head.left = pre; pre.right = head; return head };
时间复杂度:O(n)
空间复杂度:O(n)
结束语🌞
那么鱼鱼的LeetCode算法篇的「LeetCode」剑指Offer-36二叉搜索树与双向链表⚡️
就结束了,算法这个东西没有捷径,只能多写多练,多总结,文章的目的其实很简单,就是督促自己去完成算法练习并总结和输出,菜不菜不重要,但是热爱🔥,喜欢大家能够喜欢我的短文,也希望通过文章认识更多志同道合的朋友,如果你也喜欢折腾
,欢迎加我好友
,一起沙雕
,一起进步.