1
+ class MinAdjacentSwapsForPalindrome {
2
+ countRecursive ( input : string ) {
3
+ return this . recursiveHelper ( input . split ( "" ) , 0 , input . length - 1 ) ;
4
+ }
5
+
6
+ // Case 1: Ends are equal, make 0 swaps and try for internal susbtring swaps.
7
+ // Case 2: Ends are not equal
8
+ // Step 1: Attempt to make ends equal using either multiple swaps in left or right. (Take Minimum)
9
+ // Step 2: Recursively try for substring.
10
+ // Return at base.
11
+ recursiveHelper ( input : string [ ] , beg : number , end : number ) {
12
+
13
+ // Base condition, no swaps required.
14
+ if ( end <= beg ) return 0 ;
15
+
16
+ // Case 1: ends are equal.
17
+ if ( input [ beg ] === input [ end ] ) {
18
+ return this . recursiveHelper ( input , beg + 1 , end - 1 ) ;
19
+ }
20
+
21
+ // Case 2: ends are not equal.
22
+ const leftSwaps = this . swapLeft ( input , beg , end ) ;
23
+
24
+ const rightSwaps = this . swapRight ( input , beg , end ) ;
25
+
26
+ if ( leftSwaps < rightSwaps && leftSwaps !== Infinity ) {
27
+ this . swap ( input , beg , beg + leftSwaps ) ;
28
+ return leftSwaps + this . recursiveHelper ( input , beg + 1 , end - 1 ) ;
29
+ } else if ( rightSwaps !== Infinity ) {
30
+ this . swap ( input , end , end - rightSwaps ) ;
31
+ return rightSwaps + this . recursiveHelper ( input , beg + 1 , end - 1 ) ;
32
+ } else {
33
+ return - 1 ;
34
+ }
35
+ }
36
+
37
+ swap ( input : string [ ] , source : number , target : number ) {
38
+ const temp = input [ source ]
39
+ input [ source ] = input [ temp ]
40
+ input [ target ] = temp ;
41
+ }
42
+
43
+ swapLeft ( input : string [ ] , beg : number , end : number ) {
44
+ let pivot = beg + 1 ;
45
+ while ( pivot < end && input [ end ] !== input [ pivot ] ) pivot ++
46
+
47
+ if ( pivot < end ) return pivot - beg ;
48
+ return Infinity ;
49
+ }
50
+
51
+ swapRight ( input : string [ ] , beg : number , end : number ) {
52
+ let pivot = end - 1 ;
53
+ while ( pivot > beg && input [ beg ] !== input [ pivot ] ) pivot --
54
+
55
+ if ( pivot > beg ) return end - pivot ;
56
+ return Infinity
57
+ }
58
+
59
+ countIterative ( input : string ) {
60
+ let beg = 0 , end = input . length - 1 , swaps = 0 ;
61
+ const inputArr = input . split ( "" )
62
+ while ( end > beg ) {
63
+ if ( inputArr [ end ] === inputArr [ beg ] ) {
64
+ // Case 1: Ends are equal, squeeze inwards.
65
+ end -- ; beg ++ ;
66
+ } else {
67
+ // Case 2: Ends are not equal, displace left or right.
68
+ const leftSwaps = this . swapLeft ( inputArr , beg , end )
69
+ const rightSwaps = this . swapRight ( inputArr , beg , end )
70
+ if ( leftSwaps < rightSwaps && leftSwaps !== Infinity ) {
71
+ this . swap ( inputArr , beg , beg + leftSwaps )
72
+ swaps += leftSwaps
73
+ } else if ( rightSwaps !== Infinity ) {
74
+ this . swap ( inputArr , end , end - rightSwaps )
75
+ swaps += rightSwaps
76
+ } else {
77
+ return - 1
78
+ }
79
+ end -- , beg ++ ;
80
+ }
81
+ }
82
+
83
+ return swaps ;
84
+ }
85
+ }
86
+
87
+ function testMinAdjacentSwapsPalindrome ( input : string ) {
88
+ const counter = new MinAdjacentSwapsForPalindrome ( ) ;
89
+ console . log ( `Min Adjacent Swaps for input recursive: ${ input } is: ${ counter . countRecursive ( input ) } ` )
90
+ console . log ( `Min Adjacent Swaps for input iterative: ${ input } is: ${ counter . countIterative ( input ) } ` )
91
+ }
92
+
93
+ testMinAdjacentSwapsPalindrome ( "mamda" )
94
+ testMinAdjacentSwapsPalindrome ( "asflkj" )
95
+ testMinAdjacentSwapsPalindrome ( "aabb" )
96
+ testMinAdjacentSwapsPalindrome ( "ntiin" )
0 commit comments