Skip to content

Commit 172ed31

Browse files
Added solution for min adjacent swaps and serder binary tree.
1 parent eeafc92 commit 172ed31

File tree

3 files changed

+173
-0
lines changed

3 files changed

+173
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Happy to accept any contributions to this in any langugage.
5757
## Hard
5858
1. [Find Missing Positive](https://leetcode.com/problems/first-missing-positive/) | [Solution](./level_hard/LeetCode_41_Hard.ts)
5959
2. [Read N Characters Given Read 4 II - Call Multiple Times - LeetCode 158](https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/) | [Solution 1](./level_hard/LeetCode_158_Hard.java) | [Solution 2 Optimized](./level_hard/LeetCode_158_Hard_1.java)
60+
3. [Serialize Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | [Solution](./level_hard/SerializeDeserializeBinaryTree.ts)
6061

6162
## Sorting
6263
1. Bubble Sort | [Solution](./sorting/Sort_Bubble.js)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* class TreeNode {
4+
* val: number
5+
* left: TreeNode | null
6+
* right: TreeNode | null
7+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
8+
* this.val = (val===undefined ? 0 : val)
9+
* this.left = (left===undefined ? null : left)
10+
* this.right = (right===undefined ? null : right)
11+
* }
12+
* }
13+
*/
14+
15+
/**
16+
* Solution uses the depth 1st approach to solve the problem. We use a delimeter string so that multi digit
17+
* values can be treated as a single entity. Further, we can also use the breadth 1st approach. Although depth
18+
* 1st approach is easier to implement via recursion which is simpler.
19+
*
20+
* Time: O(N) since all the nodes needs to be visited once, Space: O(N) since an additional encoded space of n
21+
* is required.
22+
*
23+
* @param root
24+
*/
25+
26+
/*
27+
* Encodes a tree to a single string.
28+
*/
29+
function serialize(root: TreeNode | null): string {
30+
const result: string[] = []
31+
serializeHelper(root, result);
32+
return result.join(";");
33+
};
34+
35+
function serializeHelper(root: TreeNode | null, result: string[]) {
36+
if (root === null) {
37+
result.push("")
38+
return
39+
}
40+
41+
result.push(root.val.toString())
42+
serializeHelper(root.left, result)
43+
serializeHelper(root.right, result)
44+
}
45+
46+
function deserializeHelper(elements: string[]): TreeNode | null {
47+
48+
const elem = elements.shift()
49+
50+
if (elem === undefined || elem === "") return null;
51+
52+
const node: TreeNode = {
53+
val: parseInt(elem),
54+
left: null,
55+
right: null
56+
};
57+
58+
node.left = deserializeHelper(elements);
59+
node.right = deserializeHelper(elements);
60+
61+
return node;
62+
}
63+
64+
/*
65+
* Decodes your encoded data to tree.
66+
*/
67+
function deserialize(data: string): TreeNode | null {
68+
const elements: string[] = data.split(";");
69+
return deserializeHelper(elements);
70+
};
71+
72+
73+
/**
74+
* Your functions will be called as such:
75+
* deserialize(serialize(root));
76+
*/
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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

Comments
 (0)