From 108ac5e94f2e2ccf3539ea4f5119113365c798b6 Mon Sep 17 00:00:00 2001 From: sjain1909 Date: Thu, 18 Jul 2024 23:14:05 +0530 Subject: [PATCH 1/2] Adding solution of binary tree mirror image and rotation question. ## Fixing Issue #3540 ## Description This pull request implements the functionality for generating the mirror image of a binary tree and rotating a binary tree in C++. The changes include the addition of two main functions: one for creating the mirror image of a given binary tree and another for performing left and right rotations of the tree. These features enhance the data structures and algorithms (DSA) folder by providing essential tree manipulation techniques. ## Type of PR - [ ] Bug fix - [x] Feature enhancement - [ ] Documentation update - [ ] Security enhancement - [ ] Other (specify): _______________ ## Checklist - [x] I have performed a self-review of my code. - [x] I have read and followed the Contribution Guidelines. - [x] I have tested the changes thoroughly before submitting this pull request. - [x] I have provided relevant issue numbers, screenshots, and videos after making the changes. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have followed the code style guidelines of this project. - [x] I have checked for any existing open issues that my pull request may address. - [x] I have ensured that my changes do not break any existing functionality. - [x] Each contributor is allowed to create a maximum of 4 issues per day. This helps us manage and address issues efficiently. - [x] I have read the resources for guidance listed below. - [x] I have followed security best practices in my code changes. ## Additional Context The implementation includes two main features for binary trees: 1. **Mirror Image of Binary Tree:** This function recursively swaps the left and right children of each node in the binary tree, producing a mirror image. 2. **Binary Tree Rotation:** Functions for performing left and right rotations of the binary tree. These rotations are crucial for balancing operations in certain types of binary trees, such as AVL trees. ## Resources for Guidance Please read the following resources before submitting your contribution: - [x] [Code Harbor Hub Community Features](https://www.codeharborhub.live/community/features) - [x] [Markdown Guide](https://www.markdownguide.org/) --- .../0400-0499/0493-reverse-pairs.md | 344 +++++++++--------- dsa/Advance/binaryTree-mirror-rotation.md | 216 +++++++++++ 2 files changed, 388 insertions(+), 172 deletions(-) create mode 100644 dsa/Advance/binaryTree-mirror-rotation.md diff --git a/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md b/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md index ab99d358c..9596f9a73 100644 --- a/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md +++ b/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md @@ -1,172 +1,172 @@ ---- -id: reverse-pairs -title: Reverse Pairs -sidebar_label: 0493 - Reverse Pairs -tags: - - Leetcode - - Merge Sort ---- - -## Problem Statement - -Given an integer array `nums`, return the number of reverse pairs in the array. - -A reverse pair is defined as a pair `(i, j)` where: - -- $0 <= i < j < nums.length and$ -- $nums[i] > 2 * nums[j].$ - -## Examples - -### Example 1 - -- Input: `nums = [1,3,2,3,1]` -- Output: `2` -- Explanation: The reverse pairs are: - - `(1, 4)` -> `nums[1] = 3`, `nums[4] = 1`, `3 > 2 * 1` - - `(3, 4)` -> `nums[3] = 3`, `nums[4] = 1`, `3 > 2 * 1` - -### Example 2 - -- Input: `nums = [2,4,3,5,1]` -- Output: `3` -- Explanation: The reverse pairs are: - - `(1, 4)` -> `nums[1] = 4`, `nums[4] = 1`, `4 > 2 * 1` - - `(2, 4)` -> `nums[2] = 3`, `nums[4] = 1`, `3 > 2 * 1` - - `(3, 4)` -> `nums[3] = 5`, `nums[4] = 1`, `5 > 2 * 1` - -## Constraints - -- $1 <= nums.length <= 5 * 104$ -- $-231 <= nums[i] <= 231 - 1$ - -## Algorithm - -To solve this problem efficiently, we can use a modified merge sort algorithm, which not only sorts the array but also counts the number of reverse pairs during the merging process. The idea is to leverage the divide-and-conquer approach to count pairs in `O(n log n)` time complexity. - -### Steps: - -1. **Divide**: Split the array into two halves. -2. **Count**: Count the reverse pairs in each half recursively. -3. **Merge and Count**: While merging the two halves, count the reverse pairs where one element is from the left half and the other is from the right half. - -## Code - -### Python - -```python -class Solution: - def reversePairs(self, nums: List[int]) -> int: - def merge_sort(nums, l, r): - if l >= r: - return 0 - - mid = (l + r) // 2 - count = merge_sort(nums, l, mid) + merge_sort(nums, mid + 1, r) - - j = mid + 1 - for i in range(l, mid + 1): - while j <= r and nums[i] > 2 * nums[j]: - j += 1 - count += j - (mid + 1) - - nums[l:r + 1] = sorted(nums[l:r + 1]) - return count - - return merge_sort(nums, 0, len(nums) - 1) -``` - -### C++ - -```cpp -#include -using namespace std; - -class Solution { -public: - int reversePairs(vector& nums) { - return reversePairsSub(nums, 0, nums.size() - 1); - } - -private: - int reversePairsSub(vector& nums, int l, int r) { - if (l >= r) return 0; - - int m = l + ((r - l) >> 1); - int res = reversePairsSub(nums, l, m) + reversePairsSub(nums, m + 1, r); - - int i = l, j = m + 1, k = 0, p = m + 1; - vector merge(r - l + 1); - - while (i <= m) { - while (p <= r && nums[i] > 2L * nums[p]) p++; - res += p - (m + 1); - - while (j <= r && nums[i] >= nums[j]) merge[k++] = nums[j++]; - merge[k++] = nums[i++]; - } - - while (j <= r) merge[k++] = nums[j++]; - - copy(merge.begin(), merge.end(), nums.begin() + l); - - return res; - } -}; -``` - -### Java - -```java -import java.util.Arrays; - -class Solution { - public int reversePairs(int[] nums) { - return mergeSort(nums, 0, nums.length - 1); - } - - private int mergeSort(int[] nums, int left, int right) { - if (left >= right) return 0; - - int mid = left + (right - left) / 2; - int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); - - int j = mid + 1; - for (int i = left; i <= mid; i++) { - while (j <= right && nums[i] > 2L * nums[j]) j++; - count += j - (mid + 1); - } - - Arrays.sort(nums, left, right + 1); - return count; - } -} -``` - -### JavaScript - -```javascript -var reversePairs = function (nums) { - function mergeSort(nums, left, right) { - if (left >= right) return 0; - - let mid = left + Math.floor((right - left) / 2); - let count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); - - let j = mid + 1; - for (let i = left; i <= mid; i++) { - while (j <= right && nums[i] > 2 * nums[j]) j++; - count += j - (mid + 1); - } - - nums.splice( - left, - right - left + 1, - ...nums.slice(left, right + 1).sort((a, b) => a - b) - ); - return count; - } - - return mergeSort(nums, 0, nums.length - 1); -}; -``` +--- +id: reverse-pairs +title: Reverse Pairs +sidebar_label: 0493 - Reverse Pairs +tags: + - Leetcode + - Merge Sort +--- + +## Problem Statement + +Given an integer array `nums`, return the number of reverse pairs in the array. + +A reverse pair is defined as a pair `(i, j)` where: + +- $0 <= i < j < nums.length and$ +- $nums[i] > 2 * nums[j].$ + +## Examples + +### Example 1 + +- Input: `nums = [1,3,2,3,1]` +- Output: `2` +- Explanation: The reverse pairs are: + - `(1, 4)` -> `nums[1] = 3`, `nums[4] = 1`, `3 > 2 * 1` + - `(3, 4)` -> `nums[3] = 3`, `nums[4] = 1`, `3 > 2 * 1` + +### Example 2 + +- Input: `nums = [2,4,3,5,1]` +- Output: `3` +- Explanation: The reverse pairs are: + - `(1, 4)` -> `nums[1] = 4`, `nums[4] = 1`, `4 > 2 * 1` + - `(2, 4)` -> `nums[2] = 3`, `nums[4] = 1`, `3 > 2 * 1` + - `(3, 4)` -> `nums[3] = 5`, `nums[4] = 1`, `5 > 2 * 1` + +## Constraints + +- $1 <= nums.length <= 5 * 104$ +- $-231 <= nums[i] <= 231 - 1$ + +## Algorithm + +To solve this problem efficiently, we can use a modified merge sort algorithm, which not only sorts the array but also counts the number of reverse pairs during the merging process. The idea is to leverage the divide-and-conquer approach to count pairs in `O(n log n)` time complexity. + +### Steps: + +1. **Divide**: Split the array into two halves. +2. **Count**: Count the reverse pairs in each half recursively. +3. **Merge and Count**: While merging the two halves, count the reverse pairs where one element is from the left half and the other is from the right half. + +## Code + +### Python + +```python +class Solution: + def reversePairs(self, nums: List[int]) -> int: + def merge_sort(nums, l, r): + if l >= r: + return 0 + + mid = (l + r) // 2 + count = merge_sort(nums, l, mid) + merge_sort(nums, mid + 1, r) + + j = mid + 1 + for i in range(l, mid + 1): + while j <= r and nums[i] > 2 * nums[j]: + j += 1 + count += j - (mid + 1) + + nums[l:r + 1] = sorted(nums[l:r + 1]) + return count + + return merge_sort(nums, 0, len(nums) - 1) +``` + +### C++ + +```cpp +#include +using namespace std; + +class Solution { +public: + int reversePairs(vector& nums) { + return reversePairsSub(nums, 0, nums.size() - 1); + } + +private: + int reversePairsSub(vector& nums, int l, int r) { + if (l >= r) return 0; + + int m = l + ((r - l) >> 1); + int res = reversePairsSub(nums, l, m) + reversePairsSub(nums, m + 1, r); + + int i = l, j = m + 1, k = 0, p = m + 1; + vector merge(r - l + 1); + + while (i <= m) { + while (p <= r && nums[i] > 2L * nums[p]) p++; + res += p - (m + 1); + + while (j <= r && nums[i] >= nums[j]) merge[k++] = nums[j++]; + merge[k++] = nums[i++]; + } + + while (j <= r) merge[k++] = nums[j++]; + + copy(merge.begin(), merge.end(), nums.begin() + l); + + return res; + } +}; +``` + +### Java + +```java +import java.util.Arrays; + +class Solution { + public int reversePairs(int[] nums) { + return mergeSort(nums, 0, nums.length - 1); + } + + private int mergeSort(int[] nums, int left, int right) { + if (left >= right) return 0; + + int mid = left + (right - left) / 2; + int count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); + + int j = mid + 1; + for (int i = left; i <= mid; i++) { + while (j <= right && nums[i] > 2L * nums[j]) j++; + count += j - (mid + 1); + } + + Arrays.sort(nums, left, right + 1); + return count; + } +} +``` + +### JavaScript + +```javascript +var reversePairs = function (nums) { + function mergeSort(nums, left, right) { + if (left >= right) return 0; + + let mid = left + Math.floor((right - left) / 2); + let count = mergeSort(nums, left, mid) + mergeSort(nums, mid + 1, right); + + let j = mid + 1; + for (let i = left; i <= mid; i++) { + while (j <= right && nums[i] > 2 * nums[j]) j++; + count += j - (mid + 1); + } + + nums.splice( + left, + right - left + 1, + ...nums.slice(left, right + 1).sort((a, b) => a - b) + ); + return count; + } + + return mergeSort(nums, 0, nums.length - 1); +}; +``` diff --git a/dsa/Advance/binaryTree-mirror-rotation.md b/dsa/Advance/binaryTree-mirror-rotation.md new file mode 100644 index 000000000..76b184853 --- /dev/null +++ b/dsa/Advance/binaryTree-mirror-rotation.md @@ -0,0 +1,216 @@ +--- +id: binary-tree-mirror-rotate +title: Binary Tree Mirror and Rotation Solution +sidebar_label: 0005 - Binary Tree Mirror and Rotation +tags: [Binary Tree, Mirror Image, Tree Rotation, Algorithm, C++, Problem Solving] +description: This is a solution to create the mirror image and perform rotations (left and right) on a binary tree. +--- + +## Problem Statement + +### Problem Description + +Implement a feature to create the mirror image and perform rotations (left and right) on a binary tree. This functionality will allow users to easily transform binary trees for various algorithmic and visualization purposes. + +### Examples + +**Example 1:** + +```plaintext +Input: Binary Tree = [4, 2, 7, 1, 3, 6, 9] + + 4 + / \ + 2 7 + / \ / \ + 1 3 6 9 + +Mirror Image Output: + + 4 + / \ + 7 2 + / \ / \ + 9 6 3 1 + +``` +**Example 2:** + +```plaintext +Input: Binary Tree = [4, 2, 7, 1, 3, 6, 9] +Rotation (Left) Output: + + 2 + / \ + 1 4 + \ + 7 + / \ + 6 9 + +Rotation (Right) Output: + + 7 + / \ + 4 9 + / \ + 2 6 + / \ + 1 3 + + +``` +### Constraints + +- The input is a binary tree. +- The tree can have up to 10^5 nodes. + +## Solution of Given Problem + +### Intuition and Approach + +To solve the problem, we can break it down into three parts: + +1. Mirror Image: +- Swap the left and right children of each node recursively. + +2. Left Rotation: +- Rotate the tree around a specific node such that the node's right child becomes its parent. + +3. Right Rotation: +- Rotate the tree around a specific node such that the node's left child becomes its parent. + +### Approaches + +#### Codes in Different Languages + + + + + ```cpp +#include +using namespace std; + +struct TreeNode { + int val; + TreeNode* left; + TreeNode* right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; + +void mirror(TreeNode* node) { + if (node == NULL) + return; + + swap(node->left, node->right); + mirror(node->left); + mirror(node->right); +} + +TreeNode* leftRotate(TreeNode* root) { + if (root == NULL || root->right == NULL) + return root; + + TreeNode* newRoot = root->right; + root->right = newRoot->left; + newRoot->left = root; + + return newRoot; +} + +TreeNode* rightRotate(TreeNode* root) { + if (root == NULL || root->left == NULL) + return root; + + TreeNode* newRoot = root->left; + root->left = newRoot->right; + newRoot->right = root; + + return newRoot; +} + +void inorder(TreeNode* root) { + if (root == NULL) + return; + inorder(root->left); + cout << root->val << " "; + inorder(root->right); +} + +int main() { + int n, val; + cout << "Enter the number of nodes in the tree: "; + cin >> n; + + if (n == 0) { + cout << "The tree is empty." << endl; + return 0; + } + + cout << "Enter the values of the nodes: "; + vector nodes(n); + for (int i = 0; i < n; ++i) { + cin >> val; + nodes[i] = new TreeNode(val); + } + + for (int i = 0; i < n; ++i) { + int leftIndex, rightIndex; + cout << "Enter the left and right child indices for node with value " << nodes[i]->val << " (use -1 for no child): "; + cin >> leftIndex >> rightIndex; + if (leftIndex != -1) nodes[i]->left = nodes[leftIndex]; + if (rightIndex != -1) nodes[i]->right = nodes[rightIndex]; + } + + TreeNode* root = nodes[0]; + + cout << "Original Tree: "; + inorder(root); + cout << "\n"; + + mirror(root); + cout << "Mirror Image: "; + inorder(root); + cout << "\n"; + + root = leftRotate(root); + cout << "Left Rotation: "; + inorder(root); + cout << "\n"; + + root = rightRotate(root); + cout << "Right Rotation: "; + inorder(root); + cout << "\n"; + + return 0; +} + ``` + + + +### Complexity Analysis + +- **Time Complexity:** $O(n)$ +- **Space Complexity:** $O(h)$, where `h` is the height of the tree (due to the recursion stack). + +The time complexity is linear because each node is visited once. The space complexity is determined by the depth of the recursion stack. + +## Video Explanation of Given Problem + + +--- + +

