寻找二叉搜索树错误的节点
Posted 上后谈爱情
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寻找二叉搜索树错误的节点相关的知识,希望对你有一定的参考价值。
一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请找到这两个错误节点并返回他们的值。保证二叉树中结点的值各不相同。
给定一棵树的根结点,请返回两个调换了位置的值,其中小的值在前。
第一种方式:采用递归的方式---加大其运算效率
第一次出现逆序对选择较大值,第二次出现的逆序对选择较小值 ---此算法只能找到2对出现 错误的位置
1 import java.util.*; 2 3 /* 4 public class TreeNode { 5 int val = 0; 6 TreeNode left = null; 7 TreeNode right = null; 8 public TreeNode(int val) { 9 this.val = val; 10 } 11 }*/ 12 public class FindErrorNode { 13 public int[] findError(TreeNode root) { 14 // write code here 采用的是递归的形式 15 if(root==null) return null; 16 ArrayList<Integer> arr=new ArrayList<Integer>(); 17 Order(root,arr); 18 19 int [] res_index=new int[2]; 20 int [] res=new int[2]; 21 int count=0; boolean is=true; 22 //第一次出现逆序对选择较大位置,第二次出现逆序对选择较小位置 23 for(int i=0;i<arr.size()-1;i++) 24 { 25 int diff=arr.get(i+1)-arr.get(i); 26 if(diff<0) 27 { 28 if(is) 29 { 30 res_index[count++]=i; 31 is=false; 32 } 33 else 34 { 35 res_index[count++]=i+1;is=true; 36 } 37 38 } 39 } 40 41 if(count<2) 42 { 43 res_index[count]=res_index[0]+1; 44 } 45 46 47 48 res[0]=arr.get(res_index[1]); 49 res[1]=arr.get(res_index[0]); 50 return res; 51 52 } 53 public void Order(TreeNode root,ArrayList<Integer> arr) 54 { 55 if(root==null) return ; 56 57 if(root.left!=null) Order(root.left,arr); 58 arr.add(root.val); 59 if(root.right!=null) Order(root.right,arr); 60 } 61 }
第二种:使用非递归进行中序遍历
1 if(root==null) return null; 2 int [] res=new int[2]; 3 LinkedList<TreeNode> stack=new LinkedList<>();//保证堆栈先进后出的特性 4 TreeNode[] errornodes=new TreeNode[2]; 5 stack.add(root);TreeNode prenode=null; 6 while(!stack.isEmpty()) 7 { 8 //非递归 将左子树root 节点压入stack中 9 while(root!=null) 10 { 11 root=root.left; 12 if(root!=null) 13 stack.add(root); 14 } 15 16 root=stack.removeLast();// stack 中最末尾元素 17 18 if(prenode!=null && prenode.val>root.val)// stack 记录父节点,出现问题 父节点比左孩子树大 19 { 20 // 第一次出现逆序对,选择前节点,如果出现第二个逆序对,选择后节点 21 errornodes[0]=(errornodes[0]==null?prenode:errornodes[0]); 22 errornodes[1]=root; 23 24 } 25 26 prenode=root; 27 root=root.right; 28 if(root!=null) 29 stack.add(root); 30 } 31 32 res[0]=errornodes[1].val; 33 res[1]=errornodes[0].val; 34 return res;
如果对其进行修改--查找到多处出现处错误的 二叉搜索树点:
1. 使用层次遍历或者
1 public static int[] findError(TreeNode root) 2 { 3 if(root==null) return null; 4 int [] res=new int[2]; 5 LinkedList<TreeNode> stack=new LinkedList<>();//保证堆栈先进后出的特性 6 TreeNode[] errornodes=new TreeNode[10]; 7 stack.add(root);TreeNode prenode=null; 8 9 int count=1; 10 while(!stack.isEmpty()) 11 { 12 //非递归 将左子树root 节点压入stack中 13 while(root!=null) 14 { 15 root=root.left; 16 if(root!=null) 17 stack.add(root); 18 } 19 20 root=stack.removeLast();// stack 中最末尾元素 21 22 if(prenode!=null && prenode.val>root.val)// stack 记录父节点,出现问题 父节点比左孩子树大 23 { 24 // 第一次出现逆序对,选择前节点,如果出现第二个逆序对,选择后节点 25 errornodes[0]=(errornodes[0]==null?prenode:errornodes[0]); 26 errornodes[count++]=root; 27 28 } 29 30 prenode=root; 31 root=root.right; 32 if(root!=null) 33 stack.add(root); 34 } 35 36 37 for(int i=0;i<count;i++) 38 { 39 System.out.print(errornodes[i].val+" "); 40 } 41 return res; 42 43 }
输入树:int array[]={5,3,6,-1,-1,2,-1,-1,1,-1,-1}; 6节点值与1 节点值发生调换;3节点值与2节点发生调换
以上是关于寻找二叉搜索树错误的节点的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段