Merge branch 'main' of https://github.com/MakeContributions/DSA into added-new-algorithm
commit
3fe14144fb
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
Algorithm:
|
||||
(i) Traverse the list and push all of its nodes onto a stack.
|
||||
(ii) Traverse the list from the head node again and pop a value
|
||||
from the stack top and connect them in reverse order.
|
||||
|
||||
|
||||
TIME COMPLEXITY: O(n), as we are traversing over the linked list of size N using a while loop.
|
||||
SPACE COMPLEXITY: o(n), as we are using stack of size N in worst case which is extra space.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <stack>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Node {
|
||||
public:
|
||||
int data;
|
||||
Node *next;
|
||||
};
|
||||
Node *head;
|
||||
|
||||
void Print(Node* n);
|
||||
void RevList();
|
||||
|
||||
int main() {
|
||||
head = NULL;
|
||||
|
||||
Node *first = new Node;
|
||||
Node *second = new Node;
|
||||
Node *third = new Node;
|
||||
Node *fourth = new Node;
|
||||
Node *fifth = new Node;
|
||||
Node *sixth = new Node;
|
||||
Node *seventh = new Node;
|
||||
|
||||
head = first;
|
||||
|
||||
first->data = 10;
|
||||
first->next = second;
|
||||
|
||||
second->data = 20;
|
||||
second->next = third;
|
||||
|
||||
third->data = 30;
|
||||
third->next = fourth;
|
||||
|
||||
fourth->data = 40;
|
||||
fourth->next = fifth;
|
||||
|
||||
fifth->data = 50;
|
||||
fifth->next = sixth;
|
||||
|
||||
sixth->data = 60;
|
||||
sixth->next = seventh;
|
||||
|
||||
seventh->data = 70;
|
||||
seventh->next = NULL;
|
||||
|
||||
Print(head);
|
||||
|
||||
RevList();
|
||||
cout<<endl;
|
||||
Print(head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Print(Node* n){
|
||||
if(n==NULL){
|
||||
return;
|
||||
}
|
||||
cout<<n->data<<" ";
|
||||
Print(n->next);
|
||||
}
|
||||
void RevList() {
|
||||
if(head == NULL) return;
|
||||
stack<Node *> st;
|
||||
Node * temp = head;
|
||||
while(temp!= NULL){
|
||||
st.push(temp);
|
||||
temp = temp->next;
|
||||
}
|
||||
temp = st.top();
|
||||
head = temp;
|
||||
st.pop();
|
||||
|
||||
while(!st.empty()) {
|
||||
temp->next = st.top();
|
||||
temp = temp->next;
|
||||
st.pop();
|
||||
}
|
||||
temp->next = NULL;
|
||||
}
|
|
@ -78,7 +78,7 @@
|
|||
- [Find Merge Point of two singly linked list](Linked-Lists/Find-Merge-Point.cpp)
|
||||
- [Segregate Even Odd Nodes of linked list](Linked-Lists/segregate-even-odd-nodes-of-linked-list.cpp)
|
||||
- [Remove Duplicate in Sorted linked list](Linked-Lists/remove-duplicates-in-sorted-linked-list.cpp)
|
||||
|
||||
- [Reverse the linked list using stack](Linked-Lists/reverse-the-list-using-stack.cpp)
|
||||
## Searching
|
||||
|
||||
- [Linear Search](Searching/linear-search.cpp)
|
||||
|
@ -99,6 +99,7 @@
|
|||
- [Infix to postfix expression conversion](Stacks/infix-to-postfix.cpp)
|
||||
- [Stock Span Problem using Stacks](Stacks/stock-span-problem.cpp)
|
||||
- [Prefix to Postfix expression conversion](Stacks/prefix_to_postfix.cpp)
|
||||
- [Redundant Parenthesis](Stacks/redundant-parenthesis.cpp)
|
||||
|
||||
## Sorting
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
// RedundantParenthesis
|
||||
// Given a string of balanced expression, find if it contains a redundant parenthesis or not. A set of parenthesis are redundant if the same sub-expression is surrounded by unnecessary or multiple brackets. Print True if redundant, else False.
|
||||
|
||||
// Algorithm
|
||||
// 1. We iterate through the given expression and for each character in the expression, if the character is an open parenthesis ‘(‘ or any operators, we push it to the stack.
|
||||
// 2. If the character is close parenthesis ‘)’, then pop characters from the stack till matching open parenthesis ‘(‘ is found.
|
||||
// For any sub-expression of expression, if we are able to pick any sub-expression of expression surrounded by (), then we again left with () as part of string, we have redundant braces.
|
||||
// We iterate through the given expression and for each character in the expression, if the character is an open parenthesis ‘(‘ or any of the operators or operands, we push it to the stack. If the character is close parenthesis ‘)’, then pop characters from the stack till matching open parenthesis ‘(‘ is found.
|
||||
// Now for redundancy two condition will arise while popping-
|
||||
// 1. If immediate pop hits an open parenthesis ‘(‘, then we have found a duplicate parenthesis. For example, (((a+b))+c) has duplicate brackets around a+b. When we reach the second “)” after a+b, we have “((” in the stack. Since the top of stack is an opening bracket, we conclude that there are duplicate brackets.
|
||||
// 2. If immediate pop doesn’t hit any operand(‘*’, ‘+’, ‘/’, ‘-‘) then it indicates the presence of unwanted brackets surrounded by expression. For instance, (a)+b contain unwanted () around a thus it is redundant.
|
||||
|
||||
|
||||
|
||||
// solution
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "Enter the string:" << endl;
|
||||
string s;
|
||||
cin >> s;
|
||||
// create a stack of characters
|
||||
stack<char> st;
|
||||
bool ans = false;
|
||||
|
||||
// Iterate through the given expression
|
||||
for (int i = 0; i < s.size(); i++)
|
||||
{
|
||||
if (s[i] == '+' or s[i] == '-' or s[i] == '*' or s[i] == '/')
|
||||
{
|
||||
st.push(s[i]);
|
||||
}
|
||||
else if (s[i] == '(')
|
||||
{
|
||||
// if current character is close parenthesis '('
|
||||
st.push(s[i]);
|
||||
}
|
||||
else if (s[i] == ')')
|
||||
{
|
||||
// if current character is close parenthesis ')'
|
||||
if (st.top() == '(')
|
||||
{
|
||||
ans = true;
|
||||
}
|
||||
while (st.top() == '+' or st.top() == '-' or st.top() == '*' or st.top() == '/')
|
||||
{
|
||||
st.pop();
|
||||
}
|
||||
st.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (ans)
|
||||
{
|
||||
cout << "True";
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "False";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Input :
|
||||
// For example:
|
||||
// 1. ((a+b))
|
||||
// 2. (a+b*(c-d))
|
||||
|
||||
// Output:
|
||||
// 1. True, ((a+b)) can reduced to (a+b), this is Redundant
|
||||
// 2. False, (a+b*(c-d)) doesn't have any redundant or multiple
|
||||
// brackets
|
|
@ -0,0 +1,178 @@
|
|||
import java.util.*;
|
||||
|
||||
/*
|
||||
Problem Name - Permutation Sequence
|
||||
|
||||
Description
|
||||
The set [1, 2, 3, ..., n] contains a total of n! unique permutations.
|
||||
|
||||
By listing and labeling all of the permutations in order, we get the following sequence for n = 3:
|
||||
|
||||
1. "123"
|
||||
2. "132"
|
||||
3. "213"
|
||||
4. "231"
|
||||
5. "312"
|
||||
6. "321"
|
||||
Given n and k, return the kth permutation sequence.
|
||||
|
||||
Sample Cases:
|
||||
Example 1:
|
||||
Input: n = 3, k = 3
|
||||
Output: "213"
|
||||
|
||||
Example 2:
|
||||
Input: n = 4, k = 9
|
||||
Output: "2314"
|
||||
|
||||
Example 3:
|
||||
Input: n = 3, k = 1
|
||||
// Output: "123"
|
||||
|
||||
Constraints:
|
||||
|
||||
1 <= n <= 9
|
||||
1 <= k <= n!
|
||||
|
||||
You can also practice this question on LeetCode(https://leetcode.com/problems/permutation-sequence/)*/
|
||||
|
||||
|
||||
/***Brute Force is to form an array of n size and then compute all the permutations and store it in the list and then trace it with (k-1)**
|
||||
**Caution : the permutations should be in sorted order to get the answer**
|
||||
*This will give TLE as we have to calculate all the permutations*
|
||||
```
|
||||
class Solution {
|
||||
public String getPermutation(int n, int k) {
|
||||
int ar[] = new int[n];
|
||||
|
||||
for(int x=1;x<=n;x++)
|
||||
ar[x-1]=x;
|
||||
List<List<Integer>> ans=new ArrayList<>();
|
||||
backtrack(ans,new ArrayList<>(),ar);
|
||||
String s="";
|
||||
for(int x:ans.get(k-1))
|
||||
s+=x;
|
||||
|
||||
return s;
|
||||
}
|
||||
public void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){
|
||||
if(tempList.size() == nums.length){
|
||||
list.add(new ArrayList<>(tempList));
|
||||
} else{
|
||||
for(int i = 0; i < nums.length; i++){
|
||||
if(tempList.contains(nums[i])) continue; // element already exists, skip
|
||||
tempList.add(nums[i]);
|
||||
backtrack(list, tempList, nums);
|
||||
tempList.remove(tempList.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
**Best Approach**
|
||||
I'm sure somewhere can be simplified so it'd be nice if anyone can let me know. The pattern was that:
|
||||
|
||||
say n = 4, you have {1, 2, 3, 4}
|
||||
|
||||
If you were to list out all the permutations you have
|
||||
|
||||
1 + (permutations of 2, 3, 4)
|
||||
|
||||
2 + (permutations of 1, 3, 4)
|
||||
|
||||
3 + (permutations of 1, 2, 4)
|
||||
|
||||
4 + (permutations of 1, 2, 3)
|
||||
|
||||
|
||||
We know how to calculate the number of permutations of n numbers... n! So each of those with permutations of 3 numbers means there are 6 possible permutations. Meaning there would be a total of 24 permutations in this particular one. So if you were to look for the (k = 14) 14th permutation, it would be in the
|
||||
|
||||
3 + (permutations of 1, 2, 4) subset.
|
||||
|
||||
To programmatically get that, you take k = 13 (subtract 1 because of things always starting at 0) and divide that by the 6 we got from the factorial, which would give you the index of the number you want. In the array {1, 2, 3, 4}, k/(n-1)! = 13/(4-1)! = 13/3! = 13/6 = 2. The array {1, 2, 3, 4} has a value of 3 at index 2. So the first number is a 3.
|
||||
|
||||
Then the problem repeats with less numbers.
|
||||
|
||||
The permutations of {1, 2, 4} would be:
|
||||
|
||||
1 + (permutations of 2, 4)
|
||||
|
||||
2 + (permutations of 1, 4)
|
||||
|
||||
4 + (permutations of 1, 2)
|
||||
|
||||
But our k is no longer the 14th, because in the previous step, we've already eliminated the 12 4-number permutations starting with 1 and 2. So you subtract 12 from k.. which gives you 1. Programmatically that would be...
|
||||
|
||||
k = k - (index from previous) * (n-1)! = k - 2*(n-1)! = 13 - 2*(3)! = 1
|
||||
|
||||
In this second step, permutations of 2 numbers has only 2 possibilities, meaning each of the three permutations listed above a has two possibilities, giving a total of 6. We're looking for the first one, so that would be in the 1 + (permutations of 2, 4) subset.
|
||||
|
||||
Meaning: index to get number from is k / (n - 2)! = 1 / (4-2)! = 1 / 2! = 0.. from {1, 2, 4}, index 0 is 1
|
||||
|
||||
|
||||
so the numbers we have so far is 3, 1... and then repeating without explanations.
|
||||
|
||||
|
||||
{2, 4}
|
||||
|
||||
k = k - (index from previous) * (n-2)! = k - 0 * (n - 2)! = 1 - 0 = 1;
|
||||
|
||||
third number's index = k / (n - 3)! = 1 / (4-3)! = 1/ 1! = 1... from {2, 4}, index 1 has 4
|
||||
|
||||
Third number is 4
|
||||
|
||||
|
||||
{2}
|
||||
|
||||
k = k - (index from previous) * (n - 3)! = k - 1 * (4 - 3)! = 1 - 1 = 0;
|
||||
|
||||
third number's index = k / (n - 4)! = 0 / (4-4)! = 0/ 1 = 0... from {2}, index 0 has 2
|
||||
|
||||
Fourth number is 2
|
||||
|
||||
|
||||
Giving us 3142. If you manually list out the permutations using DFS method, it would be 3142. Done! It really was all about pattern finding.
|
||||
*/
|
||||
|
||||
public class permutation_sequence {
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n = sc.nextInt();
|
||||
int k = sc.nextInt();
|
||||
|
||||
System.out.println(getPermutation(n, k));
|
||||
}
|
||||
|
||||
public static String getPermutation(int n, int k) {
|
||||
List<Integer> numbers = new ArrayList<>();
|
||||
StringBuilder s = new StringBuilder();
|
||||
// create an array of factorial lookup
|
||||
|
||||
int fact[] = new int[n+1];
|
||||
fact[0] = 1;
|
||||
for(int x=1;x<=n;x++)
|
||||
fact[x]=fact[x-1]*x;
|
||||
// factorial[] = {1, 1, 2, 6, 24, ... n!}
|
||||
|
||||
// create a list of numbers to get indices
|
||||
for(int x = 1 ;x <= n ;x++)
|
||||
numbers.add(x);
|
||||
|
||||
k--;
|
||||
// numbers = {1, 2, 3, 4}
|
||||
|
||||
for(int x = 1 ;x <= n ;x++ ){
|
||||
int i=k/fact[n-x];
|
||||
s.append(String.valueOf(numbers.get(i)));
|
||||
numbers.remove(i);
|
||||
k-=i*fact[n-x];
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
- [Random Node in Linked List](Maths/algorithms_random_node.java)
|
||||
- [Square Root using BinarySearch](Maths/square-root.java)
|
||||
- [Roman Numerals Conversion](Maths/roman-numerals.java)
|
||||
- [Permutation Sequence](Maths/permutation_sequence.java)
|
||||
|
||||
## Queues
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@
|
|||
- [Max Heap](src/heaps/max-heap.js)
|
||||
- [Min Heap](src/heaps/min-heap.js)
|
||||
|
||||
## Graphs
|
||||
|
||||
- [Breadth First Search](src/graph/breadth-first-search.js)
|
||||
- [Depth First Search](src/graph/depth-first-search.js)
|
||||
|
||||
## Trie
|
||||
|
||||
- [Trie Implementation](src/trie/trie-implementation.js)
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
// Program to print BFS traversal from a given source vertex s.
|
||||
// breadthFirstSearch(graph, source) traverses vertices reachable from source.
|
||||
// for the implementation we need the queue data structure;
|
||||
|
||||
// Queue class
|
||||
class Queue {
|
||||
// Array is used to implement a Queue
|
||||
constructor() {
|
||||
this.items = [];
|
||||
}
|
||||
|
||||
// enqueue function
|
||||
enqueue(element) {
|
||||
// adding element to the queue
|
||||
this.items.push(element);
|
||||
}
|
||||
// dequeue function
|
||||
// removing element from the queue
|
||||
// returns underflow when called
|
||||
// on empty queue
|
||||
dequeue() {
|
||||
if (this.isEmpty()) {
|
||||
return 'Underflow';
|
||||
}
|
||||
return this.items.shift();
|
||||
}
|
||||
// isEmpty function
|
||||
isEmpty() {
|
||||
// return true if the queue is empty.
|
||||
return this.items.length == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Graph {
|
||||
// defining vertex array and
|
||||
// adjacent list
|
||||
constructor(noOfVertices) {
|
||||
this.noOfVertices = noOfVertices;
|
||||
this.AdjList = new Map();
|
||||
}
|
||||
// add the requeired vertex in the graph
|
||||
addVertex(v) {
|
||||
this.AdjList.set(v, []);
|
||||
}
|
||||
// addition of edges in the graph as the added edge are bidirectional
|
||||
addEdge(v, w) {
|
||||
this.AdjList.get(v).push(w);
|
||||
this.AdjList.get(w).push(v);
|
||||
}
|
||||
}
|
||||
const breadthFirstSearch = (g, source) => {
|
||||
const visited = {};
|
||||
const q = new Queue();
|
||||
visited[source] = true;
|
||||
q.enqueue(source);
|
||||
|
||||
while (!q.isEmpty()) {
|
||||
// Dequeue a vertex from queue and print it
|
||||
const getQueueElement = q.dequeue();
|
||||
console.log(getQueueElement);
|
||||
const getList = g.AdjList.get(getQueueElement);
|
||||
// Get all adjacent vertices of the dequeued
|
||||
// vertex s. If a adjacent has not been visited,
|
||||
// then mark it visited and enqueue it
|
||||
for (let i = 0; i < getList.length; i++) {
|
||||
const neigh = getList[i];
|
||||
if (!visited[neigh]) {
|
||||
visited[neigh] = true;
|
||||
q.enqueue(neigh);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const g = new Graph(6);
|
||||
// adding vertices
|
||||
for (let i = 1; i <= 6; i++) {
|
||||
g.addVertex(i);
|
||||
}
|
||||
g.addEdge(1, 2);
|
||||
g.addEdge(2, 4);
|
||||
g.addEdge(3, 1);
|
||||
g.addEdge(1, 4);
|
||||
g.addEdge(5, 3);
|
||||
g.addEdge(6, 3);
|
||||
|
||||
breadthFirstSearch(g, 6);
|
||||
// when we start bfs for the given graph from point 6 the output is as follow;
|
||||
// output 6 3 1 5 2 4
|
||||
|
||||
// Time complexity: O(n), where n is the number of vertices in graph
|
||||
// Space complexity: O(n), where n is the number of vertices in graph
|
|
@ -0,0 +1,56 @@
|
|||
class Graph {
|
||||
// defining vertex array and
|
||||
// adjacent list
|
||||
constructor(noOfVertices) {
|
||||
this.noOfVertices = noOfVertices;
|
||||
this.AdjList = new Map();
|
||||
}
|
||||
// add the requeired vertex in the graph
|
||||
addVertex(v) {
|
||||
this.AdjList.set(v, []);
|
||||
}
|
||||
// addition of edges in the graph as the added edge are bidirectional
|
||||
addEdge(v, w) {
|
||||
this.AdjList.get(v).push(w);
|
||||
this.AdjList.get(w).push(v);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive function which process and explore
|
||||
// all the adjacent vertex of the vertex with which it is called
|
||||
|
||||
const depthFirstSearch = (g, currVertex, visited) => {
|
||||
visited[currVertex] = true;
|
||||
console.log(currVertex);
|
||||
|
||||
const getNeighbours = g.AdjList.get(currVertex);
|
||||
// Recursive call for the non visited vertex
|
||||
for (let i = 0; i < getNeighbours.length; i++) {
|
||||
const getElement = getNeighbours[i];
|
||||
if (!visited[getElement]) {
|
||||
depthFirstSearch(g, getElement, visited);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const g = new Graph(6);
|
||||
const visited = {};
|
||||
// adding vertices
|
||||
for (let i = 1; i <= 6; i++) {
|
||||
g.addVertex(i);
|
||||
}
|
||||
g.addEdge(1, 2);
|
||||
g.addEdge(2, 4);
|
||||
g.addEdge(3, 1);
|
||||
g.addEdge(1, 4);
|
||||
g.addEdge(5, 3);
|
||||
g.addEdge(6, 3);
|
||||
|
||||
depthFirstSearch(g, 6, visited);
|
||||
// for the given graph when we explore it from vertex 6 the output is as follow;
|
||||
// output 6 3 1 2 4 5
|
||||
|
||||
// TIME COMPLEXITY OF THE PROGRAM
|
||||
// O(V+E)
|
||||
// where V is number of vertices
|
||||
// and E is number of edges
|
|
@ -33,3 +33,7 @@ require('./stacks/two-stack');
|
|||
|
||||
// Queue
|
||||
require('./queues/queue');
|
||||
|
||||
//Graphs
|
||||
require('./graph/breadth-first-search');
|
||||
require('./graph/depth-first-search');
|
||||
|
|
Loading…
Reference in New Issue