好!recover-binary-search-tree(难)& 两种好的空间O(n)解法 & 空间O(1)解法
https://leetcode.com/mockinterview/session/result/xyc51it/
https://leetcode.com/problems/recover-binary-search-tree/ // 想到了Space O(N)的解法:方法是直接将BST放平,然后重新排序,然后比较一下就可以。
// 原题中提到说,有 Space O(Constant)的方法,还要研究一下 看了Discuss,也上网搜了一下,发现空间O(1)可以用 Morris遍历的方法。单独写了一篇博客,方法介绍如下:
http://www.cnblogs.com/charlesblc/p/6013506.html
下面是leetcode这道题目我的解答。没有使用O(1)空间复杂度,使用了O(n)空间复杂度。 还用到了Java里面 Arrays.sort方法,也需要注意toArray函数的参数。 除了这种解法,还有一种,是我之前做的方法,也很好,通过两个数字记录可能出错的位置,很巧妙,在这个后面给出。
package com.company;import java.util.*; class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
} class StkNode {
TreeNode tn;
int count;
StkNode(TreeNode tn) {
this.tn = tn;
count = 0;
}
} class Solution { List<Integer> getArray(TreeNode root) { List<Integer> ret = new ArrayList<>();
if (root.left != null) {
ret.addAll(getArray(root.left));
}
ret.add(root.val);
if (root.right != null) {
ret.addAll(getArray(root.right));
}
return ret;
} public void recoverTree(TreeNode root) { // Space O(N)的解法,想到了是直接将BST放平,然后重新排序,然后比较一下就可以。 // 分情况, 左ok, 右ok, 1. 上ok, 2. 上不ok
// 左不ok, 或者右不ok, 1. 上ok,
// 想不清楚,先用直接的方法:
if (root == null) {
return;
}
List<Integer> ret = getArray(root);
Integer[] sortRet= ret.toArray(new Integer[0]);
Arrays.sort(sortRet); int[] change = new int[2];
int[] index = new int[2];
int ii = 0;
for (int i=0; i<sortRet.length; i++) {
//System.out.printf("old: %d, new: %d\n", ret.get(i), sortRet[i]);
if (ret.get(i) != sortRet[i]) {
index[ii] = i+1;
change[ii] = sortRet[i];
ii++;
if (ii >= 2) {
break;
}
}
}
//System.out.printf("ii:%d\n", ii); Stack<StkNode> stk = new Stack<>();
int count = 0;
int k = 0;
StkNode stkRoot = new StkNode(root);
stk.push(stkRoot);
while (!stk.isEmpty()) {
StkNode tmp = stk.pop();
//System.out.printf("here: %d, %d, %d\n", tmp.count, count, tmp.tn.val);
if (tmp.count == 1) {
count++;
if (count == index[k]) {
//System.out.printf("here: %d\n", count);
tmp.tn.val = change[k];
k++;
if (k>=2) {
return;
}
}
if (tmp.tn.right != null) {
StkNode newTmp = new StkNode(tmp.tn.right);
stk.push(newTmp);
}
}
else {
tmp.count++;
stk.push(tmp);
if (tmp.tn.left != null) {
StkNode newTmp = new StkNode(tmp.tn.left);
stk.push(newTmp);
}
}
} }
} public class Main { public static void main(String[] args) {
System.out.println("Hello!");
Solution solution = new Solution(); TreeNode root = new TreeNode(2);
TreeNode root2 = new TreeNode(3);
TreeNode root3 = new TreeNode(1);
root.left = root2;
root.right = root3;
solution.recoverTree(root);
System.out.printf("Get ret: \n");
System.out.printf("Get ret1: %d\n", root.left.val);
System.out.printf("Get ret2: %d\n", root.val);
System.out.printf("Get ret3: %d\n", root.right.val);
System.out.println(); /*Iterator<List<Integer>> iterator = ret.iterator();
while (iterator.hasNext()) {
Iterator iter = iterator.next().iterator();
while (iter.hasNext()) {
System.out.printf("%d,", iter.next());
}
System.out.println();
}*/ System.out.println(); }
}
下面我之前的解法,也很好,通过两个数字来记录可能的出错位置,并且在遍历的同时,更新这个位置。需要对出错的规律有深刻了解,比如在解法中,first_result位置就始终没有变过,因为一旦找到就可以不变,通过second_result位置的改变,就能满足条件:
https://leetcode.com/problems/recover-binary-search-tree/ /**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
stack < pair <TreeNode*, int> > stk;
public:
void recoverTree(TreeNode* root) {
if (root == NULL) {
return;
}
pair<TreeNode*, int> pr(root, 0);
stk.push(pr); TreeNode * first_result = NULL;
TreeNode * last_result = NULL;
TreeNode* last = NULL; pair<TreeNode*, int> tmp;
TreeNode* tn_tmp; while ( !stk.empty() ) {
tmp = stk.top();
stk.pop(); if (tmp.second == 0) {
// left
tn_tmp = tmp.first;
pair<TreeNode*, int> tmp_cur(tn_tmp, 1);
stk.push(tmp_cur); if (tn_tmp->left != NULL) {
pair<TreeNode*, int> tmp_left(tn_tmp->left, 0);
stk.push(tmp_left);
} }
else {
// right
tn_tmp = tmp.first;
if (last != NULL && last->val > tn_tmp->val) {
// Found
if (first_result == NULL ) {
first_result = last;
last_result = tn_tmp;
}
else {
last_result = tn_tmp;
break;
}
}
last = tn_tmp; if (tn_tmp->right != NULL) {
pair<TreeNode*, int> tmp_pr(tn_tmp->right, 0);
stk.push(tmp_pr);
} } } if (first_result != NULL && last_result != NULL) {
int swap = first_result->val;
first_result->val = last_result->val;
last_result->val = swap;
}
return; } };
好!recover-binary-search-tree(难)& 两种好的空间O(n)解法 & 空间O(1)解法的更多相关文章
- [LeetCode] Validate Binary Search Tree (两种解法)
Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- 【LeetCode练习题】Recover Binary Search Tree
Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...
- LeetCode: Recover Binary Search Tree 解题报告
Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...
- [LeetCode] 99. Recover Binary Search Tree(复原BST) ☆☆☆☆☆
Recover Binary Search Tree leetcode java https://leetcode.com/problems/recover-binary-search-tree/di ...
- [线索二叉树] [LeetCode] 不需要栈或者别的辅助空间,完成二叉树的中序遍历。题:Recover Binary Search Tree,Binary Tree Inorder Traversal
既上篇关于二叉搜索树的文章后,这篇文章介绍一种针对二叉树的新的中序遍历方式,它的特点是不需要递归或者使用栈,而是纯粹使用循环的方式,完成中序遍历. 线索二叉树介绍 首先我们引入“线索二叉树”的概念: ...
- 【LeetCode】99. Recover Binary Search Tree
Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...
- 【LeetCode】99. Recover Binary Search Tree 解题报告(Python)
[LeetCode]99. Recover Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/p ...
- 【leetcode】Recover Binary Search Tree
Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...
- 39. Recover Binary Search Tree && Validate Binary Search Tree
Recover Binary Search Tree OJ: https://oj.leetcode.com/problems/recover-binary-search-tree/ Two elem ...
随机推荐
- JGibbLDA:java版本的LDA(Latent Dirichlet Allocation)实现、修改及使用
转载自:http://blog.csdn.net/memray/article/details/16810763 一.概述 JGibbLDA是一个java版本的LDA(Latent Dirichl ...
- [转载]非常完善的Log4net详细说明
前言 此篇文章是我见过写得最好的一片关于Log4Net的文章,内容由简入难,而且面面俱到,堪称入门和精通的佳作,特从懒惰的肥兔的转载过来. 1.概述 log4net是.Net下一个非常优秀的开源日志记 ...
- sqlserver insert into select
Insert into [fenxi].[dbo].[analysisresult]( [dayofweek] ,[quarter] ,[reporttime] ,[type] ,[value]) s ...
- 2659: [Beijing wc2012]算不出的算式 - BZOJ
最近有点颓废,刷水题,数学题(根本不会做啊) 题意:求 q,p是两个奇质数 网上题解就直接说是几何意义,问了别人才知道 我们在坐标轴上画出来就是在线段y=(q/p)x下方的格点和y=(p/q)x下方的 ...
- MySQL之重设密码(忘记密码)讲解
Windows下的实际操作如下: 1.关闭正在运行的MySQL. 2.打开DOS窗口,转到mysql\bin目录. 3.输入mysqld(或mysqld-nt) --skip-grant-tables ...
- WPF 显示初始化界面
今天在看<WPF编程宝典>时,看到了Application类,该类可以做很多事情,我认为比较实用的是显示初始化界面,因为之前有个项目在打开的时候要加载好多dll,非常耗时,让客户等的蛋疼, ...
- springMVC 简单事例
本帖最后由 悲观主义者一枚 于 2015-1-31 17:55 编辑 使用SpringMvc开发Android WebService入门教程1.首先大家先创建一个JavaWeb项目2.然后加入Spri ...
- 查看 dmp 字符集
用Oracle的exp工具导出的dmp文件也包含了字符集信息,dmp文件的第2和第3个字节记录了dmp文件的字符集.如果dmp文件不大,比如只有几M或几十M,可以用UltraEdit打开(16进制方式 ...
- 如何使用yum来下载RPM包而不进行安装
如何使用yum来下载RPM包而不进行安装 2015-03-23 13:15 theo-l译 linux.cn 字号:T | T yum是基于Red Hat的系统(如CentOS.Fedora.RHEl ...
- C#中sealed关键字
C#中sealed关键字 1. sealed关键字 当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承.类似于Java中final关键字. 在下面的示例中,类 B ...