From a23e2a2623d1010d7920ee31c74b693c17b05f8b Mon Sep 17 00:00:00 2001 From: Anusha Date: Thu, 16 Nov 2023 23:31:52 +0530 Subject: [PATCH 01/53] added inorder traversal --- inorder traversal/BinaryTree.class | Bin 0 -> 1256 bytes inorder traversal/BinaryTree.java | 51 ++++++ inorder traversal/Readme.md | 249 +++++++++++++++++++++++++++++ inorder traversal/TreeNode.class | Bin 0 -> 319 bytes inorder traversal/inorder.cpp | 38 +++++ inorder traversal/inorder.py | 26 +++ 6 files changed, 364 insertions(+) create mode 100644 inorder traversal/BinaryTree.class create mode 100644 inorder traversal/BinaryTree.java create mode 100644 inorder traversal/Readme.md create mode 100644 inorder traversal/TreeNode.class create mode 100644 inorder traversal/inorder.cpp create mode 100644 inorder traversal/inorder.py diff --git a/inorder traversal/BinaryTree.class b/inorder traversal/BinaryTree.class new file mode 100644 index 0000000000000000000000000000000000000000..a92100e4f3112d000f03556eeddc1780ac5719cb GIT binary patch literal 1256 zcmaJ=TTc@~6#k~SE$d<{mm;XOg+fcKRPj#n0##y@f+lS+#;2hjVd-|a?oLViPy7=; zXjBX)KKkH~GM?QnP(tIw&Ym;p%y+)?&741fkA4AI!wVGw1Qmodgb`tg@ACs*G`P82 ze6_PL8j>Nhs++oe!Vt_YZjT^}5e2G-3(y#%bz6unt0@>lhImieYV~-lq~aoC3gQ|r zVT>Z{y2TwCY1vI-*KK|vY=;{Rqq)vC}(Qa$6#y*DXsr(&n8_A@{7N6U9S@087OpSW!{Js)EO^i1Z*b zr;kN953H6b`fB;QZt#Y*>>k6%K{@(~KKM&+HVxrqs+QI2c1q_75A2*dSnqYjko3Wp z{pVX6yvsgBnHxq;m!ia=RZLUZWrI78a1^XD%%AIN7*z#jhUEWKX>$C&kfuQh(BlJw zpu0ze)*^Y==+EdM&L4t(CWGM?t!@~I)8nAIA=^!@5rDfpoBxee{wtIp82y5AvZjv+ z2j7tN^?1W_=)J-xO#|u zwcwc(WPXF%~`3;=aG($BFsaO`=@r^Y#1ALnQ)9T4#yr w95PtIU1aebdDKxr6H73NeTQfVDdP5d5BKRGr6wNH_W)1HQ^|UUbvifw55A!&LI3~& literal 0 HcmV?d00001 diff --git a/inorder traversal/BinaryTree.java b/inorder traversal/BinaryTree.java new file mode 100644 index 00000000..412a4948 --- /dev/null +++ b/inorder traversal/BinaryTree.java @@ -0,0 +1,51 @@ +class TreeNode { + int data; + // Store integer data + TreeNode left = null, + // Left child reference + right = null; + // Right child reference + + public TreeNode(int data) { + // Constructor to create a new TreeNode + this.data = data; + // Assign the given data to this node + } +} + +public class BinaryTree { +// Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + + public static void main(String[] args) { + + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } +} \ No newline at end of file diff --git a/inorder traversal/Readme.md b/inorder traversal/Readme.md new file mode 100644 index 00000000..8e18794e --- /dev/null +++ b/inorder traversal/Readme.md @@ -0,0 +1,249 @@ +# Exploring Binary Trees and Inorder Traversal + +## Introduction to Trees +A tree is a hierarchical data structure which is composed of nodes, where each node has at maximum two children and they are called as left child and right child. This interconnected system is reminiscent of an upside-down tree, with the topmost node called the root. In this structure, nodes hold data, and edges represent connections between nodes. Trees play a crucial role in computer science, serving as versatile tools for tasks such as searching, sorting, and analysis. Each node's ability to have multiple children allows for the creation of complex hierarchical relationships, making trees an indispensable concept for organizing and manipulating data efficiently. Whether utilized for representing hierarchical relationships, optimizing search algorithms, or structuring databases, trees form a foundational element in computer science, contributing to the systematic and effective management of information. + +## Introduction to Inorder Traversal +Inorder traversal is a method of traversing a binary tree in a specific order. It starts from the leftmost node and moves towards the rightmost node, visiting the left subtree first, then the root, and finally the right subtree. This traversal strategy is fundamental for exploring and processing binary trees systematically. + +## Overview +The provided Python code defines a binary tree node using a class named `Node` and demonstrates recursive inorder traversal. The `Node` class has a constructor initializing the node with some data and two pointers, `left` and `right`, representing the left and right children. + +## Step-by-Step Explanation + +# Using Python + +**Explanation:** + +1. **Node Class Definition:** + +```python +class Node: + def __init__(self, data): + self.data = data + self.left = self.right = None +``` + +This class defines the structure of a binary tree node. Each node has a data attribute to store the value of the node, and left and right attributes to point to the left and right children, respectively. + +2. **Inorder Traversal Function:** + +```python +def inorder(root): + if root: + inorder(root.left) + print(root.data, end=" ") + inorder(root.right) +``` + +This function, inorder, is a recursive implementation of the inorder traversal algorithm. It takes a root node as an argument and performs the following steps: +=> Check if the current root exists. +=> Recursively traverse the left subtree. +=> Print the value of the current node. +=> Recursively traverse the right subtree. + +3.**Driver Code and Tree Initialization** + +```python + if __name__ == "__main__": + root = Node(80) + root.left = Node(20) + root.right = Node(30) + root.left.left = Node(40) + root.left.right = Node(350) + root.right.left = Node(460) + root.right.right = Node(70) +``` + +In the __main__ block, a binary tree is created with the following structure: + + 80 + / \ + 20 30 + / \ / \ + 40 350 460 70 + + +4. **Inorder Traversal Call** + +```python + inorder(root) +``` + +This line calls the inorder function with the root of the tree, initiating the inorder traversal. The result is the values of the nodes printed in ascending order. + +In summary, the code defines a binary tree, initializes it with specific values, and then performs an inorder traversal, printing the values of the nodes in ascending order. The recursive nature of the inorder function is key to traversing the tree systematically. + +# using C++ + +**Explanation** + +1. **Header Inclusion**: + + ```cpp + #include + ``` + + This line includes a standard C++ library header, which is a common practice to include necessary headers like `` for input and output. + +2. **Node Class Definition:** + + ```cpp + class Node { + public: + int data; + Node *left = NULL; + Node *right = NULL; + + // Node constructor initializes data + Node(int val) { + data = val; + } + }; + ``` + + This part defines a `Node` class representing nodes in a binary tree. Each node contains an integer `data`, a pointer to the left child (`left`), and a pointer to the right child (`right`). The constructor initializes the node with the provided data value. + +3. **Inorder Traversal Function:** + + ```cpp + void inorder(Node* root) { + // call inorder for the left subtree + if (root != NULL) { + inorder(root->left); + // Print root node data + std::cout << root->data << " "; + // call inorder for the right subtree + inorder(root->right); + } + } + ``` + + The `inorder` function performs recursive inorder traversal on the binary tree. It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. + +4. **Main Function:** + + ```cpp + int main() { + // Creating the binary tree + Node* root = new Node(10); + root->left = new Node(20); + root->right = new Node(30); + root->left->left = new Node(40); + root->left->right = new Node(50); + root->right->left = new Node(60); + root->right->right = new Node(70); + + // Displaying the binary tree in inorder traversal + inorder(root); + + // Inorder traversal of the tree + return 0; + } + ``` + + In the `main` function, a binary tree is created with specific values. Nodes are allocated dynamically using the `new` keyword. The `inorder` function is then called to display the binary tree in inorder traversal, printing the values of the nodes in ascending order. + +In summary, this C++ program defines a binary tree using a `Node` class, creates a binary tree with specific values, and performs an inorder traversal to display the tree's content. The code demonstrates the concept of recursive traversal in a binary tree. +This code will output `40 20 50 10 60 30 70`, which is a correct + +# using Java + +**explanation** + +1. **TreeNode Class Definition:** + ```java + class TreeNode { + int data; + TreeNode left = null, right = null; + + public TreeNode(int data) { + this.data = data; + } + } + ``` + + - `TreeNode` class defines the structure of a binary tree node. + - It has an `int` variable `data` to store the node's value and references (`left` and `right`) to its left and right children. + - The constructor initializes a new `TreeNode` with the given data. + +2. **BinaryTree Class:** + ```java + public class BinaryTree { + // Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + ``` + - This class contains a method `inorderTraversal` that performs recursive inorder traversal on a binary tree. + - It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. + - InorderTraversal` is a static method used for inorder traversal of the binary tree. + - It is a recursive function that traverses the left subtree, prints the data of the current node, and then traverses the right subtree. + +3. **Main Method:** + ```java + public static void main(String[] args) { + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } + ``` + + - The `main` method is the entry point of the program. + - It creates an instance of the `TreeNode` class, representing the root of the binary tree, with a data value of 10. + - Child nodes are added to the root, forming a binary tree structure. + - The `inorderTraversal` method is called to perform an inorder traversal of the tree, printing the nodes in ascending order. + + +4. **Tree Structure:** + ``` + 10 + / \ + 20 30 + / \ / \ + 40 50 60 70 + ``` + +5. **Output:** + ``` + Inorder Traversal: 40 20 50 10 60 30 70 + ``` + +In summary, this Java program demonstrates the creation of a binary tree, addition of nodes, and the execution of an inorder traversal. The `TreeNode` class encapsulates the node structure, and the `BinaryTree` class utilizes it to construct and traverse the binary tree. + + +## Time and Space Complexity Analysis +- Time Complexity: The time complexity of the inorder traversal is O(n), where n is the number of nodes in the tree. This is because each node is visited once. +- Space Complexity: The space complexity is O(h), where h is the height of the binary tree. In the worst case (skewed tree), the height is n, making the space complexity O(n). In a balanced tree, the height is log(n), resulting in a space complexity of O(log(n)). + +## Real-World Applications +Binary trees and inorder traversal have applications in various domains, including: +- **Database Indexing:** Binary trees are used in database systems to efficiently index and search for records. +- **Expression Trees:** In compilers, expression trees are used to represent mathematical expressions for efficient evaluation. +- **File Systems:** File systems often use tree structures to organize and locate files efficiently. + +## Conclusion +Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. \ No newline at end of file diff --git a/inorder traversal/TreeNode.class b/inorder traversal/TreeNode.class new file mode 100644 index 0000000000000000000000000000000000000000..d4badf481c5a509407b357271971eaa3f304222b GIT binary patch literal 319 zcmXw!Piw+J5XIjn(U^2KR_#A}=}~jgYr#@z3k5;!q2hg`Tf34*SYn|cs|P7~=m+SB zDt#O1Vc+Zwzj-tB^LzLPaEFT+9{do2L=AO;_C~#{QLc*h=qcOiWhqdX&parcXp{CjZ2byQz-l4rVQP(xT2}YV|+e3Q{k4YB4;yl v3a{%?Pncbkc6=}Wf=I<4p_68Mxkvl6qED$E1k{Kcphdqfn(RMg&BOU0Zcj3B literal 0 HcmV?d00001 diff --git a/inorder traversal/inorder.cpp b/inorder traversal/inorder.cpp new file mode 100644 index 00000000..2d38d517 --- /dev/null +++ b/inorder traversal/inorder.cpp @@ -0,0 +1,38 @@ +#include + +class Node{ + public: + int data; + Node *left=NULL; + Node *right=NULL; + + // Node constructor initializes data + Node(int val){ + data=val; + } +}; +void inorder(Node* root){ + // call inorder for left subtree + if(root!=NULL){ + inorder(root->left); + // Print root node data + std::cout<data<<" "; + // call inorder for right subtree + inorder(root->right); + } +} + +int main(){ + // Creating the binary tree + Node* root=new Node(10); + root->left=new Node(20); + root->right=new Node(30); + root->left->left=new Node(40); + root->left->right=new Node(50); + root->right->left=new Node(60); + root->right->right=new Node(70); + // Displaying the binary tree in inorder traversal + inorder(root); + // Inorder traversal of the tree + return 0; +} \ No newline at end of file diff --git a/inorder traversal/inorder.py b/inorder traversal/inorder.py new file mode 100644 index 00000000..471f9d21 --- /dev/null +++ b/inorder traversal/inorder.py @@ -0,0 +1,26 @@ +# Definition for a binary tree node +class Node: + def __init__(self,data): + self.data=data + self.left=self.right=None +# Recursive Inorder Traversal. +def inorder(root): + # Check if the root exists + if root: + # Perform an inorder traversal on the left subtree + inorder(root.left) + # Print the value of the current node + print(root.data,end=" ") + # Perform an inorder traversal on the right subtree + inorder(root.right) + # Driver code to test above function +# The values of nodes are given below : +if __name__=="__main__": + root=Node(80) + root.left=Node(20) + root.right=Node(30) + root.left.left=Node(40) + root.left.right=Node(350) + root.right.left=Node(460) + root.right.right=Node(70) + inorder(root) \ No newline at end of file From b0a2555db7f241ea9cfcbfeecac7bdec1ac2e595 Mon Sep 17 00:00:00 2001 From: Anusha Date: Thu, 16 Nov 2023 23:43:10 +0530 Subject: [PATCH 02/53] adding inorder traversal file --- README.md | 167 ------------------------------------------------------ 1 file changed, 167 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index a834d0e7..00000000 --- a/README.md +++ /dev/null @@ -1,167 +0,0 @@ - - - - -## Instructions - -Git setup instructions to make contributions to the repository. - - - -## Install Git - -Download the latest version of `Git`. - -https://git-scm.com/download - - - -## Clone this repository - -Create a folder to clone the repository. - -Open the terminal and run the following git command: -```bash -git clone https://github.com/venkys-io/Code-Blogs.git -``` - - - -If this is the first time using git. A browser tab pops up to login into your GitHub account. - -and set the default config username and email. This is necessary to make any commits on the repository. - -```bash -git config --global user.name "yourUserName" -git config --global user.email "YourEmailId@gmail.com" -``` - -## Create a branch - -Change to the repository directory on your computer (if you are not already there): - -```bash -cd Code-Blogs -``` - -make sure you are in the correct directory. -```bash -C:\Users\....\Code-blogs\> -``` - -Now create a branch using `git checkout` command: - -``` -git checkout -b "yourBranchName" -``` - -you will be switched to your branch. - -## Make changes or Add your files - -Now write your blogs. - -Open vs-code in the repository. - -Shortcut: -```bash - C:\Users\....\Code-blogs\> code . -``` - - -To create a blog for the program `programs-prod/algorithms/Arrays/Easy/Palindrome` - -Create a `README.md` file as specified format. - -Example: - -
-Code-Blogs
-  └───Arrays
-        ├───Easy
-        │   └───Palindrome
-        |       └───README.md
-        └───Medium
-
-
- - -Now write the blog in `markdown`. - -To know more about markdown. visit - -[Cheatsheet1](https://www.freecodecamp.org/news/markdown-cheatsheet/)
-[Cheatsheet2](https://www.markdownguide.org/cheat-sheet/) - - - - - - - -## Commit those changes. - -Even though you have created a file. `Git` actually doesn't track those files. - -you can check the status of your branch. using `git status` command. - -```bash -git status -``` - -It displays all the changes you made on the branch. - - -Add those changes to the branch you just created using the `git add` command: - -```bash -git add . -``` - -Now commit those changes using the git commit command: - -```bash -git commit -m "your commit message" -``` - - -## Push changes to GitHub. - -push the changes using the command `git push` - -```bash -git push -u origin your-branch-name -``` - -replace your-branch-name with the name of the branch you created earlier. - - -- Note: You might get Authentication errors if it was your first time. - - - -## Raise a Pull Request for review. - -Now open GitHub to see those changes. - -Now open `pull request` tab on GitHub repository. - -Hit on Compare & Pull request. - -Mention your changes. - -Hit on create pull request. - - - - -## Suggestions - -It is good a have knowledge on Git, GitHub. - -Here are few free resources. You can try. - -[Youtube1](https://youtu.be/vwj89i2FmG0?si=C79oYDwj2A7Iqhta)
-[Youtube2](https://youtu.be/Ez8F0nW6S-w?si=FH0luDqtp9WiWqgp)
-[Youtube3](https://youtu.be/CvUiKWv2-C0?si=6Nx71vP7WXtAAbqe)
-[GitHub-Resource](https://github.com/firstcontributions/first-contributions) \ No newline at end of file From 54faf551d7630fd1b5d7e0abe5ac93fec1c2f4d7 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sat, 18 Nov 2023 12:47:57 +0530 Subject: [PATCH 03/53] Update inorder.py --- inorder traversal/inorder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inorder traversal/inorder.py b/inorder traversal/inorder.py index 471f9d21..9204581a 100644 --- a/inorder traversal/inorder.py +++ b/inorder traversal/inorder.py @@ -23,4 +23,4 @@ def inorder(root): root.left.right=Node(350) root.right.left=Node(460) root.right.right=Node(70) - inorder(root) \ No newline at end of file + inorder(root) From fbf83deae7a9f2a294d9bd4cc8fc0c4306fe54b0 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sat, 18 Nov 2023 12:50:37 +0530 Subject: [PATCH 04/53] Delete inorder traversal/BinaryTree.class --- inorder traversal/BinaryTree.class | Bin 1256 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 inorder traversal/BinaryTree.class diff --git a/inorder traversal/BinaryTree.class b/inorder traversal/BinaryTree.class deleted file mode 100644 index a92100e4f3112d000f03556eeddc1780ac5719cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1256 zcmaJ=TTc@~6#k~SE$d<{mm;XOg+fcKRPj#n0##y@f+lS+#;2hjVd-|a?oLViPy7=; zXjBX)KKkH~GM?QnP(tIw&Ym;p%y+)?&741fkA4AI!wVGw1Qmodgb`tg@ACs*G`P82 ze6_PL8j>Nhs++oe!Vt_YZjT^}5e2G-3(y#%bz6unt0@>lhImieYV~-lq~aoC3gQ|r zVT>Z{y2TwCY1vI-*KK|vY=;{Rqq)vC}(Qa$6#y*DXsr(&n8_A@{7N6U9S@087OpSW!{Js)EO^i1Z*b zr;kN953H6b`fB;QZt#Y*>>k6%K{@(~KKM&+HVxrqs+QI2c1q_75A2*dSnqYjko3Wp z{pVX6yvsgBnHxq;m!ia=RZLUZWrI78a1^XD%%AIN7*z#jhUEWKX>$C&kfuQh(BlJw zpu0ze)*^Y==+EdM&L4t(CWGM?t!@~I)8nAIA=^!@5rDfpoBxee{wtIp82y5AvZjv+ z2j7tN^?1W_=)J-xO#|u zwcwc(WPXF%~`3;=aG($BFsaO`=@r^Y#1ALnQ)9T4#yr w95PtIU1aebdDKxr6H73NeTQfVDdP5d5BKRGr6wNH_W)1HQ^|UUbvifw55A!&LI3~& From e35c1e32b06d8ba9511910467036f34d54e98d41 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sat, 18 Nov 2023 12:51:01 +0530 Subject: [PATCH 05/53] Delete inorder traversal/TreeNode.class --- inorder traversal/TreeNode.class | Bin 319 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 inorder traversal/TreeNode.class diff --git a/inorder traversal/TreeNode.class b/inorder traversal/TreeNode.class deleted file mode 100644 index d4badf481c5a509407b357271971eaa3f304222b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 319 zcmXw!Piw+J5XIjn(U^2KR_#A}=}~jgYr#@z3k5;!q2hg`Tf34*SYn|cs|P7~=m+SB zDt#O1Vc+Zwzj-tB^LzLPaEFT+9{do2L=AO;_C~#{QLc*h=qcOiWhqdX&parcXp{CjZ2byQz-l4rVQP(xT2}YV|+e3Q{k4YB4;yl v3a{%?Pncbkc6=}Wf=I<4p_68Mxkvl6qED$E1k{Kcphdqfn(RMg&BOU0Zcj3B From 204d5ed3e0854afad081191443051e9dbd835415 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:09:12 +0530 Subject: [PATCH 06/53] Add files via upload --- Strings/Medium/String to Integer/Readme.md | 481 ++++++++++++++++++ Strings/Medium/String to Integer/main.java | 26 + .../String to Integer/stringtointeger.cpp | 31 ++ .../String to Integer/stringtointeger.py | 40 ++ 4 files changed, 578 insertions(+) create mode 100644 Strings/Medium/String to Integer/Readme.md create mode 100644 Strings/Medium/String to Integer/main.java create mode 100644 Strings/Medium/String to Integer/stringtointeger.cpp create mode 100644 Strings/Medium/String to Integer/stringtointeger.py diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md new file mode 100644 index 00000000..00f5ce87 --- /dev/null +++ b/Strings/Medium/String to Integer/Readme.md @@ -0,0 +1,481 @@ +# Exploring Strings and Converting them to Integers : + +"Exploring Strings and Converting them to Integers" concept likely involves working with strings in a programming context and performing operations that involve converting these strings into integer values. + +**Exploring Strings** : This suggests that we will be working with strings, which are sequences of characters. Exploring strings may involve tasks such as accessing individual characters, finding the length of a string, or manipulating the content in various ways. +**Converting Strings to Integers** : The main task is likely to involve converting strings into integer values. This conversion is common in programming when dealing with user input or data read from external sources, where the input is initially in the form of text (string) but needs to be processed as numerical values (integers). + +# Introduction to Strings: + +A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. +Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. + +# Introduction to the String to Integer Theory: + +One of the frequent challenges encountered in programming involves converting strings to integers. This operation is particularly crucial when dealing with user inputs, file parsing, or scenarios where numeric values need extraction from a textual context. The process entails considering signs, handling leading whitespaces, and ensuring that the resulting integer falls within the appropriate range. + +# Overview of String to Integer: + +The problem involves working with strings, extracting numerical information from them, converting this information to integers, and potentially performing operations on these integers. The specific details would depend on the context and requirements of the problem as defined in the prompt or task description. +some of the common tasks that might encounter within this problem statement: + +**Parsing Integers** : Extracting numerical values from a string. This involves identifying and extracting the sequence of characters that represents an integer. + +**Handling Edge Cases** : Dealing with situations where the string may not represent a valid integer (e.g., contains non-numeric characters). Error handling may be required. + +**Performing Arithmetic Operations** : Once the strings are converted to integers, you might be asked to perform various arithmetic operations (addition, subtraction, multiplication, etc.) on these values. + +**Output Formatting** : Displaying the results in a specified format, which may involve converting integers back to strings for output. + +# PYTHON +# code +```python +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// python program to convert string to integer +// Stable: Yes +// Inplace: No +// Adaptive: Yes + +// Space complexity:O(n) +// Time complexity:O(1) + +def check(answer): + # Check if the answer is less than the minimum 32-bit signed integer + if answer < -2**31: + return -2**31 + # Check if the answer is greater than or equal to the maximum 32-bit signed integer + elif answer >= 2**31: + return 2**31 - 1 + else: + return answer + +def myAtoi(string): + # Initialize variables + answer = 0 + sign = 0 # 0 represents no sign, 1 represents positive sign, -1 represents negative sign + i = 0 + + # Skip leading whitespaces + while i < len(string) and string[i] == " ": + i += 1 + # If the entire string is composed of whitespaces, return the current answer + if i == len(string): + return answer + + # Check for positive sign + if string[i] == "+" and sign == 0: + sign = 1 + i += 1 + + # Check for negative sign + if i < len(string) and string[i] == "-" and sign == 0: + sign = -1 + i += 1 + + # Process the digits of the string + while i < len(string): + # Check if the current character is a digit + if string[i].isdigit(): + # Update the answer by multiplying it by 10 and adding the current digit + answer = answer * 10 + int(string[i]) + i += 1 + else: + # If a non-digit character is encountered, apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + + # Apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + +# Test the function with the provided string "42" +if __name__ == "__main__": + s = "42" + print(myAtoi(s)) + +``` +# Code Explanation + +1. **`check` function:** + ```python + def check(answer): + if answer < -2**31: + return -2**31 + elif answer >= 2**31: + return 2**31 - 1 + else: + return answer + ``` + - This function takes an `answer` as input and checks if it is within the range of a 32-bit signed integer. If it's less than the minimum value, it returns the minimum value. If it's greater than or equal to the maximum value, it returns the maximum value. Otherwise, it returns the original answer. + +2. **`myAtoi` function:** + ```python + def myAtoi(string): + answer = 0 + sign = 0 + i = 0 + + # Skip leading whitespaces + while i < len(string) and string[i] == " ": + i += 1 + if i == len(string): + return answer + + # Check for positive sign + if string[i] == "+" and sign == 0: + sign = 1 + i += 1 + + # Check for negative sign + if i < len(string) and string[i] == "-" and sign == 0: + sign = -1 + i += 1 + + # Process the digits of the string + while i < len(string): + if string[i].isdigit(): + # Update the answer by multiplying it by 10 and adding the current digit + answer = answer * 10 + int(string[i]) + i += 1 + else: + # If a non-digit character is encountered, apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + + # Apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + ``` + - This function takes a string `string` as input and converts it to an integer according to the rules specified. + - It initializes `answer` to store the result, `sign` to store the sign of the number, and `i` as an index to iterate through the string. + - It skips leading whitespaces in the string. + - It checks for positive or negative signs and sets the `sign` accordingly. + - It iterates through the string, processes digits, and updates the `answer`. + - If a non-digit character is encountered, it applies the sign if present and returns the result after checking for overflow using the `check` function. + - Finally, it returns the checked and signed result. + +3. **Test the function:** + ```python + if __name__ == "__main__": + s = "42" + print(myAtoi(s)) + ``` + - It tests the `myAtoi` function with the input string "42" and prints the result. + +The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of a 32-bit signed integer. The `check` function ensures that the result does not exceed the specified integer limits. + +# C++ +code +```c++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program to convert string to integer +// Stable: Yes +// Inplace: No +// Adaptive: No + +// Space complexity: O(n) +// Time complexity: O(1) + +#include + +int atoi(std::string s) +{ + int num = 0, i = 0, sign = 1; + while (s[i] == ' ') + { + i++; + } + if (i < s.length() && (s[i] == '-' || s[i] == '+')) + { + sign = s[i] == '+' ? 1 : -1; + i++; + } + while (i < s.length() && isdigit(s[i])) + { + + if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) + return sign == 1 ? INT_MAX : INT_MIN; + num = ((num * 10) + (s[i] - '0')); + i++; + } + return num * sign; +} + +int main() +{ + std::string s = "42"; + std::cout << atoi(s); + return 0; +} +``` +# Code Explanation + +1. **Function Definition:** + ```cpp + int myAtoi(const std::string &str) { + ``` + - The function `myAtoi` is defined, taking a constant reference to a `std::string` as input and returning an integer. + +2. **Variable Initialization:** + ```cpp + long result = 0; + int sign = 1; // 1 represents positive sign, -1 represents negative sign + size_t i = 0; + ``` + - Initialize `result` to store the converted integer. + - Initialize `sign` to 1 by default (positive sign). + - Initialize `i` as an index to iterate through the string. + +3. **Skip Leading Whitespaces:** + ```cpp + while (i < str.length() && isspace(str[i])) { + i++; + } + ``` + - Use a `while` loop to skip leading whitespaces in the input string. + +4. **Check for Positive or Negative Sign:** + ```cpp + if (i < str.length() && (str[i] == '+' || str[i] == '-')) { + sign = (str[i++] == '-') ? -1 : 1; + } + ``` + - Check for the presence of a positive or negative sign. + - Update the `sign` accordingly and increment `i` if a sign is found. + +5. **Process Digits:** + ```cpp + while (i < str.length() && isdigit(str[i])) { + result = result * 10 + (str[i++] - '0'); + + // Check for overflow + if (result * sign > INT_MAX) { + return INT_MAX; + } else if (result * sign < INT_MIN) { + return INT_MIN; + } + } + ``` + - Iterate through the string, processing digits and updating the `result`. + - Check for overflow by comparing against `INT_MAX` and `INT_MIN`. Return appropriate values if overflow is detected. + +6. **Apply Sign and Return Result:** + ```cpp + return static_cast(result * sign); + } + ``` + - Apply the sign to the result and return the final converted integer. + +7. **Main Function:** + ```cpp + int main() { + std::string s = "42"; + std::cout << myAtoi(s) << std::endl; + return 0; + } + ``` + - In the `main` function, a test string "42" is provided, and the result of the `myAtoi` function is printed. + +The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of an integer. The `myAtoi` function returns the converted integer, and the `main` function tests it with the string "42". + +# java +# code +```java +public class main{ + + static int atoi(String s) { + int num = 0, i = 0, sign = 1; + while (i < s.length() && s.charAt(i) == ' ') { + i++; + } + if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = s.charAt(i) == '+' ? 1 : -1; + i++; + } + while (i < s.length() && Character.isDigit(s.charAt(i))) { + int digit = s.charAt(i) - '0'; + if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + num = (num * 10) + digit; + i++; + } + return num * sign; + } + public static void main(String[] args) { + String s="42"; + System.out.println(atoi(s)); + } +} + +``` +# Code Explanation + +1. **Class Definition:** + ```java + public class Main { + ``` + - The class is named `Main`. + +2. **Static `atoi` Method:** + ```java + static int atoi(String s) { + ``` + - A static method named `atoi` is defined, which takes a `String` as input and returns an `int`. + +3. **Variable Initialization:** + ```java + int num = 0, i = 0, sign = 1; + ``` + - Initialize `num` to store the converted integer. + - Initialize `i` as an index to iterate through the string. + - Initialize `sign` to 1 by default (positive sign). + +4. **Skip Leading Whitespaces:** + ```java + while (i < s.length() && s.charAt(i) == ' ') { + i++; + } + ``` + - Use a `while` loop to skip leading whitespaces in the input string. + +5. **Check for Positive or Negative Sign:** + ```java + if (i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = s.charAt(i) == '+' ? 1 : -1; + i++; + } + ``` + - Check for the presence of a positive or negative sign. + - Update the `sign` accordingly and increment `i` if a sign is found. + +6. **Process Digits:** + ```java + while (i < s.length() && Character.isDigit(s.charAt(i))) { + int digit = s.charAt(i) - '0'; + if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + num = (num * 10) + digit; + i++; + } + ``` + - Iterate through the string, processing digits and updating the `num`. + - Check for overflow by comparing against `Integer.MAX_VALUE`. + - Return `Integer.MAX_VALUE` or `Integer.MIN_VALUE` if overflow is detected. + +7. **Return Result:** + ```java + return num * sign; + } + ``` + - Apply the sign to the result (`num`) and return the final converted integer. + +8. **Main Method:** + ```java + public static void main(String[] args) { + String s = "42"; + System.out.println(atoi(s)); + } + ``` + - The `main` method tests the `atoi` method with the string "42" and prints the result. + +The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of an integer. The `atoi` method returns the converted integer, and the `main` method tests it with the string "42". + +**Time and Space Complexity Analysis**: + +The time and space complexity for the atoi method, which converts a string to an integer. + +# Time Complexity: + +The time complexity of the atoi method is O(n), where n is the length of the input string. + + The while loop for skipping leading whitespaces runs in O(n) time because, in the worst case, it may have to iterate through the entire string. + The subsequent while loop for processing digits also runs in O(n) time, where n is the length of the string. This loop iterates through the digits of the string, and each iteration takes constant time. + +Therefore, the overall time complexity is O(n). +Space Complexity: + +The space complexity of the atoi method is O(1), constant space. + + The variables num, i, and sign are integers and require constant space regardless of the size of the input string. + No additional data structures are used that scale with the input size. + +The space complexity is constant or O(1). + +# Real-World Applications of string to integer + +Converting a string to an integer is a common operation in various real-world applications. Here are some examples: + +1. **User Input Processing:** + - In applications that accept user input, such as command-line interfaces or forms on websites, string-to-integer conversion is necessary to interpret numeric inputs provided by users. + +2. **Data Validation:** + - When dealing with external data sources, such as files or databases, where data is often represented as strings, converting relevant string values to integers is crucial for data validation and ensuring that the data meets expected numeric formats. + +3. **Parsing and Interpreting Configuration Files:** + - Many applications use configuration files to store settings. When reading these files, string-to-integer conversion is employed to interpret numeric configurations, such as specifying the number of threads, timeouts, or buffer sizes. + +4. **Network Protocols:** + - In network programming, especially when dealing with protocols that transmit data in string format, converting certain fields to integers is common. For instance, parsing HTTP headers or handling custom network protocols may involve converting string representations of numerical values to integers. + +5. **Database Operations:** + - In database applications, where data is often retrieved in string format, converting relevant data to integers is necessary for performing numerical operations or ensuring consistency in data types. + +6. **Mathematical Computations:** + - In scientific computing or applications involving mathematical calculations, converting strings to integers is essential when processing mathematical expressions or user-provided numerical data. + +7. **Financial Applications:** + - In financial software, handling monetary values often involves converting string representations of amounts to integers (or floating-point numbers) for accurate calculations. + +8. **Gaming and Graphics Programming:** + - Game development and graphics programming may require converting string representations of parameters, such as screen dimensions or frame rates, to integers for configuring the game environment or rendering settings. + +9. **Command-Line Interfaces (CLI):** + - CLI applications often take user inputs as strings, and converting these inputs to integers is necessary for executing numeric commands or configuring the behavior of the application. + +10. **Sensor Data Processing:** + - In embedded systems or IoT applications, sensor data received in string format may need to be converted to integers for further analysis or decision-making based on numeric thresholds. + +In essence, string-to-integer conversion is a fundamental operation in software development, as it facilitates the integration and processing of numerical information in various domains. +In addition to the real-world applications mentioned earlier, let's explore some theoretical scenarios or examples where string-to-integer conversion plays a crucial role: + +1. **Algorithmic Problem Solving:** + - In algorithmic problems, you may encounter scenarios where input is provided as strings, and converting these strings to integers is a common step. For example, when implementing algorithms that involve mathematical computations, sorting, or searching, converting string inputs to integers allows for efficient processing. + +2. **String Matching Algorithms:** + - String matching algorithms, such as the Knuth-Morris-Pratt algorithm or the Boyer-Moore algorithm, may involve comparing and manipulating string representations of integers. Converting these strings to integers allows for efficient pattern matching and searching. + +3. **Abstract Data Types (ADTs):** + - In the design and implementation of abstract data types, converting string representations of numerical data to actual integers is often necessary. For instance, when implementing a priority queue where elements are associated with numeric priorities provided as strings, conversion to integers is crucial for proper ordering. + +4. **Parsing and Interpretation of Domain-Specific Languages:** + - When working with domain-specific languages or custom file formats, interpreting and parsing string representations of numeric values is fundamental. Converting these strings to integers allows for the proper interpretation of data and execution of language-specific commands. + +5. **Code Analysis and Transformation:** + - In static code analysis or transformation tools, understanding and manipulating numeric constants within code may require converting string representations to integers. This is useful for performing optimizations, refactoring, or analyzing code patterns. + +6. **Symbolic Computation:** + - In symbolic computation systems, where algebraic expressions are manipulated symbolically, converting string representations of numeric coefficients or constants to actual integers is necessary for performing mathematical operations. + +7. **Formal Language Theory:** + - In formal language theory, automata, and compilers, parsing numeric literals from strings is a common operation. Converting these literals to integers is crucial for generating executable code or performing language analysis. + +8. **Graph Theory and Network Analysis:** + - When working with graph representations, especially in scenarios where nodes or edges are labeled with numeric identifiers provided as strings, converting these identifiers to integers facilitates efficient graph algorithms and analysis. + +9. **Cryptography:** + - In cryptographic applications, handling cryptographic keys or parameters, often represented as strings, may require converting these string representations to integers for cryptographic operations. + +10. **Educational Examples:** + - In educational contexts, when teaching programming or algorithms, string-to-integer conversion serves as a fundamental concept. Exercises and examples often involve converting user inputs or string data to integers for various purposes. + +In theoretical scenarios, the importance of string-to-integer conversion arises in the context of solving abstract problems, designing algorithms, and implementing various computational concepts. \ No newline at end of file diff --git a/Strings/Medium/String to Integer/main.java b/Strings/Medium/String to Integer/main.java new file mode 100644 index 00000000..bedd751b --- /dev/null +++ b/Strings/Medium/String to Integer/main.java @@ -0,0 +1,26 @@ +public class main{ + + static int atoi(String s) { + int num = 0, i = 0, sign = 1; + while (i < s.length() && s.charAt(i) == ' ') { + i++; + } + if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = s.charAt(i) == '+' ? 1 : -1; + i++; + } + while (i < s.length() && Character.isDigit(s.charAt(i))) { + int digit = s.charAt(i) - '0'; + if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + num = (num * 10) + digit; + i++; + } + return num * sign; + } + public static void main(String[] args) { + String s="42"; + System.out.println(atoi(s)); + } +} \ No newline at end of file diff --git a/Strings/Medium/String to Integer/stringtointeger.cpp b/Strings/Medium/String to Integer/stringtointeger.cpp new file mode 100644 index 00000000..bdb57305 --- /dev/null +++ b/Strings/Medium/String to Integer/stringtointeger.cpp @@ -0,0 +1,31 @@ +#include + +int atoi(std::string s) +{ + int num = 0, i = 0, sign = 1; + while (s[i] == ' ') + { + i++; + } + if (i < s.length() && (s[i] == '-' || s[i] == '+')) + { + sign = s[i] == '+' ? 1 : -1; + i++; + } + while (i < s.length() && isdigit(s[i])) + { + + if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) + return sign == 1 ? INT_MAX : INT_MIN; + num = ((num * 10) + (s[i] - '0')); + i++; + } + return num * sign; +} + +int main() +{ + std::string s = "42"; + std::cout << atoi(s); + return 0; +} \ No newline at end of file diff --git a/Strings/Medium/String to Integer/stringtointeger.py b/Strings/Medium/String to Integer/stringtointeger.py new file mode 100644 index 00000000..28122421 --- /dev/null +++ b/Strings/Medium/String to Integer/stringtointeger.py @@ -0,0 +1,40 @@ +def check(answer): + if answer<-2**31: + return -2**31 + elif answer>=2**31: + return 2**31-1 + else: + return answer + +def myAtoi(string): + answer=0 + sign=0 + i=0 + + while(i Date: Sun, 19 Nov 2023 17:12:41 +0530 Subject: [PATCH 07/53] Delete inorder traversal --- inorder traversal/BinaryTree.java | 51 ------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 inorder traversal/BinaryTree.java diff --git a/inorder traversal/BinaryTree.java b/inorder traversal/BinaryTree.java deleted file mode 100644 index 412a4948..00000000 --- a/inorder traversal/BinaryTree.java +++ /dev/null @@ -1,51 +0,0 @@ -class TreeNode { - int data; - // Store integer data - TreeNode left = null, - // Left child reference - right = null; - // Right child reference - - public TreeNode(int data) { - // Constructor to create a new TreeNode - this.data = data; - // Assign the given data to this node - } -} - -public class BinaryTree { -// Method for inorder traversal - - static void inorderTraversal(TreeNode root) { - if (root != null) { - inorderTraversal(root.left); - System.out.print(root.data + " "); - inorderTraversal(root.right); - } - } - - public static void main(String[] args) { - - // Creating a binary tree with root node having data 10 - TreeNode root = new TreeNode(10); - - // Adding nodes to the root of the created binary tree - // Adding left and right child nodes to the root - root.left = new TreeNode(20); - root.right = new TreeNode(30); - - // Adding left and right child nodes to the left child of the root - root.left.left = new TreeNode(40); - root.left.right = new TreeNode(50); - - // Adding left and right child nodes to the right child of the root - root.right.left = new TreeNode(60); - root.right.right = new TreeNode(70); - - // Printing the message before performing inorder traversal - System.out.print("Inorder Traversal: "); - - // Calling the inorderTraversal method to perform inorder traversal - inorderTraversal(root); - } -} \ No newline at end of file From cc09779ab3328d3ed6a5a85b65dedcaebea70653 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:14:17 +0530 Subject: [PATCH 08/53] Delete inorder traversal directory --- inorder traversal/Readme.md | 249 ---------------------------------- inorder traversal/inorder.cpp | 38 ------ inorder traversal/inorder.py | 26 ---- 3 files changed, 313 deletions(-) delete mode 100644 inorder traversal/Readme.md delete mode 100644 inorder traversal/inorder.cpp delete mode 100644 inorder traversal/inorder.py diff --git a/inorder traversal/Readme.md b/inorder traversal/Readme.md deleted file mode 100644 index 8e18794e..00000000 --- a/inorder traversal/Readme.md +++ /dev/null @@ -1,249 +0,0 @@ -# Exploring Binary Trees and Inorder Traversal - -## Introduction to Trees -A tree is a hierarchical data structure which is composed of nodes, where each node has at maximum two children and they are called as left child and right child. This interconnected system is reminiscent of an upside-down tree, with the topmost node called the root. In this structure, nodes hold data, and edges represent connections between nodes. Trees play a crucial role in computer science, serving as versatile tools for tasks such as searching, sorting, and analysis. Each node's ability to have multiple children allows for the creation of complex hierarchical relationships, making trees an indispensable concept for organizing and manipulating data efficiently. Whether utilized for representing hierarchical relationships, optimizing search algorithms, or structuring databases, trees form a foundational element in computer science, contributing to the systematic and effective management of information. - -## Introduction to Inorder Traversal -Inorder traversal is a method of traversing a binary tree in a specific order. It starts from the leftmost node and moves towards the rightmost node, visiting the left subtree first, then the root, and finally the right subtree. This traversal strategy is fundamental for exploring and processing binary trees systematically. - -## Overview -The provided Python code defines a binary tree node using a class named `Node` and demonstrates recursive inorder traversal. The `Node` class has a constructor initializing the node with some data and two pointers, `left` and `right`, representing the left and right children. - -## Step-by-Step Explanation - -# Using Python - -**Explanation:** - -1. **Node Class Definition:** - -```python -class Node: - def __init__(self, data): - self.data = data - self.left = self.right = None -``` - -This class defines the structure of a binary tree node. Each node has a data attribute to store the value of the node, and left and right attributes to point to the left and right children, respectively. - -2. **Inorder Traversal Function:** - -```python -def inorder(root): - if root: - inorder(root.left) - print(root.data, end=" ") - inorder(root.right) -``` - -This function, inorder, is a recursive implementation of the inorder traversal algorithm. It takes a root node as an argument and performs the following steps: -=> Check if the current root exists. -=> Recursively traverse the left subtree. -=> Print the value of the current node. -=> Recursively traverse the right subtree. - -3.**Driver Code and Tree Initialization** - -```python - if __name__ == "__main__": - root = Node(80) - root.left = Node(20) - root.right = Node(30) - root.left.left = Node(40) - root.left.right = Node(350) - root.right.left = Node(460) - root.right.right = Node(70) -``` - -In the __main__ block, a binary tree is created with the following structure: - - 80 - / \ - 20 30 - / \ / \ - 40 350 460 70 - - -4. **Inorder Traversal Call** - -```python - inorder(root) -``` - -This line calls the inorder function with the root of the tree, initiating the inorder traversal. The result is the values of the nodes printed in ascending order. - -In summary, the code defines a binary tree, initializes it with specific values, and then performs an inorder traversal, printing the values of the nodes in ascending order. The recursive nature of the inorder function is key to traversing the tree systematically. - -# using C++ - -**Explanation** - -1. **Header Inclusion**: - - ```cpp - #include - ``` - - This line includes a standard C++ library header, which is a common practice to include necessary headers like `` for input and output. - -2. **Node Class Definition:** - - ```cpp - class Node { - public: - int data; - Node *left = NULL; - Node *right = NULL; - - // Node constructor initializes data - Node(int val) { - data = val; - } - }; - ``` - - This part defines a `Node` class representing nodes in a binary tree. Each node contains an integer `data`, a pointer to the left child (`left`), and a pointer to the right child (`right`). The constructor initializes the node with the provided data value. - -3. **Inorder Traversal Function:** - - ```cpp - void inorder(Node* root) { - // call inorder for the left subtree - if (root != NULL) { - inorder(root->left); - // Print root node data - std::cout << root->data << " "; - // call inorder for the right subtree - inorder(root->right); - } - } - ``` - - The `inorder` function performs recursive inorder traversal on the binary tree. It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. - -4. **Main Function:** - - ```cpp - int main() { - // Creating the binary tree - Node* root = new Node(10); - root->left = new Node(20); - root->right = new Node(30); - root->left->left = new Node(40); - root->left->right = new Node(50); - root->right->left = new Node(60); - root->right->right = new Node(70); - - // Displaying the binary tree in inorder traversal - inorder(root); - - // Inorder traversal of the tree - return 0; - } - ``` - - In the `main` function, a binary tree is created with specific values. Nodes are allocated dynamically using the `new` keyword. The `inorder` function is then called to display the binary tree in inorder traversal, printing the values of the nodes in ascending order. - -In summary, this C++ program defines a binary tree using a `Node` class, creates a binary tree with specific values, and performs an inorder traversal to display the tree's content. The code demonstrates the concept of recursive traversal in a binary tree. -This code will output `40 20 50 10 60 30 70`, which is a correct - -# using Java - -**explanation** - -1. **TreeNode Class Definition:** - ```java - class TreeNode { - int data; - TreeNode left = null, right = null; - - public TreeNode(int data) { - this.data = data; - } - } - ``` - - - `TreeNode` class defines the structure of a binary tree node. - - It has an `int` variable `data` to store the node's value and references (`left` and `right`) to its left and right children. - - The constructor initializes a new `TreeNode` with the given data. - -2. **BinaryTree Class:** - ```java - public class BinaryTree { - // Method for inorder traversal - - static void inorderTraversal(TreeNode root) { - if (root != null) { - inorderTraversal(root.left); - System.out.print(root.data + " "); - inorderTraversal(root.right); - } - } - ``` - - This class contains a method `inorderTraversal` that performs recursive inorder traversal on a binary tree. - - It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. - - InorderTraversal` is a static method used for inorder traversal of the binary tree. - - It is a recursive function that traverses the left subtree, prints the data of the current node, and then traverses the right subtree. - -3. **Main Method:** - ```java - public static void main(String[] args) { - // Creating a binary tree with root node having data 10 - TreeNode root = new TreeNode(10); - - // Adding nodes to the root of the created binary tree - // Adding left and right child nodes to the root - root.left = new TreeNode(20); - root.right = new TreeNode(30); - - // Adding left and right child nodes to the left child of the root - root.left.left = new TreeNode(40); - root.left.right = new TreeNode(50); - - // Adding left and right child nodes to the right child of the root - root.right.left = new TreeNode(60); - root.right.right = new TreeNode(70); - - // Printing the message before performing inorder traversal - System.out.print("Inorder Traversal: "); - - // Calling the inorderTraversal method to perform inorder traversal - inorderTraversal(root); - } - ``` - - - The `main` method is the entry point of the program. - - It creates an instance of the `TreeNode` class, representing the root of the binary tree, with a data value of 10. - - Child nodes are added to the root, forming a binary tree structure. - - The `inorderTraversal` method is called to perform an inorder traversal of the tree, printing the nodes in ascending order. - - -4. **Tree Structure:** - ``` - 10 - / \ - 20 30 - / \ / \ - 40 50 60 70 - ``` - -5. **Output:** - ``` - Inorder Traversal: 40 20 50 10 60 30 70 - ``` - -In summary, this Java program demonstrates the creation of a binary tree, addition of nodes, and the execution of an inorder traversal. The `TreeNode` class encapsulates the node structure, and the `BinaryTree` class utilizes it to construct and traverse the binary tree. - - -## Time and Space Complexity Analysis -- Time Complexity: The time complexity of the inorder traversal is O(n), where n is the number of nodes in the tree. This is because each node is visited once. -- Space Complexity: The space complexity is O(h), where h is the height of the binary tree. In the worst case (skewed tree), the height is n, making the space complexity O(n). In a balanced tree, the height is log(n), resulting in a space complexity of O(log(n)). - -## Real-World Applications -Binary trees and inorder traversal have applications in various domains, including: -- **Database Indexing:** Binary trees are used in database systems to efficiently index and search for records. -- **Expression Trees:** In compilers, expression trees are used to represent mathematical expressions for efficient evaluation. -- **File Systems:** File systems often use tree structures to organize and locate files efficiently. - -## Conclusion -Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. \ No newline at end of file diff --git a/inorder traversal/inorder.cpp b/inorder traversal/inorder.cpp deleted file mode 100644 index 2d38d517..00000000 --- a/inorder traversal/inorder.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include - -class Node{ - public: - int data; - Node *left=NULL; - Node *right=NULL; - - // Node constructor initializes data - Node(int val){ - data=val; - } -}; -void inorder(Node* root){ - // call inorder for left subtree - if(root!=NULL){ - inorder(root->left); - // Print root node data - std::cout<data<<" "; - // call inorder for right subtree - inorder(root->right); - } -} - -int main(){ - // Creating the binary tree - Node* root=new Node(10); - root->left=new Node(20); - root->right=new Node(30); - root->left->left=new Node(40); - root->left->right=new Node(50); - root->right->left=new Node(60); - root->right->right=new Node(70); - // Displaying the binary tree in inorder traversal - inorder(root); - // Inorder traversal of the tree - return 0; -} \ No newline at end of file diff --git a/inorder traversal/inorder.py b/inorder traversal/inorder.py deleted file mode 100644 index 9204581a..00000000 --- a/inorder traversal/inorder.py +++ /dev/null @@ -1,26 +0,0 @@ -# Definition for a binary tree node -class Node: - def __init__(self,data): - self.data=data - self.left=self.right=None -# Recursive Inorder Traversal. -def inorder(root): - # Check if the root exists - if root: - # Perform an inorder traversal on the left subtree - inorder(root.left) - # Print the value of the current node - print(root.data,end=" ") - # Perform an inorder traversal on the right subtree - inorder(root.right) - # Driver code to test above function -# The values of nodes are given below : -if __name__=="__main__": - root=Node(80) - root.left=Node(20) - root.right=Node(30) - root.left.left=Node(40) - root.left.right=Node(350) - root.right.left=Node(460) - root.right.right=Node(70) - inorder(root) From 8e08c3333f3c7a55df6c97394ef159945c298913 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:18:31 +0530 Subject: [PATCH 09/53] Add files via upload --- Trees/Easy/Inorder Traversal/BinaryTree.java | 51 +++ Trees/Easy/Inorder Traversal/Readme.md | 373 +++++++++++++++++++ Trees/Easy/Inorder Traversal/inorder.cpp | 38 ++ Trees/Easy/Inorder Traversal/inorder.py | 26 ++ 4 files changed, 488 insertions(+) create mode 100644 Trees/Easy/Inorder Traversal/BinaryTree.java create mode 100644 Trees/Easy/Inorder Traversal/Readme.md create mode 100644 Trees/Easy/Inorder Traversal/inorder.cpp create mode 100644 Trees/Easy/Inorder Traversal/inorder.py diff --git a/Trees/Easy/Inorder Traversal/BinaryTree.java b/Trees/Easy/Inorder Traversal/BinaryTree.java new file mode 100644 index 00000000..14f798bf --- /dev/null +++ b/Trees/Easy/Inorder Traversal/BinaryTree.java @@ -0,0 +1,51 @@ +class TreeNode { + int data; + // Store integer data + TreeNode left = null, + // Left child reference + right = null; + // Right child reference + + public TreeNode(int data) { + // Constructor to create a new TreeNode + this.data = data; + // Assign the given data to this node + } +} + +public class BinaryTree { +// Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + + public static void main(String[] args) { + + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } +} \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/Readme.md b/Trees/Easy/Inorder Traversal/Readme.md new file mode 100644 index 00000000..d8829cd0 --- /dev/null +++ b/Trees/Easy/Inorder Traversal/Readme.md @@ -0,0 +1,373 @@ +# Exploring Binary Trees and Inorder Traversal + +## Introduction to Trees +A tree is a hierarchical data structure which is composed of nodes, where each node has at maximum two children and they are called as left child and right child. This interconnected system is reminiscent of an upside-down tree, with the topmost node called the root. In this structure, nodes hold data, and edges represent connections between nodes. Trees play a crucial role in computer science, serving as versatile tools for tasks such as searching, sorting, and analysis. Each node's ability to have multiple children allows for the creation of complex hierarchical relationships, making trees an indispensable concept for organizing and manipulating data efficiently. Whether utilized for representing hierarchical relationships, optimizing search algorithms, or structuring databases, trees form a foundational element in computer science, contributing to the systematic and effective management of information. + +## Introduction to Inorder Traversal +Inorder traversal is a method of traversing a binary tree in a specific order. It starts from the leftmost node and moves towards the rightmost node, visiting the left subtree first, then the root, and finally the right subtree. This traversal strategy is fundamental for exploring and processing binary trees systematically. + +## Overview +The provided Python code defines a binary tree node using a class named `Node` and demonstrates recursive inorder traversal. The `Node` class has a constructor initializing the node with some data and two pointers, `left` and `right`, representing the left and right children. + +## Step-by-Step Explanation + +# Using Python +# code + +```python +class Node: + def __init__(self,data): + self.data=data + self.left=self.right=None +# Recursive Inorder Traversal. +def inorder(root): + # Check if the root exists + if root: + # Perform an inorder traversal on the left subtree + inorder(root.left) + # Print the value of the current node + print(root.data,end=" ") + # Perform an inorder traversal on the right subtree + inorder(root.right) + # Driver code to test above function +# The values of nodes are given below : +if __name__=="__main__": + root=Node(80) + root.left=Node(20) + root.right=Node(30) + root.left.left=Node(40) + root.left.right=Node(350) + root.right.left=Node(460) + root.right.right=Node(70) + inorder(root) +``` + +**Explanation:** + +1. **Node Class Definition:** + +```python +class Node: + def __init__(self, data): + self.data = data + self.left = self.right = None +``` + +This class defines the structure of a binary tree node. Each node has a data attribute to store the value of the node, and left and right attributes to point to the left and right children, respectively. + +2. **Inorder Traversal Function:** + +```python +def inorder(root): + if root: + inorder(root.left) + print(root.data, end=" ") + inorder(root.right) +``` + +This function, inorder, is a recursive implementation of the inorder traversal algorithm. It takes a root node as an argument and performs the following steps: +=> Check if the current root exists. +=> Recursively traverse the left subtree. +=> Print the value of the current node. +=> Recursively traverse the right subtree. + +3.**Driver Code and Tree Initialization** + +```python + if __name__ == "__main__": + root = Node(80) + root.left = Node(20) + root.right = Node(30) + root.left.left = Node(40) + root.left.right = Node(350) + root.right.left = Node(460) + root.right.right = Node(70) +``` + +In the __main__ block, a binary tree is created with the following structure: + + 80 + / \ + 20 30 + / \ / \ + 40 350 460 70 + + +4. **Inorder Traversal Call** + +```python + inorder(root) +``` + +This line calls the inorder function with the root of the tree, initiating the inorder traversal. The result is the values of the nodes printed in ascending order. + +In summary, the code defines a binary tree, initializes it with specific values, and then performs an inorder traversal, printing the values of the nodes in ascending order. The recursive nature of the inorder function is key to traversing the tree systematically. + +# using C++ +# code +```c++ +#include + +class Node{ + public: + int data; + Node *left=NULL; + Node *right=NULL; + + // Node constructor initializes data + Node(int val){ + data=val; + } +}; +void inorder(Node* root){ + // call inorder for left subtree + if(root!=NULL){ + inorder(root->left); + // Print root node data + std::cout<data<<" "; + // call inorder for right subtree + inorder(root->right); + } +} + +int main(){ + // Creating the binary tree + Node* root=new Node(10); + root->left=new Node(20); + root->right=new Node(30); + root->left->left=new Node(40); + root->left->right=new Node(50); + root->right->left=new Node(60); + root->right->right=new Node(70); + // Displaying the binary tree in inorder traversal + inorder(root); + // Inorder traversal of the tree + return 0; +} +``` +**Explanation** + +1. **Header Inclusion**: + + ```cpp + #include + ``` + + This line includes a standard C++ library header, which is a common practice to include necessary headers like `` for input and output. + +2. **Node Class Definition:** + + ```cpp + class Node { + public: + int data; + Node *left = NULL; + Node *right = NULL; + + // Node constructor initializes data + Node(int val) { + data = val; + } + }; + ``` + + This part defines a `Node` class representing nodes in a binary tree. Each node contains an integer `data`, a pointer to the left child (`left`), and a pointer to the right child (`right`). The constructor initializes the node with the provided data value. + +3. **Inorder Traversal Function:** + + ```cpp + void inorder(Node* root) { + // call inorder for the left subtree + if (root != NULL) { + inorder(root->left); + // Print root node data + std::cout << root->data << " "; + // call inorder for the right subtree + inorder(root->right); + } + } + ``` + + The `inorder` function performs recursive inorder traversal on the binary tree. It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. + +4. **Main Function:** + + ```cpp + int main() { + // Creating the binary tree + Node* root = new Node(10); + root->left = new Node(20); + root->right = new Node(30); + root->left->left = new Node(40); + root->left->right = new Node(50); + root->right->left = new Node(60); + root->right->right = new Node(70); + + // Displaying the binary tree in inorder traversal + inorder(root); + + // Inorder traversal of the tree + return 0; + } + ``` + + In the `main` function, a binary tree is created with specific values. Nodes are allocated dynamically using the `new` keyword. The `inorder` function is then called to display the binary tree in inorder traversal, printing the values of the nodes in ascending order. + +In summary, this C++ program defines a binary tree using a `Node` class, creates a binary tree with specific values, and performs an inorder traversal to display the tree's content. The code demonstrates the concept of recursive traversal in a binary tree. +This code will output `40 20 50 10 60 30 70`, which is a correct + +# using Java +# Code + +```java +class TreeNode { + int data; + // Store integer data + TreeNode left = null, + // Left child reference + right = null; + // Right child reference + + public TreeNode(int data) { + // Constructor to create a new TreeNode + this.data = data; + // Assign the given data to this node + } +} + +public class BinaryTree { +// Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + + public static void main(String[] args) { + + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } +} + +``` +**explanation** + +1. **TreeNode Class Definition:** + ```java + class TreeNode { + int data; + TreeNode left = null, right = null; + + public TreeNode(int data) { + this.data = data; + } + } + ``` + + - `TreeNode` class defines the structure of a binary tree node. + - It has an `int` variable `data` to store the node's value and references (`left` and `right`) to its left and right children. + - The constructor initializes a new `TreeNode` with the given data. + +2. **BinaryTree Class:** + ```java + public class BinaryTree { + // Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + ``` + - This class contains a method `inorderTraversal` that performs recursive inorder traversal on a binary tree. + - It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. + - InorderTraversal` is a static method used for inorder traversal of the binary tree. + - It is a recursive function that traverses the left subtree, prints the data of the current node, and then traverses the right subtree. + +3. **Main Method:** + ```java + public static void main(String[] args) { + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } + ``` + + - The `main` method is the entry point of the program. + - It creates an instance of the `TreeNode` class, representing the root of the binary tree, with a data value of 10. + - Child nodes are added to the root, forming a binary tree structure. + - The `inorderTraversal` method is called to perform an inorder traversal of the tree, printing the nodes in ascending order. + + +4. **Tree Structure:** + ``` + 10 + / \ + 20 30 + / \ / \ + 40 50 60 70 + ``` + +5. **Output:** + ``` + Inorder Traversal: 40 20 50 10 60 30 70 + ``` + +In summary, this Java program demonstrates the creation of a binary tree, addition of nodes, and the execution of an inorder traversal. The `TreeNode` class encapsulates the node structure, and the `BinaryTree` class utilizes it to construct and traverse the binary tree. + + +## Time and Space Complexity Analysis +- Time Complexity: The time complexity of the inorder traversal is O(n), where n is the number of nodes in the tree. This is because each node is visited once. +- Space Complexity: The space complexity is O(h), where h is the height of the binary tree. In the worst case (skewed tree), the height is n, making the space complexity O(n). In a balanced tree, the height is log(n), resulting in a space complexity of O(log(n)). + +## Real-World Applications +Binary trees and inorder traversal have applications in various domains, including: +- **Database Indexing:** Binary trees are used in database systems to efficiently index and search for records. +- **Expression Trees:** In compilers, expression trees are used to represent mathematical expressions for efficient evaluation. +- **File Systems:** File systems often use tree structures to organize and locate files efficiently. + +## Conclusion +Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/inorder.cpp b/Trees/Easy/Inorder Traversal/inorder.cpp new file mode 100644 index 00000000..2c04554e --- /dev/null +++ b/Trees/Easy/Inorder Traversal/inorder.cpp @@ -0,0 +1,38 @@ +#include + +class Node{ + public: + int data; + Node *left=NULL; + Node *right=NULL; + + // Node constructor initializes data + Node(int val){ + data=val; + } +}; +void inorder(Node* root){ + // call inorder for left subtree + if(root!=NULL){ + inorder(root->left); + // Print root node data + std::cout<data<<" "; + // call inorder for right subtree + inorder(root->right); + } +} + +int main(){ + // Creating the binary tree + Node* root=new Node(10); + root->left=new Node(20); + root->right=new Node(30); + root->left->left=new Node(40); + root->left->right=new Node(50); + root->right->left=new Node(60); + root->right->right=new Node(70); + // Displaying the binary tree in inorder traversal + inorder(root); + // Inorder traversal of the tree + return 0; +} \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/inorder.py b/Trees/Easy/Inorder Traversal/inorder.py new file mode 100644 index 00000000..cb629501 --- /dev/null +++ b/Trees/Easy/Inorder Traversal/inorder.py @@ -0,0 +1,26 @@ +# Definition for a binary tree node +class Node: + def __init__(self,data): + self.data=data + self.left=self.right=None +# Recursive Inorder Traversal. +def inorder(root): + # Check if the root exists + if root: + # Perform an inorder traversal on the left subtree + inorder(root.left) + # Print the value of the current node + print(root.data,end=" ") + # Perform an inorder traversal on the right subtree + inorder(root.right) + # Driver code to test above function +# The values of nodes are given below : +if __name__=="__main__": + root=Node(80) + root.left=Node(20) + root.right=Node(30) + root.left.left=Node(40) + root.left.right=Node(350) + root.right.left=Node(460) + root.right.right=Node(70) + inorder(root) \ No newline at end of file From 3362f3858ac0713a6b332b9c198957ac0b6b27eb Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:33:00 +0530 Subject: [PATCH 10/53] Delete NQueen.md --- NQueen.md | 431 ------------------------------------------------------ 1 file changed, 431 deletions(-) delete mode 100644 NQueen.md diff --git a/NQueen.md b/NQueen.md deleted file mode 100644 index 63e25db6..00000000 --- a/NQueen.md +++ /dev/null @@ -1,431 +0,0 @@ -# Exploring Backtracking Algorithm:N Queen Problem - -Today, we dive into the fascinating world of backtracking algorithms and uncover one of their most captivating mysteries – backtracking algorithms. Get ready to embark on an adventure that will challenge your mind and leave you with newfound insights into the power of backtracking! - -## **Introduction to Backtracking Algorithm** - -The backtracking algorithm is a powerful technique used to solve problems that can be broken down into a series of decisions. It is commonly employed in constraint satisfaction problems, combinatorial optimization, and other algorithmic challenges where exhaustive search is necessary. Backtracking involves a systematic search through the space of all possible solutions. - -Problems associated with backtracking can be categorized into 3 categories: - -- **Decision Problems:** Here, we search for a feasible solution. -- **Optimization Problems:** For this type of problems, we search for the best solution. -- **Enumeration Problems:** We find set of all possible feasible solutions to the problems of this type. - -The backtracking algorithm can be used to solve various problems such as the N-Queens problem, the Sudoku puzzle, graph coloring problems, and other constraint satisfaction problems. Its ability to systematically explore all possible solutions makes it a fundamental technique in the field of algorithm design and optimization. However, it is important to note that the efficiency of the backtracking algorithm depends on the reducing of the search space and the identification of constraints to reduce unnecessary exploration. - -## **N Queen Problem** - -The N-Queens problem is a classic puzzle that involves placing N chess queens on an N×N chessboard in such a way that no two queens can threaten each other. In chess, a queen can move horizontally, vertically, and diagonally, which means that no two queens should share the same row, column, or diagonal on the chessboard. - -The primary goal of the N-Queens problem is to find a placement of N queens on an N×N chessboard so that no two queens can attack each other. This requires a systematic approach to exploring possible configurations while adhering to the constraints imposed by the rules of chess. One of the key challenges is to find an efficient algorithm to solve the problem, especially for larger values of N, as the search space grows exponentially with N. - -The N-Queens problem serves as a benchmark for evaluating various algorithms, particularly those involving backtracking, constraint satisfaction, and combinatorial optimization. - -Solving the N-Queens problem efficiently demonstrates the ability to design algorithms that can systematically explore and navigate complex search spaces, making it a fundamental problem in the field of algorithm design and optimization. - -## Overview Of Backtracking Algorithm - -The N-Queens problem algorithm is a classic example of a backtracking algorithm, and it is used to solve the N-Queens puzzle. The goal of the N-Queens puzzle is to place N chess queens on an N×N chessboard in such a way that no two queens can attack each other, i.e., no two queens can share the same row, column, or diagonal. In this section, we will provide an overview of the backtracking algorithm and discuss its implementation. - -Backtracking involves constructing a solution incrementally, making a series of choices to build a candidate solution one step at a time. - -The algorithm systematically explores the solution space by making a decision at each step and recursively exploring all possible choices, while maintaining a record of the choices made. - -At each step, the algorithm checks whether the current partial solution violates any constraints. If the constraints are violated, it abandons that branch of the search space and backtracks to the previous decision point. - -Backtracking is typically implemented using recursion. The recursive nature allows the algorithm to go deeper into the search space and backtrack to explore alternative choices when needed. - -## Code - -```python -# Copyrights to venkys.io -# For more programs visit venkys.io -# Python program for NQeens - -# Function to take user input -def getBoard(n): - result=[] - board=[[0 for i in range(n)] for j in range(n)] - return board,result -# result=[] - -# Function to print board -def printboard(board,n): - for i in range(n): - for j in range(n): - if board[i][j]: - print("Q",end=" ") - else: - print("_",end=" ") - print() - -# Function to check if the given box is safe or not -def isSafe(board,row,col): - - # For same row - for i in range(col): - if board[row][i]: - return False - - # For same column - for i in range(row): - if board[i][col]: - return False - - - # For left upper diagonal - i=row - j=col - while i>=0 and j>=0: - if board[i][j]: - return False - i-=1 - j-=1 - - # For right upper diagonal - i=row - j=col - while j>=0 and i= 0 && r >= 0; c--, r--) { - if (board[r][c] == 'Q') { - return false; - } - } - // upper right - r = row; - for (int c = col; c < board.length && r >= 0; c++, r--) { - if (board[r][c] == 'Q') { - return false; - } - } - // lower left - r = row; - for (int c = col; c >= 0 && r < board.length; c--, r++) { - if (board[r][c] == 'Q') { - return false; - } - } - // lower right - r = row; - for (int c = col; r < board.length && c < board.length; r++, c++) { - if (board[r][c] == 'Q') { - return false; - } - } - return true; - } - - // updating the queen position in board - public static void saveBoard(char[][] board, List> allBoards) { - String row; - List newBoard = new ArrayList<>(); - for (int i = 0; i < board.length; i++) { - row = ""; - for (int j = 0; j < board[0].length; j++) { - if (board[i][j] == 'Q') { - row += 'Q'; - System.out.print("Q"+" "); - } else { - row += '.'; - System.out.print("_"+" "); - } - } - System.out.println(); - newBoard.add(row); - } - allBoards.add(newBoard); - System.out.println("------------------------"); - } - - // placing the queen in correct position in board - public static void helper(char[][] board, List> allBoards, int col) { - if (col == board.length) { - saveBoard(board, allBoards); - return; - } - for (int row = 0; row < board.length; row++) { - if (isSafe(row, col, board)) { - board[row][col] = 'Q'; - helper(board, allBoards, col + 1); - board[row][col] = '.'; - } - } - } - - // return board after placing the queen - public static List> solveQueens(int n) { - List> allBoards = new ArrayList<>(); - char[][] board = new char[n][n]; - helper(board, allBoards, 0); - return allBoards; - } - - public static void main(String[] args) { - - int n = 4; - - List> lst = solveQueens(n); - System.out.println("Queen can be placed in chess board by the following code:"); - System.out.println(lst); - } -} -``` - -## Explanation - -Now we have the basic understanding of backtracking algorithm and the concept of N queen problem. - -Let’s dive into the step-by-step process of placing N queens on a board using backtracking. - -[1.Is](http://1.Is)safe Function: - -In the first step the ‘isSafe’ function checks whether placing a queen at a given position is safe, considering the row, column, and both diagonals. - -2.saveBoard Function - -In the next step the ‘saveBoard’ function prints the current chessboard configuration and saves it in a list. - -3.helper Function - -In this step the ‘helper’ function is a recursive backtracking function that tries to place queens column-wise, ensuring that they do not attack each other. It calls ‘saveBoard’ when a valid placement is found. - -4.solveQueen Function - -In this step the ‘solveQueens’ function initializes the chessboard and calls the ‘helper’ function to find all valid configurations. - -5.main Function - -In the ‘main’ function, the program sets ‘n’ to 4 (you can change it to solve for different board sizes) and then calls ‘solveQueens’. The resulting configurations are printed. - -## Code - -```cpp -// Copyrights to venkys.io -// For more programs visit venkys.io -// CPP program for NQeens - -#include - -using namespace std; - -bool isSafe(int row,int col,vector> &board){ - for(int j=0;j=0 && r>=0; c--,r--){ - if(board[r][c] == 'Q'){ - return false; - } - } - - for(int r=row,c=col;c>=0 && r< board.size();c--,r++){ - if(board[r][c] == 'Q') return false; - } - return true; - -} - -void saveBoard(vector> board,vector> allBoards){ - string row; - vector newBoard; - for(int i=0;i> board,vector> allBoards,int col){ - if(col == board.size()){ - saveBoard(board,allBoards); - return ; - } - for(int row=0;row> solveQueens(int n){ - vector> allBoards; - vector> board(n,vector(n,'.')); - helper(board,allBoards,0); - return allBoards; - -} - -int main(){ - - int n=4; - vector> lst = solveQueens(n); - cout<<"Queen can be placed in chess board by the following code"< Date: Mon, 4 Dec 2023 20:42:01 +0530 Subject: [PATCH 11/53] Add files via upload added palindrome partitioning --- Strings/Medium/PalindromePartitioning.java | 39 +++ Strings/Medium/Readme.md | 379 +++++++++++++++++++++ Strings/Medium/palindromepartition.py | 22 ++ Strings/Medium/palindrompartition.c++ | 53 +++ 4 files changed, 493 insertions(+) create mode 100644 Strings/Medium/PalindromePartitioning.java create mode 100644 Strings/Medium/Readme.md create mode 100644 Strings/Medium/palindromepartition.py create mode 100644 Strings/Medium/palindrompartition.c++ diff --git a/Strings/Medium/PalindromePartitioning.java b/Strings/Medium/PalindromePartitioning.java new file mode 100644 index 00000000..d7a87445 --- /dev/null +++ b/Strings/Medium/PalindromePartitioning.java @@ -0,0 +1,39 @@ +import java.util.ArrayList; +import java.util.List; + +class PalindromePartitioning { + static boolean checkPalindrome(String str, int startIndex, int lastIndex){ + while(startIndex <= lastIndex){ + if(str.charAt(startIndex) != str.charAt(lastIndex)) + return false; + startIndex++; + lastIndex--; + } + return true; + } + static void palindromePartition(int index, List ds, List> output, String str){ + if(index == str.length()){ + output.add(new ArrayList<>(ds)); + return; + } + for(int i = index; i < str.length(); i++){ + if(checkPalindrome(str, index, i)){ + ds.add(str.substring(index, i + 1)); + palindromePartition(i+1, ds, output, str); + ds.remove(ds.size()-1); + } + } + } + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s="aab"; + System.out.println(partition(s)); + } + +} \ No newline at end of file diff --git a/Strings/Medium/Readme.md b/Strings/Medium/Readme.md new file mode 100644 index 00000000..a7f6163f --- /dev/null +++ b/Strings/Medium/Readme.md @@ -0,0 +1,379 @@ +# Exploring palindrome partitioning using Strings: + +Exploring palindrome partitioning with strings often involves dynamic programming. The idea is to build a table or array to store intermediate results, helping to avoid redundant computations and improve the overall efficiency of the algorithm. + +# Introduction to Strings: + +A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. +Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. + +# Introduction to the Palindrome Partitioning Theory: + +A palindrome is a sequence of characters that reads the same backward as forward. Examples include "level," "radar," and "madam". Palindrome partitioning is a concept in theoretical computer science and mathematics that involves breaking down a string into substrings, with the condition that each substring is a palindrome.The goal of palindrome partitioning is to find all possible ways to split a given string into palindromic substrings. + +# Overview of Palindrome Partitioning: + +Given a string, the problem is to find all possible ways to partition it into palindromic substrings. + +# PYTHON +# code + +```python +# Copyrights to venkys.io +# For more information, visit https://venkys.io + +# python program for Palindrome Partitioning +# Stable: No +# Inplace: No +# Adaptive: Not Applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) + +# Space complexity:O(n^2) +# Time complexity:O(n^2) + +def partition(string): + # Initialize dynamic programming array + dp=[[] for _ in range(len(string)+1)] + + # Initialize the first state with an empty partition + dp[0]=[[]] + +# Iterate over each character of the string + for j in range(1,len(string)+1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j]==string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each+[string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +if __name__=="__main__": + string="ababa" + print(partition(string)) +``` +# Code Explanation + +1. **Dynamic Programming Array (`dp`):** + - `dp` is a list of lists used for dynamic programming. It represents the state of the algorithm at each position in the input string. + +2. **Initialization:** + - `dp[0]` is initialized with an empty list representing the empty partition for the first state. + +3. **Iterating Over Characters (`j`):** + - The outer loop (`for j in range(1, len(string) + 1)`) iterates over each character in the input string, starting from the second character. + +4. **Iterating Over Previous Characters (`i`):** + - The inner loop (`for i in range(j)`) iterates through each previous character (from the beginning of the string up to `j`). + +5. **Palindrome Check:** + - `if string[i:j] == string[i:j][::-1]:` checks if the substring from `i` to `j` is a palindrome. + +6. **Updating Partitions:** + - If the substring is a palindrome, it extends the partitions ending at position `i` with the palindrome substring. It uses a nested loop to iterate through each existing partition at position `i` (`for each in dp[i]`) and appends the current palindrome substring to create new partitions. + +7. **Final Result:** + - The final state is represented by `dp[-1]`, which contains all valid partitions, and it is returned as the output of the function. + +8. **Example Usage:** + - The provided example with `string = "ababa"` demonstrates how the function can be called and prints the result of partitioning the given string into palindromic substrings. + +The algorithm employs dynamic programming to efficiently find and extend palindrome partitions in the input string. + +# C++ +# code + +```C++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program Palindrome Partitioning +// Stable: No +// Inplace:No +// Adaptive: Not applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) + +// Space complexity:O(n^2) +// Time complexity:O(n^2) + +#include +bool isPalindrome(std::string s, int i, int j) { + // While loop checks the string symmetrically. + while (i <= j) { + // If characters at different ends don't match, it's not a palindrome. + if (s[i++] != s[j--]) return false; + } + // If loop finished, the string is a palindrome. + return true; +} +void util(int i,std::string s,std::vector>& res,std::vector& path){ + // base case: when string s is fully processed + if(i==s.size()){ + res.push_back(path); + return ; + } + // iteratively checking each substring + for(int j=i;j> partition (std::string s){ + // Output list of all palindrome partitions + std::vector> res; + // List to keep track of the current path + std::vector path; + // Utility function to find all palindrome partitions + util(0,s,res,path); + return res; +} +int main(){ + // initial string to be partitioned + std::string s = "aaab"; + // function call to get all partitions + std::vector> ans=partition(s); + // loop to print all partitions + for(auto& a:ans){ + for(auto& b:a){ + std::cout< ds, List> output, String str){ + if(index == str.length()){ + output.add(new ArrayList<>(ds)); + return; + } + for(int i = index; i < str.length(); i++){ + if(checkPalindrome(str, index, i)){ + ds.add(str.substring(index, i + 1)); + palindromePartition(i+1, ds, output, str); + ds.remove(ds.size()-1); + } + } + } + + // Main function to return all the palindrome partitioning + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s="aab"; + System.out.println(partition(s)); + } + +} + +``` +# Code Explanation + +Certainly! Let's break down the provided Java code step by step: + +```java +import java.util.ArrayList; +import java.util.List; + +class PalindromePartitioning { + + // Function to check if a substring is a palindrome + static boolean checkPalindrome(String str, int startIndex, int lastIndex) { + while (startIndex <= lastIndex) { + if (str.charAt(startIndex) != str.charAt(lastIndex)) + return false; + startIndex++; + lastIndex--; + } + return true; + } + + // Function to generate all the palindrome partitioning + static void palindromePartition(int index, List ds, List> output, String str) { + if (index == str.length()) { + output.add(new ArrayList<>(ds)); + return; + } + for (int i = index; i < str.length(); i++) { + if (checkPalindrome(str, index, i)) { + ds.add(str.substring(index, i + 1)); + palindromePartition(i + 1, ds, output, str); + ds.remove(ds.size() - 1); + } + } + } + + // Main function to return all the palindrome partitioning + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s = "aab"; + System.out.println(partition(s)); + } + +} +``` + +**Explanation:** + +1. **`checkPalindrome` Function:** + - This function checks whether a given substring of a string is a palindrome. + - It takes three parameters: + - `str`: The input string. + - `startIndex`: The starting index of the substring. + - `lastIndex`: The ending index of the substring. + - It uses a `while` loop to check if the characters at the given indices are equal, iterating towards the center of the substring. If at any point they are not equal, the function returns `false`. Otherwise, it returns `true`. + +2. **`palindromePartition` Function:** + - This recursive function generates all possible palindrome partitions of the input string. + - It takes four parameters: + - `index`: The current index in the string. + - `ds`: A list representing the current path of partitions. + - `output`: A list of lists to store all palindrome partitions. + - `str`: The input string. + - The base case is when the `index` reaches the length of the string. At this point, the current path (`ds`) is added to the `output` list. + - It uses a `for` loop to iterate from the current index to the end of the string. + - If the substring from the current index to the loop variable `i` is a palindrome (checked using `checkPalindrome`), it adds the substring to the current path (`ds`) and recursively calls itself with the updated index (`i + 1`). + - After the recursive call, it removes the last added substring from the current path to explore other possibilities. + +3. **`partition` Function:** + - This is the main function that initializes the necessary lists and calls `palindromePartition` to find all palindrome partitions. + - It takes the input string `s`, creates an empty list for the output, and an empty list for the current path (`ds`). + - It calls `palindromePartition` with the initial index (`0`), current path (`ds`), output list (`output`), and the input string (`s`). + +4. **`main` Function:** + - The `main` function demonstrates the usage of the `partition` function on the string "aab." + - It prints the result obtained from the `partition` function. + +**Example Output:** + +[[a, a, b], [aa, b]] + + +The code efficiently finds and prints all possible palindrome partitions of the input string "aab" using a recursive approach. + + +**Time and Space Complexity Analysis**: + +# Time Complexity: +O(n^2), where n is the length of the input string. +The dynamic programming table is typically a 2D array of size n x n, and each entry requires constant time to compute. +# Space Complexity: +O(n^2). +The space complexity is determined by the 2D table used for memoization or tabulation. + +# Real-World Applications of Palindrome Partitioning + +Palindrome partitioning, while primarily a concept used in algorithmic problem-solving, has applications in various real-world scenarios. Here are some areas where the concept of palindrome partitioning or similar techniques can be applied: + +1. **Genomic Sequence Analysis:** + - In bioinformatics, palindrome partitioning techniques can be used for analyzing DNA or RNA sequences. Identifying palindromic sequences can provide insights into the structure and function of genetic material. + +2. **Text Processing and Pattern Matching:** + - Palindrome partitioning concepts can be applied in text processing and pattern matching. For example, identifying palindromic patterns in text can be useful in natural language processing or searching for specific structures in documents. + +3. **Data Compression:** + - Palindromes can be leveraged in data compression algorithms. Identifying and encoding repeated palindromic patterns efficiently can contribute to the compression of data. + +4. **Cryptography:** + - In certain cryptographic algorithms, palindromic structures or related concepts might be employed for creating secure key structures or encoding information. + +5. **Speech Processing:** + - Palindrome partitioning techniques could be applied in speech processing, especially in the analysis of phonetic or acoustic sequences. + +6. **Fault-Tolerant Systems:** + - Palindrome-related algorithms can be used in fault-tolerant systems, where the identification of symmetric or repeating patterns helps in recognizing and correcting errors. + +7. **Robotics and Image Processing:** + - Palindrome partitioning methods may find applications in robotics and image processing. For instance, in image recognition, identifying symmetrical patterns can aid in object recognition. + +8. **Algorithmic Design and Optimization:** + - Understanding and solving problems related to palindrome partitioning contribute to the development of efficient algorithms. These algorithms, in turn, find applications in various computational fields, including data analysis and optimization. + +9. **Network Security:** + - Palindrome partitioning or related concepts might be used in analyzing network traffic patterns or identifying anomalies in network behavior, contributing to network security. + +10. **Game Design:** + - Some game algorithms may involve palindrome partitioning or similar techniques, especially in puzzle-solving or pattern recognition games. diff --git a/Strings/Medium/palindromepartition.py b/Strings/Medium/palindromepartition.py new file mode 100644 index 00000000..15b4cd2d --- /dev/null +++ b/Strings/Medium/palindromepartition.py @@ -0,0 +1,22 @@ +def partition(string): + # Initialize dynamic programming array + dp=[[] for _ in range(len(string)+1)] + + # Initialize the first state with an empty partition + dp[0]=[[]] + +# Iterate over each character of the string + for j in range(1,len(string)+1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j]==string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each+[string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +if __name__=="__main__": + string="ababa" + print(partition(string)) diff --git a/Strings/Medium/palindrompartition.c++ b/Strings/Medium/palindrompartition.c++ new file mode 100644 index 00000000..3d7c28c0 --- /dev/null +++ b/Strings/Medium/palindrompartition.c++ @@ -0,0 +1,53 @@ +#include +bool isPalindrome(std::string s, int i, int j) { + // While loop checks the string symmetrically. + while (i <= j) { + // If characters at different ends don't match, it's not a palindrome. + if (s[i++] != s[j--]) return false; + } + // If loop finished, the string is a palindrome. + return true; +} +void util(int i,std::string s,std::vector>& res,std::vector& path){ + // base case: when string s is fully processed + if(i==s.size()){ + res.push_back(path); + return ; + } + + // iteratively checking each substring + for(int j=i;j> partition (std::string s){ + // Output list of all palindrome partitions + std::vector> res; + // List to keep track of the current path + std::vector path; + // Utility function to find all palindrome partitions + util(0,s,res,path); + return res; +} +int main(){ + // initial string to be partitioned + std::string s = "aaab"; + // function call to get all partitions + std::vector> ans=partition(s); + // loop to print all partitions + for(auto& a:ans){ + for(auto& b:a){ + std::cout< Date: Mon, 4 Dec 2023 20:45:08 +0530 Subject: [PATCH 12/53] Delete Strings/Medium/palindrompartition --- Strings/Medium/palindrompartition.c++ | 53 --------------------------- 1 file changed, 53 deletions(-) delete mode 100644 Strings/Medium/palindrompartition.c++ diff --git a/Strings/Medium/palindrompartition.c++ b/Strings/Medium/palindrompartition.c++ deleted file mode 100644 index 3d7c28c0..00000000 --- a/Strings/Medium/palindrompartition.c++ +++ /dev/null @@ -1,53 +0,0 @@ -#include -bool isPalindrome(std::string s, int i, int j) { - // While loop checks the string symmetrically. - while (i <= j) { - // If characters at different ends don't match, it's not a palindrome. - if (s[i++] != s[j--]) return false; - } - // If loop finished, the string is a palindrome. - return true; -} -void util(int i,std::string s,std::vector>& res,std::vector& path){ - // base case: when string s is fully processed - if(i==s.size()){ - res.push_back(path); - return ; - } - - // iteratively checking each substring - for(int j=i;j> partition (std::string s){ - // Output list of all palindrome partitions - std::vector> res; - // List to keep track of the current path - std::vector path; - // Utility function to find all palindrome partitions - util(0,s,res,path); - return res; -} -int main(){ - // initial string to be partitioned - std::string s = "aaab"; - // function call to get all partitions - std::vector> ans=partition(s); - // loop to print all partitions - for(auto& a:ans){ - for(auto& b:a){ - std::cout< Date: Mon, 4 Dec 2023 20:45:58 +0530 Subject: [PATCH 13/53] Delete Strings/Medium/PalindromePartitioning.java,Readme.md,palindrome.py --- Strings/Medium/PalindromePartitioning.java | 39 ---------------------- 1 file changed, 39 deletions(-) delete mode 100644 Strings/Medium/PalindromePartitioning.java diff --git a/Strings/Medium/PalindromePartitioning.java b/Strings/Medium/PalindromePartitioning.java deleted file mode 100644 index d7a87445..00000000 --- a/Strings/Medium/PalindromePartitioning.java +++ /dev/null @@ -1,39 +0,0 @@ -import java.util.ArrayList; -import java.util.List; - -class PalindromePartitioning { - static boolean checkPalindrome(String str, int startIndex, int lastIndex){ - while(startIndex <= lastIndex){ - if(str.charAt(startIndex) != str.charAt(lastIndex)) - return false; - startIndex++; - lastIndex--; - } - return true; - } - static void palindromePartition(int index, List ds, List> output, String str){ - if(index == str.length()){ - output.add(new ArrayList<>(ds)); - return; - } - for(int i = index; i < str.length(); i++){ - if(checkPalindrome(str, index, i)){ - ds.add(str.substring(index, i + 1)); - palindromePartition(i+1, ds, output, str); - ds.remove(ds.size()-1); - } - } - } - static List> partition(String s) { - List> output = new ArrayList<>(); - List ds = new ArrayList<>(); - palindromePartition(0, ds, output, s); - return output; - } - - public static void main(String[] args) { - String s="aab"; - System.out.println(partition(s)); - } - -} \ No newline at end of file From e38410fb3b4dbd93ff8f9cec82b11829b2c106f2 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:46:16 +0530 Subject: [PATCH 14/53] Delete Strings/Medium/Readme.md --- Strings/Medium/Readme.md | 379 --------------------------------------- 1 file changed, 379 deletions(-) delete mode 100644 Strings/Medium/Readme.md diff --git a/Strings/Medium/Readme.md b/Strings/Medium/Readme.md deleted file mode 100644 index a7f6163f..00000000 --- a/Strings/Medium/Readme.md +++ /dev/null @@ -1,379 +0,0 @@ -# Exploring palindrome partitioning using Strings: - -Exploring palindrome partitioning with strings often involves dynamic programming. The idea is to build a table or array to store intermediate results, helping to avoid redundant computations and improve the overall efficiency of the algorithm. - -# Introduction to Strings: - -A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. -Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. - -# Introduction to the Palindrome Partitioning Theory: - -A palindrome is a sequence of characters that reads the same backward as forward. Examples include "level," "radar," and "madam". Palindrome partitioning is a concept in theoretical computer science and mathematics that involves breaking down a string into substrings, with the condition that each substring is a palindrome.The goal of palindrome partitioning is to find all possible ways to split a given string into palindromic substrings. - -# Overview of Palindrome Partitioning: - -Given a string, the problem is to find all possible ways to partition it into palindromic substrings. - -# PYTHON -# code - -```python -# Copyrights to venkys.io -# For more information, visit https://venkys.io - -# python program for Palindrome Partitioning -# Stable: No -# Inplace: No -# Adaptive: Not Applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) - -# Space complexity:O(n^2) -# Time complexity:O(n^2) - -def partition(string): - # Initialize dynamic programming array - dp=[[] for _ in range(len(string)+1)] - - # Initialize the first state with an empty partition - dp[0]=[[]] - -# Iterate over each character of the string - for j in range(1,len(string)+1): - # Iterate through each previous character - for i in range(j): - # Check if the substring is a palindrome - if string[i:j]==string[i:j][::-1]: - # If so, extend the partitions ending at i with the palindrome substring - for each in dp[i]: - dp[j].append(each+[string[i:j]]) - # Return the final state, which contains all valid partitions - return dp[-1] - -if __name__=="__main__": - string="ababa" - print(partition(string)) -``` -# Code Explanation - -1. **Dynamic Programming Array (`dp`):** - - `dp` is a list of lists used for dynamic programming. It represents the state of the algorithm at each position in the input string. - -2. **Initialization:** - - `dp[0]` is initialized with an empty list representing the empty partition for the first state. - -3. **Iterating Over Characters (`j`):** - - The outer loop (`for j in range(1, len(string) + 1)`) iterates over each character in the input string, starting from the second character. - -4. **Iterating Over Previous Characters (`i`):** - - The inner loop (`for i in range(j)`) iterates through each previous character (from the beginning of the string up to `j`). - -5. **Palindrome Check:** - - `if string[i:j] == string[i:j][::-1]:` checks if the substring from `i` to `j` is a palindrome. - -6. **Updating Partitions:** - - If the substring is a palindrome, it extends the partitions ending at position `i` with the palindrome substring. It uses a nested loop to iterate through each existing partition at position `i` (`for each in dp[i]`) and appends the current palindrome substring to create new partitions. - -7. **Final Result:** - - The final state is represented by `dp[-1]`, which contains all valid partitions, and it is returned as the output of the function. - -8. **Example Usage:** - - The provided example with `string = "ababa"` demonstrates how the function can be called and prints the result of partitioning the given string into palindromic substrings. - -The algorithm employs dynamic programming to efficiently find and extend palindrome partitions in the input string. - -# C++ -# code - -```C++ -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// C++ program Palindrome Partitioning -// Stable: No -// Inplace:No -// Adaptive: Not applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) - -// Space complexity:O(n^2) -// Time complexity:O(n^2) - -#include -bool isPalindrome(std::string s, int i, int j) { - // While loop checks the string symmetrically. - while (i <= j) { - // If characters at different ends don't match, it's not a palindrome. - if (s[i++] != s[j--]) return false; - } - // If loop finished, the string is a palindrome. - return true; -} -void util(int i,std::string s,std::vector>& res,std::vector& path){ - // base case: when string s is fully processed - if(i==s.size()){ - res.push_back(path); - return ; - } - // iteratively checking each substring - for(int j=i;j> partition (std::string s){ - // Output list of all palindrome partitions - std::vector> res; - // List to keep track of the current path - std::vector path; - // Utility function to find all palindrome partitions - util(0,s,res,path); - return res; -} -int main(){ - // initial string to be partitioned - std::string s = "aaab"; - // function call to get all partitions - std::vector> ans=partition(s); - // loop to print all partitions - for(auto& a:ans){ - for(auto& b:a){ - std::cout< ds, List> output, String str){ - if(index == str.length()){ - output.add(new ArrayList<>(ds)); - return; - } - for(int i = index; i < str.length(); i++){ - if(checkPalindrome(str, index, i)){ - ds.add(str.substring(index, i + 1)); - palindromePartition(i+1, ds, output, str); - ds.remove(ds.size()-1); - } - } - } - - // Main function to return all the palindrome partitioning - static List> partition(String s) { - List> output = new ArrayList<>(); - List ds = new ArrayList<>(); - palindromePartition(0, ds, output, s); - return output; - } - - public static void main(String[] args) { - String s="aab"; - System.out.println(partition(s)); - } - -} - -``` -# Code Explanation - -Certainly! Let's break down the provided Java code step by step: - -```java -import java.util.ArrayList; -import java.util.List; - -class PalindromePartitioning { - - // Function to check if a substring is a palindrome - static boolean checkPalindrome(String str, int startIndex, int lastIndex) { - while (startIndex <= lastIndex) { - if (str.charAt(startIndex) != str.charAt(lastIndex)) - return false; - startIndex++; - lastIndex--; - } - return true; - } - - // Function to generate all the palindrome partitioning - static void palindromePartition(int index, List ds, List> output, String str) { - if (index == str.length()) { - output.add(new ArrayList<>(ds)); - return; - } - for (int i = index; i < str.length(); i++) { - if (checkPalindrome(str, index, i)) { - ds.add(str.substring(index, i + 1)); - palindromePartition(i + 1, ds, output, str); - ds.remove(ds.size() - 1); - } - } - } - - // Main function to return all the palindrome partitioning - static List> partition(String s) { - List> output = new ArrayList<>(); - List ds = new ArrayList<>(); - palindromePartition(0, ds, output, s); - return output; - } - - public static void main(String[] args) { - String s = "aab"; - System.out.println(partition(s)); - } - -} -``` - -**Explanation:** - -1. **`checkPalindrome` Function:** - - This function checks whether a given substring of a string is a palindrome. - - It takes three parameters: - - `str`: The input string. - - `startIndex`: The starting index of the substring. - - `lastIndex`: The ending index of the substring. - - It uses a `while` loop to check if the characters at the given indices are equal, iterating towards the center of the substring. If at any point they are not equal, the function returns `false`. Otherwise, it returns `true`. - -2. **`palindromePartition` Function:** - - This recursive function generates all possible palindrome partitions of the input string. - - It takes four parameters: - - `index`: The current index in the string. - - `ds`: A list representing the current path of partitions. - - `output`: A list of lists to store all palindrome partitions. - - `str`: The input string. - - The base case is when the `index` reaches the length of the string. At this point, the current path (`ds`) is added to the `output` list. - - It uses a `for` loop to iterate from the current index to the end of the string. - - If the substring from the current index to the loop variable `i` is a palindrome (checked using `checkPalindrome`), it adds the substring to the current path (`ds`) and recursively calls itself with the updated index (`i + 1`). - - After the recursive call, it removes the last added substring from the current path to explore other possibilities. - -3. **`partition` Function:** - - This is the main function that initializes the necessary lists and calls `palindromePartition` to find all palindrome partitions. - - It takes the input string `s`, creates an empty list for the output, and an empty list for the current path (`ds`). - - It calls `palindromePartition` with the initial index (`0`), current path (`ds`), output list (`output`), and the input string (`s`). - -4. **`main` Function:** - - The `main` function demonstrates the usage of the `partition` function on the string "aab." - - It prints the result obtained from the `partition` function. - -**Example Output:** - -[[a, a, b], [aa, b]] - - -The code efficiently finds and prints all possible palindrome partitions of the input string "aab" using a recursive approach. - - -**Time and Space Complexity Analysis**: - -# Time Complexity: -O(n^2), where n is the length of the input string. -The dynamic programming table is typically a 2D array of size n x n, and each entry requires constant time to compute. -# Space Complexity: -O(n^2). -The space complexity is determined by the 2D table used for memoization or tabulation. - -# Real-World Applications of Palindrome Partitioning - -Palindrome partitioning, while primarily a concept used in algorithmic problem-solving, has applications in various real-world scenarios. Here are some areas where the concept of palindrome partitioning or similar techniques can be applied: - -1. **Genomic Sequence Analysis:** - - In bioinformatics, palindrome partitioning techniques can be used for analyzing DNA or RNA sequences. Identifying palindromic sequences can provide insights into the structure and function of genetic material. - -2. **Text Processing and Pattern Matching:** - - Palindrome partitioning concepts can be applied in text processing and pattern matching. For example, identifying palindromic patterns in text can be useful in natural language processing or searching for specific structures in documents. - -3. **Data Compression:** - - Palindromes can be leveraged in data compression algorithms. Identifying and encoding repeated palindromic patterns efficiently can contribute to the compression of data. - -4. **Cryptography:** - - In certain cryptographic algorithms, palindromic structures or related concepts might be employed for creating secure key structures or encoding information. - -5. **Speech Processing:** - - Palindrome partitioning techniques could be applied in speech processing, especially in the analysis of phonetic or acoustic sequences. - -6. **Fault-Tolerant Systems:** - - Palindrome-related algorithms can be used in fault-tolerant systems, where the identification of symmetric or repeating patterns helps in recognizing and correcting errors. - -7. **Robotics and Image Processing:** - - Palindrome partitioning methods may find applications in robotics and image processing. For instance, in image recognition, identifying symmetrical patterns can aid in object recognition. - -8. **Algorithmic Design and Optimization:** - - Understanding and solving problems related to palindrome partitioning contribute to the development of efficient algorithms. These algorithms, in turn, find applications in various computational fields, including data analysis and optimization. - -9. **Network Security:** - - Palindrome partitioning or related concepts might be used in analyzing network traffic patterns or identifying anomalies in network behavior, contributing to network security. - -10. **Game Design:** - - Some game algorithms may involve palindrome partitioning or similar techniques, especially in puzzle-solving or pattern recognition games. From a3c5e4bac12cce632b56b643df0905e21b99c540 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:46:31 +0530 Subject: [PATCH 15/53] Delete Strings/Medium/palindromepartition.py --- Strings/Medium/palindromepartition.py | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 Strings/Medium/palindromepartition.py diff --git a/Strings/Medium/palindromepartition.py b/Strings/Medium/palindromepartition.py deleted file mode 100644 index 15b4cd2d..00000000 --- a/Strings/Medium/palindromepartition.py +++ /dev/null @@ -1,22 +0,0 @@ -def partition(string): - # Initialize dynamic programming array - dp=[[] for _ in range(len(string)+1)] - - # Initialize the first state with an empty partition - dp[0]=[[]] - -# Iterate over each character of the string - for j in range(1,len(string)+1): - # Iterate through each previous character - for i in range(j): - # Check if the substring is a palindrome - if string[i:j]==string[i:j][::-1]: - # If so, extend the partitions ending at i with the palindrome substring - for each in dp[i]: - dp[j].append(each+[string[i:j]]) - # Return the final state, which contains all valid partitions - return dp[-1] - -if __name__=="__main__": - string="ababa" - print(partition(string)) From 7a024158a50708192e131ebff47252ac70945ae8 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 4 Dec 2023 20:48:26 +0530 Subject: [PATCH 16/53] added palindrome partitioning --- .../PalindromePartitioning.java | 39 ++ .../Medium/palindrome partitioning/Readme.md | 379 ++++++++++++++++++ .../palindromepartition.py | 22 + .../palindrompartition.c++ | 53 +++ 4 files changed, 493 insertions(+) create mode 100644 Strings/Medium/palindrome partitioning/PalindromePartitioning.java create mode 100644 Strings/Medium/palindrome partitioning/Readme.md create mode 100644 Strings/Medium/palindrome partitioning/palindromepartition.py create mode 100644 Strings/Medium/palindrome partitioning/palindrompartition.c++ diff --git a/Strings/Medium/palindrome partitioning/PalindromePartitioning.java b/Strings/Medium/palindrome partitioning/PalindromePartitioning.java new file mode 100644 index 00000000..d7a87445 --- /dev/null +++ b/Strings/Medium/palindrome partitioning/PalindromePartitioning.java @@ -0,0 +1,39 @@ +import java.util.ArrayList; +import java.util.List; + +class PalindromePartitioning { + static boolean checkPalindrome(String str, int startIndex, int lastIndex){ + while(startIndex <= lastIndex){ + if(str.charAt(startIndex) != str.charAt(lastIndex)) + return false; + startIndex++; + lastIndex--; + } + return true; + } + static void palindromePartition(int index, List ds, List> output, String str){ + if(index == str.length()){ + output.add(new ArrayList<>(ds)); + return; + } + for(int i = index; i < str.length(); i++){ + if(checkPalindrome(str, index, i)){ + ds.add(str.substring(index, i + 1)); + palindromePartition(i+1, ds, output, str); + ds.remove(ds.size()-1); + } + } + } + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s="aab"; + System.out.println(partition(s)); + } + +} \ No newline at end of file diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md new file mode 100644 index 00000000..a7f6163f --- /dev/null +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -0,0 +1,379 @@ +# Exploring palindrome partitioning using Strings: + +Exploring palindrome partitioning with strings often involves dynamic programming. The idea is to build a table or array to store intermediate results, helping to avoid redundant computations and improve the overall efficiency of the algorithm. + +# Introduction to Strings: + +A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. +Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. + +# Introduction to the Palindrome Partitioning Theory: + +A palindrome is a sequence of characters that reads the same backward as forward. Examples include "level," "radar," and "madam". Palindrome partitioning is a concept in theoretical computer science and mathematics that involves breaking down a string into substrings, with the condition that each substring is a palindrome.The goal of palindrome partitioning is to find all possible ways to split a given string into palindromic substrings. + +# Overview of Palindrome Partitioning: + +Given a string, the problem is to find all possible ways to partition it into palindromic substrings. + +# PYTHON +# code + +```python +# Copyrights to venkys.io +# For more information, visit https://venkys.io + +# python program for Palindrome Partitioning +# Stable: No +# Inplace: No +# Adaptive: Not Applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) + +# Space complexity:O(n^2) +# Time complexity:O(n^2) + +def partition(string): + # Initialize dynamic programming array + dp=[[] for _ in range(len(string)+1)] + + # Initialize the first state with an empty partition + dp[0]=[[]] + +# Iterate over each character of the string + for j in range(1,len(string)+1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j]==string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each+[string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +if __name__=="__main__": + string="ababa" + print(partition(string)) +``` +# Code Explanation + +1. **Dynamic Programming Array (`dp`):** + - `dp` is a list of lists used for dynamic programming. It represents the state of the algorithm at each position in the input string. + +2. **Initialization:** + - `dp[0]` is initialized with an empty list representing the empty partition for the first state. + +3. **Iterating Over Characters (`j`):** + - The outer loop (`for j in range(1, len(string) + 1)`) iterates over each character in the input string, starting from the second character. + +4. **Iterating Over Previous Characters (`i`):** + - The inner loop (`for i in range(j)`) iterates through each previous character (from the beginning of the string up to `j`). + +5. **Palindrome Check:** + - `if string[i:j] == string[i:j][::-1]:` checks if the substring from `i` to `j` is a palindrome. + +6. **Updating Partitions:** + - If the substring is a palindrome, it extends the partitions ending at position `i` with the palindrome substring. It uses a nested loop to iterate through each existing partition at position `i` (`for each in dp[i]`) and appends the current palindrome substring to create new partitions. + +7. **Final Result:** + - The final state is represented by `dp[-1]`, which contains all valid partitions, and it is returned as the output of the function. + +8. **Example Usage:** + - The provided example with `string = "ababa"` demonstrates how the function can be called and prints the result of partitioning the given string into palindromic substrings. + +The algorithm employs dynamic programming to efficiently find and extend palindrome partitions in the input string. + +# C++ +# code + +```C++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program Palindrome Partitioning +// Stable: No +// Inplace:No +// Adaptive: Not applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) + +// Space complexity:O(n^2) +// Time complexity:O(n^2) + +#include +bool isPalindrome(std::string s, int i, int j) { + // While loop checks the string symmetrically. + while (i <= j) { + // If characters at different ends don't match, it's not a palindrome. + if (s[i++] != s[j--]) return false; + } + // If loop finished, the string is a palindrome. + return true; +} +void util(int i,std::string s,std::vector>& res,std::vector& path){ + // base case: when string s is fully processed + if(i==s.size()){ + res.push_back(path); + return ; + } + // iteratively checking each substring + for(int j=i;j> partition (std::string s){ + // Output list of all palindrome partitions + std::vector> res; + // List to keep track of the current path + std::vector path; + // Utility function to find all palindrome partitions + util(0,s,res,path); + return res; +} +int main(){ + // initial string to be partitioned + std::string s = "aaab"; + // function call to get all partitions + std::vector> ans=partition(s); + // loop to print all partitions + for(auto& a:ans){ + for(auto& b:a){ + std::cout< ds, List> output, String str){ + if(index == str.length()){ + output.add(new ArrayList<>(ds)); + return; + } + for(int i = index; i < str.length(); i++){ + if(checkPalindrome(str, index, i)){ + ds.add(str.substring(index, i + 1)); + palindromePartition(i+1, ds, output, str); + ds.remove(ds.size()-1); + } + } + } + + // Main function to return all the palindrome partitioning + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s="aab"; + System.out.println(partition(s)); + } + +} + +``` +# Code Explanation + +Certainly! Let's break down the provided Java code step by step: + +```java +import java.util.ArrayList; +import java.util.List; + +class PalindromePartitioning { + + // Function to check if a substring is a palindrome + static boolean checkPalindrome(String str, int startIndex, int lastIndex) { + while (startIndex <= lastIndex) { + if (str.charAt(startIndex) != str.charAt(lastIndex)) + return false; + startIndex++; + lastIndex--; + } + return true; + } + + // Function to generate all the palindrome partitioning + static void palindromePartition(int index, List ds, List> output, String str) { + if (index == str.length()) { + output.add(new ArrayList<>(ds)); + return; + } + for (int i = index; i < str.length(); i++) { + if (checkPalindrome(str, index, i)) { + ds.add(str.substring(index, i + 1)); + palindromePartition(i + 1, ds, output, str); + ds.remove(ds.size() - 1); + } + } + } + + // Main function to return all the palindrome partitioning + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s = "aab"; + System.out.println(partition(s)); + } + +} +``` + +**Explanation:** + +1. **`checkPalindrome` Function:** + - This function checks whether a given substring of a string is a palindrome. + - It takes three parameters: + - `str`: The input string. + - `startIndex`: The starting index of the substring. + - `lastIndex`: The ending index of the substring. + - It uses a `while` loop to check if the characters at the given indices are equal, iterating towards the center of the substring. If at any point they are not equal, the function returns `false`. Otherwise, it returns `true`. + +2. **`palindromePartition` Function:** + - This recursive function generates all possible palindrome partitions of the input string. + - It takes four parameters: + - `index`: The current index in the string. + - `ds`: A list representing the current path of partitions. + - `output`: A list of lists to store all palindrome partitions. + - `str`: The input string. + - The base case is when the `index` reaches the length of the string. At this point, the current path (`ds`) is added to the `output` list. + - It uses a `for` loop to iterate from the current index to the end of the string. + - If the substring from the current index to the loop variable `i` is a palindrome (checked using `checkPalindrome`), it adds the substring to the current path (`ds`) and recursively calls itself with the updated index (`i + 1`). + - After the recursive call, it removes the last added substring from the current path to explore other possibilities. + +3. **`partition` Function:** + - This is the main function that initializes the necessary lists and calls `palindromePartition` to find all palindrome partitions. + - It takes the input string `s`, creates an empty list for the output, and an empty list for the current path (`ds`). + - It calls `palindromePartition` with the initial index (`0`), current path (`ds`), output list (`output`), and the input string (`s`). + +4. **`main` Function:** + - The `main` function demonstrates the usage of the `partition` function on the string "aab." + - It prints the result obtained from the `partition` function. + +**Example Output:** + +[[a, a, b], [aa, b]] + + +The code efficiently finds and prints all possible palindrome partitions of the input string "aab" using a recursive approach. + + +**Time and Space Complexity Analysis**: + +# Time Complexity: +O(n^2), where n is the length of the input string. +The dynamic programming table is typically a 2D array of size n x n, and each entry requires constant time to compute. +# Space Complexity: +O(n^2). +The space complexity is determined by the 2D table used for memoization or tabulation. + +# Real-World Applications of Palindrome Partitioning + +Palindrome partitioning, while primarily a concept used in algorithmic problem-solving, has applications in various real-world scenarios. Here are some areas where the concept of palindrome partitioning or similar techniques can be applied: + +1. **Genomic Sequence Analysis:** + - In bioinformatics, palindrome partitioning techniques can be used for analyzing DNA or RNA sequences. Identifying palindromic sequences can provide insights into the structure and function of genetic material. + +2. **Text Processing and Pattern Matching:** + - Palindrome partitioning concepts can be applied in text processing and pattern matching. For example, identifying palindromic patterns in text can be useful in natural language processing or searching for specific structures in documents. + +3. **Data Compression:** + - Palindromes can be leveraged in data compression algorithms. Identifying and encoding repeated palindromic patterns efficiently can contribute to the compression of data. + +4. **Cryptography:** + - In certain cryptographic algorithms, palindromic structures or related concepts might be employed for creating secure key structures or encoding information. + +5. **Speech Processing:** + - Palindrome partitioning techniques could be applied in speech processing, especially in the analysis of phonetic or acoustic sequences. + +6. **Fault-Tolerant Systems:** + - Palindrome-related algorithms can be used in fault-tolerant systems, where the identification of symmetric or repeating patterns helps in recognizing and correcting errors. + +7. **Robotics and Image Processing:** + - Palindrome partitioning methods may find applications in robotics and image processing. For instance, in image recognition, identifying symmetrical patterns can aid in object recognition. + +8. **Algorithmic Design and Optimization:** + - Understanding and solving problems related to palindrome partitioning contribute to the development of efficient algorithms. These algorithms, in turn, find applications in various computational fields, including data analysis and optimization. + +9. **Network Security:** + - Palindrome partitioning or related concepts might be used in analyzing network traffic patterns or identifying anomalies in network behavior, contributing to network security. + +10. **Game Design:** + - Some game algorithms may involve palindrome partitioning or similar techniques, especially in puzzle-solving or pattern recognition games. diff --git a/Strings/Medium/palindrome partitioning/palindromepartition.py b/Strings/Medium/palindrome partitioning/palindromepartition.py new file mode 100644 index 00000000..15b4cd2d --- /dev/null +++ b/Strings/Medium/palindrome partitioning/palindromepartition.py @@ -0,0 +1,22 @@ +def partition(string): + # Initialize dynamic programming array + dp=[[] for _ in range(len(string)+1)] + + # Initialize the first state with an empty partition + dp[0]=[[]] + +# Iterate over each character of the string + for j in range(1,len(string)+1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j]==string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each+[string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +if __name__=="__main__": + string="ababa" + print(partition(string)) diff --git a/Strings/Medium/palindrome partitioning/palindrompartition.c++ b/Strings/Medium/palindrome partitioning/palindrompartition.c++ new file mode 100644 index 00000000..3d7c28c0 --- /dev/null +++ b/Strings/Medium/palindrome partitioning/palindrompartition.c++ @@ -0,0 +1,53 @@ +#include +bool isPalindrome(std::string s, int i, int j) { + // While loop checks the string symmetrically. + while (i <= j) { + // If characters at different ends don't match, it's not a palindrome. + if (s[i++] != s[j--]) return false; + } + // If loop finished, the string is a palindrome. + return true; +} +void util(int i,std::string s,std::vector>& res,std::vector& path){ + // base case: when string s is fully processed + if(i==s.size()){ + res.push_back(path); + return ; + } + + // iteratively checking each substring + for(int j=i;j> partition (std::string s){ + // Output list of all palindrome partitions + std::vector> res; + // List to keep track of the current path + std::vector path; + // Utility function to find all palindrome partitions + util(0,s,res,path); + return res; +} +int main(){ + // initial string to be partitioned + std::string s = "aaab"; + // function call to get all partitions + std::vector> ans=partition(s); + // loop to print all partitions + for(auto& a:ans){ + for(auto& b:a){ + std::cout< Date: Thu, 7 Dec 2023 22:35:22 +0530 Subject: [PATCH 17/53] Update Readme.md --- Strings/Medium/String to Integer/Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md index 00f5ce87..39385511 100644 --- a/Strings/Medium/String to Integer/Readme.md +++ b/Strings/Medium/String to Integer/Readme.md @@ -390,7 +390,7 @@ public class main{ The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of an integer. The `atoi` method returns the converted integer, and the `main` method tests it with the string "42". -**Time and Space Complexity Analysis**: +# Time and Space Complexity Analysis : The time and space complexity for the atoi method, which converts a string to an integer. @@ -402,7 +402,7 @@ The time complexity of the atoi method is O(n), where n is the length of the inp The subsequent while loop for processing digits also runs in O(n) time, where n is the length of the string. This loop iterates through the digits of the string, and each iteration takes constant time. Therefore, the overall time complexity is O(n). -Space Complexity: +# Space Complexity: The space complexity of the atoi method is O(1), constant space. @@ -478,4 +478,4 @@ In addition to the real-world applications mentioned earlier, let's explore some 10. **Educational Examples:** - In educational contexts, when teaching programming or algorithms, string-to-integer conversion serves as a fundamental concept. Exercises and examples often involve converting user inputs or string data to integers for various purposes. -In theoretical scenarios, the importance of string-to-integer conversion arises in the context of solving abstract problems, designing algorithms, and implementing various computational concepts. \ No newline at end of file +In theoretical scenarios, the importance of string-to-integer conversion arises in the context of solving abstract problems, designing algorithms, and implementing various computational concepts. From 362cbd03e766f865568b06556905e438a869f952 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Thu, 7 Dec 2023 22:37:28 +0530 Subject: [PATCH 18/53] Update Readme.md --- Strings/Medium/String to Integer/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md index 39385511..b444b84b 100644 --- a/Strings/Medium/String to Integer/Readme.md +++ b/Strings/Medium/String to Integer/Readme.md @@ -171,7 +171,7 @@ if __name__ == "__main__": The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of a 32-bit signed integer. The `check` function ensures that the result does not exceed the specified integer limits. # C++ -code +# code ```c++ /* Copyrights to venkys.io For more information, visit https://venkys.io */ From 4fa2f14e28ccc4dac48715ffed6c8e81f7cd5921 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Thu, 7 Dec 2023 22:38:39 +0530 Subject: [PATCH 19/53] Update Readme.md From 17d1f3c454805006b13ee83666c4532b62dca5b8 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Thu, 7 Dec 2023 22:39:43 +0530 Subject: [PATCH 20/53] Update Readme.md --- Strings/Medium/palindrome partitioning/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md index a7f6163f..f8e846d6 100644 --- a/Strings/Medium/palindrome partitioning/Readme.md +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -335,7 +335,7 @@ class PalindromePartitioning { The code efficiently finds and prints all possible palindrome partitions of the input string "aab" using a recursive approach. -**Time and Space Complexity Analysis**: +# Time and Space Complexity Analysis: # Time Complexity: O(n^2), where n is the length of the input string. From cffbff3e07104926adfab22b495b93019ce19e32 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 11 Dec 2023 20:19:18 +0530 Subject: [PATCH 21/53] added max heap CRUD --- Heaps/Hard/MaxHeapCRUD.java | 121 +++++++ Heaps/Hard/Readme.md | 594 +++++++++++++++++++++++++++++++++++ Heaps/Hard/max heap CRUD.py | 93 ++++++ Heaps/Hard/max_heap_CRUD.c++ | 113 +++++++ 4 files changed, 921 insertions(+) create mode 100644 Heaps/Hard/MaxHeapCRUD.java create mode 100644 Heaps/Hard/Readme.md create mode 100644 Heaps/Hard/max heap CRUD.py create mode 100644 Heaps/Hard/max_heap_CRUD.c++ diff --git a/Heaps/Hard/MaxHeapCRUD.java b/Heaps/Hard/MaxHeapCRUD.java new file mode 100644 index 00000000..f8a6ff78 --- /dev/null +++ b/Heaps/Hard/MaxHeapCRUD.java @@ -0,0 +1,121 @@ +import java.util.ArrayList; +import java.util.List; + +// Class representing a max heap with CRUD operations +class MaxHeapCRUD { + private List heap; + + // Constructor initializes an empty list for the heap + public MaxHeapCRUD() { + this.heap = new ArrayList<>(); + } + + // Move the element up the heap until the heap property is restored + private void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap.get(parent) >= heap.get(index)) { + break; + } + // Swap the current element with its parent + int temp = heap.get(parent); + heap.set(parent, heap.get(index)); + heap.set(index, temp); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + private void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap.get(left) > heap.get(largest)) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap.get(right) > heap.get(largest)) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + int temp = heap.get(largest); + heap.set(largest, heap.get(index)); + heap.set(index, temp); + maxHeapify(largest); + } + } + + // Add a new element to the heap and percolate it up to maintain the heap property + public void insert(int val) { + heap.add(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + public int getMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + return heap.get(0); + } + + // Update the value, percolate up, and max heapify to maintain the heap property + public void update(int oldVal, int newVal) { + int index = heap.indexOf(oldVal); + if (index != -1) { + heap.set(index, newVal); + percolateUp(index); + maxHeapify(index); + } else { + System.out.println("Value not in heap"); + } + } + + // Replace the root with the last element, pop the last element, and max heapify + public void deleteMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + heap.set(0, heap.remove(heap.size() - 1)); + maxHeapify(0); + } + + // Print all values in the heap + public void printHeap() { + for (int i : heap) { + System.out.print(i + " "); + } + System.out.println(); + } + + // Main method demonstrating usage of the MaxHeapCRUD class + public static void main(String[] args) { + MaxHeapCRUD heap = new MaxHeapCRUD(); + + heap.insert(12); + heap.insert(10); + heap.insert(52); + heap.insert(100); + heap.insert(50); + + System.out.print("All values in heap: "); + heap.printHeap(); + + System.out.println("Max Value: " + heap.getMax()); + + heap.update(12, 5); + + System.out.println("Max Value after update: " + heap.getMax()); + + heap.deleteMax(); + + System.out.println("Max Value after deletion: " + heap.getMax()); + + System.out.print("All values in heap: "); + heap.printHeap(); + } +} \ No newline at end of file diff --git a/Heaps/Hard/Readme.md b/Heaps/Hard/Readme.md new file mode 100644 index 00000000..233b5857 --- /dev/null +++ b/Heaps/Hard/Readme.md @@ -0,0 +1,594 @@ +# Exploring Max-Heap using CRUD operations : + +## Introduction to Heaps: + +Heaps are a fundamental data structure used in computer science for efficient implementation of priority queues and various graph algorithms. A heap is a specialized tree-based structure that satisfies the heap property. + +A binary heap is a complete binary tree where every parent node has a value greater than or equal to its children. This structure allows for quick retrieval and removal of the maximum element, making it an ideal choice for priority queue implementations. + +## Introduction to Max-Heap CRUD Operations: + +In the context of heaps, CRUD operations refer to Create, Read, Update, and Delete. Max-Heap CRUD operations involve manipulating a max heap, ensuring that it maintains the heap property at all times. + +Let's dive into each CRUD operation: + +### Overview of Max-Heap CRUD Operations: + +1. **Create (Insertion):** + - **Description:** Adds a new element to the max heap while maintaining the heap property. + - **Implementation:** The new element is appended to the end of the heap, and then the `percolate_up` method is called to ensure that the heap property is restored. + +2. **Read (Get Maximum):** + - **Description:** Returns the maximum element in the max heap, which is always the root. + - **Implementation:** Simply retrieves the element at the root of the heap. + +3. **Update (Modify Element):** + - **Description:** Updates an existing value in the max heap while preserving the heap property. + - **Implementation:** Finds the index of the old value, updates it with the new value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. + +4. **Delete (Remove Maximum):** + - **Description:** Removes the maximum element (root) from the max heap while maintaining the heap property. + - **Implementation:** Replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. + +These CRUD operations provide a comprehensive set of functionalities for working with a max heap. They ensure that the heap property is consistently upheld, allowing for efficient management of data in various applications. + + +# PYTHON +# code + +```python +# Copyrights to venkys.io +# For more information, visit https://venkys.io + +# python program for Max-Heap CRUD +# Stable: Yes +# Inplace: Yes +# Adaptive: Yes + +# Space complexity:O(n) +# Time complexity: +# Insertion: O(log N) +# Get Max: O(1) +# Update: O(log N) +# Delete Max: O(log N) + +class MaxHeap: + def __init__(self): + # Initialize an empty list to represent the heap + self.heap = [] + + def percolate_up(self, index): + # Move the element up the heap until the heap property is restored + while index > 0: + parent = (index - 1) // 2 + if self.heap[parent] >= self.heap[index]: + break + # Swap the current element with its parent + self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] + index = parent + + def max_heapify(self, index): + # Ensure the heap property is maintained starting from the given index + left = 2 * index + 1 + right = 2 * index + 2 + largest = index + + # Check if the left child is larger than the current largest element + if left < len(self.heap) and self.heap[left] > self.heap[largest]: + largest = left + # Check if the right child is larger than the current largest element + if right < len(self.heap) and self.heap[right] > self.heap[largest]: + largest = right + + # If the largest element is not the current index, swap and continue heapifying + if largest != index: + self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] + self.max_heapify(largest) + + def insert(self, val): + # Add a new element to the heap and percolate it up to maintain the heap property + self.heap.append(val) + self.percolate_up(len(self.heap) - 1) + + def get_max(self): + # Return the maximum element in the heap (root of the heap) + if len(self.heap) == 0: + raise Exception("Heap is empty") + return self.heap[0] + + def update(self, old_val, new_val): + try: + # Find the index of the old value in the heap + index = self.heap.index(old_val) + # Update the value, percolate up, and max heapify to maintain the heap property + self.heap[index] = new_val + self.percolate_up(index) + self.max_heapify(index) + except ValueError: + print("Value not in heap") + + def delete_max(self): + if len(self.heap) == 0: + raise Exception("Heap is empty") + # Replace the root with the last element, pop the last element, and max heapify + self.heap[0] = self.heap.pop() + self.max_heapify(0) + + def print_heap(self): + # Print all values in the heap + print(" ".join(map(str, self.heap))) + + +def main(): + # Initialize max heap + heap = MaxHeap() + + # Insert elements into heap + heap.insert(12) + heap.insert(10) + heap.insert(-10) + heap.insert(100) + + # Print all values in heap + heap.print_heap() + + # Get max value in heap + print("Max Value:", heap.get_max()) + + # Update value in heap + heap.update(12, 5) + print("Max Value after update:", heap.get_max()) + + # Delete max value from heap + heap.delete_max() + print("Max Value after deletion:", heap.get_max()) + + # Print all values in heap after deletion + heap.print_heap() + +``` +# Code Explanation + +The provided code implements a MaxHeap class in Python, allowing users to perform CRUD operations (Create, Read, Update, Delete) on a max heap data structure. Let's break down the code and provide a clear explanation: + + +# Step 1 - Initialization: +``` + self.heap = [] +``` +The `MaxHeap` class is initialized with an empty list, `self.heap`, which will store the elements of the max heap. + +# Step 2 - Percolate Up: +```python +def percolate_up(self, index): +``` +The `percolate_up` method is used during insertion to move a newly added element up the heap until the heap property is restored. It compares the element with its parent and swaps them if needed. + +# Step 3 - Max Heapify: + +```python +def max_heapify(self, index): +``` +The `max_heapify` method is used to maintain the heap property from a given index. It compares the element with its left and right children, swaps with the largest child if needed, and recursively continues the process. + +# Step 4 - Insertion: + +```python +def insert(self, val): +``` +The `insert` method adds a new element to the heap and then calls `percolate_up` to ensure the heap property is maintained. + +# Step 5 - Get Max: + +```python +def get_max(self): +``` +The `get_max` method returns the maximum element in the heap, which is the root. + +# Step 6 - Update: + +```python +def update(self, old_val, new_val): +``` +The `update` method updates an existing value in the heap. It finds the index, updates the value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. + +# Step 7 - Delete Max: + +```python +def delete_max(self): +``` +The `delete_max` method removes the maximum element (root) from the heap. It replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. + +# Step 8 - Print Heap: + +```python +def print_heap(self): +``` +The `print_heap` method prints all values in the heap. + +# Step 9 - Main Function: + +```python +def main(): + # Initialize max heap + heap = MaxHeap() +``` +The `main` function demonstrates the usage of the `MaxHeap` class by initializing a heap, performing insertions, updates, deletions, and printing the heap at different stages. + +This implementation provides a clear and organized way to work with Max-Heaps in Python. + +# C++ +# code + +```C++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program for Max_Heap CRUD +// Stable: No +// Inplace: Yes +// Adaptive: No + +// Space complexity: O(N) +// Time complexity: +// Insertion: O(log N) +// Get Max: O(1) +// Update: O(log N) +// Delete Max: O(log N) + +#include +#include +#include + +class MaxHeap { +private: + std::vector heap; + + // Move the element up the heap until the heap property is restored + void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap[parent] >= heap[index]) { + break; + } + std::swap(heap[parent], heap[index]); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap[left] > heap[largest]) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap[right] > heap[largest]) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + std::swap(heap[largest], heap[index]); + maxHeapify(largest); + } + } + +public: + // Add a new element to the heap and percolate it up to maintain the heap property + void insert(int val) { + heap.push_back(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + int getMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + return heap[0]; + } + + // Update the value, percolate up, and max heapify to maintain the heap property + void update(int old_val, int new_val) { + auto it = std::find(heap.begin(), heap.end(), old_val); + if (it != heap.end()) { + *it = new_val; + percolateUp(it - heap.begin()); + maxHeapify(it - heap.begin()); + } else { + std::cout << "Value not in heap" << std::endl; + } + } + + // Replace the root with the last element, pop the last element, and max heapify + void deleteMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + heap[0] = heap.back(); + heap.pop_back(); + maxHeapify(0); + } + + // Print all values in the heap + void printHeap() { + for (int i : heap) { + std::cout << i << " "; + } + std::cout << std::endl; + } +}; + +int main() { + // Example usage of the MaxHeap class + MaxHeap heap; + + heap.insert(12); + heap.insert(10); + heap.insert(-10); + heap.insert(100); + + std::cout << "All values in heap: "; + heap.printHeap(); + + std::cout << "Max Value: " << heap.getMax() << std::endl; + + heap.update(12, 5); + std::cout << "Max Value after update: " << heap.getMax() << std::endl; + + heap.deleteMax(); + std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + + std::cout << "All values in heap: "; + heap.printHeap(); + + return 0; +} +``` +# java +# code + +```java +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// java program for Max-Heap CRUD +// Stable: No +// Inplace: Yes +// Adaptive: No + +// Space complexity: O(N) +// Time complexity: + // Insertion: O(log N) + // Get Max: O(1) + // Update: O(log N) + // Delete Max: O(log N) + +import java.util.ArrayList; +import java.util.List; + +// Class representing a max heap with CRUD operations +class MaxHeapCRUD { + private List heap; + + // Constructor initializes an empty list for the heap + public MaxHeapCRUD() { + this.heap = new ArrayList<>(); + } + + // Move the element up the heap until the heap property is restored + private void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap.get(parent) >= heap.get(index)) { + break; + } + // Swap the current element with its parent + int temp = heap.get(parent); + heap.set(parent, heap.get(index)); + heap.set(index, temp); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + private void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap.get(left) > heap.get(largest)) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap.get(right) > heap.get(largest)) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + int temp = heap.get(largest); + heap.set(largest, heap.get(index)); + heap.set(index, temp); + maxHeapify(largest); + } + } + + // Add a new element to the heap and percolate it up to maintain the heap property + public void insert(int val) { + heap.add(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + public int getMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + return heap.get(0); + } + + // Update the value, percolate up, and max heapify to maintain the heap property + public void update(int oldVal, int newVal) { + int index = heap.indexOf(oldVal); + if (index != -1) { + heap.set(index, newVal); + percolateUp(index); + maxHeapify(index); + } else { + System.out.println("Value not in heap"); + } + } + + // Replace the root with the last element, pop the last element, and max heapify + public void deleteMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + heap.set(0, heap.remove(heap.size() - 1)); + maxHeapify(0); + } + + // Print all values in the heap + public void printHeap() { + for (int i : heap) { + System.out.print(i + " "); + } + System.out.println(); + } + + // Main method demonstrating usage of the MaxHeapCRUD class + public static void main(String[] args) { + MaxHeapCRUD heap = new MaxHeapCRUD(); + + heap.insert(12); + heap.insert(10); + heap.insert(52); + heap.insert(100); + heap.insert(50); + + System.out.print("All values in heap: "); + heap.printHeap(); + + System.out.println("Max Value: " + heap.getMax()); + + heap.update(12, 5); + + System.out.println("Max Value after update: " + heap.getMax()); + + heap.deleteMax(); + + System.out.println("Max Value after deletion: " + heap.getMax()); + + System.out.print("All values in heap: "); + heap.printHeap(); + } +} +``` +# Code Explanation + Step by step explanation for Java and C++ : + +1. **Class Definition (MaxHeap):** + - The code defines a class named `MaxHeap` representing a Max Heap data structure. + - Private member for c++: `std::vector heap` is used to store the elements of the heap. + -It uses a private list (heap) to store the elements of the heap in java. + - The class has a constructor in java (MaxHeapCRUD()) that initializes an empty list for the heap. + + +2. **percolateUp Function:** + - Private method `percolateUp` moves an element up the heap until the heap property is restored. + - It takes an index as a parameter and swaps the element with its parent until the heap property is satisfied. + +3. **maxHeapify Function:** + - Private method `maxHeapify` ensures the heap property is maintained starting from a given index. + - It compares the element with its left and right children, swapping it with the largest child if needed. + +4. **insert Function:** + - Public method `insert` adds a new element to the heap and ensures the heap property by calling `percolateUp`. + +5. **getMax Function:** + - Public method `getMax` returns the maximum element in the heap (the root). + +6. **update Function:** + - Public method `update` updates a specified element in the heap with a new value. + - It uses `std::find` to locate the element, updates it, and then calls `percolateUp` and `maxHeapify` to maintain the heap property. + +7. **deleteMax Function:** + - Public method `deleteMax` removes the maximum element (root) from the heap. + - It replaces the root with the last element, pops the last element, and calls `maxHeapify` to restore the heap property. + +8. **printHeap Function:** + - Public method `printHeap` prints all values in the heap. + +9. **main Function:** + - In the `main` function: + - An instance of `MaxHeap` named `heap` is created in c++.An instance of MaxHeapCRUD named heap is created in java + - Elements (12, 10, -10, 100,50) are inserted into the heap using `insert`. + - All values in the heap are printed using `printHeap`. + - The maximum value in the heap is printed using `getMax`. + - An update is performed, changing the value 12 to 5 using `update`. + - The maximum value after the update is printed. + - The maximum element is deleted using `deleteMax`. + - The maximum value after deletion is printed. + - Finally, all values in the heap after deletion are printed. + +This code demonstrates the basic operations (insertion, update, deletion) on a Max Heap. + + + +**Time and Space Complexity Analysis**: + +# Time Complexity: +The time complexities for the Max Heap CRUD (Create, Read, Update, Delete) operations are as follows: + +1. **Insertion (Create):** + - Time Complexity: O(log n) + - Explanation: The worst-case time complexity for inserting an element into a max heap is logarithmic in the number of elements, as the element needs to be percolated up the height of the heap. The height of a binary heap is log(n) where n is the number of elements. + +2. **GetMax (Read):** + - Time Complexity: O(1) + - Explanation: Retrieving the maximum element (root) in a max heap can be done in constant time as the maximum element is always at the root. + +3. **Update:** + - Time Complexity: O(log n) + - Explanation: Updating an element in a max heap involves two operations: percolating up (up to log n steps) and max heapifying (up to log n steps). Therefore, the overall time complexity is logarithmic. + +4. **DeleteMax (Delete):** + - Time Complexity: O(log n) + - Explanation: Deleting the maximum element involves replacing the root with the last element, which may require percolating down the height of the heap to maintain the heap property. The worst-case time complexity is logarithmic. + +These time complexities assume that the underlying data structure is a binary heap. The actual performance may vary based on implementation details and the specific operations performed. + +# Space Complexity: +The space complexity for Max Heap CRUD (Create, Read, Update, Delete) operations is O(n), where n is the number of elements in the heap. + +1. **Insertion (Create):** + - Explanation: The insertion operation generally doesn't require additional space proportional to the number of elements. The new element is added to the existing heap in-place. + +2. **GetMax (Read):** + - Explanation: Reading the maximum element involves accessing the root of the heap. It doesn't require additional space proportional to the number of elements. + +3. **Update:** + - Explanation: The update operation is performed in-place without requiring additional space. + +4. **DeleteMax (Delete):** + - Explanation: The delete operation involves replacing the root with the last element and then adjusting the heap structure. It is performed in-place without requiring additional space. + +# Real-World Applications of MAX-HEAP CRUD(Create,Read,Update,Delete) + +1. **Task Scheduling:** Priority scheduling based on task priority levels. +2. **Job Scheduling:** Allocating jobs to machines based on priority. +3. **Dijkstra's Algorithm:** Finding the shortest path in a graph. +4. **Huffman Coding:** Data compression algorithm. +5. **Order Processing:** Managing orders based on their priority in e-commerce systems. +6. **Operating System Task Scheduling:** Assigning priority to tasks for execution. +7. **Network Routing Algorithms:** Determining the optimal path for data packets. +8. **Emergency Room Triage:** Prioritizing patients based on the severity of their condition. +9. **Database Indexing:** Managing indexes to speed up query performance. +10. **Wireless Sensor Networks:** Energy-efficient data aggregation in sensor networks. diff --git a/Heaps/Hard/max heap CRUD.py b/Heaps/Hard/max heap CRUD.py new file mode 100644 index 00000000..628e1243 --- /dev/null +++ b/Heaps/Hard/max heap CRUD.py @@ -0,0 +1,93 @@ +class MaxHeap: + def __init__(self): + # Initialize an empty list to represent the heap + self.heap = [] + + def percolate_up(self, index): + # Move the element up the heap until the heap property is restored + while index > 0: + parent = (index - 1) // 2 + if self.heap[parent] >= self.heap[index]: + break + # Swap the current element with its parent + self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] + index = parent + + def max_heapify(self, index): + # Ensure the heap property is maintained starting from the given index + left = 2 * index + 1 + right = 2 * index + 2 + largest = index + + # Check if the left child is larger than the current largest element + if left < len(self.heap) and self.heap[left] > self.heap[largest]: + largest = left + # Check if the right child is larger than the current largest element + if right < len(self.heap) and self.heap[right] > self.heap[largest]: + largest = right + + # If the largest element is not the current index, swap and continue heapifying + if largest != index: + self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] + self.max_heapify(largest) + + def insert(self, val): + # Add a new element to the heap and percolate it up to maintain the heap property + self.heap.append(val) + self.percolate_up(len(self.heap) - 1) + + def get_max(self): + # Return the maximum element in the heap (root of the heap) + if len(self.heap) == 0: + raise Exception("Heap is empty") + return self.heap[0] + + def update(self, old_val, new_val): + try: + # Find the index of the old value in the heap + index = self.heap.index(old_val) + # Update the value, percolate up, and max heapify to maintain the heap property + self.heap[index] = new_val + self.percolate_up(index) + self.max_heapify(index) + except ValueError: + print("Value not in heap") + + def delete_max(self): + if len(self.heap) == 0: + raise Exception("Heap is empty") + # Replace the root with the last element, pop the last element, and max heapify + self.heap[0] = self.heap.pop() + self.max_heapify(0) + + def print_heap(self): + # Print all values in the heap + print(" ".join(map(str, self.heap))) + + +def main(): + # Initialize max heap + heap = MaxHeap() + + # Insert elements into heap + heap.insert(12) + heap.insert(10) + heap.insert(-10) + heap.insert(100) + + # Print all values in heap + heap.print_heap() + + # Get max value in heap + print("Max Value:", heap.get_max()) + + # Update value in heap + heap.update(12, 5) + print("Max Value after update:", heap.get_max()) + + # Delete max value from heap + heap.delete_max() + print("Max Value after deletion:", heap.get_max()) + + # Print all values in heap after deletion + heap.print_heap() \ No newline at end of file diff --git a/Heaps/Hard/max_heap_CRUD.c++ b/Heaps/Hard/max_heap_CRUD.c++ new file mode 100644 index 00000000..0cebbbdc --- /dev/null +++ b/Heaps/Hard/max_heap_CRUD.c++ @@ -0,0 +1,113 @@ +#include +#include +#include + +class MaxHeap { +private: + std::vector heap; + + // Move the element up the heap until the heap property is restored + void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap[parent] >= heap[index]) { + break; + } + std::swap(heap[parent], heap[index]); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap[left] > heap[largest]) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap[right] > heap[largest]) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + std::swap(heap[largest], heap[index]); + maxHeapify(largest); + } + } + +public: + // Add a new element to the heap and percolate it up to maintain the heap property + void insert(int val) { + heap.push_back(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + int getMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + return heap[0]; + } + + // Update the value, percolate up, and max heapify to maintain the heap property + void update(int old_val, int new_val) { + auto it = std::find(heap.begin(), heap.end(), old_val); + if (it != heap.end()) { + *it = new_val; + percolateUp(it - heap.begin()); + maxHeapify(it - heap.begin()); + } else { + std::cout << "Value not in heap" << std::endl; + } + } + + // Replace the root with the last element, pop the last element, and max heapify + void deleteMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + heap[0] = heap.back(); + heap.pop_back(); + maxHeapify(0); + } + + // Print all values in the heap + void printHeap() { + for (int i : heap) { + std::cout << i << " "; + } + std::cout << std::endl; + } +}; + +int main() { + // Example usage of the MaxHeap class + MaxHeap heap; + + heap.insert(12); + heap.insert(10); + heap.insert(-10); + heap.insert(100); + + std::cout << "All values in heap: "; + heap.printHeap(); + + std::cout << "Max Value: " << heap.getMax() << std::endl; + + heap.update(12, 5); + std::cout << "Max Value after update: " << heap.getMax() << std::endl; + + heap.deleteMax(); + std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + + std::cout << "All values in heap: "; + heap.printHeap(); + + return 0; +} From 9c5deef42ffe7e7835dd40c8ea6db2ca24ef8182 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 11 Dec 2023 20:38:05 +0530 Subject: [PATCH 22/53] Delete Heaps/Hard directory --- Heaps/Hard/MaxHeapCRUD.java | 121 ------- Heaps/Hard/Readme.md | 594 ----------------------------------- Heaps/Hard/max heap CRUD.py | 93 ------ Heaps/Hard/max_heap_CRUD.c++ | 113 ------- 4 files changed, 921 deletions(-) delete mode 100644 Heaps/Hard/MaxHeapCRUD.java delete mode 100644 Heaps/Hard/Readme.md delete mode 100644 Heaps/Hard/max heap CRUD.py delete mode 100644 Heaps/Hard/max_heap_CRUD.c++ diff --git a/Heaps/Hard/MaxHeapCRUD.java b/Heaps/Hard/MaxHeapCRUD.java deleted file mode 100644 index f8a6ff78..00000000 --- a/Heaps/Hard/MaxHeapCRUD.java +++ /dev/null @@ -1,121 +0,0 @@ -import java.util.ArrayList; -import java.util.List; - -// Class representing a max heap with CRUD operations -class MaxHeapCRUD { - private List heap; - - // Constructor initializes an empty list for the heap - public MaxHeapCRUD() { - this.heap = new ArrayList<>(); - } - - // Move the element up the heap until the heap property is restored - private void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap.get(parent) >= heap.get(index)) { - break; - } - // Swap the current element with its parent - int temp = heap.get(parent); - heap.set(parent, heap.get(index)); - heap.set(index, temp); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - private void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap.get(left) > heap.get(largest)) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap.get(right) > heap.get(largest)) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - int temp = heap.get(largest); - heap.set(largest, heap.get(index)); - heap.set(index, temp); - maxHeapify(largest); - } - } - - // Add a new element to the heap and percolate it up to maintain the heap property - public void insert(int val) { - heap.add(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - public int getMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - return heap.get(0); - } - - // Update the value, percolate up, and max heapify to maintain the heap property - public void update(int oldVal, int newVal) { - int index = heap.indexOf(oldVal); - if (index != -1) { - heap.set(index, newVal); - percolateUp(index); - maxHeapify(index); - } else { - System.out.println("Value not in heap"); - } - } - - // Replace the root with the last element, pop the last element, and max heapify - public void deleteMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - heap.set(0, heap.remove(heap.size() - 1)); - maxHeapify(0); - } - - // Print all values in the heap - public void printHeap() { - for (int i : heap) { - System.out.print(i + " "); - } - System.out.println(); - } - - // Main method demonstrating usage of the MaxHeapCRUD class - public static void main(String[] args) { - MaxHeapCRUD heap = new MaxHeapCRUD(); - - heap.insert(12); - heap.insert(10); - heap.insert(52); - heap.insert(100); - heap.insert(50); - - System.out.print("All values in heap: "); - heap.printHeap(); - - System.out.println("Max Value: " + heap.getMax()); - - heap.update(12, 5); - - System.out.println("Max Value after update: " + heap.getMax()); - - heap.deleteMax(); - - System.out.println("Max Value after deletion: " + heap.getMax()); - - System.out.print("All values in heap: "); - heap.printHeap(); - } -} \ No newline at end of file diff --git a/Heaps/Hard/Readme.md b/Heaps/Hard/Readme.md deleted file mode 100644 index 233b5857..00000000 --- a/Heaps/Hard/Readme.md +++ /dev/null @@ -1,594 +0,0 @@ -# Exploring Max-Heap using CRUD operations : - -## Introduction to Heaps: - -Heaps are a fundamental data structure used in computer science for efficient implementation of priority queues and various graph algorithms. A heap is a specialized tree-based structure that satisfies the heap property. - -A binary heap is a complete binary tree where every parent node has a value greater than or equal to its children. This structure allows for quick retrieval and removal of the maximum element, making it an ideal choice for priority queue implementations. - -## Introduction to Max-Heap CRUD Operations: - -In the context of heaps, CRUD operations refer to Create, Read, Update, and Delete. Max-Heap CRUD operations involve manipulating a max heap, ensuring that it maintains the heap property at all times. - -Let's dive into each CRUD operation: - -### Overview of Max-Heap CRUD Operations: - -1. **Create (Insertion):** - - **Description:** Adds a new element to the max heap while maintaining the heap property. - - **Implementation:** The new element is appended to the end of the heap, and then the `percolate_up` method is called to ensure that the heap property is restored. - -2. **Read (Get Maximum):** - - **Description:** Returns the maximum element in the max heap, which is always the root. - - **Implementation:** Simply retrieves the element at the root of the heap. - -3. **Update (Modify Element):** - - **Description:** Updates an existing value in the max heap while preserving the heap property. - - **Implementation:** Finds the index of the old value, updates it with the new value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. - -4. **Delete (Remove Maximum):** - - **Description:** Removes the maximum element (root) from the max heap while maintaining the heap property. - - **Implementation:** Replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. - -These CRUD operations provide a comprehensive set of functionalities for working with a max heap. They ensure that the heap property is consistently upheld, allowing for efficient management of data in various applications. - - -# PYTHON -# code - -```python -# Copyrights to venkys.io -# For more information, visit https://venkys.io - -# python program for Max-Heap CRUD -# Stable: Yes -# Inplace: Yes -# Adaptive: Yes - -# Space complexity:O(n) -# Time complexity: -# Insertion: O(log N) -# Get Max: O(1) -# Update: O(log N) -# Delete Max: O(log N) - -class MaxHeap: - def __init__(self): - # Initialize an empty list to represent the heap - self.heap = [] - - def percolate_up(self, index): - # Move the element up the heap until the heap property is restored - while index > 0: - parent = (index - 1) // 2 - if self.heap[parent] >= self.heap[index]: - break - # Swap the current element with its parent - self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] - index = parent - - def max_heapify(self, index): - # Ensure the heap property is maintained starting from the given index - left = 2 * index + 1 - right = 2 * index + 2 - largest = index - - # Check if the left child is larger than the current largest element - if left < len(self.heap) and self.heap[left] > self.heap[largest]: - largest = left - # Check if the right child is larger than the current largest element - if right < len(self.heap) and self.heap[right] > self.heap[largest]: - largest = right - - # If the largest element is not the current index, swap and continue heapifying - if largest != index: - self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] - self.max_heapify(largest) - - def insert(self, val): - # Add a new element to the heap and percolate it up to maintain the heap property - self.heap.append(val) - self.percolate_up(len(self.heap) - 1) - - def get_max(self): - # Return the maximum element in the heap (root of the heap) - if len(self.heap) == 0: - raise Exception("Heap is empty") - return self.heap[0] - - def update(self, old_val, new_val): - try: - # Find the index of the old value in the heap - index = self.heap.index(old_val) - # Update the value, percolate up, and max heapify to maintain the heap property - self.heap[index] = new_val - self.percolate_up(index) - self.max_heapify(index) - except ValueError: - print("Value not in heap") - - def delete_max(self): - if len(self.heap) == 0: - raise Exception("Heap is empty") - # Replace the root with the last element, pop the last element, and max heapify - self.heap[0] = self.heap.pop() - self.max_heapify(0) - - def print_heap(self): - # Print all values in the heap - print(" ".join(map(str, self.heap))) - - -def main(): - # Initialize max heap - heap = MaxHeap() - - # Insert elements into heap - heap.insert(12) - heap.insert(10) - heap.insert(-10) - heap.insert(100) - - # Print all values in heap - heap.print_heap() - - # Get max value in heap - print("Max Value:", heap.get_max()) - - # Update value in heap - heap.update(12, 5) - print("Max Value after update:", heap.get_max()) - - # Delete max value from heap - heap.delete_max() - print("Max Value after deletion:", heap.get_max()) - - # Print all values in heap after deletion - heap.print_heap() - -``` -# Code Explanation - -The provided code implements a MaxHeap class in Python, allowing users to perform CRUD operations (Create, Read, Update, Delete) on a max heap data structure. Let's break down the code and provide a clear explanation: - - -# Step 1 - Initialization: -``` - self.heap = [] -``` -The `MaxHeap` class is initialized with an empty list, `self.heap`, which will store the elements of the max heap. - -# Step 2 - Percolate Up: -```python -def percolate_up(self, index): -``` -The `percolate_up` method is used during insertion to move a newly added element up the heap until the heap property is restored. It compares the element with its parent and swaps them if needed. - -# Step 3 - Max Heapify: - -```python -def max_heapify(self, index): -``` -The `max_heapify` method is used to maintain the heap property from a given index. It compares the element with its left and right children, swaps with the largest child if needed, and recursively continues the process. - -# Step 4 - Insertion: - -```python -def insert(self, val): -``` -The `insert` method adds a new element to the heap and then calls `percolate_up` to ensure the heap property is maintained. - -# Step 5 - Get Max: - -```python -def get_max(self): -``` -The `get_max` method returns the maximum element in the heap, which is the root. - -# Step 6 - Update: - -```python -def update(self, old_val, new_val): -``` -The `update` method updates an existing value in the heap. It finds the index, updates the value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. - -# Step 7 - Delete Max: - -```python -def delete_max(self): -``` -The `delete_max` method removes the maximum element (root) from the heap. It replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. - -# Step 8 - Print Heap: - -```python -def print_heap(self): -``` -The `print_heap` method prints all values in the heap. - -# Step 9 - Main Function: - -```python -def main(): - # Initialize max heap - heap = MaxHeap() -``` -The `main` function demonstrates the usage of the `MaxHeap` class by initializing a heap, performing insertions, updates, deletions, and printing the heap at different stages. - -This implementation provides a clear and organized way to work with Max-Heaps in Python. - -# C++ -# code - -```C++ -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// C++ program for Max_Heap CRUD -// Stable: No -// Inplace: Yes -// Adaptive: No - -// Space complexity: O(N) -// Time complexity: -// Insertion: O(log N) -// Get Max: O(1) -// Update: O(log N) -// Delete Max: O(log N) - -#include -#include -#include - -class MaxHeap { -private: - std::vector heap; - - // Move the element up the heap until the heap property is restored - void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap[parent] >= heap[index]) { - break; - } - std::swap(heap[parent], heap[index]); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap[left] > heap[largest]) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap[right] > heap[largest]) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - std::swap(heap[largest], heap[index]); - maxHeapify(largest); - } - } - -public: - // Add a new element to the heap and percolate it up to maintain the heap property - void insert(int val) { - heap.push_back(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - int getMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - return heap[0]; - } - - // Update the value, percolate up, and max heapify to maintain the heap property - void update(int old_val, int new_val) { - auto it = std::find(heap.begin(), heap.end(), old_val); - if (it != heap.end()) { - *it = new_val; - percolateUp(it - heap.begin()); - maxHeapify(it - heap.begin()); - } else { - std::cout << "Value not in heap" << std::endl; - } - } - - // Replace the root with the last element, pop the last element, and max heapify - void deleteMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - heap[0] = heap.back(); - heap.pop_back(); - maxHeapify(0); - } - - // Print all values in the heap - void printHeap() { - for (int i : heap) { - std::cout << i << " "; - } - std::cout << std::endl; - } -}; - -int main() { - // Example usage of the MaxHeap class - MaxHeap heap; - - heap.insert(12); - heap.insert(10); - heap.insert(-10); - heap.insert(100); - - std::cout << "All values in heap: "; - heap.printHeap(); - - std::cout << "Max Value: " << heap.getMax() << std::endl; - - heap.update(12, 5); - std::cout << "Max Value after update: " << heap.getMax() << std::endl; - - heap.deleteMax(); - std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; - - std::cout << "All values in heap: "; - heap.printHeap(); - - return 0; -} -``` -# java -# code - -```java -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// java program for Max-Heap CRUD -// Stable: No -// Inplace: Yes -// Adaptive: No - -// Space complexity: O(N) -// Time complexity: - // Insertion: O(log N) - // Get Max: O(1) - // Update: O(log N) - // Delete Max: O(log N) - -import java.util.ArrayList; -import java.util.List; - -// Class representing a max heap with CRUD operations -class MaxHeapCRUD { - private List heap; - - // Constructor initializes an empty list for the heap - public MaxHeapCRUD() { - this.heap = new ArrayList<>(); - } - - // Move the element up the heap until the heap property is restored - private void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap.get(parent) >= heap.get(index)) { - break; - } - // Swap the current element with its parent - int temp = heap.get(parent); - heap.set(parent, heap.get(index)); - heap.set(index, temp); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - private void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap.get(left) > heap.get(largest)) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap.get(right) > heap.get(largest)) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - int temp = heap.get(largest); - heap.set(largest, heap.get(index)); - heap.set(index, temp); - maxHeapify(largest); - } - } - - // Add a new element to the heap and percolate it up to maintain the heap property - public void insert(int val) { - heap.add(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - public int getMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - return heap.get(0); - } - - // Update the value, percolate up, and max heapify to maintain the heap property - public void update(int oldVal, int newVal) { - int index = heap.indexOf(oldVal); - if (index != -1) { - heap.set(index, newVal); - percolateUp(index); - maxHeapify(index); - } else { - System.out.println("Value not in heap"); - } - } - - // Replace the root with the last element, pop the last element, and max heapify - public void deleteMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - heap.set(0, heap.remove(heap.size() - 1)); - maxHeapify(0); - } - - // Print all values in the heap - public void printHeap() { - for (int i : heap) { - System.out.print(i + " "); - } - System.out.println(); - } - - // Main method demonstrating usage of the MaxHeapCRUD class - public static void main(String[] args) { - MaxHeapCRUD heap = new MaxHeapCRUD(); - - heap.insert(12); - heap.insert(10); - heap.insert(52); - heap.insert(100); - heap.insert(50); - - System.out.print("All values in heap: "); - heap.printHeap(); - - System.out.println("Max Value: " + heap.getMax()); - - heap.update(12, 5); - - System.out.println("Max Value after update: " + heap.getMax()); - - heap.deleteMax(); - - System.out.println("Max Value after deletion: " + heap.getMax()); - - System.out.print("All values in heap: "); - heap.printHeap(); - } -} -``` -# Code Explanation - Step by step explanation for Java and C++ : - -1. **Class Definition (MaxHeap):** - - The code defines a class named `MaxHeap` representing a Max Heap data structure. - - Private member for c++: `std::vector heap` is used to store the elements of the heap. - -It uses a private list (heap) to store the elements of the heap in java. - - The class has a constructor in java (MaxHeapCRUD()) that initializes an empty list for the heap. - - -2. **percolateUp Function:** - - Private method `percolateUp` moves an element up the heap until the heap property is restored. - - It takes an index as a parameter and swaps the element with its parent until the heap property is satisfied. - -3. **maxHeapify Function:** - - Private method `maxHeapify` ensures the heap property is maintained starting from a given index. - - It compares the element with its left and right children, swapping it with the largest child if needed. - -4. **insert Function:** - - Public method `insert` adds a new element to the heap and ensures the heap property by calling `percolateUp`. - -5. **getMax Function:** - - Public method `getMax` returns the maximum element in the heap (the root). - -6. **update Function:** - - Public method `update` updates a specified element in the heap with a new value. - - It uses `std::find` to locate the element, updates it, and then calls `percolateUp` and `maxHeapify` to maintain the heap property. - -7. **deleteMax Function:** - - Public method `deleteMax` removes the maximum element (root) from the heap. - - It replaces the root with the last element, pops the last element, and calls `maxHeapify` to restore the heap property. - -8. **printHeap Function:** - - Public method `printHeap` prints all values in the heap. - -9. **main Function:** - - In the `main` function: - - An instance of `MaxHeap` named `heap` is created in c++.An instance of MaxHeapCRUD named heap is created in java - - Elements (12, 10, -10, 100,50) are inserted into the heap using `insert`. - - All values in the heap are printed using `printHeap`. - - The maximum value in the heap is printed using `getMax`. - - An update is performed, changing the value 12 to 5 using `update`. - - The maximum value after the update is printed. - - The maximum element is deleted using `deleteMax`. - - The maximum value after deletion is printed. - - Finally, all values in the heap after deletion are printed. - -This code demonstrates the basic operations (insertion, update, deletion) on a Max Heap. - - - -**Time and Space Complexity Analysis**: - -# Time Complexity: -The time complexities for the Max Heap CRUD (Create, Read, Update, Delete) operations are as follows: - -1. **Insertion (Create):** - - Time Complexity: O(log n) - - Explanation: The worst-case time complexity for inserting an element into a max heap is logarithmic in the number of elements, as the element needs to be percolated up the height of the heap. The height of a binary heap is log(n) where n is the number of elements. - -2. **GetMax (Read):** - - Time Complexity: O(1) - - Explanation: Retrieving the maximum element (root) in a max heap can be done in constant time as the maximum element is always at the root. - -3. **Update:** - - Time Complexity: O(log n) - - Explanation: Updating an element in a max heap involves two operations: percolating up (up to log n steps) and max heapifying (up to log n steps). Therefore, the overall time complexity is logarithmic. - -4. **DeleteMax (Delete):** - - Time Complexity: O(log n) - - Explanation: Deleting the maximum element involves replacing the root with the last element, which may require percolating down the height of the heap to maintain the heap property. The worst-case time complexity is logarithmic. - -These time complexities assume that the underlying data structure is a binary heap. The actual performance may vary based on implementation details and the specific operations performed. - -# Space Complexity: -The space complexity for Max Heap CRUD (Create, Read, Update, Delete) operations is O(n), where n is the number of elements in the heap. - -1. **Insertion (Create):** - - Explanation: The insertion operation generally doesn't require additional space proportional to the number of elements. The new element is added to the existing heap in-place. - -2. **GetMax (Read):** - - Explanation: Reading the maximum element involves accessing the root of the heap. It doesn't require additional space proportional to the number of elements. - -3. **Update:** - - Explanation: The update operation is performed in-place without requiring additional space. - -4. **DeleteMax (Delete):** - - Explanation: The delete operation involves replacing the root with the last element and then adjusting the heap structure. It is performed in-place without requiring additional space. - -# Real-World Applications of MAX-HEAP CRUD(Create,Read,Update,Delete) - -1. **Task Scheduling:** Priority scheduling based on task priority levels. -2. **Job Scheduling:** Allocating jobs to machines based on priority. -3. **Dijkstra's Algorithm:** Finding the shortest path in a graph. -4. **Huffman Coding:** Data compression algorithm. -5. **Order Processing:** Managing orders based on their priority in e-commerce systems. -6. **Operating System Task Scheduling:** Assigning priority to tasks for execution. -7. **Network Routing Algorithms:** Determining the optimal path for data packets. -8. **Emergency Room Triage:** Prioritizing patients based on the severity of their condition. -9. **Database Indexing:** Managing indexes to speed up query performance. -10. **Wireless Sensor Networks:** Energy-efficient data aggregation in sensor networks. diff --git a/Heaps/Hard/max heap CRUD.py b/Heaps/Hard/max heap CRUD.py deleted file mode 100644 index 628e1243..00000000 --- a/Heaps/Hard/max heap CRUD.py +++ /dev/null @@ -1,93 +0,0 @@ -class MaxHeap: - def __init__(self): - # Initialize an empty list to represent the heap - self.heap = [] - - def percolate_up(self, index): - # Move the element up the heap until the heap property is restored - while index > 0: - parent = (index - 1) // 2 - if self.heap[parent] >= self.heap[index]: - break - # Swap the current element with its parent - self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] - index = parent - - def max_heapify(self, index): - # Ensure the heap property is maintained starting from the given index - left = 2 * index + 1 - right = 2 * index + 2 - largest = index - - # Check if the left child is larger than the current largest element - if left < len(self.heap) and self.heap[left] > self.heap[largest]: - largest = left - # Check if the right child is larger than the current largest element - if right < len(self.heap) and self.heap[right] > self.heap[largest]: - largest = right - - # If the largest element is not the current index, swap and continue heapifying - if largest != index: - self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] - self.max_heapify(largest) - - def insert(self, val): - # Add a new element to the heap and percolate it up to maintain the heap property - self.heap.append(val) - self.percolate_up(len(self.heap) - 1) - - def get_max(self): - # Return the maximum element in the heap (root of the heap) - if len(self.heap) == 0: - raise Exception("Heap is empty") - return self.heap[0] - - def update(self, old_val, new_val): - try: - # Find the index of the old value in the heap - index = self.heap.index(old_val) - # Update the value, percolate up, and max heapify to maintain the heap property - self.heap[index] = new_val - self.percolate_up(index) - self.max_heapify(index) - except ValueError: - print("Value not in heap") - - def delete_max(self): - if len(self.heap) == 0: - raise Exception("Heap is empty") - # Replace the root with the last element, pop the last element, and max heapify - self.heap[0] = self.heap.pop() - self.max_heapify(0) - - def print_heap(self): - # Print all values in the heap - print(" ".join(map(str, self.heap))) - - -def main(): - # Initialize max heap - heap = MaxHeap() - - # Insert elements into heap - heap.insert(12) - heap.insert(10) - heap.insert(-10) - heap.insert(100) - - # Print all values in heap - heap.print_heap() - - # Get max value in heap - print("Max Value:", heap.get_max()) - - # Update value in heap - heap.update(12, 5) - print("Max Value after update:", heap.get_max()) - - # Delete max value from heap - heap.delete_max() - print("Max Value after deletion:", heap.get_max()) - - # Print all values in heap after deletion - heap.print_heap() \ No newline at end of file diff --git a/Heaps/Hard/max_heap_CRUD.c++ b/Heaps/Hard/max_heap_CRUD.c++ deleted file mode 100644 index 0cebbbdc..00000000 --- a/Heaps/Hard/max_heap_CRUD.c++ +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include - -class MaxHeap { -private: - std::vector heap; - - // Move the element up the heap until the heap property is restored - void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap[parent] >= heap[index]) { - break; - } - std::swap(heap[parent], heap[index]); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap[left] > heap[largest]) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap[right] > heap[largest]) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - std::swap(heap[largest], heap[index]); - maxHeapify(largest); - } - } - -public: - // Add a new element to the heap and percolate it up to maintain the heap property - void insert(int val) { - heap.push_back(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - int getMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - return heap[0]; - } - - // Update the value, percolate up, and max heapify to maintain the heap property - void update(int old_val, int new_val) { - auto it = std::find(heap.begin(), heap.end(), old_val); - if (it != heap.end()) { - *it = new_val; - percolateUp(it - heap.begin()); - maxHeapify(it - heap.begin()); - } else { - std::cout << "Value not in heap" << std::endl; - } - } - - // Replace the root with the last element, pop the last element, and max heapify - void deleteMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - heap[0] = heap.back(); - heap.pop_back(); - maxHeapify(0); - } - - // Print all values in the heap - void printHeap() { - for (int i : heap) { - std::cout << i << " "; - } - std::cout << std::endl; - } -}; - -int main() { - // Example usage of the MaxHeap class - MaxHeap heap; - - heap.insert(12); - heap.insert(10); - heap.insert(-10); - heap.insert(100); - - std::cout << "All values in heap: "; - heap.printHeap(); - - std::cout << "Max Value: " << heap.getMax() << std::endl; - - heap.update(12, 5); - std::cout << "Max Value after update: " << heap.getMax() << std::endl; - - heap.deleteMax(); - std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; - - std::cout << "All values in heap: "; - heap.printHeap(); - - return 0; -} From 9b9f2c2d7458593a7c8d0b3a773e45a3444caa7a Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 11 Dec 2023 20:39:46 +0530 Subject: [PATCH 23/53] Add files via upload --- Heaps/Hard/MaxHeapCRUD.java | 121 +++++++ Heaps/Hard/Readme.md | 594 +++++++++++++++++++++++++++++++++++ Heaps/Hard/max heap CRUD.py | 93 ++++++ Heaps/Hard/max_heap_CRUD.c++ | 113 +++++++ 4 files changed, 921 insertions(+) create mode 100644 Heaps/Hard/MaxHeapCRUD.java create mode 100644 Heaps/Hard/Readme.md create mode 100644 Heaps/Hard/max heap CRUD.py create mode 100644 Heaps/Hard/max_heap_CRUD.c++ diff --git a/Heaps/Hard/MaxHeapCRUD.java b/Heaps/Hard/MaxHeapCRUD.java new file mode 100644 index 00000000..f8a6ff78 --- /dev/null +++ b/Heaps/Hard/MaxHeapCRUD.java @@ -0,0 +1,121 @@ +import java.util.ArrayList; +import java.util.List; + +// Class representing a max heap with CRUD operations +class MaxHeapCRUD { + private List heap; + + // Constructor initializes an empty list for the heap + public MaxHeapCRUD() { + this.heap = new ArrayList<>(); + } + + // Move the element up the heap until the heap property is restored + private void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap.get(parent) >= heap.get(index)) { + break; + } + // Swap the current element with its parent + int temp = heap.get(parent); + heap.set(parent, heap.get(index)); + heap.set(index, temp); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + private void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap.get(left) > heap.get(largest)) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap.get(right) > heap.get(largest)) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + int temp = heap.get(largest); + heap.set(largest, heap.get(index)); + heap.set(index, temp); + maxHeapify(largest); + } + } + + // Add a new element to the heap and percolate it up to maintain the heap property + public void insert(int val) { + heap.add(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + public int getMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + return heap.get(0); + } + + // Update the value, percolate up, and max heapify to maintain the heap property + public void update(int oldVal, int newVal) { + int index = heap.indexOf(oldVal); + if (index != -1) { + heap.set(index, newVal); + percolateUp(index); + maxHeapify(index); + } else { + System.out.println("Value not in heap"); + } + } + + // Replace the root with the last element, pop the last element, and max heapify + public void deleteMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + heap.set(0, heap.remove(heap.size() - 1)); + maxHeapify(0); + } + + // Print all values in the heap + public void printHeap() { + for (int i : heap) { + System.out.print(i + " "); + } + System.out.println(); + } + + // Main method demonstrating usage of the MaxHeapCRUD class + public static void main(String[] args) { + MaxHeapCRUD heap = new MaxHeapCRUD(); + + heap.insert(12); + heap.insert(10); + heap.insert(52); + heap.insert(100); + heap.insert(50); + + System.out.print("All values in heap: "); + heap.printHeap(); + + System.out.println("Max Value: " + heap.getMax()); + + heap.update(12, 5); + + System.out.println("Max Value after update: " + heap.getMax()); + + heap.deleteMax(); + + System.out.println("Max Value after deletion: " + heap.getMax()); + + System.out.print("All values in heap: "); + heap.printHeap(); + } +} \ No newline at end of file diff --git a/Heaps/Hard/Readme.md b/Heaps/Hard/Readme.md new file mode 100644 index 00000000..233b5857 --- /dev/null +++ b/Heaps/Hard/Readme.md @@ -0,0 +1,594 @@ +# Exploring Max-Heap using CRUD operations : + +## Introduction to Heaps: + +Heaps are a fundamental data structure used in computer science for efficient implementation of priority queues and various graph algorithms. A heap is a specialized tree-based structure that satisfies the heap property. + +A binary heap is a complete binary tree where every parent node has a value greater than or equal to its children. This structure allows for quick retrieval and removal of the maximum element, making it an ideal choice for priority queue implementations. + +## Introduction to Max-Heap CRUD Operations: + +In the context of heaps, CRUD operations refer to Create, Read, Update, and Delete. Max-Heap CRUD operations involve manipulating a max heap, ensuring that it maintains the heap property at all times. + +Let's dive into each CRUD operation: + +### Overview of Max-Heap CRUD Operations: + +1. **Create (Insertion):** + - **Description:** Adds a new element to the max heap while maintaining the heap property. + - **Implementation:** The new element is appended to the end of the heap, and then the `percolate_up` method is called to ensure that the heap property is restored. + +2. **Read (Get Maximum):** + - **Description:** Returns the maximum element in the max heap, which is always the root. + - **Implementation:** Simply retrieves the element at the root of the heap. + +3. **Update (Modify Element):** + - **Description:** Updates an existing value in the max heap while preserving the heap property. + - **Implementation:** Finds the index of the old value, updates it with the new value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. + +4. **Delete (Remove Maximum):** + - **Description:** Removes the maximum element (root) from the max heap while maintaining the heap property. + - **Implementation:** Replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. + +These CRUD operations provide a comprehensive set of functionalities for working with a max heap. They ensure that the heap property is consistently upheld, allowing for efficient management of data in various applications. + + +# PYTHON +# code + +```python +# Copyrights to venkys.io +# For more information, visit https://venkys.io + +# python program for Max-Heap CRUD +# Stable: Yes +# Inplace: Yes +# Adaptive: Yes + +# Space complexity:O(n) +# Time complexity: +# Insertion: O(log N) +# Get Max: O(1) +# Update: O(log N) +# Delete Max: O(log N) + +class MaxHeap: + def __init__(self): + # Initialize an empty list to represent the heap + self.heap = [] + + def percolate_up(self, index): + # Move the element up the heap until the heap property is restored + while index > 0: + parent = (index - 1) // 2 + if self.heap[parent] >= self.heap[index]: + break + # Swap the current element with its parent + self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] + index = parent + + def max_heapify(self, index): + # Ensure the heap property is maintained starting from the given index + left = 2 * index + 1 + right = 2 * index + 2 + largest = index + + # Check if the left child is larger than the current largest element + if left < len(self.heap) and self.heap[left] > self.heap[largest]: + largest = left + # Check if the right child is larger than the current largest element + if right < len(self.heap) and self.heap[right] > self.heap[largest]: + largest = right + + # If the largest element is not the current index, swap and continue heapifying + if largest != index: + self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] + self.max_heapify(largest) + + def insert(self, val): + # Add a new element to the heap and percolate it up to maintain the heap property + self.heap.append(val) + self.percolate_up(len(self.heap) - 1) + + def get_max(self): + # Return the maximum element in the heap (root of the heap) + if len(self.heap) == 0: + raise Exception("Heap is empty") + return self.heap[0] + + def update(self, old_val, new_val): + try: + # Find the index of the old value in the heap + index = self.heap.index(old_val) + # Update the value, percolate up, and max heapify to maintain the heap property + self.heap[index] = new_val + self.percolate_up(index) + self.max_heapify(index) + except ValueError: + print("Value not in heap") + + def delete_max(self): + if len(self.heap) == 0: + raise Exception("Heap is empty") + # Replace the root with the last element, pop the last element, and max heapify + self.heap[0] = self.heap.pop() + self.max_heapify(0) + + def print_heap(self): + # Print all values in the heap + print(" ".join(map(str, self.heap))) + + +def main(): + # Initialize max heap + heap = MaxHeap() + + # Insert elements into heap + heap.insert(12) + heap.insert(10) + heap.insert(-10) + heap.insert(100) + + # Print all values in heap + heap.print_heap() + + # Get max value in heap + print("Max Value:", heap.get_max()) + + # Update value in heap + heap.update(12, 5) + print("Max Value after update:", heap.get_max()) + + # Delete max value from heap + heap.delete_max() + print("Max Value after deletion:", heap.get_max()) + + # Print all values in heap after deletion + heap.print_heap() + +``` +# Code Explanation + +The provided code implements a MaxHeap class in Python, allowing users to perform CRUD operations (Create, Read, Update, Delete) on a max heap data structure. Let's break down the code and provide a clear explanation: + + +# Step 1 - Initialization: +``` + self.heap = [] +``` +The `MaxHeap` class is initialized with an empty list, `self.heap`, which will store the elements of the max heap. + +# Step 2 - Percolate Up: +```python +def percolate_up(self, index): +``` +The `percolate_up` method is used during insertion to move a newly added element up the heap until the heap property is restored. It compares the element with its parent and swaps them if needed. + +# Step 3 - Max Heapify: + +```python +def max_heapify(self, index): +``` +The `max_heapify` method is used to maintain the heap property from a given index. It compares the element with its left and right children, swaps with the largest child if needed, and recursively continues the process. + +# Step 4 - Insertion: + +```python +def insert(self, val): +``` +The `insert` method adds a new element to the heap and then calls `percolate_up` to ensure the heap property is maintained. + +# Step 5 - Get Max: + +```python +def get_max(self): +``` +The `get_max` method returns the maximum element in the heap, which is the root. + +# Step 6 - Update: + +```python +def update(self, old_val, new_val): +``` +The `update` method updates an existing value in the heap. It finds the index, updates the value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. + +# Step 7 - Delete Max: + +```python +def delete_max(self): +``` +The `delete_max` method removes the maximum element (root) from the heap. It replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. + +# Step 8 - Print Heap: + +```python +def print_heap(self): +``` +The `print_heap` method prints all values in the heap. + +# Step 9 - Main Function: + +```python +def main(): + # Initialize max heap + heap = MaxHeap() +``` +The `main` function demonstrates the usage of the `MaxHeap` class by initializing a heap, performing insertions, updates, deletions, and printing the heap at different stages. + +This implementation provides a clear and organized way to work with Max-Heaps in Python. + +# C++ +# code + +```C++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program for Max_Heap CRUD +// Stable: No +// Inplace: Yes +// Adaptive: No + +// Space complexity: O(N) +// Time complexity: +// Insertion: O(log N) +// Get Max: O(1) +// Update: O(log N) +// Delete Max: O(log N) + +#include +#include +#include + +class MaxHeap { +private: + std::vector heap; + + // Move the element up the heap until the heap property is restored + void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap[parent] >= heap[index]) { + break; + } + std::swap(heap[parent], heap[index]); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap[left] > heap[largest]) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap[right] > heap[largest]) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + std::swap(heap[largest], heap[index]); + maxHeapify(largest); + } + } + +public: + // Add a new element to the heap and percolate it up to maintain the heap property + void insert(int val) { + heap.push_back(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + int getMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + return heap[0]; + } + + // Update the value, percolate up, and max heapify to maintain the heap property + void update(int old_val, int new_val) { + auto it = std::find(heap.begin(), heap.end(), old_val); + if (it != heap.end()) { + *it = new_val; + percolateUp(it - heap.begin()); + maxHeapify(it - heap.begin()); + } else { + std::cout << "Value not in heap" << std::endl; + } + } + + // Replace the root with the last element, pop the last element, and max heapify + void deleteMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + heap[0] = heap.back(); + heap.pop_back(); + maxHeapify(0); + } + + // Print all values in the heap + void printHeap() { + for (int i : heap) { + std::cout << i << " "; + } + std::cout << std::endl; + } +}; + +int main() { + // Example usage of the MaxHeap class + MaxHeap heap; + + heap.insert(12); + heap.insert(10); + heap.insert(-10); + heap.insert(100); + + std::cout << "All values in heap: "; + heap.printHeap(); + + std::cout << "Max Value: " << heap.getMax() << std::endl; + + heap.update(12, 5); + std::cout << "Max Value after update: " << heap.getMax() << std::endl; + + heap.deleteMax(); + std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + + std::cout << "All values in heap: "; + heap.printHeap(); + + return 0; +} +``` +# java +# code + +```java +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// java program for Max-Heap CRUD +// Stable: No +// Inplace: Yes +// Adaptive: No + +// Space complexity: O(N) +// Time complexity: + // Insertion: O(log N) + // Get Max: O(1) + // Update: O(log N) + // Delete Max: O(log N) + +import java.util.ArrayList; +import java.util.List; + +// Class representing a max heap with CRUD operations +class MaxHeapCRUD { + private List heap; + + // Constructor initializes an empty list for the heap + public MaxHeapCRUD() { + this.heap = new ArrayList<>(); + } + + // Move the element up the heap until the heap property is restored + private void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap.get(parent) >= heap.get(index)) { + break; + } + // Swap the current element with its parent + int temp = heap.get(parent); + heap.set(parent, heap.get(index)); + heap.set(index, temp); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + private void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap.get(left) > heap.get(largest)) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap.get(right) > heap.get(largest)) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + int temp = heap.get(largest); + heap.set(largest, heap.get(index)); + heap.set(index, temp); + maxHeapify(largest); + } + } + + // Add a new element to the heap and percolate it up to maintain the heap property + public void insert(int val) { + heap.add(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + public int getMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + return heap.get(0); + } + + // Update the value, percolate up, and max heapify to maintain the heap property + public void update(int oldVal, int newVal) { + int index = heap.indexOf(oldVal); + if (index != -1) { + heap.set(index, newVal); + percolateUp(index); + maxHeapify(index); + } else { + System.out.println("Value not in heap"); + } + } + + // Replace the root with the last element, pop the last element, and max heapify + public void deleteMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + heap.set(0, heap.remove(heap.size() - 1)); + maxHeapify(0); + } + + // Print all values in the heap + public void printHeap() { + for (int i : heap) { + System.out.print(i + " "); + } + System.out.println(); + } + + // Main method demonstrating usage of the MaxHeapCRUD class + public static void main(String[] args) { + MaxHeapCRUD heap = new MaxHeapCRUD(); + + heap.insert(12); + heap.insert(10); + heap.insert(52); + heap.insert(100); + heap.insert(50); + + System.out.print("All values in heap: "); + heap.printHeap(); + + System.out.println("Max Value: " + heap.getMax()); + + heap.update(12, 5); + + System.out.println("Max Value after update: " + heap.getMax()); + + heap.deleteMax(); + + System.out.println("Max Value after deletion: " + heap.getMax()); + + System.out.print("All values in heap: "); + heap.printHeap(); + } +} +``` +# Code Explanation + Step by step explanation for Java and C++ : + +1. **Class Definition (MaxHeap):** + - The code defines a class named `MaxHeap` representing a Max Heap data structure. + - Private member for c++: `std::vector heap` is used to store the elements of the heap. + -It uses a private list (heap) to store the elements of the heap in java. + - The class has a constructor in java (MaxHeapCRUD()) that initializes an empty list for the heap. + + +2. **percolateUp Function:** + - Private method `percolateUp` moves an element up the heap until the heap property is restored. + - It takes an index as a parameter and swaps the element with its parent until the heap property is satisfied. + +3. **maxHeapify Function:** + - Private method `maxHeapify` ensures the heap property is maintained starting from a given index. + - It compares the element with its left and right children, swapping it with the largest child if needed. + +4. **insert Function:** + - Public method `insert` adds a new element to the heap and ensures the heap property by calling `percolateUp`. + +5. **getMax Function:** + - Public method `getMax` returns the maximum element in the heap (the root). + +6. **update Function:** + - Public method `update` updates a specified element in the heap with a new value. + - It uses `std::find` to locate the element, updates it, and then calls `percolateUp` and `maxHeapify` to maintain the heap property. + +7. **deleteMax Function:** + - Public method `deleteMax` removes the maximum element (root) from the heap. + - It replaces the root with the last element, pops the last element, and calls `maxHeapify` to restore the heap property. + +8. **printHeap Function:** + - Public method `printHeap` prints all values in the heap. + +9. **main Function:** + - In the `main` function: + - An instance of `MaxHeap` named `heap` is created in c++.An instance of MaxHeapCRUD named heap is created in java + - Elements (12, 10, -10, 100,50) are inserted into the heap using `insert`. + - All values in the heap are printed using `printHeap`. + - The maximum value in the heap is printed using `getMax`. + - An update is performed, changing the value 12 to 5 using `update`. + - The maximum value after the update is printed. + - The maximum element is deleted using `deleteMax`. + - The maximum value after deletion is printed. + - Finally, all values in the heap after deletion are printed. + +This code demonstrates the basic operations (insertion, update, deletion) on a Max Heap. + + + +**Time and Space Complexity Analysis**: + +# Time Complexity: +The time complexities for the Max Heap CRUD (Create, Read, Update, Delete) operations are as follows: + +1. **Insertion (Create):** + - Time Complexity: O(log n) + - Explanation: The worst-case time complexity for inserting an element into a max heap is logarithmic in the number of elements, as the element needs to be percolated up the height of the heap. The height of a binary heap is log(n) where n is the number of elements. + +2. **GetMax (Read):** + - Time Complexity: O(1) + - Explanation: Retrieving the maximum element (root) in a max heap can be done in constant time as the maximum element is always at the root. + +3. **Update:** + - Time Complexity: O(log n) + - Explanation: Updating an element in a max heap involves two operations: percolating up (up to log n steps) and max heapifying (up to log n steps). Therefore, the overall time complexity is logarithmic. + +4. **DeleteMax (Delete):** + - Time Complexity: O(log n) + - Explanation: Deleting the maximum element involves replacing the root with the last element, which may require percolating down the height of the heap to maintain the heap property. The worst-case time complexity is logarithmic. + +These time complexities assume that the underlying data structure is a binary heap. The actual performance may vary based on implementation details and the specific operations performed. + +# Space Complexity: +The space complexity for Max Heap CRUD (Create, Read, Update, Delete) operations is O(n), where n is the number of elements in the heap. + +1. **Insertion (Create):** + - Explanation: The insertion operation generally doesn't require additional space proportional to the number of elements. The new element is added to the existing heap in-place. + +2. **GetMax (Read):** + - Explanation: Reading the maximum element involves accessing the root of the heap. It doesn't require additional space proportional to the number of elements. + +3. **Update:** + - Explanation: The update operation is performed in-place without requiring additional space. + +4. **DeleteMax (Delete):** + - Explanation: The delete operation involves replacing the root with the last element and then adjusting the heap structure. It is performed in-place without requiring additional space. + +# Real-World Applications of MAX-HEAP CRUD(Create,Read,Update,Delete) + +1. **Task Scheduling:** Priority scheduling based on task priority levels. +2. **Job Scheduling:** Allocating jobs to machines based on priority. +3. **Dijkstra's Algorithm:** Finding the shortest path in a graph. +4. **Huffman Coding:** Data compression algorithm. +5. **Order Processing:** Managing orders based on their priority in e-commerce systems. +6. **Operating System Task Scheduling:** Assigning priority to tasks for execution. +7. **Network Routing Algorithms:** Determining the optimal path for data packets. +8. **Emergency Room Triage:** Prioritizing patients based on the severity of their condition. +9. **Database Indexing:** Managing indexes to speed up query performance. +10. **Wireless Sensor Networks:** Energy-efficient data aggregation in sensor networks. diff --git a/Heaps/Hard/max heap CRUD.py b/Heaps/Hard/max heap CRUD.py new file mode 100644 index 00000000..628e1243 --- /dev/null +++ b/Heaps/Hard/max heap CRUD.py @@ -0,0 +1,93 @@ +class MaxHeap: + def __init__(self): + # Initialize an empty list to represent the heap + self.heap = [] + + def percolate_up(self, index): + # Move the element up the heap until the heap property is restored + while index > 0: + parent = (index - 1) // 2 + if self.heap[parent] >= self.heap[index]: + break + # Swap the current element with its parent + self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] + index = parent + + def max_heapify(self, index): + # Ensure the heap property is maintained starting from the given index + left = 2 * index + 1 + right = 2 * index + 2 + largest = index + + # Check if the left child is larger than the current largest element + if left < len(self.heap) and self.heap[left] > self.heap[largest]: + largest = left + # Check if the right child is larger than the current largest element + if right < len(self.heap) and self.heap[right] > self.heap[largest]: + largest = right + + # If the largest element is not the current index, swap and continue heapifying + if largest != index: + self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] + self.max_heapify(largest) + + def insert(self, val): + # Add a new element to the heap and percolate it up to maintain the heap property + self.heap.append(val) + self.percolate_up(len(self.heap) - 1) + + def get_max(self): + # Return the maximum element in the heap (root of the heap) + if len(self.heap) == 0: + raise Exception("Heap is empty") + return self.heap[0] + + def update(self, old_val, new_val): + try: + # Find the index of the old value in the heap + index = self.heap.index(old_val) + # Update the value, percolate up, and max heapify to maintain the heap property + self.heap[index] = new_val + self.percolate_up(index) + self.max_heapify(index) + except ValueError: + print("Value not in heap") + + def delete_max(self): + if len(self.heap) == 0: + raise Exception("Heap is empty") + # Replace the root with the last element, pop the last element, and max heapify + self.heap[0] = self.heap.pop() + self.max_heapify(0) + + def print_heap(self): + # Print all values in the heap + print(" ".join(map(str, self.heap))) + + +def main(): + # Initialize max heap + heap = MaxHeap() + + # Insert elements into heap + heap.insert(12) + heap.insert(10) + heap.insert(-10) + heap.insert(100) + + # Print all values in heap + heap.print_heap() + + # Get max value in heap + print("Max Value:", heap.get_max()) + + # Update value in heap + heap.update(12, 5) + print("Max Value after update:", heap.get_max()) + + # Delete max value from heap + heap.delete_max() + print("Max Value after deletion:", heap.get_max()) + + # Print all values in heap after deletion + heap.print_heap() \ No newline at end of file diff --git a/Heaps/Hard/max_heap_CRUD.c++ b/Heaps/Hard/max_heap_CRUD.c++ new file mode 100644 index 00000000..0cebbbdc --- /dev/null +++ b/Heaps/Hard/max_heap_CRUD.c++ @@ -0,0 +1,113 @@ +#include +#include +#include + +class MaxHeap { +private: + std::vector heap; + + // Move the element up the heap until the heap property is restored + void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap[parent] >= heap[index]) { + break; + } + std::swap(heap[parent], heap[index]); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap[left] > heap[largest]) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap[right] > heap[largest]) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + std::swap(heap[largest], heap[index]); + maxHeapify(largest); + } + } + +public: + // Add a new element to the heap and percolate it up to maintain the heap property + void insert(int val) { + heap.push_back(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + int getMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + return heap[0]; + } + + // Update the value, percolate up, and max heapify to maintain the heap property + void update(int old_val, int new_val) { + auto it = std::find(heap.begin(), heap.end(), old_val); + if (it != heap.end()) { + *it = new_val; + percolateUp(it - heap.begin()); + maxHeapify(it - heap.begin()); + } else { + std::cout << "Value not in heap" << std::endl; + } + } + + // Replace the root with the last element, pop the last element, and max heapify + void deleteMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + heap[0] = heap.back(); + heap.pop_back(); + maxHeapify(0); + } + + // Print all values in the heap + void printHeap() { + for (int i : heap) { + std::cout << i << " "; + } + std::cout << std::endl; + } +}; + +int main() { + // Example usage of the MaxHeap class + MaxHeap heap; + + heap.insert(12); + heap.insert(10); + heap.insert(-10); + heap.insert(100); + + std::cout << "All values in heap: "; + heap.printHeap(); + + std::cout << "Max Value: " << heap.getMax() << std::endl; + + heap.update(12, 5); + std::cout << "Max Value after update: " << heap.getMax() << std::endl; + + heap.deleteMax(); + std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + + std::cout << "All values in heap: "; + heap.printHeap(); + + return 0; +} From 5cabcd31d8f962b6e03c4b993bb39fdb2d0986bd Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 11 Dec 2023 20:41:52 +0530 Subject: [PATCH 24/53] Update Readme.md --- Trees/Easy/Inorder Traversal/Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Trees/Easy/Inorder Traversal/Readme.md b/Trees/Easy/Inorder Traversal/Readme.md index d8829cd0..0463f6ae 100644 --- a/Trees/Easy/Inorder Traversal/Readme.md +++ b/Trees/Easy/Inorder Traversal/Readme.md @@ -7,7 +7,7 @@ A tree is a hierarchical data structure which is composed of nodes, where each n Inorder traversal is a method of traversing a binary tree in a specific order. It starts from the leftmost node and moves towards the rightmost node, visiting the left subtree first, then the root, and finally the right subtree. This traversal strategy is fundamental for exploring and processing binary trees systematically. ## Overview -The provided Python code defines a binary tree node using a class named `Node` and demonstrates recursive inorder traversal. The `Node` class has a constructor initializing the node with some data and two pointers, `left` and `right`, representing the left and right children. +The binary tree node uses a class named `Node` and demonstrates recursive inorder traversal. The `Node` class has a constructor initializing the node with some data and two pointers, `left` and `right`, representing the left and right children. ## Step-by-Step Explanation @@ -370,4 +370,4 @@ Binary trees and inorder traversal have applications in various domains, includi - **File Systems:** File systems often use tree structures to organize and locate files efficiently. ## Conclusion -Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. \ No newline at end of file +Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. From fe1aa6d458e40e756edaede2e964fcbef28a8c22 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:26:22 +0530 Subject: [PATCH 25/53] Delete Trees/Easy/Inorder Traversal directory --- Trees/Easy/Inorder Traversal/BinaryTree.java | 51 --- Trees/Easy/Inorder Traversal/Readme.md | 373 ------------------- Trees/Easy/Inorder Traversal/inorder.cpp | 38 -- Trees/Easy/Inorder Traversal/inorder.py | 26 -- 4 files changed, 488 deletions(-) delete mode 100644 Trees/Easy/Inorder Traversal/BinaryTree.java delete mode 100644 Trees/Easy/Inorder Traversal/Readme.md delete mode 100644 Trees/Easy/Inorder Traversal/inorder.cpp delete mode 100644 Trees/Easy/Inorder Traversal/inorder.py diff --git a/Trees/Easy/Inorder Traversal/BinaryTree.java b/Trees/Easy/Inorder Traversal/BinaryTree.java deleted file mode 100644 index 14f798bf..00000000 --- a/Trees/Easy/Inorder Traversal/BinaryTree.java +++ /dev/null @@ -1,51 +0,0 @@ -class TreeNode { - int data; - // Store integer data - TreeNode left = null, - // Left child reference - right = null; - // Right child reference - - public TreeNode(int data) { - // Constructor to create a new TreeNode - this.data = data; - // Assign the given data to this node - } -} - -public class BinaryTree { -// Method for inorder traversal - - static void inorderTraversal(TreeNode root) { - if (root != null) { - inorderTraversal(root.left); - System.out.print(root.data + " "); - inorderTraversal(root.right); - } - } - - public static void main(String[] args) { - - // Creating a binary tree with root node having data 10 - TreeNode root = new TreeNode(10); - - // Adding nodes to the root of the created binary tree - // Adding left and right child nodes to the root - root.left = new TreeNode(20); - root.right = new TreeNode(30); - - // Adding left and right child nodes to the left child of the root - root.left.left = new TreeNode(40); - root.left.right = new TreeNode(50); - - // Adding left and right child nodes to the right child of the root - root.right.left = new TreeNode(60); - root.right.right = new TreeNode(70); - - // Printing the message before performing inorder traversal - System.out.print("Inorder Traversal: "); - - // Calling the inorderTraversal method to perform inorder traversal - inorderTraversal(root); - } -} \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/Readme.md b/Trees/Easy/Inorder Traversal/Readme.md deleted file mode 100644 index 0463f6ae..00000000 --- a/Trees/Easy/Inorder Traversal/Readme.md +++ /dev/null @@ -1,373 +0,0 @@ -# Exploring Binary Trees and Inorder Traversal - -## Introduction to Trees -A tree is a hierarchical data structure which is composed of nodes, where each node has at maximum two children and they are called as left child and right child. This interconnected system is reminiscent of an upside-down tree, with the topmost node called the root. In this structure, nodes hold data, and edges represent connections between nodes. Trees play a crucial role in computer science, serving as versatile tools for tasks such as searching, sorting, and analysis. Each node's ability to have multiple children allows for the creation of complex hierarchical relationships, making trees an indispensable concept for organizing and manipulating data efficiently. Whether utilized for representing hierarchical relationships, optimizing search algorithms, or structuring databases, trees form a foundational element in computer science, contributing to the systematic and effective management of information. - -## Introduction to Inorder Traversal -Inorder traversal is a method of traversing a binary tree in a specific order. It starts from the leftmost node and moves towards the rightmost node, visiting the left subtree first, then the root, and finally the right subtree. This traversal strategy is fundamental for exploring and processing binary trees systematically. - -## Overview -The binary tree node uses a class named `Node` and demonstrates recursive inorder traversal. The `Node` class has a constructor initializing the node with some data and two pointers, `left` and `right`, representing the left and right children. - -## Step-by-Step Explanation - -# Using Python -# code - -```python -class Node: - def __init__(self,data): - self.data=data - self.left=self.right=None -# Recursive Inorder Traversal. -def inorder(root): - # Check if the root exists - if root: - # Perform an inorder traversal on the left subtree - inorder(root.left) - # Print the value of the current node - print(root.data,end=" ") - # Perform an inorder traversal on the right subtree - inorder(root.right) - # Driver code to test above function -# The values of nodes are given below : -if __name__=="__main__": - root=Node(80) - root.left=Node(20) - root.right=Node(30) - root.left.left=Node(40) - root.left.right=Node(350) - root.right.left=Node(460) - root.right.right=Node(70) - inorder(root) -``` - -**Explanation:** - -1. **Node Class Definition:** - -```python -class Node: - def __init__(self, data): - self.data = data - self.left = self.right = None -``` - -This class defines the structure of a binary tree node. Each node has a data attribute to store the value of the node, and left and right attributes to point to the left and right children, respectively. - -2. **Inorder Traversal Function:** - -```python -def inorder(root): - if root: - inorder(root.left) - print(root.data, end=" ") - inorder(root.right) -``` - -This function, inorder, is a recursive implementation of the inorder traversal algorithm. It takes a root node as an argument and performs the following steps: -=> Check if the current root exists. -=> Recursively traverse the left subtree. -=> Print the value of the current node. -=> Recursively traverse the right subtree. - -3.**Driver Code and Tree Initialization** - -```python - if __name__ == "__main__": - root = Node(80) - root.left = Node(20) - root.right = Node(30) - root.left.left = Node(40) - root.left.right = Node(350) - root.right.left = Node(460) - root.right.right = Node(70) -``` - -In the __main__ block, a binary tree is created with the following structure: - - 80 - / \ - 20 30 - / \ / \ - 40 350 460 70 - - -4. **Inorder Traversal Call** - -```python - inorder(root) -``` - -This line calls the inorder function with the root of the tree, initiating the inorder traversal. The result is the values of the nodes printed in ascending order. - -In summary, the code defines a binary tree, initializes it with specific values, and then performs an inorder traversal, printing the values of the nodes in ascending order. The recursive nature of the inorder function is key to traversing the tree systematically. - -# using C++ -# code -```c++ -#include - -class Node{ - public: - int data; - Node *left=NULL; - Node *right=NULL; - - // Node constructor initializes data - Node(int val){ - data=val; - } -}; -void inorder(Node* root){ - // call inorder for left subtree - if(root!=NULL){ - inorder(root->left); - // Print root node data - std::cout<data<<" "; - // call inorder for right subtree - inorder(root->right); - } -} - -int main(){ - // Creating the binary tree - Node* root=new Node(10); - root->left=new Node(20); - root->right=new Node(30); - root->left->left=new Node(40); - root->left->right=new Node(50); - root->right->left=new Node(60); - root->right->right=new Node(70); - // Displaying the binary tree in inorder traversal - inorder(root); - // Inorder traversal of the tree - return 0; -} -``` -**Explanation** - -1. **Header Inclusion**: - - ```cpp - #include - ``` - - This line includes a standard C++ library header, which is a common practice to include necessary headers like `` for input and output. - -2. **Node Class Definition:** - - ```cpp - class Node { - public: - int data; - Node *left = NULL; - Node *right = NULL; - - // Node constructor initializes data - Node(int val) { - data = val; - } - }; - ``` - - This part defines a `Node` class representing nodes in a binary tree. Each node contains an integer `data`, a pointer to the left child (`left`), and a pointer to the right child (`right`). The constructor initializes the node with the provided data value. - -3. **Inorder Traversal Function:** - - ```cpp - void inorder(Node* root) { - // call inorder for the left subtree - if (root != NULL) { - inorder(root->left); - // Print root node data - std::cout << root->data << " "; - // call inorder for the right subtree - inorder(root->right); - } - } - ``` - - The `inorder` function performs recursive inorder traversal on the binary tree. It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. - -4. **Main Function:** - - ```cpp - int main() { - // Creating the binary tree - Node* root = new Node(10); - root->left = new Node(20); - root->right = new Node(30); - root->left->left = new Node(40); - root->left->right = new Node(50); - root->right->left = new Node(60); - root->right->right = new Node(70); - - // Displaying the binary tree in inorder traversal - inorder(root); - - // Inorder traversal of the tree - return 0; - } - ``` - - In the `main` function, a binary tree is created with specific values. Nodes are allocated dynamically using the `new` keyword. The `inorder` function is then called to display the binary tree in inorder traversal, printing the values of the nodes in ascending order. - -In summary, this C++ program defines a binary tree using a `Node` class, creates a binary tree with specific values, and performs an inorder traversal to display the tree's content. The code demonstrates the concept of recursive traversal in a binary tree. -This code will output `40 20 50 10 60 30 70`, which is a correct - -# using Java -# Code - -```java -class TreeNode { - int data; - // Store integer data - TreeNode left = null, - // Left child reference - right = null; - // Right child reference - - public TreeNode(int data) { - // Constructor to create a new TreeNode - this.data = data; - // Assign the given data to this node - } -} - -public class BinaryTree { -// Method for inorder traversal - - static void inorderTraversal(TreeNode root) { - if (root != null) { - inorderTraversal(root.left); - System.out.print(root.data + " "); - inorderTraversal(root.right); - } - } - - public static void main(String[] args) { - - // Creating a binary tree with root node having data 10 - TreeNode root = new TreeNode(10); - - // Adding nodes to the root of the created binary tree - // Adding left and right child nodes to the root - root.left = new TreeNode(20); - root.right = new TreeNode(30); - - // Adding left and right child nodes to the left child of the root - root.left.left = new TreeNode(40); - root.left.right = new TreeNode(50); - - // Adding left and right child nodes to the right child of the root - root.right.left = new TreeNode(60); - root.right.right = new TreeNode(70); - - // Printing the message before performing inorder traversal - System.out.print("Inorder Traversal: "); - - // Calling the inorderTraversal method to perform inorder traversal - inorderTraversal(root); - } -} - -``` -**explanation** - -1. **TreeNode Class Definition:** - ```java - class TreeNode { - int data; - TreeNode left = null, right = null; - - public TreeNode(int data) { - this.data = data; - } - } - ``` - - - `TreeNode` class defines the structure of a binary tree node. - - It has an `int` variable `data` to store the node's value and references (`left` and `right`) to its left and right children. - - The constructor initializes a new `TreeNode` with the given data. - -2. **BinaryTree Class:** - ```java - public class BinaryTree { - // Method for inorder traversal - - static void inorderTraversal(TreeNode root) { - if (root != null) { - inorderTraversal(root.left); - System.out.print(root.data + " "); - inorderTraversal(root.right); - } - } - ``` - - This class contains a method `inorderTraversal` that performs recursive inorder traversal on a binary tree. - - It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. - - InorderTraversal` is a static method used for inorder traversal of the binary tree. - - It is a recursive function that traverses the left subtree, prints the data of the current node, and then traverses the right subtree. - -3. **Main Method:** - ```java - public static void main(String[] args) { - // Creating a binary tree with root node having data 10 - TreeNode root = new TreeNode(10); - - // Adding nodes to the root of the created binary tree - // Adding left and right child nodes to the root - root.left = new TreeNode(20); - root.right = new TreeNode(30); - - // Adding left and right child nodes to the left child of the root - root.left.left = new TreeNode(40); - root.left.right = new TreeNode(50); - - // Adding left and right child nodes to the right child of the root - root.right.left = new TreeNode(60); - root.right.right = new TreeNode(70); - - // Printing the message before performing inorder traversal - System.out.print("Inorder Traversal: "); - - // Calling the inorderTraversal method to perform inorder traversal - inorderTraversal(root); - } - ``` - - - The `main` method is the entry point of the program. - - It creates an instance of the `TreeNode` class, representing the root of the binary tree, with a data value of 10. - - Child nodes are added to the root, forming a binary tree structure. - - The `inorderTraversal` method is called to perform an inorder traversal of the tree, printing the nodes in ascending order. - - -4. **Tree Structure:** - ``` - 10 - / \ - 20 30 - / \ / \ - 40 50 60 70 - ``` - -5. **Output:** - ``` - Inorder Traversal: 40 20 50 10 60 30 70 - ``` - -In summary, this Java program demonstrates the creation of a binary tree, addition of nodes, and the execution of an inorder traversal. The `TreeNode` class encapsulates the node structure, and the `BinaryTree` class utilizes it to construct and traverse the binary tree. - - -## Time and Space Complexity Analysis -- Time Complexity: The time complexity of the inorder traversal is O(n), where n is the number of nodes in the tree. This is because each node is visited once. -- Space Complexity: The space complexity is O(h), where h is the height of the binary tree. In the worst case (skewed tree), the height is n, making the space complexity O(n). In a balanced tree, the height is log(n), resulting in a space complexity of O(log(n)). - -## Real-World Applications -Binary trees and inorder traversal have applications in various domains, including: -- **Database Indexing:** Binary trees are used in database systems to efficiently index and search for records. -- **Expression Trees:** In compilers, expression trees are used to represent mathematical expressions for efficient evaluation. -- **File Systems:** File systems often use tree structures to organize and locate files efficiently. - -## Conclusion -Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. diff --git a/Trees/Easy/Inorder Traversal/inorder.cpp b/Trees/Easy/Inorder Traversal/inorder.cpp deleted file mode 100644 index 2c04554e..00000000 --- a/Trees/Easy/Inorder Traversal/inorder.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include - -class Node{ - public: - int data; - Node *left=NULL; - Node *right=NULL; - - // Node constructor initializes data - Node(int val){ - data=val; - } -}; -void inorder(Node* root){ - // call inorder for left subtree - if(root!=NULL){ - inorder(root->left); - // Print root node data - std::cout<data<<" "; - // call inorder for right subtree - inorder(root->right); - } -} - -int main(){ - // Creating the binary tree - Node* root=new Node(10); - root->left=new Node(20); - root->right=new Node(30); - root->left->left=new Node(40); - root->left->right=new Node(50); - root->right->left=new Node(60); - root->right->right=new Node(70); - // Displaying the binary tree in inorder traversal - inorder(root); - // Inorder traversal of the tree - return 0; -} \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/inorder.py b/Trees/Easy/Inorder Traversal/inorder.py deleted file mode 100644 index cb629501..00000000 --- a/Trees/Easy/Inorder Traversal/inorder.py +++ /dev/null @@ -1,26 +0,0 @@ -# Definition for a binary tree node -class Node: - def __init__(self,data): - self.data=data - self.left=self.right=None -# Recursive Inorder Traversal. -def inorder(root): - # Check if the root exists - if root: - # Perform an inorder traversal on the left subtree - inorder(root.left) - # Print the value of the current node - print(root.data,end=" ") - # Perform an inorder traversal on the right subtree - inorder(root.right) - # Driver code to test above function -# The values of nodes are given below : -if __name__=="__main__": - root=Node(80) - root.left=Node(20) - root.right=Node(30) - root.left.left=Node(40) - root.left.right=Node(350) - root.right.left=Node(460) - root.right.right=Node(70) - inorder(root) \ No newline at end of file From ae4fd7d49a86d123503c88db0841832c6b42a607 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:26:42 +0530 Subject: [PATCH 26/53] Delete Strings directory --- Strings/Medium/String to Integer/Readme.md | 481 ------------------ Strings/Medium/String to Integer/main.java | 26 - .../String to Integer/stringtointeger.cpp | 31 -- .../String to Integer/stringtointeger.py | 40 -- .../PalindromePartitioning.java | 39 -- .../Medium/palindrome partitioning/Readme.md | 379 -------------- .../palindromepartition.py | 22 - .../palindrompartition.c++ | 53 -- 8 files changed, 1071 deletions(-) delete mode 100644 Strings/Medium/String to Integer/Readme.md delete mode 100644 Strings/Medium/String to Integer/main.java delete mode 100644 Strings/Medium/String to Integer/stringtointeger.cpp delete mode 100644 Strings/Medium/String to Integer/stringtointeger.py delete mode 100644 Strings/Medium/palindrome partitioning/PalindromePartitioning.java delete mode 100644 Strings/Medium/palindrome partitioning/Readme.md delete mode 100644 Strings/Medium/palindrome partitioning/palindromepartition.py delete mode 100644 Strings/Medium/palindrome partitioning/palindrompartition.c++ diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md deleted file mode 100644 index b444b84b..00000000 --- a/Strings/Medium/String to Integer/Readme.md +++ /dev/null @@ -1,481 +0,0 @@ -# Exploring Strings and Converting them to Integers : - -"Exploring Strings and Converting them to Integers" concept likely involves working with strings in a programming context and performing operations that involve converting these strings into integer values. - -**Exploring Strings** : This suggests that we will be working with strings, which are sequences of characters. Exploring strings may involve tasks such as accessing individual characters, finding the length of a string, or manipulating the content in various ways. -**Converting Strings to Integers** : The main task is likely to involve converting strings into integer values. This conversion is common in programming when dealing with user input or data read from external sources, where the input is initially in the form of text (string) but needs to be processed as numerical values (integers). - -# Introduction to Strings: - -A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. -Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. - -# Introduction to the String to Integer Theory: - -One of the frequent challenges encountered in programming involves converting strings to integers. This operation is particularly crucial when dealing with user inputs, file parsing, or scenarios where numeric values need extraction from a textual context. The process entails considering signs, handling leading whitespaces, and ensuring that the resulting integer falls within the appropriate range. - -# Overview of String to Integer: - -The problem involves working with strings, extracting numerical information from them, converting this information to integers, and potentially performing operations on these integers. The specific details would depend on the context and requirements of the problem as defined in the prompt or task description. -some of the common tasks that might encounter within this problem statement: - -**Parsing Integers** : Extracting numerical values from a string. This involves identifying and extracting the sequence of characters that represents an integer. - -**Handling Edge Cases** : Dealing with situations where the string may not represent a valid integer (e.g., contains non-numeric characters). Error handling may be required. - -**Performing Arithmetic Operations** : Once the strings are converted to integers, you might be asked to perform various arithmetic operations (addition, subtraction, multiplication, etc.) on these values. - -**Output Formatting** : Displaying the results in a specified format, which may involve converting integers back to strings for output. - -# PYTHON -# code -```python -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// python program to convert string to integer -// Stable: Yes -// Inplace: No -// Adaptive: Yes - -// Space complexity:O(n) -// Time complexity:O(1) - -def check(answer): - # Check if the answer is less than the minimum 32-bit signed integer - if answer < -2**31: - return -2**31 - # Check if the answer is greater than or equal to the maximum 32-bit signed integer - elif answer >= 2**31: - return 2**31 - 1 - else: - return answer - -def myAtoi(string): - # Initialize variables - answer = 0 - sign = 0 # 0 represents no sign, 1 represents positive sign, -1 represents negative sign - i = 0 - - # Skip leading whitespaces - while i < len(string) and string[i] == " ": - i += 1 - # If the entire string is composed of whitespaces, return the current answer - if i == len(string): - return answer - - # Check for positive sign - if string[i] == "+" and sign == 0: - sign = 1 - i += 1 - - # Check for negative sign - if i < len(string) and string[i] == "-" and sign == 0: - sign = -1 - i += 1 - - # Process the digits of the string - while i < len(string): - # Check if the current character is a digit - if string[i].isdigit(): - # Update the answer by multiplying it by 10 and adding the current digit - answer = answer * 10 + int(string[i]) - i += 1 - else: - # If a non-digit character is encountered, apply the sign if present and return the result after checking for overflow - if sign != 0: - answer = sign * answer - return check(answer) - - # Apply the sign if present and return the result after checking for overflow - if sign != 0: - answer = sign * answer - return check(answer) - -# Test the function with the provided string "42" -if __name__ == "__main__": - s = "42" - print(myAtoi(s)) - -``` -# Code Explanation - -1. **`check` function:** - ```python - def check(answer): - if answer < -2**31: - return -2**31 - elif answer >= 2**31: - return 2**31 - 1 - else: - return answer - ``` - - This function takes an `answer` as input and checks if it is within the range of a 32-bit signed integer. If it's less than the minimum value, it returns the minimum value. If it's greater than or equal to the maximum value, it returns the maximum value. Otherwise, it returns the original answer. - -2. **`myAtoi` function:** - ```python - def myAtoi(string): - answer = 0 - sign = 0 - i = 0 - - # Skip leading whitespaces - while i < len(string) and string[i] == " ": - i += 1 - if i == len(string): - return answer - - # Check for positive sign - if string[i] == "+" and sign == 0: - sign = 1 - i += 1 - - # Check for negative sign - if i < len(string) and string[i] == "-" and sign == 0: - sign = -1 - i += 1 - - # Process the digits of the string - while i < len(string): - if string[i].isdigit(): - # Update the answer by multiplying it by 10 and adding the current digit - answer = answer * 10 + int(string[i]) - i += 1 - else: - # If a non-digit character is encountered, apply the sign if present and return the result after checking for overflow - if sign != 0: - answer = sign * answer - return check(answer) - - # Apply the sign if present and return the result after checking for overflow - if sign != 0: - answer = sign * answer - return check(answer) - ``` - - This function takes a string `string` as input and converts it to an integer according to the rules specified. - - It initializes `answer` to store the result, `sign` to store the sign of the number, and `i` as an index to iterate through the string. - - It skips leading whitespaces in the string. - - It checks for positive or negative signs and sets the `sign` accordingly. - - It iterates through the string, processes digits, and updates the `answer`. - - If a non-digit character is encountered, it applies the sign if present and returns the result after checking for overflow using the `check` function. - - Finally, it returns the checked and signed result. - -3. **Test the function:** - ```python - if __name__ == "__main__": - s = "42" - print(myAtoi(s)) - ``` - - It tests the `myAtoi` function with the input string "42" and prints the result. - -The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of a 32-bit signed integer. The `check` function ensures that the result does not exceed the specified integer limits. - -# C++ -# code -```c++ -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// C++ program to convert string to integer -// Stable: Yes -// Inplace: No -// Adaptive: No - -// Space complexity: O(n) -// Time complexity: O(1) - -#include - -int atoi(std::string s) -{ - int num = 0, i = 0, sign = 1; - while (s[i] == ' ') - { - i++; - } - if (i < s.length() && (s[i] == '-' || s[i] == '+')) - { - sign = s[i] == '+' ? 1 : -1; - i++; - } - while (i < s.length() && isdigit(s[i])) - { - - if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) - return sign == 1 ? INT_MAX : INT_MIN; - num = ((num * 10) + (s[i] - '0')); - i++; - } - return num * sign; -} - -int main() -{ - std::string s = "42"; - std::cout << atoi(s); - return 0; -} -``` -# Code Explanation - -1. **Function Definition:** - ```cpp - int myAtoi(const std::string &str) { - ``` - - The function `myAtoi` is defined, taking a constant reference to a `std::string` as input and returning an integer. - -2. **Variable Initialization:** - ```cpp - long result = 0; - int sign = 1; // 1 represents positive sign, -1 represents negative sign - size_t i = 0; - ``` - - Initialize `result` to store the converted integer. - - Initialize `sign` to 1 by default (positive sign). - - Initialize `i` as an index to iterate through the string. - -3. **Skip Leading Whitespaces:** - ```cpp - while (i < str.length() && isspace(str[i])) { - i++; - } - ``` - - Use a `while` loop to skip leading whitespaces in the input string. - -4. **Check for Positive or Negative Sign:** - ```cpp - if (i < str.length() && (str[i] == '+' || str[i] == '-')) { - sign = (str[i++] == '-') ? -1 : 1; - } - ``` - - Check for the presence of a positive or negative sign. - - Update the `sign` accordingly and increment `i` if a sign is found. - -5. **Process Digits:** - ```cpp - while (i < str.length() && isdigit(str[i])) { - result = result * 10 + (str[i++] - '0'); - - // Check for overflow - if (result * sign > INT_MAX) { - return INT_MAX; - } else if (result * sign < INT_MIN) { - return INT_MIN; - } - } - ``` - - Iterate through the string, processing digits and updating the `result`. - - Check for overflow by comparing against `INT_MAX` and `INT_MIN`. Return appropriate values if overflow is detected. - -6. **Apply Sign and Return Result:** - ```cpp - return static_cast(result * sign); - } - ``` - - Apply the sign to the result and return the final converted integer. - -7. **Main Function:** - ```cpp - int main() { - std::string s = "42"; - std::cout << myAtoi(s) << std::endl; - return 0; - } - ``` - - In the `main` function, a test string "42" is provided, and the result of the `myAtoi` function is printed. - -The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of an integer. The `myAtoi` function returns the converted integer, and the `main` function tests it with the string "42". - -# java -# code -```java -public class main{ - - static int atoi(String s) { - int num = 0, i = 0, sign = 1; - while (i < s.length() && s.charAt(i) == ' ') { - i++; - } - if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { - sign = s.charAt(i) == '+' ? 1 : -1; - i++; - } - while (i < s.length() && Character.isDigit(s.charAt(i))) { - int digit = s.charAt(i) - '0'; - if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { - return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; - } - num = (num * 10) + digit; - i++; - } - return num * sign; - } - public static void main(String[] args) { - String s="42"; - System.out.println(atoi(s)); - } -} - -``` -# Code Explanation - -1. **Class Definition:** - ```java - public class Main { - ``` - - The class is named `Main`. - -2. **Static `atoi` Method:** - ```java - static int atoi(String s) { - ``` - - A static method named `atoi` is defined, which takes a `String` as input and returns an `int`. - -3. **Variable Initialization:** - ```java - int num = 0, i = 0, sign = 1; - ``` - - Initialize `num` to store the converted integer. - - Initialize `i` as an index to iterate through the string. - - Initialize `sign` to 1 by default (positive sign). - -4. **Skip Leading Whitespaces:** - ```java - while (i < s.length() && s.charAt(i) == ' ') { - i++; - } - ``` - - Use a `while` loop to skip leading whitespaces in the input string. - -5. **Check for Positive or Negative Sign:** - ```java - if (i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { - sign = s.charAt(i) == '+' ? 1 : -1; - i++; - } - ``` - - Check for the presence of a positive or negative sign. - - Update the `sign` accordingly and increment `i` if a sign is found. - -6. **Process Digits:** - ```java - while (i < s.length() && Character.isDigit(s.charAt(i))) { - int digit = s.charAt(i) - '0'; - if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { - return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; - } - num = (num * 10) + digit; - i++; - } - ``` - - Iterate through the string, processing digits and updating the `num`. - - Check for overflow by comparing against `Integer.MAX_VALUE`. - - Return `Integer.MAX_VALUE` or `Integer.MIN_VALUE` if overflow is detected. - -7. **Return Result:** - ```java - return num * sign; - } - ``` - - Apply the sign to the result (`num`) and return the final converted integer. - -8. **Main Method:** - ```java - public static void main(String[] args) { - String s = "42"; - System.out.println(atoi(s)); - } - ``` - - The `main` method tests the `atoi` method with the string "42" and prints the result. - -The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of an integer. The `atoi` method returns the converted integer, and the `main` method tests it with the string "42". - -# Time and Space Complexity Analysis : - -The time and space complexity for the atoi method, which converts a string to an integer. - -# Time Complexity: - -The time complexity of the atoi method is O(n), where n is the length of the input string. - - The while loop for skipping leading whitespaces runs in O(n) time because, in the worst case, it may have to iterate through the entire string. - The subsequent while loop for processing digits also runs in O(n) time, where n is the length of the string. This loop iterates through the digits of the string, and each iteration takes constant time. - -Therefore, the overall time complexity is O(n). -# Space Complexity: - -The space complexity of the atoi method is O(1), constant space. - - The variables num, i, and sign are integers and require constant space regardless of the size of the input string. - No additional data structures are used that scale with the input size. - -The space complexity is constant or O(1). - -# Real-World Applications of string to integer - -Converting a string to an integer is a common operation in various real-world applications. Here are some examples: - -1. **User Input Processing:** - - In applications that accept user input, such as command-line interfaces or forms on websites, string-to-integer conversion is necessary to interpret numeric inputs provided by users. - -2. **Data Validation:** - - When dealing with external data sources, such as files or databases, where data is often represented as strings, converting relevant string values to integers is crucial for data validation and ensuring that the data meets expected numeric formats. - -3. **Parsing and Interpreting Configuration Files:** - - Many applications use configuration files to store settings. When reading these files, string-to-integer conversion is employed to interpret numeric configurations, such as specifying the number of threads, timeouts, or buffer sizes. - -4. **Network Protocols:** - - In network programming, especially when dealing with protocols that transmit data in string format, converting certain fields to integers is common. For instance, parsing HTTP headers or handling custom network protocols may involve converting string representations of numerical values to integers. - -5. **Database Operations:** - - In database applications, where data is often retrieved in string format, converting relevant data to integers is necessary for performing numerical operations or ensuring consistency in data types. - -6. **Mathematical Computations:** - - In scientific computing or applications involving mathematical calculations, converting strings to integers is essential when processing mathematical expressions or user-provided numerical data. - -7. **Financial Applications:** - - In financial software, handling monetary values often involves converting string representations of amounts to integers (or floating-point numbers) for accurate calculations. - -8. **Gaming and Graphics Programming:** - - Game development and graphics programming may require converting string representations of parameters, such as screen dimensions or frame rates, to integers for configuring the game environment or rendering settings. - -9. **Command-Line Interfaces (CLI):** - - CLI applications often take user inputs as strings, and converting these inputs to integers is necessary for executing numeric commands or configuring the behavior of the application. - -10. **Sensor Data Processing:** - - In embedded systems or IoT applications, sensor data received in string format may need to be converted to integers for further analysis or decision-making based on numeric thresholds. - -In essence, string-to-integer conversion is a fundamental operation in software development, as it facilitates the integration and processing of numerical information in various domains. -In addition to the real-world applications mentioned earlier, let's explore some theoretical scenarios or examples where string-to-integer conversion plays a crucial role: - -1. **Algorithmic Problem Solving:** - - In algorithmic problems, you may encounter scenarios where input is provided as strings, and converting these strings to integers is a common step. For example, when implementing algorithms that involve mathematical computations, sorting, or searching, converting string inputs to integers allows for efficient processing. - -2. **String Matching Algorithms:** - - String matching algorithms, such as the Knuth-Morris-Pratt algorithm or the Boyer-Moore algorithm, may involve comparing and manipulating string representations of integers. Converting these strings to integers allows for efficient pattern matching and searching. - -3. **Abstract Data Types (ADTs):** - - In the design and implementation of abstract data types, converting string representations of numerical data to actual integers is often necessary. For instance, when implementing a priority queue where elements are associated with numeric priorities provided as strings, conversion to integers is crucial for proper ordering. - -4. **Parsing and Interpretation of Domain-Specific Languages:** - - When working with domain-specific languages or custom file formats, interpreting and parsing string representations of numeric values is fundamental. Converting these strings to integers allows for the proper interpretation of data and execution of language-specific commands. - -5. **Code Analysis and Transformation:** - - In static code analysis or transformation tools, understanding and manipulating numeric constants within code may require converting string representations to integers. This is useful for performing optimizations, refactoring, or analyzing code patterns. - -6. **Symbolic Computation:** - - In symbolic computation systems, where algebraic expressions are manipulated symbolically, converting string representations of numeric coefficients or constants to actual integers is necessary for performing mathematical operations. - -7. **Formal Language Theory:** - - In formal language theory, automata, and compilers, parsing numeric literals from strings is a common operation. Converting these literals to integers is crucial for generating executable code or performing language analysis. - -8. **Graph Theory and Network Analysis:** - - When working with graph representations, especially in scenarios where nodes or edges are labeled with numeric identifiers provided as strings, converting these identifiers to integers facilitates efficient graph algorithms and analysis. - -9. **Cryptography:** - - In cryptographic applications, handling cryptographic keys or parameters, often represented as strings, may require converting these string representations to integers for cryptographic operations. - -10. **Educational Examples:** - - In educational contexts, when teaching programming or algorithms, string-to-integer conversion serves as a fundamental concept. Exercises and examples often involve converting user inputs or string data to integers for various purposes. - -In theoretical scenarios, the importance of string-to-integer conversion arises in the context of solving abstract problems, designing algorithms, and implementing various computational concepts. diff --git a/Strings/Medium/String to Integer/main.java b/Strings/Medium/String to Integer/main.java deleted file mode 100644 index bedd751b..00000000 --- a/Strings/Medium/String to Integer/main.java +++ /dev/null @@ -1,26 +0,0 @@ -public class main{ - - static int atoi(String s) { - int num = 0, i = 0, sign = 1; - while (i < s.length() && s.charAt(i) == ' ') { - i++; - } - if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { - sign = s.charAt(i) == '+' ? 1 : -1; - i++; - } - while (i < s.length() && Character.isDigit(s.charAt(i))) { - int digit = s.charAt(i) - '0'; - if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { - return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; - } - num = (num * 10) + digit; - i++; - } - return num * sign; - } - public static void main(String[] args) { - String s="42"; - System.out.println(atoi(s)); - } -} \ No newline at end of file diff --git a/Strings/Medium/String to Integer/stringtointeger.cpp b/Strings/Medium/String to Integer/stringtointeger.cpp deleted file mode 100644 index bdb57305..00000000 --- a/Strings/Medium/String to Integer/stringtointeger.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include - -int atoi(std::string s) -{ - int num = 0, i = 0, sign = 1; - while (s[i] == ' ') - { - i++; - } - if (i < s.length() && (s[i] == '-' || s[i] == '+')) - { - sign = s[i] == '+' ? 1 : -1; - i++; - } - while (i < s.length() && isdigit(s[i])) - { - - if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) - return sign == 1 ? INT_MAX : INT_MIN; - num = ((num * 10) + (s[i] - '0')); - i++; - } - return num * sign; -} - -int main() -{ - std::string s = "42"; - std::cout << atoi(s); - return 0; -} \ No newline at end of file diff --git a/Strings/Medium/String to Integer/stringtointeger.py b/Strings/Medium/String to Integer/stringtointeger.py deleted file mode 100644 index 28122421..00000000 --- a/Strings/Medium/String to Integer/stringtointeger.py +++ /dev/null @@ -1,40 +0,0 @@ -def check(answer): - if answer<-2**31: - return -2**31 - elif answer>=2**31: - return 2**31-1 - else: - return answer - -def myAtoi(string): - answer=0 - sign=0 - i=0 - - while(i ds, List> output, String str){ - if(index == str.length()){ - output.add(new ArrayList<>(ds)); - return; - } - for(int i = index; i < str.length(); i++){ - if(checkPalindrome(str, index, i)){ - ds.add(str.substring(index, i + 1)); - palindromePartition(i+1, ds, output, str); - ds.remove(ds.size()-1); - } - } - } - static List> partition(String s) { - List> output = new ArrayList<>(); - List ds = new ArrayList<>(); - palindromePartition(0, ds, output, s); - return output; - } - - public static void main(String[] args) { - String s="aab"; - System.out.println(partition(s)); - } - -} \ No newline at end of file diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md deleted file mode 100644 index f8e846d6..00000000 --- a/Strings/Medium/palindrome partitioning/Readme.md +++ /dev/null @@ -1,379 +0,0 @@ -# Exploring palindrome partitioning using Strings: - -Exploring palindrome partitioning with strings often involves dynamic programming. The idea is to build a table or array to store intermediate results, helping to avoid redundant computations and improve the overall efficiency of the algorithm. - -# Introduction to Strings: - -A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. -Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. - -# Introduction to the Palindrome Partitioning Theory: - -A palindrome is a sequence of characters that reads the same backward as forward. Examples include "level," "radar," and "madam". Palindrome partitioning is a concept in theoretical computer science and mathematics that involves breaking down a string into substrings, with the condition that each substring is a palindrome.The goal of palindrome partitioning is to find all possible ways to split a given string into palindromic substrings. - -# Overview of Palindrome Partitioning: - -Given a string, the problem is to find all possible ways to partition it into palindromic substrings. - -# PYTHON -# code - -```python -# Copyrights to venkys.io -# For more information, visit https://venkys.io - -# python program for Palindrome Partitioning -# Stable: No -# Inplace: No -# Adaptive: Not Applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) - -# Space complexity:O(n^2) -# Time complexity:O(n^2) - -def partition(string): - # Initialize dynamic programming array - dp=[[] for _ in range(len(string)+1)] - - # Initialize the first state with an empty partition - dp[0]=[[]] - -# Iterate over each character of the string - for j in range(1,len(string)+1): - # Iterate through each previous character - for i in range(j): - # Check if the substring is a palindrome - if string[i:j]==string[i:j][::-1]: - # If so, extend the partitions ending at i with the palindrome substring - for each in dp[i]: - dp[j].append(each+[string[i:j]]) - # Return the final state, which contains all valid partitions - return dp[-1] - -if __name__=="__main__": - string="ababa" - print(partition(string)) -``` -# Code Explanation - -1. **Dynamic Programming Array (`dp`):** - - `dp` is a list of lists used for dynamic programming. It represents the state of the algorithm at each position in the input string. - -2. **Initialization:** - - `dp[0]` is initialized with an empty list representing the empty partition for the first state. - -3. **Iterating Over Characters (`j`):** - - The outer loop (`for j in range(1, len(string) + 1)`) iterates over each character in the input string, starting from the second character. - -4. **Iterating Over Previous Characters (`i`):** - - The inner loop (`for i in range(j)`) iterates through each previous character (from the beginning of the string up to `j`). - -5. **Palindrome Check:** - - `if string[i:j] == string[i:j][::-1]:` checks if the substring from `i` to `j` is a palindrome. - -6. **Updating Partitions:** - - If the substring is a palindrome, it extends the partitions ending at position `i` with the palindrome substring. It uses a nested loop to iterate through each existing partition at position `i` (`for each in dp[i]`) and appends the current palindrome substring to create new partitions. - -7. **Final Result:** - - The final state is represented by `dp[-1]`, which contains all valid partitions, and it is returned as the output of the function. - -8. **Example Usage:** - - The provided example with `string = "ababa"` demonstrates how the function can be called and prints the result of partitioning the given string into palindromic substrings. - -The algorithm employs dynamic programming to efficiently find and extend palindrome partitions in the input string. - -# C++ -# code - -```C++ -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// C++ program Palindrome Partitioning -// Stable: No -// Inplace:No -// Adaptive: Not applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) - -// Space complexity:O(n^2) -// Time complexity:O(n^2) - -#include -bool isPalindrome(std::string s, int i, int j) { - // While loop checks the string symmetrically. - while (i <= j) { - // If characters at different ends don't match, it's not a palindrome. - if (s[i++] != s[j--]) return false; - } - // If loop finished, the string is a palindrome. - return true; -} -void util(int i,std::string s,std::vector>& res,std::vector& path){ - // base case: when string s is fully processed - if(i==s.size()){ - res.push_back(path); - return ; - } - // iteratively checking each substring - for(int j=i;j> partition (std::string s){ - // Output list of all palindrome partitions - std::vector> res; - // List to keep track of the current path - std::vector path; - // Utility function to find all palindrome partitions - util(0,s,res,path); - return res; -} -int main(){ - // initial string to be partitioned - std::string s = "aaab"; - // function call to get all partitions - std::vector> ans=partition(s); - // loop to print all partitions - for(auto& a:ans){ - for(auto& b:a){ - std::cout< ds, List> output, String str){ - if(index == str.length()){ - output.add(new ArrayList<>(ds)); - return; - } - for(int i = index; i < str.length(); i++){ - if(checkPalindrome(str, index, i)){ - ds.add(str.substring(index, i + 1)); - palindromePartition(i+1, ds, output, str); - ds.remove(ds.size()-1); - } - } - } - - // Main function to return all the palindrome partitioning - static List> partition(String s) { - List> output = new ArrayList<>(); - List ds = new ArrayList<>(); - palindromePartition(0, ds, output, s); - return output; - } - - public static void main(String[] args) { - String s="aab"; - System.out.println(partition(s)); - } - -} - -``` -# Code Explanation - -Certainly! Let's break down the provided Java code step by step: - -```java -import java.util.ArrayList; -import java.util.List; - -class PalindromePartitioning { - - // Function to check if a substring is a palindrome - static boolean checkPalindrome(String str, int startIndex, int lastIndex) { - while (startIndex <= lastIndex) { - if (str.charAt(startIndex) != str.charAt(lastIndex)) - return false; - startIndex++; - lastIndex--; - } - return true; - } - - // Function to generate all the palindrome partitioning - static void palindromePartition(int index, List ds, List> output, String str) { - if (index == str.length()) { - output.add(new ArrayList<>(ds)); - return; - } - for (int i = index; i < str.length(); i++) { - if (checkPalindrome(str, index, i)) { - ds.add(str.substring(index, i + 1)); - palindromePartition(i + 1, ds, output, str); - ds.remove(ds.size() - 1); - } - } - } - - // Main function to return all the palindrome partitioning - static List> partition(String s) { - List> output = new ArrayList<>(); - List ds = new ArrayList<>(); - palindromePartition(0, ds, output, s); - return output; - } - - public static void main(String[] args) { - String s = "aab"; - System.out.println(partition(s)); - } - -} -``` - -**Explanation:** - -1. **`checkPalindrome` Function:** - - This function checks whether a given substring of a string is a palindrome. - - It takes three parameters: - - `str`: The input string. - - `startIndex`: The starting index of the substring. - - `lastIndex`: The ending index of the substring. - - It uses a `while` loop to check if the characters at the given indices are equal, iterating towards the center of the substring. If at any point they are not equal, the function returns `false`. Otherwise, it returns `true`. - -2. **`palindromePartition` Function:** - - This recursive function generates all possible palindrome partitions of the input string. - - It takes four parameters: - - `index`: The current index in the string. - - `ds`: A list representing the current path of partitions. - - `output`: A list of lists to store all palindrome partitions. - - `str`: The input string. - - The base case is when the `index` reaches the length of the string. At this point, the current path (`ds`) is added to the `output` list. - - It uses a `for` loop to iterate from the current index to the end of the string. - - If the substring from the current index to the loop variable `i` is a palindrome (checked using `checkPalindrome`), it adds the substring to the current path (`ds`) and recursively calls itself with the updated index (`i + 1`). - - After the recursive call, it removes the last added substring from the current path to explore other possibilities. - -3. **`partition` Function:** - - This is the main function that initializes the necessary lists and calls `palindromePartition` to find all palindrome partitions. - - It takes the input string `s`, creates an empty list for the output, and an empty list for the current path (`ds`). - - It calls `palindromePartition` with the initial index (`0`), current path (`ds`), output list (`output`), and the input string (`s`). - -4. **`main` Function:** - - The `main` function demonstrates the usage of the `partition` function on the string "aab." - - It prints the result obtained from the `partition` function. - -**Example Output:** - -[[a, a, b], [aa, b]] - - -The code efficiently finds and prints all possible palindrome partitions of the input string "aab" using a recursive approach. - - -# Time and Space Complexity Analysis: - -# Time Complexity: -O(n^2), where n is the length of the input string. -The dynamic programming table is typically a 2D array of size n x n, and each entry requires constant time to compute. -# Space Complexity: -O(n^2). -The space complexity is determined by the 2D table used for memoization or tabulation. - -# Real-World Applications of Palindrome Partitioning - -Palindrome partitioning, while primarily a concept used in algorithmic problem-solving, has applications in various real-world scenarios. Here are some areas where the concept of palindrome partitioning or similar techniques can be applied: - -1. **Genomic Sequence Analysis:** - - In bioinformatics, palindrome partitioning techniques can be used for analyzing DNA or RNA sequences. Identifying palindromic sequences can provide insights into the structure and function of genetic material. - -2. **Text Processing and Pattern Matching:** - - Palindrome partitioning concepts can be applied in text processing and pattern matching. For example, identifying palindromic patterns in text can be useful in natural language processing or searching for specific structures in documents. - -3. **Data Compression:** - - Palindromes can be leveraged in data compression algorithms. Identifying and encoding repeated palindromic patterns efficiently can contribute to the compression of data. - -4. **Cryptography:** - - In certain cryptographic algorithms, palindromic structures or related concepts might be employed for creating secure key structures or encoding information. - -5. **Speech Processing:** - - Palindrome partitioning techniques could be applied in speech processing, especially in the analysis of phonetic or acoustic sequences. - -6. **Fault-Tolerant Systems:** - - Palindrome-related algorithms can be used in fault-tolerant systems, where the identification of symmetric or repeating patterns helps in recognizing and correcting errors. - -7. **Robotics and Image Processing:** - - Palindrome partitioning methods may find applications in robotics and image processing. For instance, in image recognition, identifying symmetrical patterns can aid in object recognition. - -8. **Algorithmic Design and Optimization:** - - Understanding and solving problems related to palindrome partitioning contribute to the development of efficient algorithms. These algorithms, in turn, find applications in various computational fields, including data analysis and optimization. - -9. **Network Security:** - - Palindrome partitioning or related concepts might be used in analyzing network traffic patterns or identifying anomalies in network behavior, contributing to network security. - -10. **Game Design:** - - Some game algorithms may involve palindrome partitioning or similar techniques, especially in puzzle-solving or pattern recognition games. diff --git a/Strings/Medium/palindrome partitioning/palindromepartition.py b/Strings/Medium/palindrome partitioning/palindromepartition.py deleted file mode 100644 index 15b4cd2d..00000000 --- a/Strings/Medium/palindrome partitioning/palindromepartition.py +++ /dev/null @@ -1,22 +0,0 @@ -def partition(string): - # Initialize dynamic programming array - dp=[[] for _ in range(len(string)+1)] - - # Initialize the first state with an empty partition - dp[0]=[[]] - -# Iterate over each character of the string - for j in range(1,len(string)+1): - # Iterate through each previous character - for i in range(j): - # Check if the substring is a palindrome - if string[i:j]==string[i:j][::-1]: - # If so, extend the partitions ending at i with the palindrome substring - for each in dp[i]: - dp[j].append(each+[string[i:j]]) - # Return the final state, which contains all valid partitions - return dp[-1] - -if __name__=="__main__": - string="ababa" - print(partition(string)) diff --git a/Strings/Medium/palindrome partitioning/palindrompartition.c++ b/Strings/Medium/palindrome partitioning/palindrompartition.c++ deleted file mode 100644 index 3d7c28c0..00000000 --- a/Strings/Medium/palindrome partitioning/palindrompartition.c++ +++ /dev/null @@ -1,53 +0,0 @@ -#include -bool isPalindrome(std::string s, int i, int j) { - // While loop checks the string symmetrically. - while (i <= j) { - // If characters at different ends don't match, it's not a palindrome. - if (s[i++] != s[j--]) return false; - } - // If loop finished, the string is a palindrome. - return true; -} -void util(int i,std::string s,std::vector>& res,std::vector& path){ - // base case: when string s is fully processed - if(i==s.size()){ - res.push_back(path); - return ; - } - - // iteratively checking each substring - for(int j=i;j> partition (std::string s){ - // Output list of all palindrome partitions - std::vector> res; - // List to keep track of the current path - std::vector path; - // Utility function to find all palindrome partitions - util(0,s,res,path); - return res; -} -int main(){ - // initial string to be partitioned - std::string s = "aaab"; - // function call to get all partitions - std::vector> ans=partition(s); - // loop to print all partitions - for(auto& a:ans){ - for(auto& b:a){ - std::cout< Date: Fri, 15 Dec 2023 20:27:34 +0530 Subject: [PATCH 27/53] Delete Heaps/Hard directory --- Heaps/Hard/MaxHeapCRUD.java | 121 ------- Heaps/Hard/Readme.md | 594 ----------------------------------- Heaps/Hard/max heap CRUD.py | 93 ------ Heaps/Hard/max_heap_CRUD.c++ | 113 ------- 4 files changed, 921 deletions(-) delete mode 100644 Heaps/Hard/MaxHeapCRUD.java delete mode 100644 Heaps/Hard/Readme.md delete mode 100644 Heaps/Hard/max heap CRUD.py delete mode 100644 Heaps/Hard/max_heap_CRUD.c++ diff --git a/Heaps/Hard/MaxHeapCRUD.java b/Heaps/Hard/MaxHeapCRUD.java deleted file mode 100644 index f8a6ff78..00000000 --- a/Heaps/Hard/MaxHeapCRUD.java +++ /dev/null @@ -1,121 +0,0 @@ -import java.util.ArrayList; -import java.util.List; - -// Class representing a max heap with CRUD operations -class MaxHeapCRUD { - private List heap; - - // Constructor initializes an empty list for the heap - public MaxHeapCRUD() { - this.heap = new ArrayList<>(); - } - - // Move the element up the heap until the heap property is restored - private void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap.get(parent) >= heap.get(index)) { - break; - } - // Swap the current element with its parent - int temp = heap.get(parent); - heap.set(parent, heap.get(index)); - heap.set(index, temp); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - private void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap.get(left) > heap.get(largest)) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap.get(right) > heap.get(largest)) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - int temp = heap.get(largest); - heap.set(largest, heap.get(index)); - heap.set(index, temp); - maxHeapify(largest); - } - } - - // Add a new element to the heap and percolate it up to maintain the heap property - public void insert(int val) { - heap.add(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - public int getMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - return heap.get(0); - } - - // Update the value, percolate up, and max heapify to maintain the heap property - public void update(int oldVal, int newVal) { - int index = heap.indexOf(oldVal); - if (index != -1) { - heap.set(index, newVal); - percolateUp(index); - maxHeapify(index); - } else { - System.out.println("Value not in heap"); - } - } - - // Replace the root with the last element, pop the last element, and max heapify - public void deleteMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - heap.set(0, heap.remove(heap.size() - 1)); - maxHeapify(0); - } - - // Print all values in the heap - public void printHeap() { - for (int i : heap) { - System.out.print(i + " "); - } - System.out.println(); - } - - // Main method demonstrating usage of the MaxHeapCRUD class - public static void main(String[] args) { - MaxHeapCRUD heap = new MaxHeapCRUD(); - - heap.insert(12); - heap.insert(10); - heap.insert(52); - heap.insert(100); - heap.insert(50); - - System.out.print("All values in heap: "); - heap.printHeap(); - - System.out.println("Max Value: " + heap.getMax()); - - heap.update(12, 5); - - System.out.println("Max Value after update: " + heap.getMax()); - - heap.deleteMax(); - - System.out.println("Max Value after deletion: " + heap.getMax()); - - System.out.print("All values in heap: "); - heap.printHeap(); - } -} \ No newline at end of file diff --git a/Heaps/Hard/Readme.md b/Heaps/Hard/Readme.md deleted file mode 100644 index 233b5857..00000000 --- a/Heaps/Hard/Readme.md +++ /dev/null @@ -1,594 +0,0 @@ -# Exploring Max-Heap using CRUD operations : - -## Introduction to Heaps: - -Heaps are a fundamental data structure used in computer science for efficient implementation of priority queues and various graph algorithms. A heap is a specialized tree-based structure that satisfies the heap property. - -A binary heap is a complete binary tree where every parent node has a value greater than or equal to its children. This structure allows for quick retrieval and removal of the maximum element, making it an ideal choice for priority queue implementations. - -## Introduction to Max-Heap CRUD Operations: - -In the context of heaps, CRUD operations refer to Create, Read, Update, and Delete. Max-Heap CRUD operations involve manipulating a max heap, ensuring that it maintains the heap property at all times. - -Let's dive into each CRUD operation: - -### Overview of Max-Heap CRUD Operations: - -1. **Create (Insertion):** - - **Description:** Adds a new element to the max heap while maintaining the heap property. - - **Implementation:** The new element is appended to the end of the heap, and then the `percolate_up` method is called to ensure that the heap property is restored. - -2. **Read (Get Maximum):** - - **Description:** Returns the maximum element in the max heap, which is always the root. - - **Implementation:** Simply retrieves the element at the root of the heap. - -3. **Update (Modify Element):** - - **Description:** Updates an existing value in the max heap while preserving the heap property. - - **Implementation:** Finds the index of the old value, updates it with the new value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. - -4. **Delete (Remove Maximum):** - - **Description:** Removes the maximum element (root) from the max heap while maintaining the heap property. - - **Implementation:** Replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. - -These CRUD operations provide a comprehensive set of functionalities for working with a max heap. They ensure that the heap property is consistently upheld, allowing for efficient management of data in various applications. - - -# PYTHON -# code - -```python -# Copyrights to venkys.io -# For more information, visit https://venkys.io - -# python program for Max-Heap CRUD -# Stable: Yes -# Inplace: Yes -# Adaptive: Yes - -# Space complexity:O(n) -# Time complexity: -# Insertion: O(log N) -# Get Max: O(1) -# Update: O(log N) -# Delete Max: O(log N) - -class MaxHeap: - def __init__(self): - # Initialize an empty list to represent the heap - self.heap = [] - - def percolate_up(self, index): - # Move the element up the heap until the heap property is restored - while index > 0: - parent = (index - 1) // 2 - if self.heap[parent] >= self.heap[index]: - break - # Swap the current element with its parent - self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] - index = parent - - def max_heapify(self, index): - # Ensure the heap property is maintained starting from the given index - left = 2 * index + 1 - right = 2 * index + 2 - largest = index - - # Check if the left child is larger than the current largest element - if left < len(self.heap) and self.heap[left] > self.heap[largest]: - largest = left - # Check if the right child is larger than the current largest element - if right < len(self.heap) and self.heap[right] > self.heap[largest]: - largest = right - - # If the largest element is not the current index, swap and continue heapifying - if largest != index: - self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] - self.max_heapify(largest) - - def insert(self, val): - # Add a new element to the heap and percolate it up to maintain the heap property - self.heap.append(val) - self.percolate_up(len(self.heap) - 1) - - def get_max(self): - # Return the maximum element in the heap (root of the heap) - if len(self.heap) == 0: - raise Exception("Heap is empty") - return self.heap[0] - - def update(self, old_val, new_val): - try: - # Find the index of the old value in the heap - index = self.heap.index(old_val) - # Update the value, percolate up, and max heapify to maintain the heap property - self.heap[index] = new_val - self.percolate_up(index) - self.max_heapify(index) - except ValueError: - print("Value not in heap") - - def delete_max(self): - if len(self.heap) == 0: - raise Exception("Heap is empty") - # Replace the root with the last element, pop the last element, and max heapify - self.heap[0] = self.heap.pop() - self.max_heapify(0) - - def print_heap(self): - # Print all values in the heap - print(" ".join(map(str, self.heap))) - - -def main(): - # Initialize max heap - heap = MaxHeap() - - # Insert elements into heap - heap.insert(12) - heap.insert(10) - heap.insert(-10) - heap.insert(100) - - # Print all values in heap - heap.print_heap() - - # Get max value in heap - print("Max Value:", heap.get_max()) - - # Update value in heap - heap.update(12, 5) - print("Max Value after update:", heap.get_max()) - - # Delete max value from heap - heap.delete_max() - print("Max Value after deletion:", heap.get_max()) - - # Print all values in heap after deletion - heap.print_heap() - -``` -# Code Explanation - -The provided code implements a MaxHeap class in Python, allowing users to perform CRUD operations (Create, Read, Update, Delete) on a max heap data structure. Let's break down the code and provide a clear explanation: - - -# Step 1 - Initialization: -``` - self.heap = [] -``` -The `MaxHeap` class is initialized with an empty list, `self.heap`, which will store the elements of the max heap. - -# Step 2 - Percolate Up: -```python -def percolate_up(self, index): -``` -The `percolate_up` method is used during insertion to move a newly added element up the heap until the heap property is restored. It compares the element with its parent and swaps them if needed. - -# Step 3 - Max Heapify: - -```python -def max_heapify(self, index): -``` -The `max_heapify` method is used to maintain the heap property from a given index. It compares the element with its left and right children, swaps with the largest child if needed, and recursively continues the process. - -# Step 4 - Insertion: - -```python -def insert(self, val): -``` -The `insert` method adds a new element to the heap and then calls `percolate_up` to ensure the heap property is maintained. - -# Step 5 - Get Max: - -```python -def get_max(self): -``` -The `get_max` method returns the maximum element in the heap, which is the root. - -# Step 6 - Update: - -```python -def update(self, old_val, new_val): -``` -The `update` method updates an existing value in the heap. It finds the index, updates the value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. - -# Step 7 - Delete Max: - -```python -def delete_max(self): -``` -The `delete_max` method removes the maximum element (root) from the heap. It replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. - -# Step 8 - Print Heap: - -```python -def print_heap(self): -``` -The `print_heap` method prints all values in the heap. - -# Step 9 - Main Function: - -```python -def main(): - # Initialize max heap - heap = MaxHeap() -``` -The `main` function demonstrates the usage of the `MaxHeap` class by initializing a heap, performing insertions, updates, deletions, and printing the heap at different stages. - -This implementation provides a clear and organized way to work with Max-Heaps in Python. - -# C++ -# code - -```C++ -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// C++ program for Max_Heap CRUD -// Stable: No -// Inplace: Yes -// Adaptive: No - -// Space complexity: O(N) -// Time complexity: -// Insertion: O(log N) -// Get Max: O(1) -// Update: O(log N) -// Delete Max: O(log N) - -#include -#include -#include - -class MaxHeap { -private: - std::vector heap; - - // Move the element up the heap until the heap property is restored - void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap[parent] >= heap[index]) { - break; - } - std::swap(heap[parent], heap[index]); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap[left] > heap[largest]) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap[right] > heap[largest]) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - std::swap(heap[largest], heap[index]); - maxHeapify(largest); - } - } - -public: - // Add a new element to the heap and percolate it up to maintain the heap property - void insert(int val) { - heap.push_back(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - int getMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - return heap[0]; - } - - // Update the value, percolate up, and max heapify to maintain the heap property - void update(int old_val, int new_val) { - auto it = std::find(heap.begin(), heap.end(), old_val); - if (it != heap.end()) { - *it = new_val; - percolateUp(it - heap.begin()); - maxHeapify(it - heap.begin()); - } else { - std::cout << "Value not in heap" << std::endl; - } - } - - // Replace the root with the last element, pop the last element, and max heapify - void deleteMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - heap[0] = heap.back(); - heap.pop_back(); - maxHeapify(0); - } - - // Print all values in the heap - void printHeap() { - for (int i : heap) { - std::cout << i << " "; - } - std::cout << std::endl; - } -}; - -int main() { - // Example usage of the MaxHeap class - MaxHeap heap; - - heap.insert(12); - heap.insert(10); - heap.insert(-10); - heap.insert(100); - - std::cout << "All values in heap: "; - heap.printHeap(); - - std::cout << "Max Value: " << heap.getMax() << std::endl; - - heap.update(12, 5); - std::cout << "Max Value after update: " << heap.getMax() << std::endl; - - heap.deleteMax(); - std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; - - std::cout << "All values in heap: "; - heap.printHeap(); - - return 0; -} -``` -# java -# code - -```java -/* Copyrights to venkys.io -For more information, visit https://venkys.io */ - -// java program for Max-Heap CRUD -// Stable: No -// Inplace: Yes -// Adaptive: No - -// Space complexity: O(N) -// Time complexity: - // Insertion: O(log N) - // Get Max: O(1) - // Update: O(log N) - // Delete Max: O(log N) - -import java.util.ArrayList; -import java.util.List; - -// Class representing a max heap with CRUD operations -class MaxHeapCRUD { - private List heap; - - // Constructor initializes an empty list for the heap - public MaxHeapCRUD() { - this.heap = new ArrayList<>(); - } - - // Move the element up the heap until the heap property is restored - private void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap.get(parent) >= heap.get(index)) { - break; - } - // Swap the current element with its parent - int temp = heap.get(parent); - heap.set(parent, heap.get(index)); - heap.set(index, temp); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - private void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap.get(left) > heap.get(largest)) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap.get(right) > heap.get(largest)) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - int temp = heap.get(largest); - heap.set(largest, heap.get(index)); - heap.set(index, temp); - maxHeapify(largest); - } - } - - // Add a new element to the heap and percolate it up to maintain the heap property - public void insert(int val) { - heap.add(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - public int getMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - return heap.get(0); - } - - // Update the value, percolate up, and max heapify to maintain the heap property - public void update(int oldVal, int newVal) { - int index = heap.indexOf(oldVal); - if (index != -1) { - heap.set(index, newVal); - percolateUp(index); - maxHeapify(index); - } else { - System.out.println("Value not in heap"); - } - } - - // Replace the root with the last element, pop the last element, and max heapify - public void deleteMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - heap.set(0, heap.remove(heap.size() - 1)); - maxHeapify(0); - } - - // Print all values in the heap - public void printHeap() { - for (int i : heap) { - System.out.print(i + " "); - } - System.out.println(); - } - - // Main method demonstrating usage of the MaxHeapCRUD class - public static void main(String[] args) { - MaxHeapCRUD heap = new MaxHeapCRUD(); - - heap.insert(12); - heap.insert(10); - heap.insert(52); - heap.insert(100); - heap.insert(50); - - System.out.print("All values in heap: "); - heap.printHeap(); - - System.out.println("Max Value: " + heap.getMax()); - - heap.update(12, 5); - - System.out.println("Max Value after update: " + heap.getMax()); - - heap.deleteMax(); - - System.out.println("Max Value after deletion: " + heap.getMax()); - - System.out.print("All values in heap: "); - heap.printHeap(); - } -} -``` -# Code Explanation - Step by step explanation for Java and C++ : - -1. **Class Definition (MaxHeap):** - - The code defines a class named `MaxHeap` representing a Max Heap data structure. - - Private member for c++: `std::vector heap` is used to store the elements of the heap. - -It uses a private list (heap) to store the elements of the heap in java. - - The class has a constructor in java (MaxHeapCRUD()) that initializes an empty list for the heap. - - -2. **percolateUp Function:** - - Private method `percolateUp` moves an element up the heap until the heap property is restored. - - It takes an index as a parameter and swaps the element with its parent until the heap property is satisfied. - -3. **maxHeapify Function:** - - Private method `maxHeapify` ensures the heap property is maintained starting from a given index. - - It compares the element with its left and right children, swapping it with the largest child if needed. - -4. **insert Function:** - - Public method `insert` adds a new element to the heap and ensures the heap property by calling `percolateUp`. - -5. **getMax Function:** - - Public method `getMax` returns the maximum element in the heap (the root). - -6. **update Function:** - - Public method `update` updates a specified element in the heap with a new value. - - It uses `std::find` to locate the element, updates it, and then calls `percolateUp` and `maxHeapify` to maintain the heap property. - -7. **deleteMax Function:** - - Public method `deleteMax` removes the maximum element (root) from the heap. - - It replaces the root with the last element, pops the last element, and calls `maxHeapify` to restore the heap property. - -8. **printHeap Function:** - - Public method `printHeap` prints all values in the heap. - -9. **main Function:** - - In the `main` function: - - An instance of `MaxHeap` named `heap` is created in c++.An instance of MaxHeapCRUD named heap is created in java - - Elements (12, 10, -10, 100,50) are inserted into the heap using `insert`. - - All values in the heap are printed using `printHeap`. - - The maximum value in the heap is printed using `getMax`. - - An update is performed, changing the value 12 to 5 using `update`. - - The maximum value after the update is printed. - - The maximum element is deleted using `deleteMax`. - - The maximum value after deletion is printed. - - Finally, all values in the heap after deletion are printed. - -This code demonstrates the basic operations (insertion, update, deletion) on a Max Heap. - - - -**Time and Space Complexity Analysis**: - -# Time Complexity: -The time complexities for the Max Heap CRUD (Create, Read, Update, Delete) operations are as follows: - -1. **Insertion (Create):** - - Time Complexity: O(log n) - - Explanation: The worst-case time complexity for inserting an element into a max heap is logarithmic in the number of elements, as the element needs to be percolated up the height of the heap. The height of a binary heap is log(n) where n is the number of elements. - -2. **GetMax (Read):** - - Time Complexity: O(1) - - Explanation: Retrieving the maximum element (root) in a max heap can be done in constant time as the maximum element is always at the root. - -3. **Update:** - - Time Complexity: O(log n) - - Explanation: Updating an element in a max heap involves two operations: percolating up (up to log n steps) and max heapifying (up to log n steps). Therefore, the overall time complexity is logarithmic. - -4. **DeleteMax (Delete):** - - Time Complexity: O(log n) - - Explanation: Deleting the maximum element involves replacing the root with the last element, which may require percolating down the height of the heap to maintain the heap property. The worst-case time complexity is logarithmic. - -These time complexities assume that the underlying data structure is a binary heap. The actual performance may vary based on implementation details and the specific operations performed. - -# Space Complexity: -The space complexity for Max Heap CRUD (Create, Read, Update, Delete) operations is O(n), where n is the number of elements in the heap. - -1. **Insertion (Create):** - - Explanation: The insertion operation generally doesn't require additional space proportional to the number of elements. The new element is added to the existing heap in-place. - -2. **GetMax (Read):** - - Explanation: Reading the maximum element involves accessing the root of the heap. It doesn't require additional space proportional to the number of elements. - -3. **Update:** - - Explanation: The update operation is performed in-place without requiring additional space. - -4. **DeleteMax (Delete):** - - Explanation: The delete operation involves replacing the root with the last element and then adjusting the heap structure. It is performed in-place without requiring additional space. - -# Real-World Applications of MAX-HEAP CRUD(Create,Read,Update,Delete) - -1. **Task Scheduling:** Priority scheduling based on task priority levels. -2. **Job Scheduling:** Allocating jobs to machines based on priority. -3. **Dijkstra's Algorithm:** Finding the shortest path in a graph. -4. **Huffman Coding:** Data compression algorithm. -5. **Order Processing:** Managing orders based on their priority in e-commerce systems. -6. **Operating System Task Scheduling:** Assigning priority to tasks for execution. -7. **Network Routing Algorithms:** Determining the optimal path for data packets. -8. **Emergency Room Triage:** Prioritizing patients based on the severity of their condition. -9. **Database Indexing:** Managing indexes to speed up query performance. -10. **Wireless Sensor Networks:** Energy-efficient data aggregation in sensor networks. diff --git a/Heaps/Hard/max heap CRUD.py b/Heaps/Hard/max heap CRUD.py deleted file mode 100644 index 628e1243..00000000 --- a/Heaps/Hard/max heap CRUD.py +++ /dev/null @@ -1,93 +0,0 @@ -class MaxHeap: - def __init__(self): - # Initialize an empty list to represent the heap - self.heap = [] - - def percolate_up(self, index): - # Move the element up the heap until the heap property is restored - while index > 0: - parent = (index - 1) // 2 - if self.heap[parent] >= self.heap[index]: - break - # Swap the current element with its parent - self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] - index = parent - - def max_heapify(self, index): - # Ensure the heap property is maintained starting from the given index - left = 2 * index + 1 - right = 2 * index + 2 - largest = index - - # Check if the left child is larger than the current largest element - if left < len(self.heap) and self.heap[left] > self.heap[largest]: - largest = left - # Check if the right child is larger than the current largest element - if right < len(self.heap) and self.heap[right] > self.heap[largest]: - largest = right - - # If the largest element is not the current index, swap and continue heapifying - if largest != index: - self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] - self.max_heapify(largest) - - def insert(self, val): - # Add a new element to the heap and percolate it up to maintain the heap property - self.heap.append(val) - self.percolate_up(len(self.heap) - 1) - - def get_max(self): - # Return the maximum element in the heap (root of the heap) - if len(self.heap) == 0: - raise Exception("Heap is empty") - return self.heap[0] - - def update(self, old_val, new_val): - try: - # Find the index of the old value in the heap - index = self.heap.index(old_val) - # Update the value, percolate up, and max heapify to maintain the heap property - self.heap[index] = new_val - self.percolate_up(index) - self.max_heapify(index) - except ValueError: - print("Value not in heap") - - def delete_max(self): - if len(self.heap) == 0: - raise Exception("Heap is empty") - # Replace the root with the last element, pop the last element, and max heapify - self.heap[0] = self.heap.pop() - self.max_heapify(0) - - def print_heap(self): - # Print all values in the heap - print(" ".join(map(str, self.heap))) - - -def main(): - # Initialize max heap - heap = MaxHeap() - - # Insert elements into heap - heap.insert(12) - heap.insert(10) - heap.insert(-10) - heap.insert(100) - - # Print all values in heap - heap.print_heap() - - # Get max value in heap - print("Max Value:", heap.get_max()) - - # Update value in heap - heap.update(12, 5) - print("Max Value after update:", heap.get_max()) - - # Delete max value from heap - heap.delete_max() - print("Max Value after deletion:", heap.get_max()) - - # Print all values in heap after deletion - heap.print_heap() \ No newline at end of file diff --git a/Heaps/Hard/max_heap_CRUD.c++ b/Heaps/Hard/max_heap_CRUD.c++ deleted file mode 100644 index 0cebbbdc..00000000 --- a/Heaps/Hard/max_heap_CRUD.c++ +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include - -class MaxHeap { -private: - std::vector heap; - - // Move the element up the heap until the heap property is restored - void percolateUp(int index) { - while (index > 0) { - int parent = (index - 1) / 2; - if (heap[parent] >= heap[index]) { - break; - } - std::swap(heap[parent], heap[index]); - index = parent; - } - } - - // Ensure the heap property is maintained starting from the given index - void maxHeapify(int index) { - int left = 2 * index + 1; - int right = 2 * index + 2; - int largest = index; - - // Check if the left child is larger than the current largest element - if (left < heap.size() && heap[left] > heap[largest]) { - largest = left; - } - // Check if the right child is larger than the current largest element - if (right < heap.size() && heap[right] > heap[largest]) { - largest = right; - } - - // If the largest element is not the current index, swap and continue heapifying - if (largest != index) { - std::swap(heap[largest], heap[index]); - maxHeapify(largest); - } - } - -public: - // Add a new element to the heap and percolate it up to maintain the heap property - void insert(int val) { - heap.push_back(val); - percolateUp(heap.size() - 1); - } - - // Return the maximum element in the heap (root of the heap) - int getMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - return heap[0]; - } - - // Update the value, percolate up, and max heapify to maintain the heap property - void update(int old_val, int new_val) { - auto it = std::find(heap.begin(), heap.end(), old_val); - if (it != heap.end()) { - *it = new_val; - percolateUp(it - heap.begin()); - maxHeapify(it - heap.begin()); - } else { - std::cout << "Value not in heap" << std::endl; - } - } - - // Replace the root with the last element, pop the last element, and max heapify - void deleteMax() { - if (heap.size() == 0) { - throw "Heap is empty"; - } - heap[0] = heap.back(); - heap.pop_back(); - maxHeapify(0); - } - - // Print all values in the heap - void printHeap() { - for (int i : heap) { - std::cout << i << " "; - } - std::cout << std::endl; - } -}; - -int main() { - // Example usage of the MaxHeap class - MaxHeap heap; - - heap.insert(12); - heap.insert(10); - heap.insert(-10); - heap.insert(100); - - std::cout << "All values in heap: "; - heap.printHeap(); - - std::cout << "Max Value: " << heap.getMax() << std::endl; - - heap.update(12, 5); - std::cout << "Max Value after update: " << heap.getMax() << std::endl; - - heap.deleteMax(); - std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; - - std::cout << "All values in heap: "; - heap.printHeap(); - - return 0; -} From 0f35d08324a3077a8d3ea6c69324e1a2954aafe0 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Fri, 15 Dec 2023 20:30:23 +0530 Subject: [PATCH 28/53] add inorder traversal --- Trees/Easy/Inorder Traversal/BinaryTree.java | 51 +++ Trees/Easy/Inorder Traversal/Readme.md | 373 +++++++++++++++++++ Trees/Easy/Inorder Traversal/inorder.cpp | 38 ++ Trees/Easy/Inorder Traversal/inorder.py | 26 ++ 4 files changed, 488 insertions(+) create mode 100644 Trees/Easy/Inorder Traversal/BinaryTree.java create mode 100644 Trees/Easy/Inorder Traversal/Readme.md create mode 100644 Trees/Easy/Inorder Traversal/inorder.cpp create mode 100644 Trees/Easy/Inorder Traversal/inorder.py diff --git a/Trees/Easy/Inorder Traversal/BinaryTree.java b/Trees/Easy/Inorder Traversal/BinaryTree.java new file mode 100644 index 00000000..14f798bf --- /dev/null +++ b/Trees/Easy/Inorder Traversal/BinaryTree.java @@ -0,0 +1,51 @@ +class TreeNode { + int data; + // Store integer data + TreeNode left = null, + // Left child reference + right = null; + // Right child reference + + public TreeNode(int data) { + // Constructor to create a new TreeNode + this.data = data; + // Assign the given data to this node + } +} + +public class BinaryTree { +// Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + + public static void main(String[] args) { + + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } +} \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/Readme.md b/Trees/Easy/Inorder Traversal/Readme.md new file mode 100644 index 00000000..d8829cd0 --- /dev/null +++ b/Trees/Easy/Inorder Traversal/Readme.md @@ -0,0 +1,373 @@ +# Exploring Binary Trees and Inorder Traversal + +## Introduction to Trees +A tree is a hierarchical data structure which is composed of nodes, where each node has at maximum two children and they are called as left child and right child. This interconnected system is reminiscent of an upside-down tree, with the topmost node called the root. In this structure, nodes hold data, and edges represent connections between nodes. Trees play a crucial role in computer science, serving as versatile tools for tasks such as searching, sorting, and analysis. Each node's ability to have multiple children allows for the creation of complex hierarchical relationships, making trees an indispensable concept for organizing and manipulating data efficiently. Whether utilized for representing hierarchical relationships, optimizing search algorithms, or structuring databases, trees form a foundational element in computer science, contributing to the systematic and effective management of information. + +## Introduction to Inorder Traversal +Inorder traversal is a method of traversing a binary tree in a specific order. It starts from the leftmost node and moves towards the rightmost node, visiting the left subtree first, then the root, and finally the right subtree. This traversal strategy is fundamental for exploring and processing binary trees systematically. + +## Overview +The provided Python code defines a binary tree node using a class named `Node` and demonstrates recursive inorder traversal. The `Node` class has a constructor initializing the node with some data and two pointers, `left` and `right`, representing the left and right children. + +## Step-by-Step Explanation + +# Using Python +# code + +```python +class Node: + def __init__(self,data): + self.data=data + self.left=self.right=None +# Recursive Inorder Traversal. +def inorder(root): + # Check if the root exists + if root: + # Perform an inorder traversal on the left subtree + inorder(root.left) + # Print the value of the current node + print(root.data,end=" ") + # Perform an inorder traversal on the right subtree + inorder(root.right) + # Driver code to test above function +# The values of nodes are given below : +if __name__=="__main__": + root=Node(80) + root.left=Node(20) + root.right=Node(30) + root.left.left=Node(40) + root.left.right=Node(350) + root.right.left=Node(460) + root.right.right=Node(70) + inorder(root) +``` + +**Explanation:** + +1. **Node Class Definition:** + +```python +class Node: + def __init__(self, data): + self.data = data + self.left = self.right = None +``` + +This class defines the structure of a binary tree node. Each node has a data attribute to store the value of the node, and left and right attributes to point to the left and right children, respectively. + +2. **Inorder Traversal Function:** + +```python +def inorder(root): + if root: + inorder(root.left) + print(root.data, end=" ") + inorder(root.right) +``` + +This function, inorder, is a recursive implementation of the inorder traversal algorithm. It takes a root node as an argument and performs the following steps: +=> Check if the current root exists. +=> Recursively traverse the left subtree. +=> Print the value of the current node. +=> Recursively traverse the right subtree. + +3.**Driver Code and Tree Initialization** + +```python + if __name__ == "__main__": + root = Node(80) + root.left = Node(20) + root.right = Node(30) + root.left.left = Node(40) + root.left.right = Node(350) + root.right.left = Node(460) + root.right.right = Node(70) +``` + +In the __main__ block, a binary tree is created with the following structure: + + 80 + / \ + 20 30 + / \ / \ + 40 350 460 70 + + +4. **Inorder Traversal Call** + +```python + inorder(root) +``` + +This line calls the inorder function with the root of the tree, initiating the inorder traversal. The result is the values of the nodes printed in ascending order. + +In summary, the code defines a binary tree, initializes it with specific values, and then performs an inorder traversal, printing the values of the nodes in ascending order. The recursive nature of the inorder function is key to traversing the tree systematically. + +# using C++ +# code +```c++ +#include + +class Node{ + public: + int data; + Node *left=NULL; + Node *right=NULL; + + // Node constructor initializes data + Node(int val){ + data=val; + } +}; +void inorder(Node* root){ + // call inorder for left subtree + if(root!=NULL){ + inorder(root->left); + // Print root node data + std::cout<data<<" "; + // call inorder for right subtree + inorder(root->right); + } +} + +int main(){ + // Creating the binary tree + Node* root=new Node(10); + root->left=new Node(20); + root->right=new Node(30); + root->left->left=new Node(40); + root->left->right=new Node(50); + root->right->left=new Node(60); + root->right->right=new Node(70); + // Displaying the binary tree in inorder traversal + inorder(root); + // Inorder traversal of the tree + return 0; +} +``` +**Explanation** + +1. **Header Inclusion**: + + ```cpp + #include + ``` + + This line includes a standard C++ library header, which is a common practice to include necessary headers like `` for input and output. + +2. **Node Class Definition:** + + ```cpp + class Node { + public: + int data; + Node *left = NULL; + Node *right = NULL; + + // Node constructor initializes data + Node(int val) { + data = val; + } + }; + ``` + + This part defines a `Node` class representing nodes in a binary tree. Each node contains an integer `data`, a pointer to the left child (`left`), and a pointer to the right child (`right`). The constructor initializes the node with the provided data value. + +3. **Inorder Traversal Function:** + + ```cpp + void inorder(Node* root) { + // call inorder for the left subtree + if (root != NULL) { + inorder(root->left); + // Print root node data + std::cout << root->data << " "; + // call inorder for the right subtree + inorder(root->right); + } + } + ``` + + The `inorder` function performs recursive inorder traversal on the binary tree. It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. + +4. **Main Function:** + + ```cpp + int main() { + // Creating the binary tree + Node* root = new Node(10); + root->left = new Node(20); + root->right = new Node(30); + root->left->left = new Node(40); + root->left->right = new Node(50); + root->right->left = new Node(60); + root->right->right = new Node(70); + + // Displaying the binary tree in inorder traversal + inorder(root); + + // Inorder traversal of the tree + return 0; + } + ``` + + In the `main` function, a binary tree is created with specific values. Nodes are allocated dynamically using the `new` keyword. The `inorder` function is then called to display the binary tree in inorder traversal, printing the values of the nodes in ascending order. + +In summary, this C++ program defines a binary tree using a `Node` class, creates a binary tree with specific values, and performs an inorder traversal to display the tree's content. The code demonstrates the concept of recursive traversal in a binary tree. +This code will output `40 20 50 10 60 30 70`, which is a correct + +# using Java +# Code + +```java +class TreeNode { + int data; + // Store integer data + TreeNode left = null, + // Left child reference + right = null; + // Right child reference + + public TreeNode(int data) { + // Constructor to create a new TreeNode + this.data = data; + // Assign the given data to this node + } +} + +public class BinaryTree { +// Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + + public static void main(String[] args) { + + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } +} + +``` +**explanation** + +1. **TreeNode Class Definition:** + ```java + class TreeNode { + int data; + TreeNode left = null, right = null; + + public TreeNode(int data) { + this.data = data; + } + } + ``` + + - `TreeNode` class defines the structure of a binary tree node. + - It has an `int` variable `data` to store the node's value and references (`left` and `right`) to its left and right children. + - The constructor initializes a new `TreeNode` with the given data. + +2. **BinaryTree Class:** + ```java + public class BinaryTree { + // Method for inorder traversal + + static void inorderTraversal(TreeNode root) { + if (root != null) { + inorderTraversal(root.left); + System.out.print(root.data + " "); + inorderTraversal(root.right); + } + } + ``` + - This class contains a method `inorderTraversal` that performs recursive inorder traversal on a binary tree. + - It prints the data of each node in ascending order by first traversing the left subtree, then printing the root node's data, and finally traversing the right subtree. + - InorderTraversal` is a static method used for inorder traversal of the binary tree. + - It is a recursive function that traverses the left subtree, prints the data of the current node, and then traverses the right subtree. + +3. **Main Method:** + ```java + public static void main(String[] args) { + // Creating a binary tree with root node having data 10 + TreeNode root = new TreeNode(10); + + // Adding nodes to the root of the created binary tree + // Adding left and right child nodes to the root + root.left = new TreeNode(20); + root.right = new TreeNode(30); + + // Adding left and right child nodes to the left child of the root + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + // Adding left and right child nodes to the right child of the root + root.right.left = new TreeNode(60); + root.right.right = new TreeNode(70); + + // Printing the message before performing inorder traversal + System.out.print("Inorder Traversal: "); + + // Calling the inorderTraversal method to perform inorder traversal + inorderTraversal(root); + } + ``` + + - The `main` method is the entry point of the program. + - It creates an instance of the `TreeNode` class, representing the root of the binary tree, with a data value of 10. + - Child nodes are added to the root, forming a binary tree structure. + - The `inorderTraversal` method is called to perform an inorder traversal of the tree, printing the nodes in ascending order. + + +4. **Tree Structure:** + ``` + 10 + / \ + 20 30 + / \ / \ + 40 50 60 70 + ``` + +5. **Output:** + ``` + Inorder Traversal: 40 20 50 10 60 30 70 + ``` + +In summary, this Java program demonstrates the creation of a binary tree, addition of nodes, and the execution of an inorder traversal. The `TreeNode` class encapsulates the node structure, and the `BinaryTree` class utilizes it to construct and traverse the binary tree. + + +## Time and Space Complexity Analysis +- Time Complexity: The time complexity of the inorder traversal is O(n), where n is the number of nodes in the tree. This is because each node is visited once. +- Space Complexity: The space complexity is O(h), where h is the height of the binary tree. In the worst case (skewed tree), the height is n, making the space complexity O(n). In a balanced tree, the height is log(n), resulting in a space complexity of O(log(n)). + +## Real-World Applications +Binary trees and inorder traversal have applications in various domains, including: +- **Database Indexing:** Binary trees are used in database systems to efficiently index and search for records. +- **Expression Trees:** In compilers, expression trees are used to represent mathematical expressions for efficient evaluation. +- **File Systems:** File systems often use tree structures to organize and locate files efficiently. + +## Conclusion +Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/inorder.cpp b/Trees/Easy/Inorder Traversal/inorder.cpp new file mode 100644 index 00000000..2c04554e --- /dev/null +++ b/Trees/Easy/Inorder Traversal/inorder.cpp @@ -0,0 +1,38 @@ +#include + +class Node{ + public: + int data; + Node *left=NULL; + Node *right=NULL; + + // Node constructor initializes data + Node(int val){ + data=val; + } +}; +void inorder(Node* root){ + // call inorder for left subtree + if(root!=NULL){ + inorder(root->left); + // Print root node data + std::cout<data<<" "; + // call inorder for right subtree + inorder(root->right); + } +} + +int main(){ + // Creating the binary tree + Node* root=new Node(10); + root->left=new Node(20); + root->right=new Node(30); + root->left->left=new Node(40); + root->left->right=new Node(50); + root->right->left=new Node(60); + root->right->right=new Node(70); + // Displaying the binary tree in inorder traversal + inorder(root); + // Inorder traversal of the tree + return 0; +} \ No newline at end of file diff --git a/Trees/Easy/Inorder Traversal/inorder.py b/Trees/Easy/Inorder Traversal/inorder.py new file mode 100644 index 00000000..cb629501 --- /dev/null +++ b/Trees/Easy/Inorder Traversal/inorder.py @@ -0,0 +1,26 @@ +# Definition for a binary tree node +class Node: + def __init__(self,data): + self.data=data + self.left=self.right=None +# Recursive Inorder Traversal. +def inorder(root): + # Check if the root exists + if root: + # Perform an inorder traversal on the left subtree + inorder(root.left) + # Print the value of the current node + print(root.data,end=" ") + # Perform an inorder traversal on the right subtree + inorder(root.right) + # Driver code to test above function +# The values of nodes are given below : +if __name__=="__main__": + root=Node(80) + root.left=Node(20) + root.right=Node(30) + root.left.left=Node(40) + root.left.right=Node(350) + root.right.left=Node(460) + root.right.right=Node(70) + inorder(root) \ No newline at end of file From ff5001d8b3280f08101d6184a8a3497a50f07076 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sat, 16 Dec 2023 10:35:44 +0530 Subject: [PATCH 29/53] Add files via upload --- Strings/Medium/String to Integer/Readme.md | 482 ++++++++++++++++++ Strings/Medium/String to Integer/main.java | 26 + .../String to Integer/stringtointeger.cpp | 31 ++ .../String to Integer/stringtointeger.py | 40 ++ .../PalindromePartitioning.java | 39 ++ .../Medium/palindrome partitioning/Readme.md | 327 ++++++++++++ .../palindromepartition.py | 22 + .../palindrompartition.c++ | 53 ++ 8 files changed, 1020 insertions(+) create mode 100644 Strings/Medium/String to Integer/Readme.md create mode 100644 Strings/Medium/String to Integer/main.java create mode 100644 Strings/Medium/String to Integer/stringtointeger.cpp create mode 100644 Strings/Medium/String to Integer/stringtointeger.py create mode 100644 Strings/Medium/palindrome partitioning/PalindromePartitioning.java create mode 100644 Strings/Medium/palindrome partitioning/Readme.md create mode 100644 Strings/Medium/palindrome partitioning/palindromepartition.py create mode 100644 Strings/Medium/palindrome partitioning/palindrompartition.c++ diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md new file mode 100644 index 00000000..18ddabd6 --- /dev/null +++ b/Strings/Medium/String to Integer/Readme.md @@ -0,0 +1,482 @@ +# Exploring Strings and Converting them to Integers : + +"Exploring Strings and Converting them to Integers" concept likely involves working with strings in a programming context and performing operations that involve converting these strings into integer values. + +**Exploring Strings** : This suggests that we will be working with strings, which are sequences of characters. Exploring strings may involve tasks such as accessing individual characters, finding the length of a string, or manipulating the content in various ways. +**Converting Strings to Integers** : The main task is likely to involve converting strings into integer values. This conversion is common in programming when dealing with user input or data read from external sources, where the input is initially in the form of text (string) but needs to be processed as numerical values (integers). + +# Introduction to Strings: + +A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. +Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. + +# Introduction to the String to Integer Theory: + +One of the frequent challenges encountered in programming involves converting strings to integers. This operation is particularly crucial when dealing with user inputs, file parsing, or scenarios where numeric values need extraction from a textual context. The process entails considering signs, handling leading whitespaces, and ensuring that the resulting integer falls within the appropriate range. + +# Overview of String to Integer: + +The problem involves working with strings, extracting numerical information from them, converting this information to integers, and potentially performing operations on these integers. The specific details would depend on the context and requirements of the problem as defined in the prompt or task description. +some of the common tasks that might encounter within this problem statement: + +**Parsing Integers** : Extracting numerical values from a string. This involves identifying and extracting the sequence of characters that represents an integer. + +**Handling Edge Cases** : Dealing with situations where the string may not represent a valid integer (e.g., contains non-numeric characters). Error handling may be required. + +**Performing Arithmetic Operations** : Once the strings are converted to integers, you might be asked to perform various arithmetic operations (addition, subtraction, multiplication, etc.) on these values. + +**Output Formatting** : Displaying the results in a specified format, which may involve converting integers back to strings for output. + +# PYTHON +# code +```python +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// python program to convert string to integer +// Stable: Yes +// Inplace: No +// Adaptive: Yes + +// Space complexity:O(n) +// Time complexity:O(1) + +def check(answer): + # Check if the answer is less than the minimum 32-bit signed integer + if answer < -2**31: + return -2**31 + # Check if the answer is greater than or equal to the maximum 32-bit signed integer + elif answer >= 2**31: + return 2**31 - 1 + else: + return answer + +def myAtoi(string): + # Initialize variables + answer = 0 + sign = 0 # 0 represents no sign, 1 represents positive sign, -1 represents negative sign + i = 0 + + # Skip leading whitespaces + while i < len(string) and string[i] == " ": + i += 1 + # If the entire string is composed of whitespaces, return the current answer + if i == len(string): + return answer + + # Check for positive sign + if string[i] == "+" and sign == 0: + sign = 1 + i += 1 + + # Check for negative sign + if i < len(string) and string[i] == "-" and sign == 0: + sign = -1 + i += 1 + + # Process the digits of the string + while i < len(string): + # Check if the current character is a digit + if string[i].isdigit(): + # Update the answer by multiplying it by 10 and adding the current digit + answer = answer * 10 + int(string[i]) + i += 1 + else: + # If a non-digit character is encountered, apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + + # Apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + +# Test the function with the provided string "42" +if __name__ == "__main__": + s = "42" + print(myAtoi(s)) + +``` +# Code Explanation + +1. **`check` function:** + ```python + def check(answer): + if answer < -2**31: + return -2**31 + elif answer >= 2**31: + return 2**31 - 1 + else: + return answer + ``` + - This function takes an `answer` as input and checks if it is within the range of a 32-bit signed integer. If it's less than the minimum value, it returns the minimum value. If it's greater than or equal to the maximum value, it returns the maximum value. Otherwise, it returns the original answer. + +2. **`myAtoi` function:** + ```python + def myAtoi(string): + answer = 0 + sign = 0 + i = 0 + + # Skip leading whitespaces + while i < len(string) and string[i] == " ": + i += 1 + if i == len(string): + return answer + + # Check for positive sign + if string[i] == "+" and sign == 0: + sign = 1 + i += 1 + + # Check for negative sign + if i < len(string) and string[i] == "-" and sign == 0: + sign = -1 + i += 1 + + # Process the digits of the string + while i < len(string): + if string[i].isdigit(): + # Update the answer by multiplying it by 10 and adding the current digit + answer = answer * 10 + int(string[i]) + i += 1 + else: + # If a non-digit character is encountered, apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + + # Apply the sign if present and return the result after checking for overflow + if sign != 0: + answer = sign * answer + return check(answer) + ``` + - This function takes a string `string` as input and converts it to an integer according to the rules specified. + - It initializes `answer` to store the result, `sign` to store the sign of the number, and `i` as an index to iterate through the string. + - It skips leading whitespaces in the string. + - It checks for positive or negative signs and sets the `sign` accordingly. + - It iterates through the string, processes digits, and updates the `answer`. + - If a non-digit character is encountered, it applies the sign if present and returns the result after checking for overflow using the `check` function. + - Finally, it returns the checked and signed result. + +3. **Test the function:** + ```python + if __name__ == "__main__": + s = "42" + print(myAtoi(s)) + ``` + - It tests the `myAtoi` function with the input string "42" and prints the result. + +The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of a 32-bit signed integer. The `check` function ensures that the result does not exceed the specified integer limits. + +# C++ +code +```c++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program to convert string to integer +// Stable: Yes +// Inplace: No +// Adaptive: No + +// Space complexity: O(n) +// Time complexity: O(1) + +#include + +int atoi(std::string s) +{ + int num = 0, i = 0, sign = 1; + while (s[i] == ' ') + { + i++; + } + if (i < s.length() && (s[i] == '-' || s[i] == '+')) + { + sign = s[i] == '+' ? 1 : -1; + i++; + } + while (i < s.length() && isdigit(s[i])) + { + + if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) + return sign == 1 ? INT_MAX : INT_MIN; + num = ((num * 10) + (s[i] - '0')); + i++; + } + return num * sign; +} + +int main() +{ + std::string s = "42"; + std::cout << atoi(s); + return 0; +} +``` +# Code Explanation + +1. **Function Definition:** + ```cpp + int myAtoi(const std::string &str) { + ``` + - The function `myAtoi` is defined, taking a constant reference to a `std::string` as input and returning an integer. + +2. **Variable Initialization:** + ```cpp + long result = 0; + int sign = 1; // 1 represents positive sign, -1 represents negative sign + size_t i = 0; + ``` + - Initialize `result` to store the converted integer. + - Initialize `sign` to 1 by default (positive sign). + - Initialize `i` as an index to iterate through the string. + +3. **Skip Leading Whitespaces:** + ```cpp + while (i < str.length() && isspace(str[i])) { + i++; + } + ``` + - Use a `while` loop to skip leading whitespaces in the input string. + +4. **Check for Positive or Negative Sign:** + ```cpp + if (i < str.length() && (str[i] == '+' || str[i] == '-')) { + sign = (str[i++] == '-') ? -1 : 1; + } + ``` + - Check for the presence of a positive or negative sign. + - Update the `sign` accordingly and increment `i` if a sign is found. + +5. **Process Digits:** + ```cpp + while (i < str.length() && isdigit(str[i])) { + result = result * 10 + (str[i++] - '0'); + + // Check for overflow + if (result * sign > INT_MAX) { + return INT_MAX; + } else if (result * sign < INT_MIN) { + return INT_MIN; + } + } + ``` + - Iterate through the string, processing digits and updating the `result`. + - Check for overflow by comparing against `INT_MAX` and `INT_MIN`. Return appropriate values if overflow is detected. + +6. **Apply Sign and Return Result:** + ```cpp + return static_cast(result * sign); + } + ``` + - Apply the sign to the result and return the final converted integer. + +7. **Main Function:** + ```cpp + int main() { + std::string s = "42"; + std::cout << myAtoi(s) << std::endl; + return 0; + } + ``` + - In the `main` function, a test string "42" is provided, and the result of the `myAtoi` function is printed. + +The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of an integer. The `myAtoi` function returns the converted integer, and the `main` function tests it with the string "42". + +# java +# code +```java +public class main{ + + static int atoi(String s) { + int num = 0, i = 0, sign = 1; + while (i < s.length() && s.charAt(i) == ' ') { + i++; + } + if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = s.charAt(i) == '+' ? 1 : -1; + i++; + } + while (i < s.length() && Character.isDigit(s.charAt(i))) { + int digit = s.charAt(i) - '0'; + if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + num = (num * 10) + digit; + i++; + } + return num * sign; + } + public static void main(String[] args) { + String s="42"; + System.out.println(atoi(s)); + } +} + +``` +# Code Explanation + +1. **Class Definition:** + ```java + public class Main { + ``` + - The class is named `Main`. + +2. **Static `atoi` Method:** + ```java + static int atoi(String s) { + ``` + - A static method named `atoi` is defined, which takes a `String` as input and returns an `int`. + +3. **Variable Initialization:** + ```java + int num = 0, i = 0, sign = 1; + ``` + - Initialize `num` to store the converted integer. + - Initialize `i` as an index to iterate through the string. + - Initialize `sign` to 1 by default (positive sign). + +4. **Skip Leading Whitespaces:** + ```java + while (i < s.length() && s.charAt(i) == ' ') { + i++; + } + ``` + - Use a `while` loop to skip leading whitespaces in the input string. + +5. **Check for Positive or Negative Sign:** + ```java + if (i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = s.charAt(i) == '+' ? 1 : -1; + i++; + } + ``` + - Check for the presence of a positive or negative sign. + - Update the `sign` accordingly and increment `i` if a sign is found. + +6. **Process Digits:** + ```java + while (i < s.length() && Character.isDigit(s.charAt(i))) { + int digit = s.charAt(i) - '0'; + if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + num = (num * 10) + digit; + i++; + } + ``` + - Iterate through the string, processing digits and updating the `num`. + - Check for overflow by comparing against `Integer.MAX_VALUE`. + - Return `Integer.MAX_VALUE` or `Integer.MIN_VALUE` if overflow is detected. + +7. **Return Result:** + ```java + return num * sign; + } + ``` + - Apply the sign to the result (`num`) and return the final converted integer. + +8. **Main Method:** + ```java + public static void main(String[] args) { + String s = "42"; + System.out.println(atoi(s)); + } + ``` + - The `main` method tests the `atoi` method with the string "42" and prints the result. + +The code essentially converts a given string to an integer, considering positive and negative signs, and handles overflow by checking against the limits of an integer. The `atoi` method returns the converted integer, and the `main` method tests it with the string "42". + +**Time and Space Complexity Analysis**: + +The time and space complexity for the atoi method, which converts a string to an integer. + +# Time Complexity: + +The time complexity of the atoi method is O(n), where n is the length of the input string. + + The while loop for skipping leading whitespaces runs in O(n) time because, in the worst case, it may have to iterate through the entire string. + The subsequent while loop for processing digits also runs in O(n) time, where n is the length of the string. This loop iterates through the digits of the string, and each iteration takes constant time. + +Therefore, the overall time complexity is O(n). + +# Space Complexity: + +The space complexity of the atoi method is O(1), constant space. + + The variables num, i, and sign are integers and require constant space regardless of the size of the input string. + No additional data structures are used that scale with the input size. + +The space complexity is constant or O(1). + +# Real-World Applications of string to integer + +Converting a string to an integer is a common operation in various real-world applications. Here are some examples: + +1. **User Input Processing:** + - In applications that accept user input, such as command-line interfaces or forms on websites, string-to-integer conversion is necessary to interpret numeric inputs provided by users. + +2. **Data Validation:** + - When dealing with external data sources, such as files or databases, where data is often represented as strings, converting relevant string values to integers is crucial for data validation and ensuring that the data meets expected numeric formats. + +3. **Parsing and Interpreting Configuration Files:** + - Many applications use configuration files to store settings. When reading these files, string-to-integer conversion is employed to interpret numeric configurations, such as specifying the number of threads, timeouts, or buffer sizes. + +4. **Network Protocols:** + - In network programming, especially when dealing with protocols that transmit data in string format, converting certain fields to integers is common. For instance, parsing HTTP headers or handling custom network protocols may involve converting string representations of numerical values to integers. + +5. **Database Operations:** + - In database applications, where data is often retrieved in string format, converting relevant data to integers is necessary for performing numerical operations or ensuring consistency in data types. + +6. **Mathematical Computations:** + - In scientific computing or applications involving mathematical calculations, converting strings to integers is essential when processing mathematical expressions or user-provided numerical data. + +7. **Financial Applications:** + - In financial software, handling monetary values often involves converting string representations of amounts to integers (or floating-point numbers) for accurate calculations. + +8. **Gaming and Graphics Programming:** + - Game development and graphics programming may require converting string representations of parameters, such as screen dimensions or frame rates, to integers for configuring the game environment or rendering settings. + +9. **Command-Line Interfaces (CLI):** + - CLI applications often take user inputs as strings, and converting these inputs to integers is necessary for executing numeric commands or configuring the behavior of the application. + +10. **Sensor Data Processing:** + - In embedded systems or IoT applications, sensor data received in string format may need to be converted to integers for further analysis or decision-making based on numeric thresholds. + +In essence, string-to-integer conversion is a fundamental operation in software development, as it facilitates the integration and processing of numerical information in various domains. +In addition to the real-world applications mentioned earlier, let's explore some theoretical scenarios or examples where string-to-integer conversion plays a crucial role: + +1. **Algorithmic Problem Solving:** + - In algorithmic problems, you may encounter scenarios where input is provided as strings, and converting these strings to integers is a common step. For example, when implementing algorithms that involve mathematical computations, sorting, or searching, converting string inputs to integers allows for efficient processing. + +2. **String Matching Algorithms:** + - String matching algorithms, such as the Knuth-Morris-Pratt algorithm or the Boyer-Moore algorithm, may involve comparing and manipulating string representations of integers. Converting these strings to integers allows for efficient pattern matching and searching. + +3. **Abstract Data Types (ADTs):** + - In the design and implementation of abstract data types, converting string representations of numerical data to actual integers is often necessary. For instance, when implementing a priority queue where elements are associated with numeric priorities provided as strings, conversion to integers is crucial for proper ordering. + +4. **Parsing and Interpretation of Domain-Specific Languages:** + - When working with domain-specific languages or custom file formats, interpreting and parsing string representations of numeric values is fundamental. Converting these strings to integers allows for the proper interpretation of data and execution of language-specific commands. + +5. **Code Analysis and Transformation:** + - In static code analysis or transformation tools, understanding and manipulating numeric constants within code may require converting string representations to integers. This is useful for performing optimizations, refactoring, or analyzing code patterns. + +6. **Symbolic Computation:** + - In symbolic computation systems, where algebraic expressions are manipulated symbolically, converting string representations of numeric coefficients or constants to actual integers is necessary for performing mathematical operations. + +7. **Formal Language Theory:** + - In formal language theory, automata, and compilers, parsing numeric literals from strings is a common operation. Converting these literals to integers is crucial for generating executable code or performing language analysis. + +8. **Graph Theory and Network Analysis:** + - When working with graph representations, especially in scenarios where nodes or edges are labeled with numeric identifiers provided as strings, converting these identifiers to integers facilitates efficient graph algorithms and analysis. + +9. **Cryptography:** + - In cryptographic applications, handling cryptographic keys or parameters, often represented as strings, may require converting these string representations to integers for cryptographic operations. + +10. **Educational Examples:** + - In educational contexts, when teaching programming or algorithms, string-to-integer conversion serves as a fundamental concept. Exercises and examples often involve converting user inputs or string data to integers for various purposes. + +In theoretical scenarios, the importance of string-to-integer conversion arises in the context of solving abstract problems, designing algorithms, and implementing various computational concepts. \ No newline at end of file diff --git a/Strings/Medium/String to Integer/main.java b/Strings/Medium/String to Integer/main.java new file mode 100644 index 00000000..bedd751b --- /dev/null +++ b/Strings/Medium/String to Integer/main.java @@ -0,0 +1,26 @@ +public class main{ + + static int atoi(String s) { + int num = 0, i = 0, sign = 1; + while (i < s.length() && s.charAt(i) == ' ') { + i++; + } + if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = s.charAt(i) == '+' ? 1 : -1; + i++; + } + while (i < s.length() && Character.isDigit(s.charAt(i))) { + int digit = s.charAt(i) - '0'; + if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { + return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } + num = (num * 10) + digit; + i++; + } + return num * sign; + } + public static void main(String[] args) { + String s="42"; + System.out.println(atoi(s)); + } +} \ No newline at end of file diff --git a/Strings/Medium/String to Integer/stringtointeger.cpp b/Strings/Medium/String to Integer/stringtointeger.cpp new file mode 100644 index 00000000..bdb57305 --- /dev/null +++ b/Strings/Medium/String to Integer/stringtointeger.cpp @@ -0,0 +1,31 @@ +#include + +int atoi(std::string s) +{ + int num = 0, i = 0, sign = 1; + while (s[i] == ' ') + { + i++; + } + if (i < s.length() && (s[i] == '-' || s[i] == '+')) + { + sign = s[i] == '+' ? 1 : -1; + i++; + } + while (i < s.length() && isdigit(s[i])) + { + + if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) + return sign == 1 ? INT_MAX : INT_MIN; + num = ((num * 10) + (s[i] - '0')); + i++; + } + return num * sign; +} + +int main() +{ + std::string s = "42"; + std::cout << atoi(s); + return 0; +} \ No newline at end of file diff --git a/Strings/Medium/String to Integer/stringtointeger.py b/Strings/Medium/String to Integer/stringtointeger.py new file mode 100644 index 00000000..28122421 --- /dev/null +++ b/Strings/Medium/String to Integer/stringtointeger.py @@ -0,0 +1,40 @@ +def check(answer): + if answer<-2**31: + return -2**31 + elif answer>=2**31: + return 2**31-1 + else: + return answer + +def myAtoi(string): + answer=0 + sign=0 + i=0 + + while(i ds, List> output, String str){ + if(index == str.length()){ + output.add(new ArrayList<>(ds)); + return; + } + for(int i = index; i < str.length(); i++){ + if(checkPalindrome(str, index, i)){ + ds.add(str.substring(index, i + 1)); + palindromePartition(i+1, ds, output, str); + ds.remove(ds.size()-1); + } + } + } + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s="aab"; + System.out.println(partition(s)); + } + +} \ No newline at end of file diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md new file mode 100644 index 00000000..4cb7e215 --- /dev/null +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -0,0 +1,327 @@ +# Exploring palindrome partitioning using Strings: + +Exploring palindrome partitioning with strings often involves dynamic programming. The idea is to build a table or array to store intermediate results, helping to avoid redundant computations and improve the overall efficiency of the algorithm. + +# Introduction to Strings: + +A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. +Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. + +# Introduction to the Palindrome Partitioning Theory: + +A palindrome is a sequence of characters that reads the same backward as forward. Examples include "level," "radar," and "madam". Palindrome partitioning is a concept in theoretical computer science and mathematics that involves breaking down a string into substrings, with the condition that each substring is a palindrome.The goal of palindrome partitioning is to find all possible ways to split a given string into palindromic substrings. + +# Overview of Palindrome Partitioning: + +Given a string, the problem is to find all possible ways to partition it into palindromic substrings. + +# PYTHON +# code + +```python +# Copyrights to venkys.io +# For more information, visit https://venkys.io + +# python program for Palindrome Partitioning +# Stable: No +# Inplace: No +# Adaptive: Not Applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) + +# Space complexity:O(n^2) +# Time complexity:O(n^2) + +def partition(string): + # Initialize dynamic programming array + dp=[[] for _ in range(len(string)+1)] + + # Initialize the first state with an empty partition + dp[0]=[[]] + +# Iterate over each character of the string + for j in range(1,len(string)+1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j]==string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each+[string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +if __name__=="__main__": + string="ababa" + print(partition(string)) +``` +# Code Explanation + +1. **Dynamic Programming Array (`dp`):** + - `dp` is a list of lists used for dynamic programming. It represents the state of the algorithm at each position in the input string. + +2. **Initialization:** + - `dp[0]` is initialized with an empty list representing the empty partition for the first state. + +3. **Iterating Over Characters (`j`):** + - The outer loop (`for j in range(1, len(string) + 1)`) iterates over each character in the input string, starting from the second character. + +4. **Iterating Over Previous Characters (`i`):** + - The inner loop (`for i in range(j)`) iterates through each previous character (from the beginning of the string up to `j`). + +5. **Palindrome Check:** + - `if string[i:j] == string[i:j][::-1]:` checks if the substring from `i` to `j` is a palindrome. + +6. **Updating Partitions:** + - If the substring is a palindrome, it extends the partitions ending at position `i` with the palindrome substring. It uses a nested loop to iterate through each existing partition at position `i` (`for each in dp[i]`) and appends the current palindrome substring to create new partitions. + +7. **Final Result:** + - The final state is represented by `dp[-1]`, which contains all valid partitions, and it is returned as the output of the function. + +8. **Example Usage:** + - The provided example with `string = "ababa"` demonstrates how the function can be called and prints the result of partitioning the given string into palindromic substrings. + +The algorithm employs dynamic programming to efficiently find and extend palindrome partitions in the input string. + +# C++ +# code + +```C++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program Palindrome Partitioning +// Stable: No +// Inplace:No +// Adaptive: Not applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) + +// Space complexity:O(n^2) +// Time complexity:O(n^2) + +#include +bool isPalindrome(std::string s, int i, int j) { + // While loop checks the string symmetrically. + while (i <= j) { + // If characters at different ends don't match, it's not a palindrome. + if (s[i++] != s[j--]) return false; + } + // If loop finished, the string is a palindrome. + return true; +} +void util(int i,std::string s,std::vector>& res,std::vector& path){ + // base case: when string s is fully processed + if(i==s.size()){ + res.push_back(path); + return ; + } + // iteratively checking each substring + for(int j=i;j> partition (std::string s){ + // Output list of all palindrome partitions + std::vector> res; + // List to keep track of the current path + std::vector path; + // Utility function to find all palindrome partitions + util(0,s,res,path); + return res; +} +int main(){ + // initial string to be partitioned + std::string s = "aaab"; + // function call to get all partitions + std::vector> ans=partition(s); + // loop to print all partitions + for(auto& a:ans){ + for(auto& b:a){ + std::cout< ds, List> output, String str){ + if(index == str.length()){ + output.add(new ArrayList<>(ds)); + return; + } + for(int i = index; i < str.length(); i++){ + if(checkPalindrome(str, index, i)){ + ds.add(str.substring(index, i + 1)); + palindromePartition(i+1, ds, output, str); + ds.remove(ds.size()-1); + } + } + } + + // Main function to return all the palindrome partitioning + static List> partition(String s) { + List> output = new ArrayList<>(); + List ds = new ArrayList<>(); + palindromePartition(0, ds, output, s); + return output; + } + + public static void main(String[] args) { + String s="aab"; + System.out.println(partition(s)); + } + +} + +``` +# Code Explanation + +1. **`checkPalindrome` Function:** + - This function checks whether a given substring of a string is a palindrome. + - It takes three parameters: + - `str`: The input string. + - `startIndex`: The starting index of the substring. + - `lastIndex`: The ending index of the substring. + - It uses a `while` loop to check if the characters at the given indices are equal, iterating towards the center of the substring. If at any point they are not equal, the function returns `false`. Otherwise, it returns `true`. + +2. **`palindromePartition` Function:** + - This recursive function generates all possible palindrome partitions of the input string. + - It takes four parameters: + - `index`: The current index in the string. + - `ds`: A list representing the current path of partitions. + - `output`: A list of lists to store all palindrome partitions. + - `str`: The input string. + - The base case is when the `index` reaches the length of the string. At this point, the current path (`ds`) is added to the `output` list. + - It uses a `for` loop to iterate from the current index to the end of the string. + - If the substring from the current index to the loop variable `i` is a palindrome (checked using `checkPalindrome`), it adds the substring to the current path (`ds`) and recursively calls itself with the updated index (`i + 1`). + - After the recursive call, it removes the last added substring from the current path to explore other possibilities. + +3. **`partition` Function:** + - This is the main function that initializes the necessary lists and calls `palindromePartition` to find all palindrome partitions. + - It takes the input string `s`, creates an empty list for the output, and an empty list for the current path (`ds`). + - It calls `palindromePartition` with the initial index (`0`), current path (`ds`), output list (`output`), and the input string (`s`). + +4. **`main` Function:** + - The `main` function demonstrates the usage of the `partition` function on the string "aab." + - It prints the result obtained from the `partition` function. + +**Example Output:** + +[[a, a, b], [aa, b]] + + +The code efficiently finds and prints all possible palindrome partitions of the input string "aab" using a recursive approach. + + +**Time and Space Complexity Analysis**: + +# Time Complexity: +O(n^2), where n is the length of the input string. +The dynamic programming table is typically a 2D array of size n x n, and each entry requires constant time to compute. +# Space Complexity: +O(n^2). +The space complexity is determined by the 2D table used for memoization or tabulation. + +# Real-World Applications of Palindrome Partitioning + +Palindrome partitioning, while primarily a concept used in algorithmic problem-solving, has applications in various real-world scenarios. Here are some areas where the concept of palindrome partitioning or similar techniques can be applied: + +1. **Genomic Sequence Analysis:** + - In bioinformatics, palindrome partitioning techniques can be used for analyzing DNA or RNA sequences. Identifying palindromic sequences can provide insights into the structure and function of genetic material. + +2. **Text Processing and Pattern Matching:** + - Palindrome partitioning concepts can be applied in text processing and pattern matching. For example, identifying palindromic patterns in text can be useful in natural language processing or searching for specific structures in documents. + +3. **Data Compression:** + - Palindromes can be leveraged in data compression algorithms. Identifying and encoding repeated palindromic patterns efficiently can contribute to the compression of data. + +4. **Cryptography:** + - In certain cryptographic algorithms, palindromic structures or related concepts might be employed for creating secure key structures or encoding information. + +5. **Speech Processing:** + - Palindrome partitioning techniques could be applied in speech processing, especially in the analysis of phonetic or acoustic sequences. + +6. **Fault-Tolerant Systems:** + - Palindrome-related algorithms can be used in fault-tolerant systems, where the identification of symmetric or repeating patterns helps in recognizing and correcting errors. + +7. **Robotics and Image Processing:** + - Palindrome partitioning methods may find applications in robotics and image processing. For instance, in image recognition, identifying symmetrical patterns can aid in object recognition. + +8. **Algorithmic Design and Optimization:** + - Understanding and solving problems related to palindrome partitioning contribute to the development of efficient algorithms. These algorithms, in turn, find applications in various computational fields, including data analysis and optimization. + +9. **Network Security:** + - Palindrome partitioning or related concepts might be used in analyzing network traffic patterns or identifying anomalies in network behavior, contributing to network security. + +10. **Game Design:** + - Some game algorithms may involve palindrome partitioning or similar techniques, especially in puzzle-solving or pattern recognition games. diff --git a/Strings/Medium/palindrome partitioning/palindromepartition.py b/Strings/Medium/palindrome partitioning/palindromepartition.py new file mode 100644 index 00000000..15b4cd2d --- /dev/null +++ b/Strings/Medium/palindrome partitioning/palindromepartition.py @@ -0,0 +1,22 @@ +def partition(string): + # Initialize dynamic programming array + dp=[[] for _ in range(len(string)+1)] + + # Initialize the first state with an empty partition + dp[0]=[[]] + +# Iterate over each character of the string + for j in range(1,len(string)+1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j]==string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each+[string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +if __name__=="__main__": + string="ababa" + print(partition(string)) diff --git a/Strings/Medium/palindrome partitioning/palindrompartition.c++ b/Strings/Medium/palindrome partitioning/palindrompartition.c++ new file mode 100644 index 00000000..3d7c28c0 --- /dev/null +++ b/Strings/Medium/palindrome partitioning/palindrompartition.c++ @@ -0,0 +1,53 @@ +#include +bool isPalindrome(std::string s, int i, int j) { + // While loop checks the string symmetrically. + while (i <= j) { + // If characters at different ends don't match, it's not a palindrome. + if (s[i++] != s[j--]) return false; + } + // If loop finished, the string is a palindrome. + return true; +} +void util(int i,std::string s,std::vector>& res,std::vector& path){ + // base case: when string s is fully processed + if(i==s.size()){ + res.push_back(path); + return ; + } + + // iteratively checking each substring + for(int j=i;j> partition (std::string s){ + // Output list of all palindrome partitions + std::vector> res; + // List to keep track of the current path + std::vector path; + // Utility function to find all palindrome partitions + util(0,s,res,path); + return res; +} +int main(){ + // initial string to be partitioned + std::string s = "aaab"; + // function call to get all partitions + std::vector> ans=partition(s); + // loop to print all partitions + for(auto& a:ans){ + for(auto& b:a){ + std::cout< Date: Sat, 16 Dec 2023 10:37:20 +0530 Subject: [PATCH 30/53] Add files via upload --- Heaps/Hard/MaxHeapCRUD.java | 121 +++++++ Heaps/Hard/Readme.md | 594 +++++++++++++++++++++++++++++++++++ Heaps/Hard/max heap CRUD.py | 92 ++++++ Heaps/Hard/max_heap_CRUD.c++ | 113 +++++++ 4 files changed, 920 insertions(+) create mode 100644 Heaps/Hard/MaxHeapCRUD.java create mode 100644 Heaps/Hard/Readme.md create mode 100644 Heaps/Hard/max heap CRUD.py create mode 100644 Heaps/Hard/max_heap_CRUD.c++ diff --git a/Heaps/Hard/MaxHeapCRUD.java b/Heaps/Hard/MaxHeapCRUD.java new file mode 100644 index 00000000..f8a6ff78 --- /dev/null +++ b/Heaps/Hard/MaxHeapCRUD.java @@ -0,0 +1,121 @@ +import java.util.ArrayList; +import java.util.List; + +// Class representing a max heap with CRUD operations +class MaxHeapCRUD { + private List heap; + + // Constructor initializes an empty list for the heap + public MaxHeapCRUD() { + this.heap = new ArrayList<>(); + } + + // Move the element up the heap until the heap property is restored + private void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap.get(parent) >= heap.get(index)) { + break; + } + // Swap the current element with its parent + int temp = heap.get(parent); + heap.set(parent, heap.get(index)); + heap.set(index, temp); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + private void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap.get(left) > heap.get(largest)) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap.get(right) > heap.get(largest)) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + int temp = heap.get(largest); + heap.set(largest, heap.get(index)); + heap.set(index, temp); + maxHeapify(largest); + } + } + + // Add a new element to the heap and percolate it up to maintain the heap property + public void insert(int val) { + heap.add(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + public int getMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + return heap.get(0); + } + + // Update the value, percolate up, and max heapify to maintain the heap property + public void update(int oldVal, int newVal) { + int index = heap.indexOf(oldVal); + if (index != -1) { + heap.set(index, newVal); + percolateUp(index); + maxHeapify(index); + } else { + System.out.println("Value not in heap"); + } + } + + // Replace the root with the last element, pop the last element, and max heapify + public void deleteMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + heap.set(0, heap.remove(heap.size() - 1)); + maxHeapify(0); + } + + // Print all values in the heap + public void printHeap() { + for (int i : heap) { + System.out.print(i + " "); + } + System.out.println(); + } + + // Main method demonstrating usage of the MaxHeapCRUD class + public static void main(String[] args) { + MaxHeapCRUD heap = new MaxHeapCRUD(); + + heap.insert(12); + heap.insert(10); + heap.insert(52); + heap.insert(100); + heap.insert(50); + + System.out.print("All values in heap: "); + heap.printHeap(); + + System.out.println("Max Value: " + heap.getMax()); + + heap.update(12, 5); + + System.out.println("Max Value after update: " + heap.getMax()); + + heap.deleteMax(); + + System.out.println("Max Value after deletion: " + heap.getMax()); + + System.out.print("All values in heap: "); + heap.printHeap(); + } +} \ No newline at end of file diff --git a/Heaps/Hard/Readme.md b/Heaps/Hard/Readme.md new file mode 100644 index 00000000..233b5857 --- /dev/null +++ b/Heaps/Hard/Readme.md @@ -0,0 +1,594 @@ +# Exploring Max-Heap using CRUD operations : + +## Introduction to Heaps: + +Heaps are a fundamental data structure used in computer science for efficient implementation of priority queues and various graph algorithms. A heap is a specialized tree-based structure that satisfies the heap property. + +A binary heap is a complete binary tree where every parent node has a value greater than or equal to its children. This structure allows for quick retrieval and removal of the maximum element, making it an ideal choice for priority queue implementations. + +## Introduction to Max-Heap CRUD Operations: + +In the context of heaps, CRUD operations refer to Create, Read, Update, and Delete. Max-Heap CRUD operations involve manipulating a max heap, ensuring that it maintains the heap property at all times. + +Let's dive into each CRUD operation: + +### Overview of Max-Heap CRUD Operations: + +1. **Create (Insertion):** + - **Description:** Adds a new element to the max heap while maintaining the heap property. + - **Implementation:** The new element is appended to the end of the heap, and then the `percolate_up` method is called to ensure that the heap property is restored. + +2. **Read (Get Maximum):** + - **Description:** Returns the maximum element in the max heap, which is always the root. + - **Implementation:** Simply retrieves the element at the root of the heap. + +3. **Update (Modify Element):** + - **Description:** Updates an existing value in the max heap while preserving the heap property. + - **Implementation:** Finds the index of the old value, updates it with the new value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. + +4. **Delete (Remove Maximum):** + - **Description:** Removes the maximum element (root) from the max heap while maintaining the heap property. + - **Implementation:** Replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. + +These CRUD operations provide a comprehensive set of functionalities for working with a max heap. They ensure that the heap property is consistently upheld, allowing for efficient management of data in various applications. + + +# PYTHON +# code + +```python +# Copyrights to venkys.io +# For more information, visit https://venkys.io + +# python program for Max-Heap CRUD +# Stable: Yes +# Inplace: Yes +# Adaptive: Yes + +# Space complexity:O(n) +# Time complexity: +# Insertion: O(log N) +# Get Max: O(1) +# Update: O(log N) +# Delete Max: O(log N) + +class MaxHeap: + def __init__(self): + # Initialize an empty list to represent the heap + self.heap = [] + + def percolate_up(self, index): + # Move the element up the heap until the heap property is restored + while index > 0: + parent = (index - 1) // 2 + if self.heap[parent] >= self.heap[index]: + break + # Swap the current element with its parent + self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] + index = parent + + def max_heapify(self, index): + # Ensure the heap property is maintained starting from the given index + left = 2 * index + 1 + right = 2 * index + 2 + largest = index + + # Check if the left child is larger than the current largest element + if left < len(self.heap) and self.heap[left] > self.heap[largest]: + largest = left + # Check if the right child is larger than the current largest element + if right < len(self.heap) and self.heap[right] > self.heap[largest]: + largest = right + + # If the largest element is not the current index, swap and continue heapifying + if largest != index: + self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] + self.max_heapify(largest) + + def insert(self, val): + # Add a new element to the heap and percolate it up to maintain the heap property + self.heap.append(val) + self.percolate_up(len(self.heap) - 1) + + def get_max(self): + # Return the maximum element in the heap (root of the heap) + if len(self.heap) == 0: + raise Exception("Heap is empty") + return self.heap[0] + + def update(self, old_val, new_val): + try: + # Find the index of the old value in the heap + index = self.heap.index(old_val) + # Update the value, percolate up, and max heapify to maintain the heap property + self.heap[index] = new_val + self.percolate_up(index) + self.max_heapify(index) + except ValueError: + print("Value not in heap") + + def delete_max(self): + if len(self.heap) == 0: + raise Exception("Heap is empty") + # Replace the root with the last element, pop the last element, and max heapify + self.heap[0] = self.heap.pop() + self.max_heapify(0) + + def print_heap(self): + # Print all values in the heap + print(" ".join(map(str, self.heap))) + + +def main(): + # Initialize max heap + heap = MaxHeap() + + # Insert elements into heap + heap.insert(12) + heap.insert(10) + heap.insert(-10) + heap.insert(100) + + # Print all values in heap + heap.print_heap() + + # Get max value in heap + print("Max Value:", heap.get_max()) + + # Update value in heap + heap.update(12, 5) + print("Max Value after update:", heap.get_max()) + + # Delete max value from heap + heap.delete_max() + print("Max Value after deletion:", heap.get_max()) + + # Print all values in heap after deletion + heap.print_heap() + +``` +# Code Explanation + +The provided code implements a MaxHeap class in Python, allowing users to perform CRUD operations (Create, Read, Update, Delete) on a max heap data structure. Let's break down the code and provide a clear explanation: + + +# Step 1 - Initialization: +``` + self.heap = [] +``` +The `MaxHeap` class is initialized with an empty list, `self.heap`, which will store the elements of the max heap. + +# Step 2 - Percolate Up: +```python +def percolate_up(self, index): +``` +The `percolate_up` method is used during insertion to move a newly added element up the heap until the heap property is restored. It compares the element with its parent and swaps them if needed. + +# Step 3 - Max Heapify: + +```python +def max_heapify(self, index): +``` +The `max_heapify` method is used to maintain the heap property from a given index. It compares the element with its left and right children, swaps with the largest child if needed, and recursively continues the process. + +# Step 4 - Insertion: + +```python +def insert(self, val): +``` +The `insert` method adds a new element to the heap and then calls `percolate_up` to ensure the heap property is maintained. + +# Step 5 - Get Max: + +```python +def get_max(self): +``` +The `get_max` method returns the maximum element in the heap, which is the root. + +# Step 6 - Update: + +```python +def update(self, old_val, new_val): +``` +The `update` method updates an existing value in the heap. It finds the index, updates the value, and then calls `percolate_up` and `max_heapify` to maintain the heap property. + +# Step 7 - Delete Max: + +```python +def delete_max(self): +``` +The `delete_max` method removes the maximum element (root) from the heap. It replaces the root with the last element, pops the last element, and then calls `max_heapify` to reorder the heap. + +# Step 8 - Print Heap: + +```python +def print_heap(self): +``` +The `print_heap` method prints all values in the heap. + +# Step 9 - Main Function: + +```python +def main(): + # Initialize max heap + heap = MaxHeap() +``` +The `main` function demonstrates the usage of the `MaxHeap` class by initializing a heap, performing insertions, updates, deletions, and printing the heap at different stages. + +This implementation provides a clear and organized way to work with Max-Heaps in Python. + +# C++ +# code + +```C++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program for Max_Heap CRUD +// Stable: No +// Inplace: Yes +// Adaptive: No + +// Space complexity: O(N) +// Time complexity: +// Insertion: O(log N) +// Get Max: O(1) +// Update: O(log N) +// Delete Max: O(log N) + +#include +#include +#include + +class MaxHeap { +private: + std::vector heap; + + // Move the element up the heap until the heap property is restored + void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap[parent] >= heap[index]) { + break; + } + std::swap(heap[parent], heap[index]); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap[left] > heap[largest]) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap[right] > heap[largest]) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + std::swap(heap[largest], heap[index]); + maxHeapify(largest); + } + } + +public: + // Add a new element to the heap and percolate it up to maintain the heap property + void insert(int val) { + heap.push_back(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + int getMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + return heap[0]; + } + + // Update the value, percolate up, and max heapify to maintain the heap property + void update(int old_val, int new_val) { + auto it = std::find(heap.begin(), heap.end(), old_val); + if (it != heap.end()) { + *it = new_val; + percolateUp(it - heap.begin()); + maxHeapify(it - heap.begin()); + } else { + std::cout << "Value not in heap" << std::endl; + } + } + + // Replace the root with the last element, pop the last element, and max heapify + void deleteMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + heap[0] = heap.back(); + heap.pop_back(); + maxHeapify(0); + } + + // Print all values in the heap + void printHeap() { + for (int i : heap) { + std::cout << i << " "; + } + std::cout << std::endl; + } +}; + +int main() { + // Example usage of the MaxHeap class + MaxHeap heap; + + heap.insert(12); + heap.insert(10); + heap.insert(-10); + heap.insert(100); + + std::cout << "All values in heap: "; + heap.printHeap(); + + std::cout << "Max Value: " << heap.getMax() << std::endl; + + heap.update(12, 5); + std::cout << "Max Value after update: " << heap.getMax() << std::endl; + + heap.deleteMax(); + std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + + std::cout << "All values in heap: "; + heap.printHeap(); + + return 0; +} +``` +# java +# code + +```java +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// java program for Max-Heap CRUD +// Stable: No +// Inplace: Yes +// Adaptive: No + +// Space complexity: O(N) +// Time complexity: + // Insertion: O(log N) + // Get Max: O(1) + // Update: O(log N) + // Delete Max: O(log N) + +import java.util.ArrayList; +import java.util.List; + +// Class representing a max heap with CRUD operations +class MaxHeapCRUD { + private List heap; + + // Constructor initializes an empty list for the heap + public MaxHeapCRUD() { + this.heap = new ArrayList<>(); + } + + // Move the element up the heap until the heap property is restored + private void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap.get(parent) >= heap.get(index)) { + break; + } + // Swap the current element with its parent + int temp = heap.get(parent); + heap.set(parent, heap.get(index)); + heap.set(index, temp); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + private void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap.get(left) > heap.get(largest)) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap.get(right) > heap.get(largest)) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + int temp = heap.get(largest); + heap.set(largest, heap.get(index)); + heap.set(index, temp); + maxHeapify(largest); + } + } + + // Add a new element to the heap and percolate it up to maintain the heap property + public void insert(int val) { + heap.add(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + public int getMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + return heap.get(0); + } + + // Update the value, percolate up, and max heapify to maintain the heap property + public void update(int oldVal, int newVal) { + int index = heap.indexOf(oldVal); + if (index != -1) { + heap.set(index, newVal); + percolateUp(index); + maxHeapify(index); + } else { + System.out.println("Value not in heap"); + } + } + + // Replace the root with the last element, pop the last element, and max heapify + public void deleteMax() { + if (heap.size() == 0) { + throw new RuntimeException("Heap is empty"); + } + heap.set(0, heap.remove(heap.size() - 1)); + maxHeapify(0); + } + + // Print all values in the heap + public void printHeap() { + for (int i : heap) { + System.out.print(i + " "); + } + System.out.println(); + } + + // Main method demonstrating usage of the MaxHeapCRUD class + public static void main(String[] args) { + MaxHeapCRUD heap = new MaxHeapCRUD(); + + heap.insert(12); + heap.insert(10); + heap.insert(52); + heap.insert(100); + heap.insert(50); + + System.out.print("All values in heap: "); + heap.printHeap(); + + System.out.println("Max Value: " + heap.getMax()); + + heap.update(12, 5); + + System.out.println("Max Value after update: " + heap.getMax()); + + heap.deleteMax(); + + System.out.println("Max Value after deletion: " + heap.getMax()); + + System.out.print("All values in heap: "); + heap.printHeap(); + } +} +``` +# Code Explanation + Step by step explanation for Java and C++ : + +1. **Class Definition (MaxHeap):** + - The code defines a class named `MaxHeap` representing a Max Heap data structure. + - Private member for c++: `std::vector heap` is used to store the elements of the heap. + -It uses a private list (heap) to store the elements of the heap in java. + - The class has a constructor in java (MaxHeapCRUD()) that initializes an empty list for the heap. + + +2. **percolateUp Function:** + - Private method `percolateUp` moves an element up the heap until the heap property is restored. + - It takes an index as a parameter and swaps the element with its parent until the heap property is satisfied. + +3. **maxHeapify Function:** + - Private method `maxHeapify` ensures the heap property is maintained starting from a given index. + - It compares the element with its left and right children, swapping it with the largest child if needed. + +4. **insert Function:** + - Public method `insert` adds a new element to the heap and ensures the heap property by calling `percolateUp`. + +5. **getMax Function:** + - Public method `getMax` returns the maximum element in the heap (the root). + +6. **update Function:** + - Public method `update` updates a specified element in the heap with a new value. + - It uses `std::find` to locate the element, updates it, and then calls `percolateUp` and `maxHeapify` to maintain the heap property. + +7. **deleteMax Function:** + - Public method `deleteMax` removes the maximum element (root) from the heap. + - It replaces the root with the last element, pops the last element, and calls `maxHeapify` to restore the heap property. + +8. **printHeap Function:** + - Public method `printHeap` prints all values in the heap. + +9. **main Function:** + - In the `main` function: + - An instance of `MaxHeap` named `heap` is created in c++.An instance of MaxHeapCRUD named heap is created in java + - Elements (12, 10, -10, 100,50) are inserted into the heap using `insert`. + - All values in the heap are printed using `printHeap`. + - The maximum value in the heap is printed using `getMax`. + - An update is performed, changing the value 12 to 5 using `update`. + - The maximum value after the update is printed. + - The maximum element is deleted using `deleteMax`. + - The maximum value after deletion is printed. + - Finally, all values in the heap after deletion are printed. + +This code demonstrates the basic operations (insertion, update, deletion) on a Max Heap. + + + +**Time and Space Complexity Analysis**: + +# Time Complexity: +The time complexities for the Max Heap CRUD (Create, Read, Update, Delete) operations are as follows: + +1. **Insertion (Create):** + - Time Complexity: O(log n) + - Explanation: The worst-case time complexity for inserting an element into a max heap is logarithmic in the number of elements, as the element needs to be percolated up the height of the heap. The height of a binary heap is log(n) where n is the number of elements. + +2. **GetMax (Read):** + - Time Complexity: O(1) + - Explanation: Retrieving the maximum element (root) in a max heap can be done in constant time as the maximum element is always at the root. + +3. **Update:** + - Time Complexity: O(log n) + - Explanation: Updating an element in a max heap involves two operations: percolating up (up to log n steps) and max heapifying (up to log n steps). Therefore, the overall time complexity is logarithmic. + +4. **DeleteMax (Delete):** + - Time Complexity: O(log n) + - Explanation: Deleting the maximum element involves replacing the root with the last element, which may require percolating down the height of the heap to maintain the heap property. The worst-case time complexity is logarithmic. + +These time complexities assume that the underlying data structure is a binary heap. The actual performance may vary based on implementation details and the specific operations performed. + +# Space Complexity: +The space complexity for Max Heap CRUD (Create, Read, Update, Delete) operations is O(n), where n is the number of elements in the heap. + +1. **Insertion (Create):** + - Explanation: The insertion operation generally doesn't require additional space proportional to the number of elements. The new element is added to the existing heap in-place. + +2. **GetMax (Read):** + - Explanation: Reading the maximum element involves accessing the root of the heap. It doesn't require additional space proportional to the number of elements. + +3. **Update:** + - Explanation: The update operation is performed in-place without requiring additional space. + +4. **DeleteMax (Delete):** + - Explanation: The delete operation involves replacing the root with the last element and then adjusting the heap structure. It is performed in-place without requiring additional space. + +# Real-World Applications of MAX-HEAP CRUD(Create,Read,Update,Delete) + +1. **Task Scheduling:** Priority scheduling based on task priority levels. +2. **Job Scheduling:** Allocating jobs to machines based on priority. +3. **Dijkstra's Algorithm:** Finding the shortest path in a graph. +4. **Huffman Coding:** Data compression algorithm. +5. **Order Processing:** Managing orders based on their priority in e-commerce systems. +6. **Operating System Task Scheduling:** Assigning priority to tasks for execution. +7. **Network Routing Algorithms:** Determining the optimal path for data packets. +8. **Emergency Room Triage:** Prioritizing patients based on the severity of their condition. +9. **Database Indexing:** Managing indexes to speed up query performance. +10. **Wireless Sensor Networks:** Energy-efficient data aggregation in sensor networks. diff --git a/Heaps/Hard/max heap CRUD.py b/Heaps/Hard/max heap CRUD.py new file mode 100644 index 00000000..0ce2f26f --- /dev/null +++ b/Heaps/Hard/max heap CRUD.py @@ -0,0 +1,92 @@ +class MaxHeap: + def __init__(self): + # Initialize an empty list to represent the heap + self.heap = [] + + def percolate_up(self, index): + # Move the element up the heap until the heap property is restored + while index > 0: + parent = (index - 1) // 2 + if self.heap[parent] >= self.heap[index]: + break + # Swap the current element with its parent + self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent] + index = parent + + def max_heapify(self, index): + # Ensure the heap property is maintained starting from the given index + left = 2 * index + 1 + right = 2 * index + 2 + largest = index + + # Check if the left child is larger than the current largest element + if left < len(self.heap) and self.heap[left] > self.heap[largest]: + largest = left + # Check if the right child is larger than the current largest element + if right < len(self.heap) and self.heap[right] > self.heap[largest]: + largest = right + + # If the largest element is not the current index, swap and continue heapifying + if largest != index: + self.heap[largest], self.heap[index] = self.heap[index], self.heap[largest] + self.max_heapify(largest) + + def insert(self, val): + # Add a new element to the heap and percolate it up to maintain the heap property + self.heap.append(val) + self.percolate_up(len(self.heap) - 1) + + def get_max(self): + # Return the maximum element in the heap (root of the heap) + if len(self.heap) == 0: + raise Exception("Heap is empty") + return self.heap[0] + + def update(self, old_val, new_val): + try: + # Find the index of the old value in the heap + index = self.heap.index(old_val) + # Update the value, percolate up, and max heapify to maintain the heap property + self.heap[index] = new_val + self.percolate_up(index) + self.max_heapify(index) + except ValueError: + print("Value not in heap") + + def delete_max(self): + if len(self.heap) == 0: + raise Exception("Heap is empty") + # Replace the root with the last element, pop the last element, and max heapify + self.heap[0] = self.heap.pop() + self.max_heapify(0) + + def print_heap(self): + # Print all values in the heap + print(" ".join(map(str, self.heap))) + +def main(): + # Initialize max heap + heap = MaxHeap() + + # Insert elements into heap + heap.insert(12) + heap.insert(10) + heap.insert(-10) + heap.insert(100) + + # Print all values in heap + heap.print_heap() + + # Get max value in heap + print("Max Value:", heap.get_max()) + + # Update value in heap + heap.update(12, 5) + print("Max Value after update:", heap.get_max()) + + # Delete max value from heap + heap.delete_max() + print("Max Value after deletion:", heap.get_max()) + + # Print all values in heap after deletion + heap.print_heap() \ No newline at end of file diff --git a/Heaps/Hard/max_heap_CRUD.c++ b/Heaps/Hard/max_heap_CRUD.c++ new file mode 100644 index 00000000..0cebbbdc --- /dev/null +++ b/Heaps/Hard/max_heap_CRUD.c++ @@ -0,0 +1,113 @@ +#include +#include +#include + +class MaxHeap { +private: + std::vector heap; + + // Move the element up the heap until the heap property is restored + void percolateUp(int index) { + while (index > 0) { + int parent = (index - 1) / 2; + if (heap[parent] >= heap[index]) { + break; + } + std::swap(heap[parent], heap[index]); + index = parent; + } + } + + // Ensure the heap property is maintained starting from the given index + void maxHeapify(int index) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int largest = index; + + // Check if the left child is larger than the current largest element + if (left < heap.size() && heap[left] > heap[largest]) { + largest = left; + } + // Check if the right child is larger than the current largest element + if (right < heap.size() && heap[right] > heap[largest]) { + largest = right; + } + + // If the largest element is not the current index, swap and continue heapifying + if (largest != index) { + std::swap(heap[largest], heap[index]); + maxHeapify(largest); + } + } + +public: + // Add a new element to the heap and percolate it up to maintain the heap property + void insert(int val) { + heap.push_back(val); + percolateUp(heap.size() - 1); + } + + // Return the maximum element in the heap (root of the heap) + int getMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + return heap[0]; + } + + // Update the value, percolate up, and max heapify to maintain the heap property + void update(int old_val, int new_val) { + auto it = std::find(heap.begin(), heap.end(), old_val); + if (it != heap.end()) { + *it = new_val; + percolateUp(it - heap.begin()); + maxHeapify(it - heap.begin()); + } else { + std::cout << "Value not in heap" << std::endl; + } + } + + // Replace the root with the last element, pop the last element, and max heapify + void deleteMax() { + if (heap.size() == 0) { + throw "Heap is empty"; + } + heap[0] = heap.back(); + heap.pop_back(); + maxHeapify(0); + } + + // Print all values in the heap + void printHeap() { + for (int i : heap) { + std::cout << i << " "; + } + std::cout << std::endl; + } +}; + +int main() { + // Example usage of the MaxHeap class + MaxHeap heap; + + heap.insert(12); + heap.insert(10); + heap.insert(-10); + heap.insert(100); + + std::cout << "All values in heap: "; + heap.printHeap(); + + std::cout << "Max Value: " << heap.getMax() << std::endl; + + heap.update(12, 5); + std::cout << "Max Value after update: " << heap.getMax() << std::endl; + + heap.deleteMax(); + std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + + std::cout << "All values in heap: "; + heap.printHeap(); + + return 0; +} From 57eab02cb0117318b8d6448823cc1b2f5a5e246d Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:34:07 +0530 Subject: [PATCH 31/53] Update palindromepartition.py --- .../palindromepartition.py | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/Strings/Medium/palindrome partitioning/palindromepartition.py b/Strings/Medium/palindrome partitioning/palindromepartition.py index 15b4cd2d..55e7f486 100644 --- a/Strings/Medium/palindrome partitioning/palindromepartition.py +++ b/Strings/Medium/palindrome partitioning/palindromepartition.py @@ -1,22 +1,44 @@ def partition(string): - # Initialize dynamic programming array - dp=[[] for _ in range(len(string)+1)] - - # Initialize the first state with an empty partition - dp[0]=[[]] - -# Iterate over each character of the string - for j in range(1,len(string)+1): - # Iterate through each previous character - for i in range(j): - # Check if the substring is a palindrome - if string[i:j]==string[i:j][::-1]: - # If so, extend the partitions ending at i with the palindrome substring - for each in dp[i]: - dp[j].append(each+[string[i:j]]) - # Return the final state, which contains all valid partitions - return dp[-1] - -if __name__=="__main__": - string="ababa" - print(partition(string)) + if string is None or not string.strip(): + return [[]] + + # Initialize dynamic programming array + dp = [[] for _ in range(len(string) + 1)] + + # Initialize the first state with an empty partition + dp[0] = [[]] + + # Iterate over each character of the string + for j in range(1, len(string) + 1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j] == string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each + [string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +def main(): + # Read input from standard input + string = input("Enter a string: ") + + # Check for None or empty string + if string is None or not string.strip(): + print("Empty or None input. Exiting.") + return + + # Call the partition function and get the result + result = partition(string) + + # Print the result + print("Partitions:") + for partition_set in result: + print(partition_set) + + # Print the count of partitions + print(f"\nNumber of Partitions: {len(result)}") + +if __name__ == "__main__": + main() From cd2c443b2da02c7c390153fc18db9a5e05875466 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:35:27 +0530 Subject: [PATCH 32/53] Update Readme.md --- .../Medium/palindrome partitioning/Readme.md | 65 +++++++++++++------ 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md index 4cb7e215..5725ef6a 100644 --- a/Strings/Medium/palindrome partitioning/Readme.md +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -31,27 +31,50 @@ Given a string, the problem is to find all possible ways to partition it into pa # Time complexity:O(n^2) def partition(string): - # Initialize dynamic programming array - dp=[[] for _ in range(len(string)+1)] - - # Initialize the first state with an empty partition - dp[0]=[[]] - -# Iterate over each character of the string - for j in range(1,len(string)+1): - # Iterate through each previous character - for i in range(j): - # Check if the substring is a palindrome - if string[i:j]==string[i:j][::-1]: - # If so, extend the partitions ending at i with the palindrome substring - for each in dp[i]: - dp[j].append(each+[string[i:j]]) - # Return the final state, which contains all valid partitions - return dp[-1] - -if __name__=="__main__": - string="ababa" - print(partition(string)) + if string is None or not string.strip(): + return [[]] + + # Initialize dynamic programming array + dp = [[] for _ in range(len(string) + 1)] + + # Initialize the first state with an empty partition + dp[0] = [[]] + + # Iterate over each character of the string + for j in range(1, len(string) + 1): + # Iterate through each previous character + for i in range(j): + # Check if the substring is a palindrome + if string[i:j] == string[i:j][::-1]: + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each + [string[i:j]]) + # Return the final state, which contains all valid partitions + return dp[-1] + +def main(): + # Read input from standard input + string = input("Enter a string: ") + + # Check for None or empty string + if string is None or not string.strip(): + print("Empty or None input. Exiting.") + return + + # Call the partition function and get the result + result = partition(string) + + # Print the result + print("Partitions:") + for partition_set in result: + print(partition_set) + + # Print the count of partitions + print(f"\nNumber of Partitions: {len(result)}") + +if __name__ == "__main__": + main() + ``` # Code Explanation From 65c0dd900bf4da30775ae3206b1602447bb42c4c Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sun, 17 Dec 2023 21:46:36 +0530 Subject: [PATCH 33/53] Update Readme.md --- .../Medium/palindrome partitioning/Readme.md | 117 +++++++++++++++--- 1 file changed, 97 insertions(+), 20 deletions(-) diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md index 5725ef6a..7c0c3569 100644 --- a/Strings/Medium/palindrome partitioning/Readme.md +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -78,29 +78,106 @@ if __name__ == "__main__": ``` # Code Explanation -1. **Dynamic Programming Array (`dp`):** - - `dp` is a list of lists used for dynamic programming. It represents the state of the algorithm at each position in the input string. +Let's go through each line of code in detail: -2. **Initialization:** - - `dp[0]` is initialized with an empty list representing the empty partition for the first state. +```python +def partition(string): + # Check if the input string is None or empty + if string is None or not string.strip(): + return [[]] + + # Initialize dynamic programming array + + +```python + dp = [[] for _ in range(len(string) + 1)] +``` + +Here, a dynamic programming array `dp` is initialized. The list comprehension creates a list of empty lists. The length of this list is set to `len(string) + 1`. The array will be used to store intermediate results during the computation of palindrome partitions. + +```python + # Initialize the first state with an empty partition + dp[0] = [[]] +``` + +The first state of the dynamic programming array is initialized to contain a single empty list. This represents the partition of an empty string. + +```python + # Iterate over each character of the string + for j in range(1, len(string) + 1): +``` + +This loop iterates over each character in the input string. The variable `j` represents the current index being considered. + +```python + # Iterate through each previous character + for i in range(j): +``` + +Within the outer loop, there is another loop that iterates over each character from the beginning of the string up to the current index (`j`). The variable `i` represents the starting index of the substring. + +```python + # Check if the substring is a palindrome + if string[i:j] == string[i:j][::-1]: +``` + +This line checks whether the substring from index `i` to `j` is a palindrome. The slicing `string[i:j]` extracts the substring, and `string[i:j][::-1]` reverses it. If the reversed substring is equal to the original substring, it is a palindrome. -3. **Iterating Over Characters (`j`):** - - The outer loop (`for j in range(1, len(string) + 1)`) iterates over each character in the input string, starting from the second character. +```python + # If so, extend the partitions ending at i with the palindrome substring + for each in dp[i]: + dp[j].append(each + [string[i:j]]) +``` + +If the substring is a palindrome, this code extends the partitions that end at index `i` with the palindrome substring. It iterates over each partition in `dp[i]` and appends a new partition formed by adding the palindrome substring. + +```python + # Return the final state, which contains all valid partitions + return dp[-1] +``` + +Finally, the function returns the last state of the dynamic programming array, which contains all valid partitions for the entire input string. + +```python +def main(): + # Read input from standard input + string = input("Enter a string: ") +``` + +The `main` function prompts the user to input a string. -4. **Iterating Over Previous Characters (`i`):** - - The inner loop (`for i in range(j)`) iterates through each previous character (from the beginning of the string up to `j`). +```python + # Check for None or empty string + if string is None or not string.strip(): + print("Empty or None input. Exiting.") + return +``` + +This checks if the input string is None or empty. If so, it prints a message and exits the program. + +```python + # Call the partition function and get the result + result = partition(string) +``` -5. **Palindrome Check:** - - `if string[i:j] == string[i:j][::-1]:` checks if the substring from `i` to `j` is a palindrome. +The `partition` function is called with the input string, and the result is stored in the variable `result`. -6. **Updating Partitions:** - - If the substring is a palindrome, it extends the partitions ending at position `i` with the palindrome substring. It uses a nested loop to iterate through each existing partition at position `i` (`for each in dp[i]`) and appends the current palindrome substring to create new partitions. +```python + # Print the result + print("Partitions:") + for partition_set in result: + print(partition_set) +``` + +The code then prints each partition set in the result. -7. **Final Result:** - - The final state is represented by `dp[-1]`, which contains all valid partitions, and it is returned as the output of the function. +```python + # Print the count of partitions + print(f"\nNumber of Partitions: {len(result)}") +``` -8. **Example Usage:** - - The provided example with `string = "ababa"` demonstrates how the function can be called and prints the result of partitioning the given string into palindromic substrings. +Finally, it prints the total number of partitions. The `len(result)` gives the count of valid partitions. + The algorithm employs dynamic programming to efficiently find and extend palindrome partitions in the input string. @@ -113,7 +190,7 @@ For more information, visit https://venkys.io */ // C++ program Palindrome Partitioning // Stable: No -// Inplace:No +// Inplace: No // Adaptive: Not applicable (Adaptivity is a characteristic more associated with sorting algorithms and may not directly apply to palindrome partitioning.) // Space complexity:O(n^2) @@ -126,7 +203,7 @@ bool isPalindrome(std::string s, int i, int j) { // If characters at different ends don't match, it's not a palindrome. if (s[i++] != s[j--]) return false; } - // If loop finished, the string is a palindrome. + // If the loop is finished, the string is a palindrome. return true; } void util(int i,std::string s,std::vector>& res,std::vector& path){ @@ -139,11 +216,11 @@ void util(int i,std::string s,std::vector>& res,std::ve for(int j=i;j Date: Sun, 17 Dec 2023 22:02:26 +0530 Subject: [PATCH 34/53] Update Readme.md --- .../Medium/palindrome partitioning/Readme.md | 252 +++++++++++++----- 1 file changed, 189 insertions(+), 63 deletions(-) diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md index 7c0c3569..3c5b5985 100644 --- a/Strings/Medium/palindrome partitioning/Readme.md +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -196,83 +196,211 @@ For more information, visit https://venkys.io */ // Space complexity:O(n^2) // Time complexity:O(n^2) -#include -bool isPalindrome(std::string s, int i, int j) { - // While loop checks the string symmetrically. - while (i <= j) { - // If characters at different ends don't match, it's not a palindrome. - if (s[i++] != s[j--]) return false; +#include +#include +#include + +// Function to find all palindrome partitions of a given string +std::vector> partition(const std::string& str) { + // Check if the input string is empty + if (str.empty()) { + return {{}}; } - // If the loop is finished, the string is a palindrome. - return true; -} -void util(int i,std::string s,std::vector>& res,std::vector& path){ - // base case: when string s is fully processed - if(i==s.size()){ - res.push_back(path); - return ; - } - // iteratively checking each substring - for(int j=i;j>> dp(str.size() + 1); + + // Initialize the first state with an empty partition + dp[0] = {{}}; + + // Iterate over each character of the string + for (size_t j = 1; j <= str.size(); ++j) { + // Iterate through each previous character + for (size_t i = 0; i < j; ++i) { + // Check if the substring is a palindrome + if (str.substr(i, j - i) == std::string(str.rbegin() + (str.size() - j), str.rend())) { + // If so, extend the partitions ending at i with the palindrome substring + for (const auto& each : dp[i]) { + dp[j].push_back(each); + dp[j].back().push_back(str.substr(i, j - i)); + } + } } } + + // Return the final state, which contains all valid partitions + return dp.back(); } -std::vector> partition (std::string s){ - // Output list of all palindrome partitions - std::vector> res; - // List to keep track of the current path - std::vector path; - // Utility function to find all palindrome partitions - util(0,s,res,path); - return res; -} -int main(){ - // initial string to be partitioned - std::string s = "aaab"; - // function call to get all partitions - std::vector> ans=partition(s); - // loop to print all partitions - for(auto& a:ans){ - for(auto& b:a){ - std::cout< +#include +#include +``` -2. **util Function:** - - The `util` function is a recursive utility function that generates all possible palindrome partitions of the input string. - - It takes parameters: - - `i`: Current index in the string. - - `s`: The input string. - - `res`: A vector of vectors to store all palindrome partitions. - - `path`: A vector to keep track of the current path of partitions. - - It uses a nested loop to iterate through all possible substrings starting from the current index `i` and checks if each substring is a palindrome using the `isPalindrome` function. - - If a palindrome substring is found, it is added to the current path, and the function is recursively called to process the rest of the string. - - After processing, the added substring is removed from the path to explore other possibilities. +1. **Header Includes:** + - `#include `: Provides input and output functionality. + - `#include `: Allows the use of dynamic arrays (vectors). + - `#include `: Enables string manipulation. -3. **partition Function:** - - The `partition` function initializes the necessary vectors (`res` and `path`) and calls the `util` function to find all palindrome partitions. +```cpp +std::vector> partition(const std::string& str) { +``` + +2. **Function Declaration - `partition`:** + - Declares a function named `partition` that takes a constant reference to a string (`str`) as an argument. + - The function returns a vector of vectors of strings, representing the palindrome partitions. + +```cpp + if (str.empty()) { + return {{}}; + } +``` + +3. **Check for Empty String:** + - Checks if the input string is empty. If so, returns a vector containing an empty vector (representing an empty partition). + +```cpp + std::vector>> dp(str.size() + 1); +``` + +4. **Dynamic Programming Array Initialization:** + - Initializes a 3D vector (`dp`) to store intermediate results during dynamic programming. + - Its size is set to `str.size() + 1` to accommodate substrings of different lengths. + +```cpp + dp[0] = {{}}; +``` + +5. **Initial State Initialization:** + - Sets the initial state of `dp` to contain a single empty vector (representing an empty partition for an empty substring). + +```cpp + for (size_t j = 1; j <= str.size(); ++j) { + for (size_t i = 0; i < j; ++i) { +``` + +6. **Nested Loops - Iterating Over Substrings:** + - Outer loop (`j`): Iterates over each character of the input string. + - Inner loop (`i`): Iterates through each previous character (from 0 to `j`). + +```cpp + if (str.substr(i, j - i) == std::string(str.rbegin() + (str.size() - j), str.rend())) { +``` -4. **main Function:** - - The `main` function demonstrates the usage of the `partition` function on the string "aaab." - - It prints all the palindrome partitions obtained in the `ans` vector. +7. **Checking for Palindrome:** + - Uses `substr` to extract the substring from index `i` to `j`. + - Compares the substring with its reverse by creating a temporary reversed string using `rbegin` and `rend`. + +```cpp + for (const auto& each : dp[i]) { + dp[j].push_back(each); + dp[j].back().push_back(str.substr(i, j - i)); + } + } + } + } +``` + +8. **Extending Partitions:** + - If the substring is a palindrome, extends the partitions ending at index `i` with the palindrome substring. + - Iterates over each partition in `dp[i]` and appends a new partition formed by adding the palindrome substring. + +```cpp + return dp.back(); +} +``` + +9. **Returning Final State:** + - Returns the last state of the dynamic programming array (`dp`), which contains all valid partitions for the entire input string. + +```cpp +int main() { + std::cout << "Enter a string: "; + std::string inputString; + std::getline(std::cin, inputString); +``` + +10. **Main Function:** + - Prompts the user to enter a string using `std::cout`. + - Reads the entire line of input using `std::getline` and stores it in `inputString`. + +```cpp + if (inputString.empty()) { + std::cout << "Empty input. Exiting." << std::endl; + return 0; + } +``` + +11. **Checking for Empty String:** + - Checks if the input string is empty. If so, prints a message and exits the program. + +```cpp + auto result = partition(inputString); +``` + +12. **Calling the Partition Function:** + - Calls the `partition` function with the input string and stores the result in the variable `result`. + +```cpp + std::cout << "Partitions:" << std::endl; + for (const auto& partitionSet : result) { + for (const auto& substring : partitionSet) { + std::cout << substring << " "; + } + std::cout << std::endl; + } +``` + +13. **Printing Partitions:** + - Prints each partition set in the result. + +```cpp + std::cout << "\nNumber of Partitions: " << result.size() << std::endl; + + return 0; +} +``` + +14. **Printing the Count of Partitions:** + - Prints the total number of partitions using `result.size()`. The program then returns 0, indicating successful execution. **Example Output:** ``` @@ -280,8 +408,6 @@ a a a b aa a b ``` -This code efficiently finds and prints all possible palindrome partitions of the input string "aaab" using a recursive approach. - # java # code From c9072f440319eb02c625c5719396fd28957c74da Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sun, 17 Dec 2023 22:16:16 +0530 Subject: [PATCH 35/53] Update Readme.md --- .../Medium/palindrome partitioning/Readme.md | 302 ++++++++++++++---- 1 file changed, 233 insertions(+), 69 deletions(-) diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md index 3c5b5985..b4e6fcd1 100644 --- a/Strings/Medium/palindrome partitioning/Readme.md +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -402,11 +402,6 @@ int main() { 14. **Printing the Count of Partitions:** - Prints the total number of partitions using `result.size()`. The program then returns 0, indicating successful execution. -**Example Output:** -``` -a a a b -aa a b -``` # java @@ -426,87 +421,256 @@ For more information, visit https://venkys.io */ import java.util.ArrayList; import java.util.List; +import java.util.Scanner; + +public class PalindromePartition { + + public static List> partition(String input) { + // Check if the input string is null or empty + if (input == null || input.trim().isEmpty()) { + List> result = new ArrayList<>(); + result.add(new ArrayList<>()); + return result; + } -class PalindromePartitioning { - // Function to check if a substring is a palindrome - static boolean checkPalindrome(String str, int startIndex, int lastIndex){ - while(startIndex <= lastIndex){ - if(str.charAt(startIndex) != str.charAt(lastIndex)) - return false; - startIndex++; - lastIndex--; + // Initialize dynamic programming array + List>[] dp = new ArrayList[input.length() + 1]; + for (int i = 0; i <= input.length(); i++) { + dp[i] = new ArrayList<>(); } - return true; + + // Initialize the first state with an empty partition + dp[0].add(new ArrayList<>()); + + // Iterate over each character of the string + for (int j = 1; j <= input.length(); j++) { + // Iterate through each previous character + for (int i = 0; i < j; i++) { + // Check if the substring is a palindrome + if (input.substring(i, j).equals(new StringBuilder(input.substring(i, j)).reverse().toString())) { + // If so, extend the partitions ending at i with the palindrome substring + for (List each : dp[i]) { + List partition = new ArrayList<>(each); + partition.add(input.substring(i, j)); + dp[j].add(partition); + } + } + } + } + + // Return the final state, which contains all valid partitions + return dp[input.length()]; } - // Function to generate all the palindrome partitioning - static void palindromePartition(int index, List ds, List> output, String str){ - if(index == str.length()){ - output.add(new ArrayList<>(ds)); + public static void main(String[] args) { + // Read input from standard input + Scanner scanner = new Scanner(System.in); + System.out.print("Enter a string: "); + String inputString = scanner.nextLine(); + + // Check for null or empty string + if (inputString == null || inputString.trim().isEmpty()) { + System.out.println("Empty or null input. Exiting."); return; } - for(int i = index; i < str.length(); i++){ - if(checkPalindrome(str, index, i)){ - ds.add(str.substring(index, i + 1)); - palindromePartition(i+1, ds, output, str); - ds.remove(ds.size()-1); + + // Call the partition function and get the result + List> result = partition(inputString); + + // Print the result + System.out.println("Partitions:"); + for (List partitionSet : result) { + System.out.println(partitionSet); + } + + // Print the count of partitions + System.out.println("\nNumber of Partitions: " + result.size()); + } +} + +``` +# Code Explanation + +Let's go through the provided Java code step by step: + +```java +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +``` + +1. **Imports:** + - Import necessary packages: `ArrayList` and `List` from `java.util` and `Scanner` for user input. + +```java +public class PalindromePartition { +``` + +2. **Class Declaration:** + - Declare a class named `PalindromePartition`. + +```java + /** + * Find all palindrome partitions of a given string. + * + * @param input The input string + * @return List of palindrome partitions + */ + public static List> partition(String input) { +``` + +3. **Method Declaration - partition:** + - Declare a method named `partition` that takes a string (`input`) as a parameter. + - The method returns a list of lists of strings, representing palindrome partitions. + - The `@param` and `@return` annotations provide documentation. + +```java + // Check if the input string is null or empty + if (input == null || input.trim().isEmpty()) { + // Return a list containing an empty list (representing an empty partition) + List> result = new ArrayList<>(); + result.add(new ArrayList<>()); + return result; + } +``` + +4. **Input Validation:** + - Check if the input string is null or empty. If true, return a list containing an empty list (representing an empty partition). + +```java + // Initialize dynamic programming array + List>[] dp = new ArrayList[input.length() + 1]; + for (int i = 0; i <= input.length(); i++) { + dp[i] = new ArrayList<>(); + } +``` + +5. **Dynamic Programming Array Initialization:** + - Initialize a 2D array (`dp`) to store intermediate results during dynamic programming. + - Each element of `dp` is a list of strings, representing partitions. + +```java + // Initialize the first state with an empty partition + dp[0].add(new ArrayList<>()); +``` + +6. **Initial State Initialization:** + - Set the initial state of `dp` to contain a single empty list (representing an empty partition for an empty substring). + +```java + // Iterate over each character of the string + for (int j = 1; j <= input.length(); j++) { + // Iterate through each previous character + for (int i = 0; i < j; i++) { +``` + +7. **Nested Loops - Iterating Over Substrings:** + - Outer loop (`j`): Iterates over each character of the input string. + - Inner loop (`i`): Iterates through each previous character (from 0 to `j`). + +```java + // Check if the substring is a palindrome + if (input.substring(i, j).equals(new StringBuilder(input.substring(i, j)).reverse().toString())) { +``` + +8. **Checking for Palindrome:** + - Use `substring` to extract the substring from index `i` to `j`. + - Compare the substring with its reverse using `StringBuilder`. + - If the substring is a palindrome: + +```java + // If so, extend the partitions ending at i with the palindrome substring + for (List each : dp[i]) { + List partition = new ArrayList<>(each); + partition.add(input.substring(i, j)); + dp[j].add(partition); + } + } } } +``` + +9. **Extending Partitions:** + - If the substring is a palindrome, extend the partitions ending at index `i` with the palindrome substring. + - Iterate over each partition in `dp[i]` and append a new partition formed by adding the palindrome substring. + +```java + // Return the final state, which contains all valid partitions + return dp[input.length()]; } +``` - // Main function to return all the palindrome partitioning - static List> partition(String s) { - List> output = new ArrayList<>(); - List ds = new ArrayList<>(); - palindromePartition(0, ds, output, s); - return output; +10. **Returning Final State:** + - Return the last state of the dynamic programming array (`dp`), which contains all valid partitions for the entire input string. + +```java + /** + * Prompts the user for input and returns the entered string. + * + * @return The user-entered string + */ + private static String getUserInput() { + Scanner scanner = new Scanner(System.in); + System.out.print("Enter a string: "); + return scanner.nextLine(); } +``` +11. **User Input Method - getUserInput:** + - A private method to prompt the user for input and return the entered string. + +```java public static void main(String[] args) { - String s="aab"; - System.out.println(partition(s)); - } + // Uncomment the line below to read input from stdin + // String inputString = getUserInput(); -} + // Example input (remove/comment this line if using stdin) + String inputString = "example"; +``` + +12. **Main Method:** + - The main method where the program starts execution. + - Optionally, read input from stdin by uncommenting the `getUserInput` line or provide an example input. +```java + // Check for null or empty string + if (inputString == null || inputString.trim().isEmpty()) { + System.out.println("Empty or null input. Exiting."); + return; + } +``` + +13. **Input Validation in Main:** + - Check if the input string is null or empty. If true, print a message and exit the program. + +```java + // Call the partition function and get the result + List> result = partition(inputString); +``` + +14. **Calling partition Function:** + - Call the `partition` function with the input string and store the result in the variable `result`. + +```java + // Print the result + System.out.println("Partitions:"); + for (List partitionSet : result) { + System.out.println(partitionSet); + } +``` + +15. **Printing Partitions:** + - Print each partition set in the result. + +```java + // Print the count of partitions + System.out.println("\nNumber of Partitions: " + result.size()); + } +} ``` -# Code Explanation -1. **`checkPalindrome` Function:** - - This function checks whether a given substring of a string is a palindrome. - - It takes three parameters: - - `str`: The input string. - - `startIndex`: The starting index of the substring. - - `lastIndex`: The ending index of the substring. - - It uses a `while` loop to check if the characters at the given indices are equal, iterating towards the center of the substring. If at any point they are not equal, the function returns `false`. Otherwise, it returns `true`. - -2. **`palindromePartition` Function:** - - This recursive function generates all possible palindrome partitions of the input string. - - It takes four parameters: - - `index`: The current index in the string. - - `ds`: A list representing the current path of partitions. - - `output`: A list of lists to store all palindrome partitions. - - `str`: The input string. - - The base case is when the `index` reaches the length of the string. At this point, the current path (`ds`) is added to the `output` list. - - It uses a `for` loop to iterate from the current index to the end of the string. - - If the substring from the current index to the loop variable `i` is a palindrome (checked using `checkPalindrome`), it adds the substring to the current path (`ds`) and recursively calls itself with the updated index (`i + 1`). - - After the recursive call, it removes the last added substring from the current path to explore other possibilities. - -3. **`partition` Function:** - - This is the main function that initializes the necessary lists and calls `palindromePartition` to find all palindrome partitions. - - It takes the input string `s`, creates an empty list for the output, and an empty list for the current path (`ds`). - - It calls `palindromePartition` with the initial index (`0`), current path (`ds`), output list (`output`), and the input string (`s`). - -4. **`main` Function:** - - The `main` function demonstrates the usage of the `partition` function on the string "aab." - - It prints the result obtained from the `partition` function. - -**Example Output:** - -[[a, a, b], [aa, b]] - - -The code efficiently finds and prints all possible palindrome partitions of the input string "aab" using a recursive approach. +16. **Printing the Count of Partitions:** + - Print the total number of partitions using `result.size()`. The program then exits. **Time and Space Complexity Analysis**: From d6147028747c0e5bd568833141a47569525e1109 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Mon, 18 Dec 2023 21:10:51 +0530 Subject: [PATCH 36/53] Update max_heap_CRUD.c++ From 121ce43434857e604ad0bb62edd2a79b883fe08f Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 19 Dec 2023 21:30:45 +0530 Subject: [PATCH 37/53] Update palindrompartition.c++ --- .../palindrompartition.c++ | 105 ++++++++++-------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/Strings/Medium/palindrome partitioning/palindrompartition.c++ b/Strings/Medium/palindrome partitioning/palindrompartition.c++ index 3d7c28c0..cf2d1b7e 100644 --- a/Strings/Medium/palindrome partitioning/palindrompartition.c++ +++ b/Strings/Medium/palindrome partitioning/palindrompartition.c++ @@ -1,53 +1,68 @@ -#include -bool isPalindrome(std::string s, int i, int j) { - // While loop checks the string symmetrically. - while (i <= j) { - // If characters at different ends don't match, it's not a palindrome. - if (s[i++] != s[j--]) return false; - } - // If loop finished, the string is a palindrome. - return true; -} -void util(int i,std::string s,std::vector>& res,std::vector& path){ - // base case: when string s is fully processed - if(i==s.size()){ - res.push_back(path); - return ; +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +#include +#include +#include + +// Function to find all palindrome partitions of a given string +std::vector> partition(const std::string& str) { + // Check if the input string is empty + if (str.empty()) { + return {{}}; } - // iteratively checking each substring - for(int j=i;j>> dp(str.size() + 1); + + // Initialize the first state with an empty partition + dp[0] = {{}}; + + // Iterate over each character of the string + for (size_t j = 1; j <= str.size(); ++j) { + // Iterate through each previous character + for (size_t i = 0; i < j; ++i) { + // Check if the substring is a palindrome + if (str.substr(i, j - i) == std::string(str.rbegin() + (str.size() - j), str.rend())) { + // If so, extend the partitions ending at i with the palindrome substring + for (const auto& each : dp[i]) { + dp[j].push_back(each); + dp[j].back().push_back(str.substr(i, j - i)); + } + } } } + + // Return the final state, which contains all valid partitions + return dp.back(); } -std::vector> partition (std::string s){ - // Output list of all palindrome partitions - std::vector> res; - // List to keep track of the current path - std::vector path; - // Utility function to find all palindrome partitions - util(0,s,res,path); - return res; -} -int main(){ - // initial string to be partitioned - std::string s = "aaab"; - // function call to get all partitions - std::vector> ans=partition(s); - // loop to print all partitions - for(auto& a:ans){ - for(auto& b:a){ - std::cout< Date: Tue, 19 Dec 2023 21:34:51 +0530 Subject: [PATCH 38/53] Update Readme.md --- Strings/Medium/palindrome partitioning/Readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Strings/Medium/palindrome partitioning/Readme.md b/Strings/Medium/palindrome partitioning/Readme.md index b4e6fcd1..4788ed4d 100644 --- a/Strings/Medium/palindrome partitioning/Readme.md +++ b/Strings/Medium/palindrome partitioning/Readme.md @@ -196,6 +196,9 @@ For more information, visit https://venkys.io */ // Space complexity:O(n^2) // Time complexity:O(n^2) +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + #include #include #include From c6d277b0ff50d3d976e529bfba96cdd276eb99da Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 19 Dec 2023 21:45:16 +0530 Subject: [PATCH 39/53] Update Readme.md From 752afc50d721c52e24b6efde0a214ee7093abd45 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Sat, 30 Dec 2023 12:00:08 +0530 Subject: [PATCH 40/53] Update BinaryTree.java --- Trees/Easy/Inorder Traversal/BinaryTree.java | 67 ++++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/Trees/Easy/Inorder Traversal/BinaryTree.java b/Trees/Easy/Inorder Traversal/BinaryTree.java index 14f798bf..48eb5d4e 100644 --- a/Trees/Easy/Inorder Traversal/BinaryTree.java +++ b/Trees/Easy/Inorder Traversal/BinaryTree.java @@ -1,21 +1,18 @@ +import java.util.Scanner; + class TreeNode { - int data; - // Store integer data - TreeNode left = null, - // Left child reference - right = null; - // Right child reference - - public TreeNode(int data) { - // Constructor to create a new TreeNode - this.data = data; - // Assign the given data to this node + int data; + TreeNode left = null; // Left child reference + TreeNode right = null; // Right child reference + + // Constructor to create a new TreeNode + public TreeNode(int data) { + this.data = data; // Assign the given data to this node } } public class BinaryTree { -// Method for inorder traversal - + // Method for inorder traversal static void inorderTraversal(TreeNode root) { if (root != null) { inorderTraversal(root.left); @@ -25,27 +22,43 @@ static void inorderTraversal(TreeNode root) { } public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); - // Creating a binary tree with root node having data 10 - TreeNode root = new TreeNode(10); + // Prompt user to enter the series of numbers + System.out.println("Enter a series of numbers separated by spaces:"); + String input = scanner.nextLine(); + String[] values = input.split("\\s+"); - // Adding nodes to the root of the created binary tree - // Adding left and right child nodes to the root - root.left = new TreeNode(20); - root.right = new TreeNode(30); - - // Adding left and right child nodes to the left child of the root - root.left.left = new TreeNode(40); - root.left.right = new TreeNode(50); + // Convert the string values to integers + int[] intValues = new int[values.length]; + for (int i = 0; i < values.length; i++) { + intValues[i] = Integer.parseInt(values[i]); + } - // Adding left and right child nodes to the right child of the root - root.right.left = new TreeNode(60); - root.right.right = new TreeNode(70); + // Build the binary tree using the series of numbers + TreeNode root = buildBinaryTree(intValues, 0); // Printing the message before performing inorder traversal System.out.print("Inorder Traversal: "); // Calling the inorderTraversal method to perform inorder traversal inorderTraversal(root); + + // Close the scanner + scanner.close(); } -} \ No newline at end of file + + // Method to build the binary tree using the series of numbers + static TreeNode buildBinaryTree(int[] values, int index) { + TreeNode node = null; + if (index < values.length) { + // Create a new node with the current value + node = new TreeNode(values[index]); + + // Recursively build the left and right subtrees + node.left = buildBinaryTree(values, 2 * index + 1); + node.right = buildBinaryTree(values, 2 * index + 2); + } + return node; + } +} From 9174d4df98b96354fd52b3024de50c6886f7d6dc Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 2 Jan 2024 20:38:42 +0530 Subject: [PATCH 41/53] Update stringtointeger.py --- .../String to Integer/stringtointeger.py | 77 ++++++++++--------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/Strings/Medium/String to Integer/stringtointeger.py b/Strings/Medium/String to Integer/stringtointeger.py index 28122421..6b421639 100644 --- a/Strings/Medium/String to Integer/stringtointeger.py +++ b/Strings/Medium/String to Integer/stringtointeger.py @@ -1,40 +1,43 @@ -def check(answer): - if answer<-2**31: - return -2**31 - elif answer>=2**31: - return 2**31-1 - else: - return answer +def convertStringToInteger(s): + # Define constants for the 32-bit signed integer range + INT_MIN, INT_MAX = -2**31, 2**31 - 1 + + # Initialize variables for the result, sign, and position in the string + answer, sign, i = 0, 1, 0 -def myAtoi(string): - answer=0 - sign=0 - i=0 + # Skip leading whitespaces + while i < len(s) and s[i] == " ": + i += 1 - while(i Date: Tue, 2 Jan 2024 21:00:47 +0530 Subject: [PATCH 42/53] Update stringtointeger.cpp --- .../String to Integer/stringtointeger.cpp | 62 ++++++++++++++----- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/Strings/Medium/String to Integer/stringtointeger.cpp b/Strings/Medium/String to Integer/stringtointeger.cpp index bdb57305..0dc06676 100644 --- a/Strings/Medium/String to Integer/stringtointeger.cpp +++ b/Strings/Medium/String to Integer/stringtointeger.cpp @@ -1,31 +1,59 @@ -#include +#include +#include +#include +#include + +// Function to convert a string to an integer +std::optional atoi(const std::string& s) { + // Check if the input string is empty + if (s.empty()) { + std::cerr << "Error: Input string is empty." << std::endl; + return std::nullopt; // Using std::optional to represent the absence of a value + } -int atoi(std::string s) -{ int num = 0, i = 0, sign = 1; - while (s[i] == ' ') - { + + // Skip leading whitespaces + while (i < s.length() && s[i] == ' ') { i++; } - if (i < s.length() && (s[i] == '-' || s[i] == '+')) - { - sign = s[i] == '+' ? 1 : -1; + + // Check for sign + if (i < s.length() && (s[i] == '-' || s[i] == '+')) { + // Determine the sign of the number + sign = (s[i] == '+') ? 1 : -1; i++; } - while (i < s.length() && isdigit(s[i])) - { - if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) - return sign == 1 ? INT_MAX : INT_MIN; + // Process digits + while (i < s.length() && std::isdigit(s[i])) { + // Check for overflow + if ((num > std::numeric_limits::max() / 10) || + ((num == std::numeric_limits::max() / 10) && (s[i] - '0' > 7))) { + std::cerr << "Error: Integer overflow." << std::endl; + return std::nullopt; + } + + // Update the result by multiplying by 10 and adding the current digit num = ((num * 10) + (s[i] - '0')); i++; } + + // Return the final result multiplied by the sign return num * sign; } -int main() -{ - std::string s = "42"; - std::cout << atoi(s); +int main() { + // Prompt the user for input + std::string input; + std::cout << "Enter a string: "; + std::getline(std::cin, input); + + // Call the atoi function and print the result + auto result = atoi(input); + if (result.has_value()) { + std::cout << "Converted integer: " << result.value() << std::endl; + } + return 0; -} \ No newline at end of file +} From 841be23481a7b45bb6eca745dbc3b8808c9fa037 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:07:45 +0530 Subject: [PATCH 43/53] Update main.java --- Strings/Medium/String to Integer/main.java | 45 ++++++++++++++++++---- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/Strings/Medium/String to Integer/main.java b/Strings/Medium/String to Integer/main.java index bedd751b..267d143f 100644 --- a/Strings/Medium/String to Integer/main.java +++ b/Strings/Medium/String to Integer/main.java @@ -1,26 +1,57 @@ -public class main{ +import java.util.Scanner; +public class Main { + + /** + * Converts a string to an integer. + * + * @param s The input string. + * @return The converted integer, or Integer.MIN_VALUE/Integer.MAX_VALUE in case of overflow. + */ static int atoi(String s) { + // Check for null or empty string + if (s == null || s.isEmpty()) { + System.err.println("Error: Input string is null or empty."); + return 0; // You can choose an appropriate value in case of an error. + } + int num = 0, i = 0, sign = 1; + + // Skip leading whitespaces while (i < s.length() && s.charAt(i) == ' ') { i++; } - if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { - sign = s.charAt(i) == '+' ? 1 : -1; + + // Check for sign + if (i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = (s.charAt(i) == '+') ? 1 : -1; i++; } + + // Process digits while (i < s.length() && Character.isDigit(s.charAt(i))) { int digit = s.charAt(i) - '0'; + // Check for overflow if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { - return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; } + + // Update the result num = (num * 10) + digit; i++; } + return num * sign; } + public static void main(String[] args) { - String s="42"; - System.out.println(atoi(s)); + // Prompt the user for input + Scanner scanner = new Scanner(System.in); + System.out.print("Enter a string: "); + String input = scanner.nextLine(); + + // Call the atoi function and print the result + int result = atoi(input); + System.out.println("Converted integer: " + result); } -} \ No newline at end of file +} From 200c68fa9975722e8ed79cc12b9a2534a902d0c4 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:09:08 +0530 Subject: [PATCH 44/53] Update Readme.md --- Strings/Medium/String to Integer/Readme.md | 45 ++++++++++++++++++---- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md index 18ddabd6..41ec37b7 100644 --- a/Strings/Medium/String to Integer/Readme.md +++ b/Strings/Medium/String to Integer/Readme.md @@ -289,30 +289,61 @@ The code essentially converts a given string to an integer, considering positive # java # code ```java -public class main{ +import java.util.Scanner; +public class Main { + + /** + * Converts a string to an integer. + * + * @param s The input string. + * @return The converted integer, or Integer.MIN_VALUE/Integer.MAX_VALUE in case of overflow. + */ static int atoi(String s) { + // Check for null or empty string + if (s == null || s.isEmpty()) { + System.err.println("Error: Input string is null or empty."); + return 0; // You can choose an appropriate value in case of an error. + } + int num = 0, i = 0, sign = 1; + + // Skip leading whitespaces while (i < s.length() && s.charAt(i) == ' ') { i++; } - if(i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { - sign = s.charAt(i) == '+' ? 1 : -1; + + // Check for sign + if (i < s.length() && (s.charAt(i) == '-' || s.charAt(i) == '+')) { + sign = (s.charAt(i) == '+') ? 1 : -1; i++; } + + // Process digits while (i < s.length() && Character.isDigit(s.charAt(i))) { int digit = s.charAt(i) - '0'; + // Check for overflow if ((num > Integer.MAX_VALUE / 10) || ((num == Integer.MAX_VALUE / 10) && (digit > 7))) { - return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; + return (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; } + + // Update the result num = (num * 10) + digit; i++; } + return num * sign; } + public static void main(String[] args) { - String s="42"; - System.out.println(atoi(s)); + // Prompt the user for input + Scanner scanner = new Scanner(System.in); + System.out.print("Enter a string: "); + String input = scanner.nextLine(); + + // Call the atoi function and print the result + int result = atoi(input); + System.out.println("Converted integer: " + result); } } @@ -479,4 +510,4 @@ In addition to the real-world applications mentioned earlier, let's explore some 10. **Educational Examples:** - In educational contexts, when teaching programming or algorithms, string-to-integer conversion serves as a fundamental concept. Exercises and examples often involve converting user inputs or string data to integers for various purposes. -In theoretical scenarios, the importance of string-to-integer conversion arises in the context of solving abstract problems, designing algorithms, and implementing various computational concepts. \ No newline at end of file +In theoretical scenarios, the importance of string-to-integer conversion arises in the context of solving abstract problems, designing algorithms, and implementing various computational concepts. From 1137ffa463c7c6e0d39e85b7d0a2832f45b4a536 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:09:45 +0530 Subject: [PATCH 45/53] Update Readme.md --- Strings/Medium/String to Integer/Readme.md | 60 ++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md index 41ec37b7..305707fe 100644 --- a/Strings/Medium/String to Integer/Readme.md +++ b/Strings/Medium/String to Integer/Readme.md @@ -184,35 +184,63 @@ For more information, visit https://venkys.io */ // Space complexity: O(n) // Time complexity: O(1) -#include +#include +#include +#include +#include + +// Function to convert a string to an integer +std::optional atoi(const std::string& s) { + // Check if the input string is empty + if (s.empty()) { + std::cerr << "Error: Input string is empty." << std::endl; + return std::nullopt; // Using std::optional to represent the absence of a value + } -int atoi(std::string s) -{ int num = 0, i = 0, sign = 1; - while (s[i] == ' ') - { + + // Skip leading whitespaces + while (i < s.length() && s[i] == ' ') { i++; } - if (i < s.length() && (s[i] == '-' || s[i] == '+')) - { - sign = s[i] == '+' ? 1 : -1; + + // Check for sign + if (i < s.length() && (s[i] == '-' || s[i] == '+')) { + // Determine the sign of the number + sign = (s[i] == '+') ? 1 : -1; i++; } - while (i < s.length() && isdigit(s[i])) - { - if ((num > INT_MAX / 10) || ((num == INT_MAX / 10) && ((s[i] - '0') > 7))) - return sign == 1 ? INT_MAX : INT_MIN; + // Process digits + while (i < s.length() && std::isdigit(s[i])) { + // Check for overflow + if ((num > std::numeric_limits::max() / 10) || + ((num == std::numeric_limits::max() / 10) && (s[i] - '0' > 7))) { + std::cerr << "Error: Integer overflow." << std::endl; + return std::nullopt; + } + + // Update the result by multiplying by 10 and adding the current digit num = ((num * 10) + (s[i] - '0')); i++; } + + // Return the final result multiplied by the sign return num * sign; } -int main() -{ - std::string s = "42"; - std::cout << atoi(s); +int main() { + // Prompt the user for input + std::string input; + std::cout << "Enter a string: "; + std::getline(std::cin, input); + + // Call the atoi function and print the result + auto result = atoi(input); + if (result.has_value()) { + std::cout << "Converted integer: " << result.value() << std::endl; + } + return 0; } ``` From f64e35b117d381384480c94e9da14efd5d1de04c Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:10:31 +0530 Subject: [PATCH 46/53] Update Readme.md --- Strings/Medium/String to Integer/Readme.md | 80 +++++++++------------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/Strings/Medium/String to Integer/Readme.md b/Strings/Medium/String to Integer/Readme.md index 305707fe..56469eeb 100644 --- a/Strings/Medium/String to Integer/Readme.md +++ b/Strings/Medium/String to Integer/Readme.md @@ -41,61 +41,49 @@ For more information, visit https://venkys.io */ // Space complexity:O(n) // Time complexity:O(1) -def check(answer): - # Check if the answer is less than the minimum 32-bit signed integer - if answer < -2**31: - return -2**31 - # Check if the answer is greater than or equal to the maximum 32-bit signed integer - elif answer >= 2**31: - return 2**31 - 1 - else: - return answer - -def myAtoi(string): - # Initialize variables - answer = 0 - sign = 0 # 0 represents no sign, 1 represents positive sign, -1 represents negative sign - i = 0 +def convertStringToInteger(s): + # Define constants for the 32-bit signed integer range + INT_MIN, INT_MAX = -2**31, 2**31 - 1 + + # Initialize variables for the result, sign, and position in the string + answer, sign, i = 0, 1, 0 # Skip leading whitespaces - while i < len(string) and string[i] == " ": + while i < len(s) and s[i] == " ": i += 1 - # If the entire string is composed of whitespaces, return the current answer - if i == len(string): - return answer - # Check for positive sign - if string[i] == "+" and sign == 0: - sign = 1 + # Check for empty string or non-numeric input + if i == len(s) or (s[i] not in ["+", "-"] and not s[i].isdigit()): + print("Error: Invalid input. Please enter a valid numeric string.") + return None + + # Handle sign + if s[i] in ["+", "-"]: + # Set the sign based on the presence of a positive or negative sign + sign = -1 if s[i] == "-" else 1 i += 1 - # Check for negative sign - if i < len(string) and string[i] == "-" and sign == 0: - sign = -1 + # Process digits + while i < len(s) and s[i].isdigit(): + digit = int(s[i]) + # Check for overflow + if (INT_MAX - digit) // 10 < answer: + return INT_MAX if sign == 1 else INT_MIN + # Update the result by multiplying by 10 and adding the current digit + answer = answer * 10 + digit i += 1 - # Process the digits of the string - while i < len(string): - # Check if the current character is a digit - if string[i].isdigit(): - # Update the answer by multiplying it by 10 and adding the current digit - answer = answer * 10 + int(string[i]) - i += 1 - else: - # If a non-digit character is encountered, apply the sign if present and return the result after checking for overflow - if sign != 0: - answer = sign * answer - return check(answer) - - # Apply the sign if present and return the result after checking for overflow - if sign != 0: - answer = sign * answer - return check(answer) - -# Test the function with the provided string "42" + # Return the final result multiplied by the sign + return sign * answer + if __name__ == "__main__": - s = "42" - print(myAtoi(s)) + # Example usage + input_string = input("Enter a string: ") + result = convertStringToInteger(input_string) + + # Check for None to handle cases of invalid input + if result is not None: + print("Converted integer:", result) ``` # Code Explanation From 615044ae32834d180ad58b3fee9caeb154a3816f Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:16:06 +0530 Subject: [PATCH 47/53] Update inorder.py --- Trees/Easy/Inorder Traversal/inorder.py | 53 ++++++++++++++++++------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/Trees/Easy/Inorder Traversal/inorder.py b/Trees/Easy/Inorder Traversal/inorder.py index cb629501..609fa126 100644 --- a/Trees/Easy/Inorder Traversal/inorder.py +++ b/Trees/Easy/Inorder Traversal/inorder.py @@ -1,8 +1,9 @@ # Definition for a binary tree node class Node: - def __init__(self,data): - self.data=data - self.left=self.right=None + def __init__(self, data): + self.data = data + self.left = self.right = None + # Recursive Inorder Traversal. def inorder(root): # Check if the root exists @@ -10,17 +11,39 @@ def inorder(root): # Perform an inorder traversal on the left subtree inorder(root.left) # Print the value of the current node - print(root.data,end=" ") + print(root.data, end=" ") # Perform an inorder traversal on the right subtree inorder(root.right) - # Driver code to test above function -# The values of nodes are given below : -if __name__=="__main__": - root=Node(80) - root.left=Node(20) - root.right=Node(30) - root.left.left=Node(40) - root.left.right=Node(350) - root.right.left=Node(460) - root.right.right=Node(70) - inorder(root) \ No newline at end of file + +if __name__ == "__main__": + try: + # Prompt the user to enter values for the binary tree + root_data = int(input("Enter the value for the root node: ")) + root = Node(root_data) + + left_data = int(input("Enter the value for the left child of the root node: ")) + root.left = Node(left_data) + + right_data = int(input("Enter the value for the right child of the root node: ")) + root.right = Node(right_data) + + left_left_data = int(input("Enter the value for the left child of the left child: ")) + root.left.left = Node(left_left_data) + + left_right_data = int(input("Enter the value for the right child of the left child: ")) + root.left.right = Node(left_right_data) + + right_left_data = int(input("Enter the value for the left child of the right child: ")) + root.right.left = Node(right_left_data) + + right_right_data = int(input("Enter the value for the right child of the right child: ")) + root.right.right = Node(right_right_data) + + # Perform Inorder Traversal + print("Inorder Traversal:") + inorder(root) + + except ValueError: + print("Error: Please enter valid integer values for the nodes.") + except Exception as e: + print(f"Error: {e}") From 01b5e532d911718df3bfd3c270a8de89291f725b Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 2 Jan 2024 21:24:05 +0530 Subject: [PATCH 48/53] Update inorder.cpp --- Trees/Easy/Inorder Traversal/inorder.cpp | 98 ++++++++++++++++-------- 1 file changed, 67 insertions(+), 31 deletions(-) diff --git a/Trees/Easy/Inorder Traversal/inorder.cpp b/Trees/Easy/Inorder Traversal/inorder.cpp index 2c04554e..3a45d169 100644 --- a/Trees/Easy/Inorder Traversal/inorder.cpp +++ b/Trees/Easy/Inorder Traversal/inorder.cpp @@ -1,38 +1,74 @@ -#include - -class Node{ - public: - int data; - Node *left=NULL; - Node *right=NULL; - - // Node constructor initializes data - Node(int val){ - data=val; - } +#include +#include + +// Definition for a binary tree node +class Node { +public: + int data; + Node* left = nullptr; + Node* right = nullptr; + + // Node constructor initializes data + Node(int val) : data(val) {} }; -void inorder(Node* root){ - // call inorder for left subtree - if(root!=NULL){ + +// Recursive Inorder Traversal +void inorder(Node* root) { + if (root != nullptr) { + // Traverse the left subtree inorder(root->left); - // Print root node data - std::cout<data<<" "; - // call inorder for right subtree + + // Print the value of the current node + std::cout << root->data << " "; + + // Traverse the right subtree inorder(root->right); } } -int main(){ - // Creating the binary tree - Node* root=new Node(10); - root->left=new Node(20); - root->right=new Node(30); - root->left->left=new Node(40); - root->left->right=new Node(50); - root->right->left=new Node(60); - root->right->right=new Node(70); - // Displaying the binary tree in inorder traversal - inorder(root); - // Inorder traversal of the tree +// Function to build a binary tree interactively based on user input +Node* buildTree() { + int rootData; + std::cout << "Enter the value for the current node: "; + std::cin >> rootData; + + auto root = new Node(rootData); + + char hasLeftChild, hasRightChild; + + // Ask user if the current node has a left child + std::cout << "Does the current node have a left child? (y/n): "; + std::cin >> hasLeftChild; + + // If yes, recursively build the left subtree + if (hasLeftChild == 'y') { + root->left = buildTree(); + } + + // Ask user if the current node has a right child + std::cout << "Does the current node have a right child? (y/n): "; + std::cin >> hasRightChild; + + // If yes, recursively build the right subtree + if (hasRightChild == 'y') { + root->right = buildTree(); + } + + return root; +} + +int main() { + try { + std::cout << "Interactive Binary Tree Construction\n"; + Node* root = buildTree(); + + std::cout << "\nInorder Traversal: "; + inorder(root); + std::cout << std::endl; + } catch (const std::exception& e) { + // Handle exceptions, if any + std::cerr << "Error: " << e.what() << std::endl; + } + return 0; -} \ No newline at end of file +} From 53a373759afe3987a34cf0a80daa87496eebd3c6 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:43:40 +0530 Subject: [PATCH 49/53] Update max heap CRUD.py --- Heaps/Hard/max heap CRUD.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/Heaps/Hard/max heap CRUD.py b/Heaps/Hard/max heap CRUD.py index 0ce2f26f..8b2d4d09 100644 --- a/Heaps/Hard/max heap CRUD.py +++ b/Heaps/Hard/max heap CRUD.py @@ -69,24 +69,39 @@ def main(): heap = MaxHeap() # Insert elements into heap - heap.insert(12) - heap.insert(10) - heap.insert(-10) - heap.insert(100) + try: + while True: + value = int(input("Enter an integer to insert into the heap (enter a non-integer to stop): ")) + heap.insert(value) + heap.print_heap() + except ValueError: + pass # Continue to the next step when a non-integer is entered # Print all values in heap + print("Heap after insertion:") heap.print_heap() # Get max value in heap print("Max Value:", heap.get_max()) # Update value in heap - heap.update(12, 5) - print("Max Value after update:", heap.get_max()) + try: + old_value = int(input("Enter the value to update: ")) + new_value = int(input("Enter the new value: ")) + heap.update(old_value, new_value) + print("Max Value after update:", heap.get_max()) + except ValueError: + print("Invalid input. Please enter integers.") # Delete max value from heap - heap.delete_max() - print("Max Value after deletion:", heap.get_max()) + try: + heap.delete_max() + print("Max Value after deletion:", heap.get_max()) + except Exception as e: + print(e) # Print all values in heap after deletion - heap.print_heap() \ No newline at end of file + heap.print_heap() + +if __name__ == "__main__": + main() From 839147cefefbdf205fcdeca09bf1d76acb98eb6d Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:51:25 +0530 Subject: [PATCH 50/53] Update max_heap_CRUD.c++ --- Heaps/Hard/max_heap_CRUD.c++ | 57 +++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/Heaps/Hard/max_heap_CRUD.c++ b/Heaps/Hard/max_heap_CRUD.c++ index 0cebbbdc..0e6af123 100644 --- a/Heaps/Hard/max_heap_CRUD.c++ +++ b/Heaps/Hard/max_heap_CRUD.c++ @@ -25,11 +25,11 @@ private: int largest = index; // Check if the left child is larger than the current largest element - if (left < heap.size() && heap[left] > heap[largest]) { + if (left < static_cast(heap.size()) && heap[left] > heap[largest]) { largest = left; } // Check if the right child is larger than the current largest element - if (right < heap.size() && heap[right] > heap[largest]) { + if (right < static_cast(heap.size()) && heap[right] > heap[largest]) { largest = right; } @@ -50,7 +50,7 @@ public: // Return the maximum element in the heap (root of the heap) int getMax() { if (heap.size() == 0) { - throw "Heap is empty"; + throw std::runtime_error("Heap is empty"); } return heap[0]; } @@ -70,7 +70,7 @@ public: // Replace the root with the last element, pop the last element, and max heapify void deleteMax() { if (heap.size() == 0) { - throw "Heap is empty"; + throw std::runtime_error("Heap is empty"); } heap[0] = heap.back(); heap.pop_back(); @@ -90,22 +90,51 @@ int main() { // Example usage of the MaxHeap class MaxHeap heap; - heap.insert(12); - heap.insert(10); - heap.insert(-10); - heap.insert(100); - + // Insert elements into the heap using user input + while (true) { + int value; + std::cout << "Enter an integer to insert into the heap (enter a non-integer to stop): "; + if (!(std::cin >> value)) { + break; + } + heap.insert(value); + std::cout << "Heap after insertion: "; + heap.printHeap(); + } + + // Print all values in heap std::cout << "All values in heap: "; heap.printHeap(); - std::cout << "Max Value: " << heap.getMax() << std::endl; + // Get max value in heap + try { + std::cout << "Max Value: " << heap.getMax() << std::endl; + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + } - heap.update(12, 5); - std::cout << "Max Value after update: " << heap.getMax() << std::endl; + // Update value in heap using user input + try { + int old_value, new_value; + std::cout << "Enter the value to update: "; + std::cin >> old_value; + std::cout << "Enter the new value: "; + std::cin >> new_value; + heap.update(old_value, new_value); + std::cout << "Max Value after update: " << heap.getMax() << std::endl; + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + } - heap.deleteMax(); - std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + // Delete max value from heap + try { + heap.deleteMax(); + std::cout << "Max Value after deletion: " << heap.getMax() << std::endl; + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; + } + // Print all values in heap after deletion std::cout << "All values in heap: "; heap.printHeap(); From a98f4587616379705ebffe3da02901244c3a64e1 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Wed, 3 Jan 2024 22:35:14 +0530 Subject: [PATCH 51/53] Update MaxHeapCRUD.java --- Heaps/Hard/MaxHeapCRUD.java | 109 ++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/Heaps/Hard/MaxHeapCRUD.java b/Heaps/Hard/MaxHeapCRUD.java index f8a6ff78..33cc206e 100644 --- a/Heaps/Hard/MaxHeapCRUD.java +++ b/Heaps/Hard/MaxHeapCRUD.java @@ -1,8 +1,10 @@ import java.util.ArrayList; +import java.util.InputMismatchException; import java.util.List; +import java.util.Scanner; -// Class representing a max heap with CRUD operations -class MaxHeapCRUD { +// MaxHeapCRUD class representing a max heap with CRUD operations +public class MaxHeapCRUD { private List heap; // Constructor initializes an empty list for the heap @@ -57,31 +59,22 @@ public void insert(int val) { // Return the maximum element in the heap (root of the heap) public int getMax() { - if (heap.size() == 0) { + if (heap.isEmpty()) { throw new RuntimeException("Heap is empty"); } return heap.get(0); } - // Update the value, percolate up, and max heapify to maintain the heap property - public void update(int oldVal, int newVal) { - int index = heap.indexOf(oldVal); - if (index != -1) { - heap.set(index, newVal); - percolateUp(index); - maxHeapify(index); - } else { - System.out.println("Value not in heap"); + // Delete the element at the specified index from the heap + public void delete(int index) { + if (index < 0 || index >= heap.size()) { + throw new RuntimeException("Invalid index"); } - } - - // Replace the root with the last element, pop the last element, and max heapify - public void deleteMax() { - if (heap.size() == 0) { - throw new RuntimeException("Heap is empty"); - } - heap.set(0, heap.remove(heap.size() - 1)); - maxHeapify(0); + // Swap the element with the last element + heap.set(index, heap.get(heap.size() - 1)); + heap.remove(heap.size() - 1); + // Max heapify to maintain the heap property + maxHeapify(index); } // Print all values in the heap @@ -96,26 +89,56 @@ public void printHeap() { public static void main(String[] args) { MaxHeapCRUD heap = new MaxHeapCRUD(); - heap.insert(12); - heap.insert(10); - heap.insert(52); - heap.insert(100); - heap.insert(50); - - System.out.print("All values in heap: "); - heap.printHeap(); - - System.out.println("Max Value: " + heap.getMax()); - - heap.update(12, 5); - - System.out.println("Max Value after update: " + heap.getMax()); - - heap.deleteMax(); - - System.out.println("Max Value after deletion: " + heap.getMax()); - - System.out.print("All values in heap: "); - heap.printHeap(); + // Insert, delete, fetch, and print elements into/from the heap using user input + try (Scanner scanner = new Scanner(System.in)) { + while (true) { + System.out.println("1. Insert element"); + System.out.println("2. Get max element"); + System.out.println("3. Delete element at index"); + System.out.println("4. Print heap"); + System.out.println("5. Exit"); + System.out.print("Enter your choice: "); + + try { + int choice = scanner.nextInt(); + switch (choice) { + case 1: + System.out.print("Enter an integer to insert into the heap: "); + heap.insert(scanner.nextInt()); + break; + case 2: + try { + System.out.println("Max Value: " + heap.getMax()); + } catch (RuntimeException e) { + System.err.println(e.getMessage()); + } + break; + case 3: + System.out.print("Enter the index to delete: "); + int deleteIndex = scanner.nextInt(); + try { + heap.delete(deleteIndex); + System.out.println("Element at index " + deleteIndex + " deleted"); + } catch (RuntimeException e) { + System.err.println(e.getMessage()); + } + break; + case 4: + System.out.print("All values in heap: "); + heap.printHeap(); + break; + case 5: + System.out.println("Exiting..."); + System.exit(0); + default: + System.out.println("Invalid choice. Please enter a number between 1 and 5."); + } + } catch (InputMismatchException e) { + System.err.println("Invalid input. Please enter a number."); + // Clear the scanner buffer to avoid an infinite loop on invalid input + scanner.next(); + } + } + } } -} \ No newline at end of file +} From fc766e3b20e6f44d7ecc5789ef3a779d32d836b9 Mon Sep 17 00:00:00 2001 From: Anusha Dhasari <97797206+Anusha-3113@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:41:47 +0530 Subject: [PATCH 52/53] added KMP algorithm --- Strings/Hard/KMPAlgorithm.java | 70 +++++ Strings/Hard/Readme.md | 503 +++++++++++++++++++++++++++++++++ Strings/Hard/kmp algorithm.cpp | 70 +++++ Strings/Hard/kmp algorithm.py | 48 ++++ 4 files changed, 691 insertions(+) create mode 100644 Strings/Hard/KMPAlgorithm.java create mode 100644 Strings/Hard/Readme.md create mode 100644 Strings/Hard/kmp algorithm.cpp create mode 100644 Strings/Hard/kmp algorithm.py diff --git a/Strings/Hard/KMPAlgorithm.java b/Strings/Hard/KMPAlgorithm.java new file mode 100644 index 00000000..8a23076c --- /dev/null +++ b/Strings/Hard/KMPAlgorithm.java @@ -0,0 +1,70 @@ +import java.util.Scanner; + +public class KMPAlgorithm { + + // Function to compute the prefix function (π) for the pattern 'p' + public static int[] computePrefixFunction(String p) { + int m = p.length(); + int[] π = new int[m]; // Initialize an array to store the prefix function values + int k = 0; // Initialize a variable for matching characters + + // Iterate through the pattern to compute the prefix function + for (int q = 1; q < m; ++q) { + // Update the matching character index while it's not zero and characters mismatch + while (k > 0 && p.charAt(k) != p.charAt(q)) { + k = π[k - 1]; + } + // If characters match, increment the matching character index + if (p.charAt(k) == p.charAt(q)) { + k += 1; + } + // Store the current matching character index in the prefix function array + π[q] = k; + } + + return π; + } + + // Function to perform pattern matching using the Knuth-Morris-Pratt (KMP) algorithm + public static void kmpMatcher(String t, String p) { + int n = t.length(); // Length of the text + int m = p.length(); // Length of the pattern + int[] π = computePrefixFunction(p); // Compute the prefix function for the pattern + int q = 0; // Initialize a variable for matching characters + + // Iterate through the text to find occurrences of the pattern + for (int i = 0; i < n; ++i) { + // Update the matching character index while it's not zero and characters mismatch + while (q > 0 && p.charAt(q) != t.charAt(i)) { + q = π[q - 1]; + } + // If characters match, increment the matching character index + if (p.charAt(q) == t.charAt(i)) { + q += 1; + } + // If the entire pattern is matched, print the occurrence + if (q == m) { + System.out.println("Pattern occurs with shift " + (i - m + 1)); + q = π[q - 1]; // Look for the next match + } + } + } + + public static void main(String[] args) { + try (Scanner scanner = new Scanner(System.in)) { + // Get user input with null safety + System.out.print("Enter the text: "); + String text = scanner.nextLine(); + System.out.print("Enter the pattern: "); + String pattern = scanner.nextLine(); + + // Check if input is not empty and contains only alphabetical characters + if (!text.isEmpty() && !pattern.isEmpty() && Character.isLetter(text.charAt(0)) + && Character.isLetter(pattern.charAt(0))) { + kmpMatcher(text, pattern); + } else { + System.out.println("Please enter valid alphabetic text and pattern."); + } + } + } +} diff --git a/Strings/Hard/Readme.md b/Strings/Hard/Readme.md new file mode 100644 index 00000000..561d62eb --- /dev/null +++ b/Strings/Hard/Readme.md @@ -0,0 +1,503 @@ +# Exploring string searching algorithm : + +String searching algorithms are techniques used to find occurrences of a specific pattern within a larger text or string. These algorithms are crucial in various applications, including text processing, data mining, bioinformatics, and many others. + +# Introduction to Strings: + +A string is a sequence of characters enclosed in double or single quotes. It can contain letters, digits, special symbols, spaces, punctuation. +Strings, an indispensable data type in programming, serve as a versatile container for sequences of characters. One of the distinctive features of strings is their ability to store and process textual information. Whether it's a single word, a sentence, or even a larger body of text, strings provide a means to work with this data programmatically. In most programming languages, strings are typically enclosed within quotation marks, such as single (' ') or double (" ") quotes, allowing the interpreter or compiler to recognize them as string literals. + +# Introduction to the Knuth-Morris-Pratt (KMP) : + +The Knuth-Morris-Pratt (KMP) algorithm is a powerful string searching algorithm that efficiently finds occurrences of a pattern within a text. Developed by Donald Knuth, Vaughan Pratt, and James H. Morris, the KMP algorithm was introduced in 1977 as a solution to the problem of searching for a pattern in linear time without unnecessary backtracking. + +The primary innovation of the KMP algorithm lies in its ability to preprocess the pattern before searching, creating a "prefix function" that helps determine the optimal positions to resume the search when a mismatch occurs. This preprocessing allows the algorithm to avoid redundant character comparisons, making it more efficient than traditional brute-force methods. + +The Knuth-Morris-Pratt algorithm stands out for its ability to achieve linear time complexity, making it a powerful tool for efficient string searching in various applications. + +# Overview of Knuth-Morris-Pratt (KMP) : + + The KMP algorithm addresses the inefficiencies of brute-force methods by using a clever precomputation technique. + + Compute Prefix Function: + The prefix function is computed by iterating through the pattern and updating values based on matching prefixes and suffixes. + + Search Using Prefix Function: + The text is scanned with the pattern, and when a mismatch occurs, the prefix function guides the algorithm to determine the optimal position to resume the search. + + Efficient Backtracking: + The KMP algorithm efficiently backtracks by using the information stored in the prefix function, eliminating redundant character comparisons. + +# PYTHON +# code +```python +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +# python program for Knuth-Morris-Pratt algorithm +# Stable: Yes +# Inplace: Yes +# Adaptive: No + +# Space complexity:O(m) +# Time complexity:O(n+m) + +def compute_prefix_function(p): + # Function to compute the prefix function (π) for the pattern 'p' + m = len(p) + π = [0] * m # Initialize an array to store the prefix function values + k = 0 # Initialize a variable for matching characters + + # Iterate through the pattern to compute the prefix function + for q in range(1, m): + # Update the matching character index while it's not zero and characters mismatch + while k > 0 and p[k] != p[q]: + k = π[k - 1] + # If characters match, increment the matching character index + if p[k] == p[q]: + k += 1 + # Store the current matching character index in the prefix function array + π[q] = k + + return π + +def kmp_matcher(t, p): + # Function to perform pattern matching using the Knuth-Morris-Pratt (KMP) algorithm + n = len(t) # Length of the text + m = len(p) # Length of the pattern + π = compute_prefix_function(p) # Compute the prefix function for the pattern + q = 0 # Initialize a variable for matching characters + + # Iterate through the text to find occurrences of the pattern + for i in range(n): + # Update the matching character index while it's not zero and characters mismatch + while q > 0 and p[q] != t[i]: + q = π[q - 1] + # If characters match, increment the matching character index + if p[q] == t[i]: + q += 1 + # If the entire pattern is matched, print the occurrence + if q == m: + print(f"Pattern occurs with shift {i - m + 1}") + q = π[q - 1] # Look for the next match + +# Get user input with null safety +text = input("Enter the text: ") +pattern = input("Enter the pattern: ") + +# Check if input is not empty and contains only alphabetical characters +if text and pattern and text.isalpha() and pattern.isalpha(): + kmp_matcher(text, pattern) +else: + print("Please enter valid text and pattern.") + +``` +# Code Explanation + +This Python code implements the Knuth-Morris-Pratt (KMP) algorithm, a string searching algorithm used to find occurrences of a pattern within a given text. Here's an explanation for each section of the code: + +1. **`compute_prefix_function(p)` Function:** + - This function computes the prefix function (π) for the given pattern `p`. + - `m = len(p)`: Calculate the length of the pattern. + - `π = [0] * m`: Initialize an array `π` to store the prefix function values, and set all values to 0. + - `k = 0`: Initialize a variable for tracking matching characters. + - The function iterates through the pattern and updates the prefix function values based on matching prefixes and suffixes. + +2. **`kmp_matcher(t, p)` Function:** + - This function performs pattern matching using the Knuth-Morris-Pratt (KMP) algorithm. + - `n = len(t)`: Calculate the length of the text. + - `m = len(p)`: Calculate the length of the pattern. + - `π = compute_prefix_function(p)`: Compute the prefix function for the pattern. + - `q = 0`: Initialize a variable for tracking matching characters. + +3. **Pattern Matching Loop:** + - The function iterates through each character in the text. + - A nested while loop updates the matching character index `q` based on the prefix function values and mismatches between characters in the pattern and text. + - If characters match, `q` is incremented. + - If the entire pattern is matched (`q == m`), it prints the occurrence with the shift index and updates `q` to continue looking for the next match. + +4. **User Input and Validation:** + - The code prompts the user to input the text and pattern. + - It checks if the input is not empty and contains only alphabetical characters using `text.isalpha()` and `pattern.isalpha()`. + - If the input is valid, it calls the `kmp_matcher` function; otherwise, it prints an error message. + +5. **Output:** + - If the user input is valid and there are pattern occurrences in the text, it prints the positions (shifts) where the pattern is found. + +Overall, this code provides a simple and functional implementation of the KMP algorithm, allowing users to find occurrences of a pattern within a given text. The use of functions enhances modularity and readability. + +# C++ + +code +```c++ +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program for Knuth-Morris-Pratt algorithm +// Stable: Yes +// In-Place: Yes +// Adaptive: No +// Space Complexity: O(m) +// Time Complexity: O(n + m) + +#include +#include +#include + +// Function to compute the prefix function (π) for the pattern 'p' +std::vector compute_prefix_function(const std::string& p) { + int m = p.length(); // Length of the pattern + std::vector π(m, 0); // Initialize an array to store the prefix function values + int k = 0; // Initialize a variable for matching characters + + // Iterate through the pattern to compute the prefix function + for (int q = 1; q < m; ++q) { + // Update the matching character index while it's not zero and characters mismatch + while (k > 0 && p[k] != p[q]) { + k = π[k - 1]; + } + // If characters match, increment the matching character index + if (p[k] == p[q]) { + k += 1; + } + // Store the current matching character index in the prefix function array + π[q] = k; + } + + return π; +} + +// Function to perform pattern matching using the Knuth-Morris-Pratt (KMP) algorithm +void kmp_matcher(const std::string& t, const std::string& p) { + int n = t.length(); // Length of the text + int m = p.length(); // Length of the pattern + std::vector π = compute_prefix_function(p); // Compute the prefix function for the pattern + int q = 0; // Initialize a variable for matching characters + + // Iterate through the text to find occurrences of the pattern + for (int i = 0; i < n; ++i) { + // Update the matching character index while it's not zero and characters mismatch + while (q > 0 && p[q] != t[i]) { + q = π[q - 1]; + } + // If characters match, increment the matching character index + if (p[q] == t[i]) { + q += 1; + } + // If the entire pattern is matched, print the occurrence + if (q == m) { + std::cout << "Pattern occurs with shift " << i - m + 1 << std::endl; + q = π[q - 1]; // Look for the next match + } + } +} + +int main() { + // Get user input with null safety + std::string text, pattern; + std::cout << "Enter the text: "; + std::cin >> text; + std::cout << "Enter the pattern: "; + std::cin >> pattern; + + // Check if input is not empty and contains only alphabetical characters + if (!text.empty() && !pattern.empty() && std::isalpha(text[0]) && std::isalpha(pattern[0])) { + kmp_matcher(text, pattern); + } + else { + std::cout << "Please enter valid alphabetic text and pattern." << std::endl; + } + + return 0; +} + +``` +# Code Explanation +Here's an explanation for the provided C++ code that implements the Knuth-Morris-Pratt (KMP) algorithm for string searching: + +1. **`compute_prefix_function` Function:** + - This function computes the prefix function (π) for the given pattern `p`. + - `int m = p.length();`: Calculate the length of the pattern. + - `std::vector π(m, 0);`: Initialize a vector to store the prefix function values, and set all values to 0. + - `int k = 0;`: Initialize a variable for tracking matching characters. + - The function iterates through the pattern and updates the prefix function values based on matching prefixes and suffixes. + +2. **`kmp_matcher` Function:** + - This function performs pattern matching using the KMP algorithm. + - `int n = t.length();`: Calculate the length of the text. + - `int m = p.length();`: Calculate the length of the pattern. + - `std::vector π = compute_prefix_function(p);`: Compute the prefix function for the pattern. + - `int q = 0;`: Initialize a variable for tracking matching characters. + +3. **Pattern Matching Loop:** + - The function iterates through each character in the text. + - A nested while loop updates the matching character index `q` based on the prefix function values and mismatches between characters in the pattern and text. + - If characters match, `q` is incremented. + - If the entire pattern is matched (`q == m`), it prints the occurrence with the shift index and updates `q` to continue looking for the next match. + +4. **User Input and Validation:** + - The code prompts the user to input the text and pattern. + - It checks if the input is not empty and contains only alphabetical characters using `std::isalpha()` similar to the Python code. + - If the input is valid, it calls the `kmp_matcher` function; otherwise, it prints an error message. + +The code is designed to efficiently find occurrences of a pattern within a given text, providing a powerful and widely used string searching algorithm. + +# java +# code +```java +/* Copyrights to venkys.io +For more information, visit https://venkys.io */ + +// C++ program for Knuth-Morris-Pratt algorithm +// Stable: Yes +// In-Place: Yes +// Adaptive: No +// Space Complexity: O(m) +// Time Complexity: O(n + m) + +import java.util.Scanner; + +public class KMPAlgorithm { + + // Function to compute the prefix function (π) for the pattern 'p' + public static int[] computePrefixFunction(String p) { + int m = p.length(); + int[] π = new int[m]; // Initialize an array to store the prefix function values + int k = 0; // Initialize a variable for matching characters + + // Iterate through the pattern to compute the prefix function + for (int q = 1; q < m; ++q) { + // Update the matching character index while it's not zero and characters mismatch + while (k > 0 && p.charAt(k) != p.charAt(q)) { + k = π[k - 1]; + } + // If characters match, increment the matching character index + if (p.charAt(k) == p.charAt(q)) { + k += 1; + } + // Store the current matching character index in the prefix function array + π[q] = k; + } + + return π; + } + + // Function to perform pattern matching using the Knuth-Morris-Pratt (KMP) algorithm + public static void kmpMatcher(String t, String p) { + int n = t.length(); // Length of the text + int m = p.length(); // Length of the pattern + int[] π = computePrefixFunction(p); // Compute the prefix function for the pattern + int q = 0; // Initialize a variable for matching characters + + // Iterate through the text to find occurrences of the pattern + for (int i = 0; i < n; ++i) { + // Update the matching character index while it's not zero and characters mismatch + while (q > 0 && p.charAt(q) != t.charAt(i)) { + q = π[q - 1]; + } + // If characters match, increment the matching character index + if (p.charAt(q) == t.charAt(i)) { + q += 1; + } + // If the entire pattern is matched, print the occurrence + if (q == m) { + System.out.println("Pattern occurs with shift " + (i - m + 1)); + q = π[q - 1]; // Look for the next match + } + } + } + + public static void main(String[] args) { + try (Scanner scanner = new Scanner(System.in)) { + // Get user input with null safety + System.out.print("Enter the text: "); + String text = scanner.nextLine(); + System.out.print("Enter the pattern: "); + String pattern = scanner.nextLine(); + + // Check if input is not empty and contains only alphabetical characters + if (!text.isEmpty() && !pattern.isEmpty() && Character.isLetter(text.charAt(0)) + && Character.isLetter(pattern.charAt(0))) { + kmpMatcher(text, pattern); + } else { + System.out.println("Please enter valid alphabetic text and pattern."); + } + } + } +} + +``` +# Code Explanation + +KMP Algorithm Explanation: + +1. **computePrefixFunction Method:** + - This method computes the prefix function (π) for the given pattern p. + - int m = p.length();: Calculate the length of the pattern. + - int[] π = new int[m];: Initialize an array to store the prefix function values. + - int k = 0;: Initialize a variable for tracking matching characters. + - The method iterates through the pattern and updates the prefix function values based on matching prefixes and suffixes. + +2. **kmpMatcher Method:** + - This method performs pattern matching using the KMP algorithm. + - int n = t.length();: Calculate the length of the text. + - int m = p.length();: Calculate the length of the pattern. + - int[] π = computePrefixFunction(p);: Compute the prefix function for the pattern + - int q = 0;: Initialize a variable for tracking matching characters. + +3. **Pattern Matching Loop:** + - The method iterates through each character in the text. + - A nested while loop updates the matching character index q based on the prefix function values and mismatches between characters in the pattern and text. + If characters match, q is incremented. + - If the entire pattern is matched (q == m), it prints the occurrence with the shift index and updates q to continue looking for the next match. + +4. **User Input and Validation:** + - The main method uses a Scanner to get user input for the text and pattern. + - It checks if the input is not empty and contains only alphabetical characters using Character.isLetter() similar to the C++ code. + - If the input is valid, it calls the kmpMatcher method; otherwise, it prints an error message. + +Overall, this Java implementation of the KMP algorithm achieves the same goal as the C++ code, providing an efficient way to find occurrences of a pattern within a given text. The core algorithm remains consistent across different programming languages. + +**Difference** + +Here are some key differences between the provided KMP algorithm implementations in Python, C++, and Java: + +### 1. **Syntax and Language Features:** + - **Python:** + - Dynamically typed language. + - Uses indentation for code blocks. + - **C++:** + - Statically typed language. + - Requires explicit type declarations. + - Uses curly braces for code blocks. + - **Java:** + - Statically typed language. + - Requires explicit type declarations. + - Uses curly braces for code blocks. + +### 2. **Data Structures:** + - **Python:** + - Uses lists for arrays. + - **C++:** + - Uses `std::vector` for dynamic arrays. + - **Java:** + - Uses arrays (`int[]`, `char[]`) for dynamic arrays. + +### 3. **Input/Output Handling:** + - **Python:** + - Uses `input()` and `print()` for user input/output. + - **C++:** + - Uses `std::cin` and `std::cout` for user input/output. + - **Java:** + - Uses `Scanner` and `System.out.println` for user input/output. + +### 4. **String Handling:** + - **Python:** + - Strings are immutable. + - Indexing starts from 0. + - **C++:** + - Uses `std::string` for string handling. + - **Java:** + - Uses `String` class for string handling. + - Strings are immutable. + +### 5. **Array Initialization:** + - **Python:** + - Uses list comprehension for array initialization. + - **C++:** + - Uses `std::vector` and array initialization. + - **Java:** + - Uses array initialization (`new int[m]`). + +### 6. **Exception Handling:** + - **Python:** + - Exception handling is more implicit. + - **C++:** + - Uses `try`, `catch` for exception handling. + - **Java:** + - Uses `try`, `catch` for exception handling. + +### 7. **Type Checking:** + - **Python:** + - Dynamically typed; type checking is done at runtime. + - **C++:** + - Statically typed; type checking is done at compile time. + - **Java:** + - Statically typed; type checking is done at compile time. + +### 8. **Memory Management:** + - **Python:** + - Automatic memory management (garbage collection). + - **C++:** + - Manual memory management using `new` and `delete`. + - **Java:** + - Automatic memory management (garbage collection). + +### 9. **Exception Handling for User Input:** + - **Python:** + - Uses `try`, `except` blocks for error handling. + - **C++ and Java:** + - Use `try`, `catch` blocks for error handling. + +### 10. **Array Indexing:** + - **Python and Java:** + - Indexing starts from 0. + - **C++:** + - Indexing starts from 0. + +These differences highlight the specific syntax and language features of each programming language. While the core logic of the KMP algorithm remains consistent, the implementation details vary to accommodate the unique aspects of each language. + +# Time and Space Complexity: + +The time and space complexity of the Knuth-Morris-Pratt (KMP) algorithm are crucial factors that determine its efficiency in solving the string matching problem. + +### Time Complexity: + +The time complexity of the KMP algorithm is O(n + m), where: +- n is the length of the text, +- m is the length of the pattern. + +This linear time complexity is achieved because, in the worst case, the algorithm only needs to iterate through each character in the text and the pattern once. The preprocessing step, which involves computing the prefix function, takes O(m) time. The actual pattern matching then takes O(n) time in the worst case. + +### Space Complexity: + +The space complexity of the KMP algorithm is O(m), where m is the length of the pattern. This space complexity is due to the storage requirements of the prefix function array (π) used during the pattern matching process. The array is of size m and is used to store information about the longest proper prefix that is also a suffix at each position in the pattern. + +In summary: +- Time Complexity: O(n + m) +- Space Complexity: O(m) + +These complexities make the KMP algorithm an efficient choice for string matching, particularly when the length of the pattern is significantly smaller than the length of the text. The linear time complexity ensures that the algorithm remains practical for large datasets. + +# Real-World Applications of KMP algorithm + +The Knuth-Morris-Pratt (KMP) algorithm, known for its efficient string matching capabilities, finds applications in various real-world scenarios. Some notable applications include: + +1. **Text Search Engines:** + - KMP is used in text search engines to quickly locate patterns within large documents or text corpora. Search engines often need to efficiently find occurrences of keywords or phrases in documents, and KMP aids in speeding up this process. + +2. **Code Editors and IDEs:** + - Integrated Development Environments (IDEs) and code editors use string matching algorithms like KMP to implement features such as code highlighting, code completion, and refactoring tools. These features often involve identifying patterns within source code efficiently. + +3. **Data Compression:** + - KMP can be applied in certain data compression algorithms, particularly those that involve searching for repeated patterns within the data. By efficiently identifying and compressing repeated patterns, data compression algorithms can achieve higher compression ratios. + +4. **Bioinformatics:** + - In bioinformatics, DNA and protein sequence analysis may involve searching for specific patterns or motifs. KMP can be utilized to efficiently find occurrences of these patterns within biological sequences, aiding researchers in genetic analysis. + +5. **Network Security:** + - KMP is used in network security applications for pattern matching in intrusion detection systems. It helps in quickly identifying specific patterns associated with malicious activities or known attack signatures in network traffic. + +6. **Spell Checking:** + - Spell-checking algorithms use string matching techniques to identify and suggest corrections for misspelled words. KMP can be employed to efficiently search for similar patterns within a dictionary of correctly spelled words. + +7. **Data Mining and Pattern Recognition:** + - KMP can be employed in data mining applications for identifying recurring patterns or trends within large datasets. It aids in efficiently searching for specific patterns of interest in data streams. + +8. **Genome Sequencing:** + - In genomics, the KMP algorithm can be used to search for specific genetic sequences or motifs within large DNA datasets. This is valuable for tasks such as genome sequencing and identifying genes associated with certain traits or diseases. + +9. **Compilers:** + - Compilers use string matching algorithms for lexical analysis, where they identify and tokenize specific patterns in the source code. KMP can contribute to efficient pattern matching during this phase of compilation. + +The KMP algorithm's efficiency in handling pattern matching makes it a versatile tool in various fields where finding occurrences of specific patterns in large datasets is a fundamental task. Its linear time complexity ensures practical applicability in scenarios involving sizable datasets. \ No newline at end of file diff --git a/Strings/Hard/kmp algorithm.cpp b/Strings/Hard/kmp algorithm.cpp new file mode 100644 index 00000000..c4d28cf1 --- /dev/null +++ b/Strings/Hard/kmp algorithm.cpp @@ -0,0 +1,70 @@ +#include +#include +#include + +// Function to compute the prefix function (π) for the pattern 'p' +std::vector compute_prefix_function(const std::string& p) { + int m = p.length(); // Length of the pattern + std::vector π(m, 0); // Initialize an array to store the prefix function values + int k = 0; // Initialize a variable for matching characters + + // Iterate through the pattern to compute the prefix function + for (int q = 1; q < m; ++q) { + // Update the matching character index while it's not zero and characters mismatch + while (k > 0 && p[k] != p[q]) { + k = π[k - 1]; + } + // If characters match, increment the matching character index + if (p[k] == p[q]) { + k += 1; + } + // Store the current matching character index in the prefix function array + π[q] = k; + } + + return π; +} + +// Function to perform pattern matching using the Knuth-Morris-Pratt (KMP) algorithm +void kmp_matcher(const std::string& t, const std::string& p) { + int n = t.length(); // Length of the text + int m = p.length(); // Length of the pattern + std::vector π = compute_prefix_function(p); // Compute the prefix function for the pattern + int q = 0; // Initialize a variable for matching characters + + // Iterate through the text to find occurrences of the pattern + for (int i = 0; i < n; ++i) { + // Update the matching character index while it's not zero and characters mismatch + while (q > 0 && p[q] != t[i]) { + q = π[q - 1]; + } + // If characters match, increment the matching character index + if (p[q] == t[i]) { + q += 1; + } + // If the entire pattern is matched, print the occurrence + if (q == m) { + std::cout << "Pattern occurs with shift " << i - m + 1 << std::endl; + q = π[q - 1]; // Look for the next match + } + } +} + +int main() { + // Get user input with null safety + std::string text, pattern; + std::cout << "Enter the text: "; + std::cin >> text; + std::cout << "Enter the pattern: "; + std::cin >> pattern; + + // Check if input is not empty and contains only alphabetical characters + if (!text.empty() && !pattern.empty() && std::isalpha(text[0]) && std::isalpha(pattern[0])) { + kmp_matcher(text, pattern); + } + else { + std::cout << "Please enter valid alphabetic text and pattern." << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/Strings/Hard/kmp algorithm.py b/Strings/Hard/kmp algorithm.py new file mode 100644 index 00000000..20d242aa --- /dev/null +++ b/Strings/Hard/kmp algorithm.py @@ -0,0 +1,48 @@ +def compute_prefix_function(p): + # Function to compute the prefix function (π) for the pattern 'p' + m = len(p) + π = [0] * m # Initialize an array to store the prefix function values + k = 0 # Initialize a variable for matching characters + + # Iterate through the pattern to compute the prefix function + for q in range(1, m): + # Update the matching character index while it's not zero and characters mismatch + while k > 0 and p[k] != p[q]: + k = π[k - 1] + # If characters match, increment the matching character index + if p[k] == p[q]: + k += 1 + # Store the current matching character index in the prefix function array + π[q] = k + + return π + +def kmp_matcher(t, p): + # Function to perform pattern matching using the Knuth-Morris-Pratt (KMP) algorithm + n = len(t) # Length of the text + m = len(p) # Length of the pattern + π = compute_prefix_function(p) # Compute the prefix function for the pattern + q = 0 # Initialize a variable for matching characters + + # Iterate through the text to find occurrences of the pattern + for i in range(n): + # Update the matching character index while it's not zero and characters mismatch + while q > 0 and p[q] != t[i]: + q = π[q - 1] + # If characters match, increment the matching character index + if p[q] == t[i]: + q += 1 + # If the entire pattern is matched, print the occurrence + if q == m: + print(f"Pattern occurs with shift {i - m + 1}") + q = π[q - 1] # Look for the next match + +# Get user input with null safety +text = input("Enter the text: ") +pattern = input("Enter the pattern: ") + +# Check if input is not empty and contains only alphabetical characters +if text and pattern and text.isalpha() and pattern.isalpha(): + kmp_matcher(text, pattern) +else: + print("Please enter valid text and pattern.") From 0a122e27e5004c4a8d0fce8fddc603ef814dd138 Mon Sep 17 00:00:00 2001 From: Sneha Vellelath <129183233+vellsneha@users.noreply.github.com> Date: Sat, 30 Mar 2024 00:29:54 +0530 Subject: [PATCH 53/53] Update Readme.md --- Trees/Easy/Inorder Traversal/Readme.md | 227 ++++++++++++++++++++++--- 1 file changed, 199 insertions(+), 28 deletions(-) diff --git a/Trees/Easy/Inorder Traversal/Readme.md b/Trees/Easy/Inorder Traversal/Readme.md index d8829cd0..cbf42a4e 100644 --- a/Trees/Easy/Inorder Traversal/Readme.md +++ b/Trees/Easy/Inorder Traversal/Readme.md @@ -32,13 +32,32 @@ def inorder(root): # Driver code to test above function # The values of nodes are given below : if __name__=="__main__": - root=Node(80) - root.left=Node(20) - root.right=Node(30) - root.left.left=Node(40) - root.left.right=Node(350) - root.right.left=Node(460) - root.right.right=Node(70) + root_data = int(input()) + root = Node(root_data) + + left_data = int(input()) + if left_data != -1: + root.left = Node(left_data) + + right_data = int(input()) + if right_data != -1: + root.right = Node(right_data) + + left_left_data = int(input()) + if left_left_data != -1: + root.left.left = Node(left_left_data) + + left_right_data = int(input()) + if left_right_data != -1: + root.left.right = Node(left_right_data) + + right_left_data = int(input()) + if right_left_data != -1: + root.right.left = Node(right_left_data) + + right_right_data = int(input()) + if right_right_data != -1: + root.right.right = Node(right_right_data) inorder(root) ``` @@ -132,13 +151,41 @@ void inorder(Node* root){ int main(){ // Creating the binary tree - Node* root=new Node(10); - root->left=new Node(20); - root->right=new Node(30); - root->left->left=new Node(40); - root->left->right=new Node(50); - root->right->left=new Node(60); - root->right->right=new Node(70); + int value; + // std::cout << "Enter value for root node: "; + std::cin >> value; + Node* root = new Node(value); + + // std::cout << "Enter value for left child of root node (or -1 if none): "; + std::cin >> value; + if (value != -1) + root->left = new Node(value); + + // std::cout << "Enter value for right child of root node (or -1 if none): "; + std::cin >> value; + if (value != -1) + root->right = new Node(value); + + // std::cout << "Enter value for left child of left child of root node (or -1 if none): "; + std::cin >> value; + if (value != -1 && root->left != nullptr) + root->left->left = new Node(value); + + // std::cout << "Enter value for right child of left child of root node (or -1 if none): "; + std::cin >> value; + if (value != -1 && root->left != nullptr) + root->left->right = new Node(value); + + // std::cout << "Enter value for left child of right child of root node (or -1 if none): "; + std::cin >> value; + if (value != -1 && root->right != nullptr) + root->right->left = new Node(value); + + // std::cout << "Enter value for right child of right child of root node (or -1 if none): "; + std::cin >> value; + if (value != -1 && root->right != nullptr) + root->right->right = new Node(value); + // Displaying the binary tree in inorder traversal inorder(root); // Inorder traversal of the tree @@ -248,24 +295,62 @@ public class BinaryTree { public static void main(String[] args) { - // Creating a binary tree with root node having data 10 - TreeNode root = new TreeNode(10); + Scanner scanner = new Scanner(System.in); + + // Input for the value of the root node + // System.out.print("Enter value for root node: "); + int rootValue = scanner.nextInt(); + TreeNode root = new TreeNode(rootValue); + + // Input for the left child of the root node + // System.out.print("Enter value for left child of root node (or -1 if none): "); + int leftChildValue = scanner.nextInt(); + if (leftChildValue != -1) + root.left = new TreeNode(leftChildValue); + + // Input for the right child of the root node + // System.out.print("Enter value for right child of root node (or -1 if none): "); + int rightChildValue = scanner.nextInt(); + if (rightChildValue != -1) + root.right = new TreeNode(rightChildValue); + + // Input for the left child of the left child of the root node + if (root.left != null) { + // System.out.print("Enter value for left child of left child of root node (or -1 if none): "); + int leftLeftChildValue = scanner.nextInt(); + if (leftLeftChildValue != -1) + root.left.left = new TreeNode(leftLeftChildValue); + } - // Adding nodes to the root of the created binary tree - // Adding left and right child nodes to the root - root.left = new TreeNode(20); - root.right = new TreeNode(30); + // Input for the right child of the left child of the root node + if (root.left != null) { + // System.out.print("Enter value for right child of left child of root node (or -1 if none): "); + int leftRightChildValue = scanner.nextInt(); + if (leftRightChildValue != -1) + root.left.right = new TreeNode(leftRightChildValue); + } - // Adding left and right child nodes to the left child of the root - root.left.left = new TreeNode(40); - root.left.right = new TreeNode(50); + // Input for the left child of the right child of the root node + if (root.right != null) { + // System.out.print("Enter value for left child of right child of root node (or -1 if none): "); + int rightLeftChildValue = scanner.nextInt(); + if (rightLeftChildValue != -1) + root.right.left = new TreeNode(rightLeftChildValue); + } - // Adding left and right child nodes to the right child of the root - root.right.left = new TreeNode(60); - root.right.right = new TreeNode(70); + // Input for the right child of the right child of the root node + if (root.right != null) { + // System.out.print("Enter value for right child of right child of root node (or -1 if none): "); + int rightRightChildValue = scanner.nextInt(); + if (rightRightChildValue != -1) + root.right.right = new TreeNode(rightRightChildValue); + } + + // Close the scanner + scanner.close(); // Printing the message before performing inorder traversal - System.out.print("Inorder Traversal: "); + // System.out.print("Inorder Traversal: "); // Calling the inorderTraversal method to perform inorder traversal inorderTraversal(root); @@ -369,5 +454,91 @@ Binary trees and inorder traversal have applications in various domains, includi - **Expression Trees:** In compilers, expression trees are used to represent mathematical expressions for efficient evaluation. - **File Systems:** File systems often use tree structures to organize and locate files efficiently. +## Test Cases: + +- Input: + Values of Nodes: + The user inputs the values of each node in the binary tree. If a node does not have a left or right child, the user enters -1. + + For example, let's consider the following input: + 1 + 2 + 3 + 4 + -1 + 5 + -1 + -1 + 6 + + Output: + The output will be the inorder traversal of the constructed binary tree. + For the provided input, the output would be: + 4 2 1 5 3 6 + + Explanation: + Input Interpretation: + - The user inputs the value of the root node, which is 1. + - Then, the user inputs the values of the left and right children of the root node, which are 2 and 3, respectively. + - Further, the user inputs the values of the left child's left child, which is 4. + - Then, the user inputs the value of the left child's right child, which is -1, indicating that there is no right child for node 2. + - Similarly, the user inputs the value of the right child's left child, which is 5, and then inputs -1 for the right child's right child. + - Finally, the user inputs the value of the right child's right child, which is 6. + + Binary Tree Construction: + - Based on the input provided, the binary tree is constructed as follows: +markdown + 1 + / \ + 2 3 + / \ + 4 6 + \ + 5 + + Inorder Traversal: + - The inorder traversal of the constructed binary tree is performed recursively. + - The values are printed in non-decreasing order as 4 2 1 5 3 6, which represents the inorder traversal path from the root node. + +- Input: + Values of Nodes: + The user inputs the values of each node in the binary tree. If a node does not have a left or right child, the user enters -1. + For example, let's consider the following input: + 10 + 20 + 30 + 40 + -1 + 50 + -1 + -1 + 60 + Output: + The output will be the inorder traversal of the constructed binary tree. + For the provided input, the output would be: + 40 20 50 10 30 60 + + Explanation: + Input Interpretation: + - The user inputs the value of the root node, which is 10. + - Then, the user inputs the values of the left and right children of the root node, which are 20 and 30, respectively. + - Further, the user inputs the values of the left child's left child, which is 40. + - Then, the user inputs the value of the left child's right child, which is -1, indicating that there is no right child for node 20. + - Similarly, the user inputs the value of the right child's left child, which is 50, and then inputs -1 for the right child's right child. + - Finally, the user inputs the value of the right child's right child, which is 60. + + Binary Tree Construction: + - Based on the input provided, the binary tree is constructed as follows: + 10 + / \ + 20 30 + / / + 40 50 + \ + 60 + Inorder Traversal: + - The inorder traversal of the constructed binary tree is performed recursively. + - The values are printed in non-decreasing order as 40 20 50 10 30 60, which represents the inorder traversal path from the root node. + ## Conclusion -Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations. \ No newline at end of file +Understanding trees and traversal algorithms, such as inorder traversal, is crucial in computer science. These codes provide a practical example of how to implement and apply inorder traversal in different languages like Python ,C++ and Java. The recursive nature of the traversal allows for elegant and concise code, making it a powerful tool for tree-related operations.