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