Authors:

+ +
+{['sjain1909'].map(username => ( + +))} +
From 82bfa6b145f88e60aec9fa676c67183938ef667e Mon Sep 17 00:00:00 2001 From: Ajay Dhangar <99037494+Ajay-Dhangar@users.noreply.github.com> Date: Fri, 19 Jul 2024 22:16:36 +0530 Subject: [PATCH 2/2] Update 0493-reverse-pairs.md --- .../lc-solutions/0400-0499/0493-reverse-pairs.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md b/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md index a11661210..861effb08 100644 --- a/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md +++ b/dsa-solutions/lc-solutions/0400-0499/0493-reverse-pairs.md @@ -1,10 +1,17 @@ --- id: reverse-pairs title: Reverse Pairs -sidebar_label: 0493 - Reverse Pairs +sidebar_label: 493-Reverse-Pairs tags: - - Leetcode + - Array + - Binary Search + - Divide and conquer + - Binary Indexed Tree + - Segment Tree - Merge Sort + - Ordered Set +description: The problem is to reverse the pairs. +sidebar_position: 2667 --- ## Problem Statement @@ -204,6 +211,7 @@ class Solution: public int reversePairs(int[] nums) { return mergeSort(nums, 0, nums.length - 1); } + public int mergeSort(int[] nums, int left, int right) { if (left >= right) { return 0;