1+ package com .rampatra .trees ;
2+
3+ import java .util .ArrayList ;
4+ import java .util .Arrays ;
5+ import java .util .List ;
6+
7+ /**
8+ * Two nodes are swapped in a BST, write a function to find these two nodes.
9+ * <p>
10+ * Approach:
11+ * 1. We perform an in-order traversal of the tree and find the 2 discontinuities, i.e, the nodes which are larger than their next node.
12+ * 2. We take the left node of the first discontinuity and the right node of the second.
13+ * <p>
14+ * Note: There is one edge case where the two nodes swapped are parent and child nodes. This means that in the in-order
15+ * traversal these two nodes will be adjacent. Therefore, in this case, these two nodes will be our answer.
16+ *
17+ * @author rampatra
18+ * @since 2019-04-06
19+ */
20+ public class TwoSwappedNodesInBST {
21+
22+ private static class TreeNode {
23+ int val ;
24+ TreeNode left ;
25+ TreeNode right ;
26+
27+ TreeNode (int val ) {
28+ this .val = val ;
29+ }
30+
31+ @ Override
32+ public String toString () {
33+ return String .valueOf (val );
34+ }
35+ }
36+
37+ private static List <TreeNode > findSwappedNodes (TreeNode root ) {
38+ List <TreeNode > inOrderTraversal = new ArrayList <>();
39+ TreeNode firstSwappedNode = null ;
40+ TreeNode secondSwappedNode = null ;
41+ TreeNode plausibleSwappedNode = null ;
42+
43+ traverseInOrder (root , inOrderTraversal );
44+
45+ for (int i = 0 ; i < inOrderTraversal .size () - 1 ; i ++) {
46+ // find nodes not in ascending order
47+ if (inOrderTraversal .get (i ).val > inOrderTraversal .get (i + 1 ).val ) {
48+ if (firstSwappedNode == null ) {
49+ firstSwappedNode = inOrderTraversal .get (i ); // take the left node from the first violation
50+ plausibleSwappedNode = inOrderTraversal .get (i + 1 );
51+ } else {
52+ secondSwappedNode = inOrderTraversal .get (i + 1 ); // take the right node from the second violation
53+ }
54+ }
55+ }
56+
57+ return Arrays .asList (firstSwappedNode , secondSwappedNode == null ? plausibleSwappedNode : secondSwappedNode );
58+ }
59+
60+ private static void traverseInOrder (TreeNode node , List <TreeNode > inOrderTraversal ) {
61+ if (node == null ) return ;
62+
63+ traverseInOrder (node .left , inOrderTraversal );
64+ inOrderTraversal .add (node );
65+ traverseInOrder (node .right , inOrderTraversal );
66+ }
67+
68+ public static void main (String [] args ) {
69+ /*
70+
71+ Test case 1: Node 8 and node 2 are swapped
72+
73+ The current BST looks like:
74+
75+ 4
76+ / \
77+ 8 2
78+ / \ / \
79+ 1 3 6 9
80+ /
81+ 0
82+
83+ Instead, the correct BST should look like:
84+
85+ 4
86+ / \
87+ 2 8
88+ / \ / \
89+ 1 3 6 9
90+ /
91+ 0
92+
93+ */
94+ TreeNode treeRoot = new TreeNode (4 );
95+ treeRoot .left = new TreeNode (8 );
96+ treeRoot .right = new TreeNode (2 );
97+ treeRoot .left .left = new TreeNode (1 );
98+ treeRoot .left .right = new TreeNode (3 );
99+ treeRoot .left .left .left = new TreeNode (0 );
100+ treeRoot .right .left = new TreeNode (6 );
101+ treeRoot .right .right = new TreeNode (9 );
102+
103+ System .out .println (findSwappedNodes (treeRoot ));
104+
105+ /*
106+
107+ Test case 2: Node 3 and node 2 are swapped (note: these are parent child nodes)
108+
109+ The current BST looks like:
110+
111+ 4
112+ / \
113+ 3 8
114+ / \ / \
115+ 1 2 6 9
116+ /
117+ 0
118+
119+ Instead, the correct BST should look like:
120+
121+ 4
122+ / \
123+ 2 8
124+ / \ / \
125+ 1 3 6 9
126+ /
127+ 0
128+
129+ */
130+ treeRoot = new TreeNode (4 );
131+ treeRoot .left = new TreeNode (3 );
132+ treeRoot .right = new TreeNode (8 );
133+ treeRoot .left .left = new TreeNode (1 );
134+ treeRoot .left .right = new TreeNode (2 );
135+ treeRoot .left .left .left = new TreeNode (0 );
136+ treeRoot .right .left = new TreeNode (6 );
137+ treeRoot .right .right = new TreeNode (9 );
138+
139+ System .out .println (findSwappedNodes (treeRoot ));
140+ }
141+ }
0 commit comments