leetcode 230. Kth Smallest Element in a BST-递归|非递归
2016-05-24 11:17
429 查看
原题链接:230. Kth Smallest Element in a BST
【思路-Java、Python】——递归实现
我们知道二分查找数(BST)的性质——任何一个节点的值均大于左子树的任意节点值,而小于右子树的任一节点值。那么这样就可以知道最小值的一个节点在树的最左端,最大值的一个节点在树的最右端。树从小到大顺序刚好满足树的中序遍历。因而,我们可以用中序遍历来处理。
由于 k 是个基本类型的数,我们知道它与应用类型不同,本轮递归的 k 值改变不会引起下一轮的改变,那么我们的处理办法可以增加一个全局变量、增加一个引用变量或增加一个方法形参,用这样的参数记录目前遍历到的是第几小的数,本题采用增加一个局部变量的方法:
cases passed. Runtime: 1
ms Your runtime beats 46.33% of javasubmissions.
cases passed. Runtime: 100
ms Your runtime beats 25.55% of pythonsubmissions.
【思路-Java、Python】——非递归实现
非递归实现需要用到一个栈,如果对非递归和递归遍历实现不是很熟悉可以参考我的另外一篇博文:
上面有详细的介绍:
cases passed. Runtime: 2
ms Your runtime beats 16.50% of javasubmissions.
cases passed. Runtime: 84
ms Your runtime beats 72.03% of pythonsubmissions.
就时间复杂度而言,时间复杂度的对比,通过本题递归和非递归的对比,我们可以简单看出递归和非递归的区别。在递归中,我们不能“终止递归”,即使采用 return也无法终止递归,为此,采用递归必须遍历完每个节点,为此我们采用①记录找到的那个节点,时间复杂度为O(n)。而非递归不同,如果找到了第 k 大的那个节点我们就直接用② return返回了。我们可以看到递归效率不一定比非递归低,如本题。实际上空间复杂度,忽略方法的压栈等操作,并且临时变量能被立即释放的话,递归的空间复杂度还更低。
本题的基础还是树的递归和非递归:
leetcode 94. Binary Tree Inorder Traversal 、leetcode
144. Binary Tree Preorder Traversal
【思路-Java、Python】——递归实现
我们知道二分查找数(BST)的性质——任何一个节点的值均大于左子树的任意节点值,而小于右子树的任一节点值。那么这样就可以知道最小值的一个节点在树的最左端,最大值的一个节点在树的最右端。树从小到大顺序刚好满足树的中序遍历。因而,我们可以用中序遍历来处理。
由于 k 是个基本类型的数,我们知道它与应用类型不同,本轮递归的 k 值改变不会引起下一轮的改变,那么我们的处理办法可以增加一个全局变量、增加一个引用变量或增加一个方法形参,用这样的参数记录目前遍历到的是第几小的数,本题采用增加一个局部变量的方法:
public class Solution { private int count, res; public int kthSmallest(TreeNode root, int k) { if (root.left != null) kthSmallest(root.left, k); if (++count == k) res = root.val; //① if (root.right != null) kthSmallest(root.right, k); return res; } }91 / 91 test
cases passed. Runtime: 1
ms Your runtime beats 46.33% of javasubmissions.
class Solution(object): def kthSmallest(self, root, k): """ :type root: TreeNode :type k: int :rtype: int """ global res, count res,count = 0,0 def dfs(root, k) : if not root : return dfs(root.left, k) global count, res count += 1 if count == k : res = root.val //① dfs(root.right, k) dfs(root,k) return res91 / 91 test
cases passed. Runtime: 100
ms Your runtime beats 25.55% of pythonsubmissions.
【思路-Java、Python】——非递归实现
非递归实现需要用到一个栈,如果对非递归和递归遍历实现不是很熟悉可以参考我的另外一篇博文:
leetcode 94. Binary Tree Inorder Traversal 、leetcode
144. Binary Tree Preorder Traversal
上面有详细的介绍:public class Solution { public int kthSmallest(TreeNode root, int k) { int ret = 0; Stack<TreeNode> stack = new Stack<TreeNode>(); while(true) { while(root != null) { stack.push(root); root = root.left; } if (stack.isEmpty()) break; root = stack.pop(); if (--k == 0) return root.val; //② root = root.right; } return 0; }91 / 91 test
cases passed. Runtime: 2
ms Your runtime beats 16.50% of javasubmissions.
class Solution(object): def kthSmallest(self, root, k): """ :type root: TreeNode :type k: int :rtype: int """ stack = [] res = 0 while 1 : while root : stack.append(root) root = root.left if not stack : break root = stack.pop() k -= 1 if k == 0 : return root.val //② root = root.right return 091 / 91 test
cases passed. Runtime: 84
ms Your runtime beats 72.03% of pythonsubmissions.
就时间复杂度而言,时间复杂度的对比,通过本题递归和非递归的对比,我们可以简单看出递归和非递归的区别。在递归中,我们不能“终止递归”,即使采用 return也无法终止递归,为此,采用递归必须遍历完每个节点,为此我们采用①记录找到的那个节点,时间复杂度为O(n)。而非递归不同,如果找到了第 k 大的那个节点我们就直接用② return返回了。我们可以看到递归效率不一定比非递归低,如本题。实际上空间复杂度,忽略方法的压栈等操作,并且临时变量能被立即释放的话,递归的空间复杂度还更低。
本题的基础还是树的递归和非递归:
leetcode 94. Binary Tree Inorder Traversal 、leetcode
144. Binary Tree Preorder Traversal
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 介绍一款信息管理系统的开源框架---jeecg
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- install and upgrade scrapy
- Scrapy的架构介绍