From f1debdc7c31b4663b9a0a50f90cd40d59c5f9ff0 Mon Sep 17 00:00:00 2001 From: nohno23 <107597229+nohno23@users.noreply.github.com> Date: Sun, 3 Jul 2022 18:29:41 -0700 Subject: [PATCH 01/63] docs(ja): add insertion sort (#771) Co-authored-by: My Name --- docs/ja/README.md | 1 + docs/ja/Sorting/Insertion-Sort.md | 66 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 docs/ja/Sorting/Insertion-Sort.md diff --git a/docs/ja/README.md b/docs/ja/README.md index 61480037..27455842 100644 --- a/docs/ja/README.md +++ b/docs/ja/README.md @@ -3,6 +3,7 @@ ## ソート - [バブルソート](./Sorting/Bubble-Sort.md) +- [挿入ソート](./Sorting/Insertion-Sort.md) ## 文字列 - [回文](./Strings/Palindrome.md) diff --git a/docs/ja/Sorting/Insertion-Sort.md b/docs/ja/Sorting/Insertion-Sort.md new file mode 100644 index 00000000..91eca30a --- /dev/null +++ b/docs/ja/Sorting/Insertion-Sort.md @@ -0,0 +1,66 @@ +# 挿入ソート  + +基本挿入法とも呼ばれる挿入ソートは、シンプルで実装が容易であり、最も安定しているソートアルゴリズムである。数値が正しい場所にない場合に、その数値を正しい位置に挿入する。平均、最悪計算量は共にO(n^2)である。 + +挿入ソートを高速化したものとしてシェルソートがある。 + +## ステップ + +1. 0番目の要素と1番目の要素を比較する。 +2. 0番目の要素が1番目の要素より大きい場合、要素を入れ替える。 +3. 2番目の要素と1つ前の要素を比較する。 +4. 2番目の要素が1つ前の要素より大きい場合、要素を入れ替える。 +5. 2番目の要素が正しい位置に来るまで2.と4.を実行する。 +6. ソートが完了するまで3.から5.を何度も繰り返す。 + +## 例 + +初期配列 +**1 4 3 9 5** + +ソート後配列 +**1 3 4 5 9** + +ステップ +**1回目** + +- ( **1 4** 3 9 5 ) → ( **1 4** 3 9 5 ), ここでアルゴリズムは最初の2つの要素を比較し、順番通りのため(4 > 1), アルゴリズムは入れ替えをしない。 + +**2回目** + +- ( 1 **4 3** 9 5 ) → ( 1 **3 4** 9 5 ), 4 > 3なので入れ替える。 +- ( **1 3** 4 9 5 ) → ( **1 3** 4 9 5 ) + +ここで選択した要素が1つ前の要素よりも大きいため、アルゴリズムは選択した要素の次の要素に移る。(この配列の場合は3の次である4) + +**3回目** +- ( 1 **3 4** 9 5 ) → ( 1 **3 4** 9 5 ) + +**4回目** +- ( 1 3 **4 9** 5 ) → ( 1 3 **4 9** 5 ) + +**5回目** +- ( 1 3 4 **9 5** ) → ( 1 3 4 **5 9** ) +- ( 1 3 **4 5** 9) → ( 1 3 **4 5** 9 ) + +さて、この時点で配列はすでにソートされたが、まだ配列の最後の要素にたどり着いていない。アルゴリズムは配列の最後の要素を選択するまで続く。 + +**6回目** +- ( 1 3 4 **5 9** ) → ( 1 3 4 **5 9** ) + +## 実装 + +- [C](../../../algorithms/C/sorting/insertion-sort.c) +- [C++](../../../algorithms/CPlusPlus/Sorting/insertion-sort.cpp) +- [CSharp](../../../algorithms/CSharp/src/Sorts/insertion-sort.cs) +- [Go](../../../algorithms/Go/sorting/insertion-sort.go) +- [Java](../../../algorithms/Java/sorting/insertion-sort.java) +- [JavaScript](../../../algorithms/JavaScript/src/sorting/insertion-sort.js) + +## 動画のURL + +[Youtube Video about Insertion Sort](https://www.youtube.com/watch?v=i-SKeOcBwko) + +## その他 + +[Wikipedia](https://en.wikipedia.org/wiki/Insertion_sort) From c780f5a641f45fe0d9d62af670399852c20e8bbd Mon Sep 17 00:00:00 2001 From: Anika Kamath <87904385+anika-kamath@users.noreply.github.com> Date: Sat, 9 Jul 2022 21:01:28 +0530 Subject: [PATCH 02/63] chore(Python): add sum of n numbers using recursion (#770) --- algorithms/Python/README.md | 1 + recursive-sum-of-n-numbers.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 recursive-sum-of-n-numbers.py diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index bc9438e9..f3fb531a 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -25,6 +25,7 @@ - [Factorial](recursion/factorial.py) - [n-th Fibonacci number](recursion/nth_fibonacci_number.py) - [Recursive Insertion Sort](recursion/recursive_insertion_sort.py) +- [Recursive Sum of n numbers](recursion/recursive-sum-of-n-numbers.py) ## Scheduling - [Interval Scheduling](scheduling/interval_scheduling.py) diff --git a/recursive-sum-of-n-numbers.py b/recursive-sum-of-n-numbers.py new file mode 100644 index 00000000..9e7014ac --- /dev/null +++ b/recursive-sum-of-n-numbers.py @@ -0,0 +1,12 @@ +def recsum(n): + if n<=1: + return(n) + else: + return(n+recsum(n-1)) + +n= 15 + +if n<0: + print("Enter a positive integer") +else: + print("Sum =",recsum(n)) From 4add09632e39386c1ca4637a41e4259a4223fd87 Mon Sep 17 00:00:00 2001 From: PrathameshSahasrabuddhe <77877305+PrathameshSahasrabuddhe@users.noreply.github.com> Date: Fri, 15 Jul 2022 18:16:44 +0530 Subject: [PATCH 03/63] chore(Python): add depth first search (#775) * Added depth first search algorithm in Python and updated README.md * Added output example in Depth First Search algorithm * bug fixes * Fixed spelling mistake on line 1 (alorithm-> algorithm) * Moved the file from recursion folder to graphs folder and updated README.md Co-authored-by: Prathamesh Sahasrabuddhe --- algorithms/Python/README.md | 2 + .../Python/graphs/depth-first-search.py | 62 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 algorithms/Python/graphs/depth-first-search.py diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index f3fb531a..b73323e6 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -27,6 +27,7 @@ - [Recursive Insertion Sort](recursion/recursive_insertion_sort.py) - [Recursive Sum of n numbers](recursion/recursive-sum-of-n-numbers.py) + ## Scheduling - [Interval Scheduling](scheduling/interval_scheduling.py) @@ -73,6 +74,7 @@ ## Graphs - [Simple Graph](graphs/graph.py) - [BFS SEQUENCE](graphs/bfs-sequence.py) +- [Depth First Search](graphs/depth-first-search.py) ## Trees - [Binary Tree](trees/binary_tree.py) diff --git a/algorithms/Python/graphs/depth-first-search.py b/algorithms/Python/graphs/depth-first-search.py new file mode 100644 index 00000000..97a80ee5 --- /dev/null +++ b/algorithms/Python/graphs/depth-first-search.py @@ -0,0 +1,62 @@ +# A dfs algorithm in Python +# This is an algorithm for traversing a graph in depth first search manner +# It is commonly used in tree/graph traversals +# Time Complexity: O(V+E) +# Space Complexity: O(V) +# V is number of vertices and E is number of edges + +""" +Refer the following example for output +Graph 1: https://cdn.programiz.com/sites/tutorial2program/files/graph-dfs-step-0.png +Graph 2: https://static.javatpoint.com/ds/images/depth-first-search-algorithm2.png + +""" + +def dfs(edges, vis, node): + if(vis[node]!=1): + vis[node] = 1 + print(node, end = " ") + + for i in edges[node]: + if(vis[i]!=1): + dfs(edges, vis, i) + + +def main(): + """ Main Function """ + + #First example + + graph1 = [] + graph1.append([1,2,3]) + graph1.append([0,2]) + graph1.append([0,1,4]) + graph1.append([0]) + graph1.append([2]) + + vis = [] + for i in range(0,10): + vis.append(0) + + print("DFS for Graph 1 is:") + dfs(graph1, vis, 0) + + #Making visited list elements 0 for second graph + for i in range(0,10): + vis[i] = 0 + + graph2 = [] + graph2.append([1, 2, 3]) + graph2.append([3]) + graph2.append([4]) + graph2.append([5, 6]) + graph2.append([5, 7]) + graph2.append([2]) + graph2.append([]) + graph2.append([]) + + print("\n\nDFS for Graph 2 is:") + dfs(graph2, vis, 0) + +if __name__=="__main__": + main() \ No newline at end of file From 7985059f7d7543d1afda33b38fdf631a36e8e889 Mon Sep 17 00:00:00 2001 From: Rakshit Gondwal <98955085+rakshitgondwal@users.noreply.github.com> Date: Wed, 20 Jul 2022 04:39:09 +0530 Subject: [PATCH 04/63] enh(CPlusPlus): add binary search (#777) Improved the code by adding the explanation of using (l + (r - l)) rather than using (l - r) while searching for the mid element. --- algorithms/CPlusPlus/Searching/binary-search.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/algorithms/CPlusPlus/Searching/binary-search.cpp b/algorithms/CPlusPlus/Searching/binary-search.cpp index 46cb09ee..0603d02e 100644 --- a/algorithms/CPlusPlus/Searching/binary-search.cpp +++ b/algorithms/CPlusPlus/Searching/binary-search.cpp @@ -7,6 +7,9 @@ int binarySearch(int arr[], int l, int r, int x) { if (r >= l) { int mid = l + (r - l) / 2; + //We use (l + (r - l)) rather than using (l - r) to avoid arithmetic overflow. + //Arithmetic overflow is the situation when the value of a variable increases + //beyond the maximum value of the memory location, and wraps around. // If the element is present at the middle itself if (arr[mid] == x) From bfcae851a0fadcc2197691cf5778ca331d5e5991 Mon Sep 17 00:00:00 2001 From: Rakshit Gondwal <98955085+rakshitgondwal@users.noreply.github.com> Date: Wed, 20 Jul 2022 04:41:47 +0530 Subject: [PATCH 05/63] enh(Java): add comments for binary search (#776) Improved the code by adding the explanation of using (l + (r - l)) rather than using (l - r) while searching for the mid element. --- algorithms/Java/searching/binary-search.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/algorithms/Java/searching/binary-search.java b/algorithms/Java/searching/binary-search.java index 519448af..db5442bf 100644 --- a/algorithms/Java/searching/binary-search.java +++ b/algorithms/Java/searching/binary-search.java @@ -5,7 +5,10 @@ class BinarySearch { int binarySearch(int arr[], int l, int r, int x) { if (r >= l) { - int mid = l + (r - l) / 2; + int mid = l + (r - l) / 2; + //We use (l + (r - l)) rather than using (l - r) to avoid arithmetic overflow. + //Arithmetic overflow is the situation when the value of a variable increases + //beyond the maximum value of the memory location, and wraps around. // If the element is present at the // middle itself From 5d703d8170834244a923f81bf2ad9ff37f96bb4d Mon Sep 17 00:00:00 2001 From: Rusu Emanuel <92999481+Emanuel181@users.noreply.github.com> Date: Tue, 2 Aug 2022 12:38:49 -0700 Subject: [PATCH 06/63] chore(C): add sieve-of-eratosthenes (#778) --- algorithms/C/README.md | 1 + algorithms/C/arrays/sieve-of-eratosthenes.c | 161 ++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 algorithms/C/arrays/sieve-of-eratosthenes.c diff --git a/algorithms/C/README.md b/algorithms/C/README.md index a1188256..0ca7c4c9 100644 --- a/algorithms/C/README.md +++ b/algorithms/C/README.md @@ -7,6 +7,7 @@ - [Reverse an array](arrays/reverse-array.c) - [Maximum difference](arrays/maximum-difference.c) - [Largest Element](arrays/largestElement.c) +- [Sieve of Eratosthenes](arrays/sieve-of-eratosthenes.c) ## Bit Manipulation diff --git a/algorithms/C/arrays/sieve-of-eratosthenes.c b/algorithms/C/arrays/sieve-of-eratosthenes.c new file mode 100644 index 00000000..52699b2c --- /dev/null +++ b/algorithms/C/arrays/sieve-of-eratosthenes.c @@ -0,0 +1,161 @@ +#include + +#define MAX 1000001 +int sieve[MAX]; + +/* + + Why do we use such a big number? Because we don't know how big the interval is, + we give as much freedom as possible; note that this number may not work for your + computer, and you will need to make it smaller, or if it works, you can make it bigger. + +*/ + + +/* + +[PROBLEM TO SOLVE]: Given a number "n", find all prime numbers till "n" inclusive. + + A prime number is a number which has only 2 divisors: 1 and itself. + +[EXAMPLE]: n = 22 + + -> The numbers are: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + + -> The prime numbers are: 2 3 5 7 11 13 17 19 + +[APPROACH]: Sieve Of Eratosthenes algorithm + +[IDEA]: + + -> We have to analyze numbers from 2 to n. So, firstly, we write them down: + + 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... n + + -> Next, we will do something which is called marking. To illustrate this, I will put "*" below the numbers. + + -> We begin from 2 till n, and for every number, we mark all its multiples till n inclusive. + + -> We are at 2, so we mark 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26 and all numbers 2 * k, with k > 1 and stop when 2 * k > n. + + 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... n + * * * * * * * * * * * * + + -> We move at 3 so we mark 6, 9, 12, 15, 18, 21, 24 and all numbers 3 * k, with k > 1 and stop when 3 * k > n. + + 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... n + * * * * * * * * * * * * * * * + + -> We continue this process by taking every number till n and marking all its multiples till n inclusive. + + -> By the end of this algorithm, the numbers that remained unmarked are only prime numbers. + +[TIME COMPLEXITY]: + + For every i till sqrt(n), we perform n / i operations, where i is prime. + + The ecuation is: + sqrt(n) * (n/3 + n/4 + n/5 + n/6 + n/7 + ...) + = sqrt(n) * n * (1/3 + 1/4 + 1/5 + 1/6 + 1/7 + ...) + The third factor, according to Euler, grows the same as ln(ln(n)) + + So the time complexity is: O(sqrt(n) * n * ln(ln(n))). + +[SPACE COMPLEXITY]: O(n) + +*/ + + +void sieve_of_eratosthenes(unsigned long long n) +{ + sieve[0] = sieve[1] = 1; // we know that 0 and 1 are already pries so we mark them + + for (unsigned long long i = 4; i <= n; i += 2) sieve[i] = 1; // We know that every even number greater than 2 is not prime. + // We can mark in advance these numbers by beginning from 4 and + // iterating from 2 to 2. + + for (unsigned long long i = 3; i * i <= n; i += 2) // it is enough to iterate till sqrt(n) + { + // marking numbers + for (unsigned long long j = i * i; j <= n; j += 2 * i) sieve[j] = 1; // We can begin from i * i because all numbers till i * i have been already marked + // We iterate with j += 2 * i to avoid even numbers marked before + } + + /* + In Sieve of Eratosthenes, we use a global array, and global variables are + automatically initialized with 0. So we use that to our advantage instead of + manually setting all memory spaces with 0. + + + We are doing marking like this: + 0 - prime + 1 - not prime + + + Why? I know that using 1 for primes and 0 for not primes would have been more + intuitive, but declaring an array in global scope, it got initialized with 0, so + it is just a waste to overwrite all memory spaces with 1. + + */ +} + + +// Utility function to print prime numbers +void print_prime_numbers(unsigned long long n) +{ + for (unsigned long long i = 2; i <= n; ++i) + { + if (sieve[i] == 0) printf("%llu ", i); // if number is not marked (it is a prime number) we print it + } +} + + +// Driver program +int main() +{ + unsigned long long n; printf("Enter number: "); scanf("%llu", &n); + sieve_of_eratosthenes(n); + + printf("\n\nPrime numbers are:\n"); + print_prime_numbers(n); + printf("\n"); +} + + +/* + + [SAMPLE INPUT 1]: + 22 + Output: 2 3 5 7 11 13 17 19 + + [SAMPLE INPUT 2]: + 46 + Output: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 + + [SAMPLE INPUT 3]: + 100 + Output: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 + +*/ + + +/* + +[OBSERVATIONS]: + + -> Note that I used unsigned long long for variables, and operations like raising to power can + easily exceed unsigned long long, so be careful with input numbers. + + -> You can play around with #define MAX 1000000001 and #define MAX_PRIMES 100000001. Try to find + which is the maximum limit accepted by your computer. + + -> To make this algorithm space-efficient, you can change to C++ and use a vector container from the STL library like + this [vector vector_name]. Before that, include vector library like #include . That + container is not a regular one. It is a memory-optimization of template classes like vector , + which uses only n/8 bytes of memory. Many modern processors work faster with bytes because they + can be accessed directly. Template class vector works directly with bits. But these things + require knowledge about template classes, which are very powerful in C++. + + -> This algorithm can be optimized using bits operations to achieve linear time. + But ln(ln(n)) can be approximated to O(1). +*/ \ No newline at end of file From 16a16eb67ed0e65fdb1c802f72b7024867c41c3b Mon Sep 17 00:00:00 2001 From: brugner Date: Wed, 10 Aug 2022 18:16:42 -0300 Subject: [PATCH 07/63] docs(Spanish): add quick sort (#793) Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> --- README.md | 18 +++++----- docs/es/CONTRIBUTING.md | 30 ++++++++++++++++ docs/es/Ordenamiento/Quick-Sort.md | 58 ++++++++++++++++++++++++++++++ docs/es/README.md | 9 +++++ 4 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 docs/es/CONTRIBUTING.md create mode 100644 docs/es/Ordenamiento/Quick-Sort.md create mode 100644 docs/es/README.md diff --git a/README.md b/README.md index a032d980..ecb02edb 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,9 @@ Data structure and Algorithm (DSA) ## Explanations + - [English](./docs/en) +- [Español](./docs/es) - [Português](./docs/pt) - [Turkish](./docs/tr) - [繁體中文](./docs/zh-tw) @@ -117,14 +119,14 @@ The programming should keep the naming convention rule of each programming langu ## Reviewers -| Programming Language | Users | -| -------------------- | ------------------------------------------------- | -| C or C++ | @Arsenic-ATG, @UG-SEP, @aayushjain7, @Ashborn-SM | -| Java | @TawfikYasser, @aayushjain7 | -| C# | @ming-tsai, @Waqar-107 | -| Go | | -| Python | @Arsenic-ATG, @sridhar-5 | -| JavaScript | @ming-tsai | +| Programming Language | Users | +| -------------------- | ------------------------------------------------ | +| C or C++ | @Arsenic-ATG, @UG-SEP, @aayushjain7, @Ashborn-SM | +| Java | @TawfikYasser, @aayushjain7 | +| C# | @ming-tsai, @Waqar-107 | +| Go | | +| Python | @Arsenic-ATG, @sridhar-5 | +| JavaScript | @ming-tsai | ## Contributors diff --git a/docs/es/CONTRIBUTING.md b/docs/es/CONTRIBUTING.md new file mode 100644 index 00000000..c6d3e0a2 --- /dev/null +++ b/docs/es/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Nombre del algoritmo + +Escribe una breve descripción del algoritmo como: + +1. Complejidad temporal +2. Complejidad espacial +3. Aplicaciones +4. Nombre del creador +5. etc... + +## Pasos + +Describe el algoritmo como pasos simples, claros y entendibles. + +## Ejemplo + +Provee al algoritmo de datos de entrada de muestra. + +## Implementación + +Enlaces a sus implementaciones en lenguajes de programación. +NOTA: El enlace debe estar solo dentro de la carpeta algorithms. + +## URL del video + +Adjunta una URL a un video que explique el algoritmo. + +## Otro + +Cualquier otra información es siempre bienvenida y debería ser incluida en esta sección. diff --git a/docs/es/Ordenamiento/Quick-Sort.md b/docs/es/Ordenamiento/Quick-Sort.md new file mode 100644 index 00000000..5b2330dc --- /dev/null +++ b/docs/es/Ordenamiento/Quick-Sort.md @@ -0,0 +1,58 @@ +# Quick Sort + +1. **Complejidad temporal:** O(n^2) ocurre cuando el pivote elegido es siempre un elemento extremo (el más pequeño o el más grande). +2. **Complejidad espacial:** O(n). +3. **Aplicaciones:** Computación comercial, búsqueda de información, investigación de operaciones, simulación dirigida por eventos, cómputos numéricos, búsqueda combinatoria. +4. **Nombre del creador:** Tony Hoare + +## Pasos + +1. Considera el último elemento de la lista como pivote. +2. Define dos variables i y j. Asigna i y j al primer y último elemento de la lista. +3. Incrementa i hasta que lista[i] > pivote y luego detente. +4. Disminuye j hasta que lista[j] < pivote y luego detente. +5. Si i < j, entonces intercambia lista[i] y lista[j]. +6. Repite los pasos 3, 4 y 5 hasta que i > j. +7. Intercambia el elemento pivote con el elemento lista[j]. + +## Ejemplo + +**Dado el vector: [10, 80, 30, 90, 40, 50, 70]** + +**Pivote (último elemento) : 70** + +**1. 10 < 70 entonces i++ e intercambia(lista[i], lista[j]):** [10, 80, 30, 90, 40, 50, 70] + +**2. 80 < 70, entonces no es necesario hacer nada:** [10, 80, 30, 90, 40, 50, 70] + +**3. 30 < 70 entonces i++ e intercambia(lista[i], lista[j]):** [10, 30, 80, 90, 40, 50, 70] + +**4. 90 < 70, entonces no es necesario hacer nada:** [10, 30, 80, 90, 40, 50, 70] + +**5. 40 < 70 entonces i++ e intercambia(lista[i], lista[j]):** [10, 30, 40, 90, 80, 50, 70] + +**6. 50 < 70 entonces i++ e intercambia(lista[i], lista[j]):** [10, 30, 40, 50, 80, 90, 70] + +**7. Intercambia lista[i+1] y el pivote:** [10, 30, 40, 50, 70, 90, 80] + +**8. Aplica Quick Sort a la parte izquierda del pivote:** [10, 30, 40, 50] + +**9. Aplica Quick Sort a la parte derecha del pivote:** [70, 80, 90] + +**10. Vector ordenado:** [10, 30, 40, 50, 70, 80, 90] + +## Implementación + +- [Java](../../../algorithms/Java/sorting/quick-sort.java) +- [JavaScript](../../../algorithms/JavaScript/src/sorting/quick-sort.js) +- [Go](../../../algorithms/Go/sorting/quicksort.go) +- [C++](../../../algorithms/CPlusPlus/Sorting/quick-sort.cpp) +- [Python](../../../algorithms/Python/sorting/quicksort.py) +- [C](../../../algorithms/C/sorting/quick-sort.c) +## URL del video + +[Video de Youtube sobre Quick Sort](https://www.youtube.com/watch?v=DYmTpUfcyT8) + +## Otro + +[Wikipedia](https://es.wikipedia.org/wiki/Quicksort) diff --git a/docs/es/README.md b/docs/es/README.md new file mode 100644 index 00000000..fcd7d5f8 --- /dev/null +++ b/docs/es/README.md @@ -0,0 +1,9 @@ +# Algoritmos + +## Ordenamiento + +- [Quick Sort](./Ordenamiento/Quick-Sort.md) + +## Otro + +[Cómo agregar nueva documentación a un algoritmo?](./CONTRIBUTING.md) From d253a29f960d879f5283721d896c038dee31d4fc Mon Sep 17 00:00:00 2001 From: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> Date: Wed, 10 Aug 2022 17:17:51 -0400 Subject: [PATCH 08/63] chore(codespell): ignore Spanish folder --- .github/workflows/codespell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 31967f78..745b104f 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -11,4 +11,4 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - run: pip install codespell - - run: codespell --ignore-words-list="ans,nnumber,nin,Hel" --quiet-level=2 --skip="**/**/package-lock.json,./docs/pt,./.github,./algorithms/CSharp/test" + - run: codespell --ignore-words-list="ans,nnumber,nin,Hel" --quiet-level=2 --skip="**/**/package-lock.json,./docs/pt,./docs/es,./.github,./algorithms/CSharp/test" From cef837425ce1f8c81c7329dbf6d0ecb8198f4078 Mon Sep 17 00:00:00 2001 From: Leong Teng Man <41246170+taimoon@users.noreply.github.com> Date: Thu, 11 Aug 2022 05:18:21 +0800 Subject: [PATCH 09/63] chore(C): add fibonacci algorithm (#794) --- algorithms/C/README.md | 1 + .../C/maths/fibonacci-number/.gitignore | 4 + algorithms/C/maths/fibonacci-number/Makefile | 4 + algorithms/C/maths/fibonacci-number/README.md | 59 ++++++++++++ algorithms/C/maths/fibonacci-number/src/fib.c | 92 +++++++++++++++++++ algorithms/C/maths/fibonacci-number/src/fib.h | 22 +++++ .../C/maths/fibonacci-number/src/main.c | 23 +++++ 7 files changed, 205 insertions(+) create mode 100644 algorithms/C/maths/fibonacci-number/.gitignore create mode 100644 algorithms/C/maths/fibonacci-number/Makefile create mode 100644 algorithms/C/maths/fibonacci-number/README.md create mode 100644 algorithms/C/maths/fibonacci-number/src/fib.c create mode 100644 algorithms/C/maths/fibonacci-number/src/fib.h create mode 100644 algorithms/C/maths/fibonacci-number/src/main.c diff --git a/algorithms/C/README.md b/algorithms/C/README.md index 0ca7c4c9..9e241b51 100644 --- a/algorithms/C/README.md +++ b/algorithms/C/README.md @@ -36,6 +36,7 @@ - [Palindrome Number](maths/palindrome.c) - [Fibonacci Series](maths/fibonacci-series.c) - [Odd or Even Number](maths/odd-or-even-number.c) +- [Fibonacci Number](maths/fibonacci-number/README.md) ## Queues diff --git a/algorithms/C/maths/fibonacci-number/.gitignore b/algorithms/C/maths/fibonacci-number/.gitignore new file mode 100644 index 00000000..2441f03a --- /dev/null +++ b/algorithms/C/maths/fibonacci-number/.gitignore @@ -0,0 +1,4 @@ +main +# binary files +*.o +*.exe \ No newline at end of file diff --git a/algorithms/C/maths/fibonacci-number/Makefile b/algorithms/C/maths/fibonacci-number/Makefile new file mode 100644 index 00000000..8214801c --- /dev/null +++ b/algorithms/C/maths/fibonacci-number/Makefile @@ -0,0 +1,4 @@ +run: main.c + .\a.exe +main.c: + gcc .\src\main.c .\src\fib.c -lm diff --git a/algorithms/C/maths/fibonacci-number/README.md b/algorithms/C/maths/fibonacci-number/README.md new file mode 100644 index 00000000..7d5101c1 --- /dev/null +++ b/algorithms/C/maths/fibonacci-number/README.md @@ -0,0 +1,59 @@ +# Fibonacci Number +Fibonacci numbers form a Fibonacci sequence where given any number (excluding first 2 terms) is a sum of its two preceding numbers. Usually, the sequence is either start with 0 and 1 or 1 and 1. Below is a Fibonacci sequnce starting from 0 and 1: + +$$ +0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, \dots +$$ + +The problem is to calculate the n-th term Fibonacci number given two starting numbers. + +## Prerequisites +- C compiler (or IDE) +- MAKE software (optional if you compile the source files manually) + + +## Instructions +- using makefile + ```bash + make # or mingw32-make + ``` +- compile using gcc + ``` + cd \fibonacci-number + gcc .\src\main.c + ``` +## Note +The sequence can be described by a recurrent function as below: + +$$ +\begin{align*} + F(0) &= 0 \\ + F(1) &= 1 \\ + F(n) &= F(n-1) + F(n-2) +\end{align*} +$$ + +- This provides a direct recursive implementation. The time complexity is $O(2^n)$. It can be improved through memomization. +- It can done iteratively using 2 more states variables. The time complexity is $O(n)$. +- There exists a clever logarithmic algorithm $O(\log{n})$ in computing n-th term Fibonacci number. The computations can be in form of matrix multiplication, then we can devise some form of Ancient Egyptian multiplication (i.e.: double and squaring) to improve the algorithm. [reference](https://rybczak.net/2015/11/01/calculation-of-fibonacci-numbers-in-logarithmic-number-of-steps/) +- Lastly, there also exist a formula to approximate n-term Fibonacci number $O(1)$. [reference](https://mathworld.wolfram.com/BinetsFibonacciNumberFormula.html) + +The given implementations shall assume that the Fibonacci sequence is starting from 0 and 1. The reader may try to generalize it to certain extent as a practice. + +## Test Cases & Output + +1. Example output of calling function: +``` +/* some code */ +printf("%d", iter_fib(7)); +printf("%d\n", memo_fib(7)); +/* some code */ +``` + +``` +13 +13 +``` +2. The code should yield the same output as other version. + +3. The sum of even Fibonacci numbers below 4000000 should be 4613732. [Adapted from Project Euler.net](https://projecteuler.net/problem=2) diff --git a/algorithms/C/maths/fibonacci-number/src/fib.c b/algorithms/C/maths/fibonacci-number/src/fib.c new file mode 100644 index 00000000..41196239 --- /dev/null +++ b/algorithms/C/maths/fibonacci-number/src/fib.c @@ -0,0 +1,92 @@ +#include"fib.h" +#include // sqrt, pow are used in binet_fib + +int recur_fib(int n){ + if(n == 0 || n == 1) + return n; + else + return recur_fib(n-1) + recur_fib(n-2); +} +int iter_fib(int n){ + if(n == 0 || n == 1) + return n; + int prev2 = 0; + int prev1 = 1; + int res = prev1 + prev2; + for(n = n - 2; n > 0; --n){ + prev2 = prev1; + prev1 = res; + res = prev1 + prev2; + } + return res; +} + +// it should be called before using the function memo_fib() +void memomizing_fib(){ + memomized_fib[0] = 0; + memomized_fib[1] = 1; + for(int i = 2; i < MAXSIZE; ++i) + memomized_fib[i] = memomized_fib[i-1]+memomized_fib[i-2]; +} + +// return memomized value if exists, or else compute it as usual +int memo_fib(int n){ + if(n < MAXSIZE && n >= 0) + return memomized_fib[n]; + else + return memo_fib(n-1) + memo_fib(n-2); +} +/** + * fibonacci based linear transformation (linear algebra) + * reference: https://rybczak.net/2015/11/01/calculation-of-fibonacci-numbers-in-logarithmic-number-of-steps/ +*/ +int iter_log_fib(int n){ + int a = 0; + int b = 1; + int p = 0; + int q = 1; + while(n > 0){ + if(n%2 == 0){ + int prev_p = p; + int prev_q = q; + p = prev_p*prev_p + prev_q*prev_q; + q = (2*prev_p + prev_q)*prev_q; + n = n/2; + } + else{ + int prev_a = a; + int prev_b = b; + --n; + a = p*prev_a + q*prev_b; + b = q*prev_a + (p+q)*prev_b; + } + } + return a; +} + +/** + * fibonacci based linear transformation (linear algebra) + * reference: https://rybczak.net/2015/11/01/calculation-of-fibonacci-numbers-in-logarithmic-number-of-steps/ +*/ +int log_fib_helper(int n, int a, int b, int p, int q){ + if(n == 0) + return a; + else if(n%2 == 0) + return log_fib_helper(n/2, a, b, p*p+q*q, (2*p+q)*q); + else + return log_fib_helper(n-1, p*a + q*b, q*a+(p+q)*b, p, q); +} + +int log_fib(int n){ + return log_fib_helper(n,0,1,0,1); +} +/** + * Closed form formula + * reference: https://mathworld.wolfram.com/BinetsFibonacciNumberFormula.html +*/ +int binet_fib(int n){ + const double golden_ratio = (1+sqrt(5))/2; + const double conjugate_golden_ratio = 1-golden_ratio; + double res = (pow(golden_ratio,n) - pow(conjugate_golden_ratio, n))/sqrt(5); + return round(res); +} diff --git a/algorithms/C/maths/fibonacci-number/src/fib.h b/algorithms/C/maths/fibonacci-number/src/fib.h new file mode 100644 index 00000000..c770d96d --- /dev/null +++ b/algorithms/C/maths/fibonacci-number/src/fib.h @@ -0,0 +1,22 @@ +#ifndef FIB_H_INCLUDED +#define FIB_H_INCLUDED + +/** + * fib(n) takes nonnegative number n + * return n-th term fibonacci number. + * The prefix highlights its algorithm used + */ + +int recur_fib(int n); +int iter_fib(int n); + +#define MAXSIZE 30 +int memomized_fib[MAXSIZE]; +void memomizing_fib(); // it should be called before using the function memo_fib() + +int memo_fib(int n); +int iter_log_fib(int n); +int log_fib(int n); +int binet_fib(int n); + +#endif \ No newline at end of file diff --git a/algorithms/C/maths/fibonacci-number/src/main.c b/algorithms/C/maths/fibonacci-number/src/main.c new file mode 100644 index 00000000..8bc173fc --- /dev/null +++ b/algorithms/C/maths/fibonacci-number/src/main.c @@ -0,0 +1,23 @@ +#include +#include"fib.h" + +int main(){ + memomizing_fib(); // this is to initialize the memomized table + int n = 15; + printf("%d\n", recur_fib(n)); // it becomes slow as n get larger for recur_fib + for(int i = 0; i <= 35; ++i){ + printf("n = %d\t", i); + printf(" %d", iter_fib(i)); + printf(" %d", memo_fib(i)); + printf(" %d", log_fib(i)); + printf(" %d", binet_fib(i)); + printf(" %d\n", iter_log_fib(i)); + } + int sum = 0; + int bound = 4000000; + for(int i = 0; memo_fib(i) < bound; ++i) + if(memo_fib(i)%2 == 0) + sum += memo_fib(i); + printf("The sum of even Fibonacci number below %d = %d", bound, sum); + return 0; +} From e42f4bb0b1e7f7b7413e95038eb8f9aac997e45e Mon Sep 17 00:00:00 2001 From: Ashad <93534298+Ashad001@users.noreply.github.com> Date: Thu, 11 Aug 2022 23:52:36 +0500 Subject: [PATCH 10/63] chore(CPlusPlus): add reverse number algorithm (#789) Co-authored-by: Arsenic <54987647+Arsenic-ATG@users.noreply.github.com> --- algorithms/C/maths/fibonacci-number/src/fib.c | 2 +- algorithms/C/maths/fibonacci-number/src/fib.h | 7 ++-- .../C/maths/fibonacci-number/src/main.c | 2 +- algorithms/CPlusPlus/README.md | 1 + .../CPlusPlus/Recursion/reverse-a-number.cpp | 34 +++++++++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 algorithms/CPlusPlus/Recursion/reverse-a-number.cpp diff --git a/algorithms/C/maths/fibonacci-number/src/fib.c b/algorithms/C/maths/fibonacci-number/src/fib.c index 41196239..25ead35d 100644 --- a/algorithms/C/maths/fibonacci-number/src/fib.c +++ b/algorithms/C/maths/fibonacci-number/src/fib.c @@ -1,4 +1,4 @@ -#include"fib.h" +#include"./fib.h" // NOLINT(build/include) #include // sqrt, pow are used in binet_fib int recur_fib(int n){ diff --git a/algorithms/C/maths/fibonacci-number/src/fib.h b/algorithms/C/maths/fibonacci-number/src/fib.h index c770d96d..febadaf1 100644 --- a/algorithms/C/maths/fibonacci-number/src/fib.h +++ b/algorithms/C/maths/fibonacci-number/src/fib.h @@ -1,5 +1,6 @@ -#ifndef FIB_H_INCLUDED -#define FIB_H_INCLUDED + +#ifndef ALGORITHMS_C_MATHS_FIBONACCI_NUMBER_SRC_FIB_H_ +#define ALGORITHMS_C_MATHS_FIBONACCI_NUMBER_SRC_FIB_H_ /** * fib(n) takes nonnegative number n @@ -19,4 +20,4 @@ int iter_log_fib(int n); int log_fib(int n); int binet_fib(int n); -#endif \ No newline at end of file +#endif // ALGORITHMS_C_MATHS_FIBONACCI_NUMBER_SRC_FIB_H_" diff --git a/algorithms/C/maths/fibonacci-number/src/main.c b/algorithms/C/maths/fibonacci-number/src/main.c index 8bc173fc..7e0759db 100644 --- a/algorithms/C/maths/fibonacci-number/src/main.c +++ b/algorithms/C/maths/fibonacci-number/src/main.c @@ -1,5 +1,5 @@ #include -#include"fib.h" +#include"./fib.h" // NOLINT(build/include) int main(){ memomizing_fib(); // this is to initialize the memomized table diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index c545fa88..0350073e 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -186,6 +186,7 @@ - [Product of two numbers](Recursion\product-of-numbers.cpp) - [Product of digits in a number](Recursion\product-of-digits.cpp) - [Linear search using recursion](Recursion/linear-search.cpp) +- [Reverse a number using recursion](Recursion/reverse-a-number.cpp) ## Number System diff --git a/algorithms/CPlusPlus/Recursion/reverse-a-number.cpp b/algorithms/CPlusPlus/Recursion/reverse-a-number.cpp new file mode 100644 index 00000000..884402bc --- /dev/null +++ b/algorithms/CPlusPlus/Recursion/reverse-a-number.cpp @@ -0,0 +1,34 @@ +/* +Description: Program to reverse integer using recursion +Time complexity: O(n) where n is the number of digits in the integer +*/ + +#include +#include +using namespace std; + +int Helper(int n ,int base , int ans) +{ + if(n < 1) + return ans; + ans = ans * base + (n % 10); // Update the ans for every digit + return Helper(n / 10, base , ans); +} + +int Rev(int n) +{ + return Helper(n , 10, 0); +} + + +int main(int argc, char const *argv[]) +{ + cout << Rev(13579); + + return 0; +} +/* +Input: 13579 +Output: 97531 +*/ + From ac970481a91868b59278889ed2f2b36a6ccd068b Mon Sep 17 00:00:00 2001 From: brugner Date: Fri, 12 Aug 2022 09:39:22 -0300 Subject: [PATCH 11/63] chore(CSharp): add quick sort (#798) --- algorithms/CSharp/README.md | 12 +++ algorithms/CSharp/src/Sorts/quick-sort.cs | 93 ++++++++++++++++++++++ algorithms/CSharp/test/Sorts/quick-sort.cs | 39 +++++++++ 3 files changed, 144 insertions(+) create mode 100644 algorithms/CSharp/src/Sorts/quick-sort.cs create mode 100644 algorithms/CSharp/test/Sorts/quick-sort.cs diff --git a/algorithms/CSharp/README.md b/algorithms/CSharp/README.md index 44fd6457..5f17d0b7 100644 --- a/algorithms/CSharp/README.md +++ b/algorithms/CSharp/README.md @@ -1,45 +1,57 @@ # C# + To run the `.cs` file, kindly use [.Net Finddle](https://dotnetfiddle.net/) ## Arrays + - [Single Number](src/Arrays/single-number.cs) ## Dynamic Programming + - [Longest Common Subsequence](src/Dynamic-Programming/longest-common-subsequence.cs) ## Number Theory + - [Big Mod Algorithm](src/Number-Theory/big-mod.cs) - [Sieve of Eratosthenes](src/Number-Theory/sieve-of-eratosthenes.cs) - [Bitwise Sieve of Eratosthenes](src/Number-Theory/bitwise-sieve-of-eratosthenes.cs) ## Sorts + - [Bubble Sort](src/Sorts/bubble-sort.cs) - [Insertion Sort](src/Sorts/insertion-sort.cs) - [Selection Sort](src/Sorts/selection-sort.cs) - [Counting Sort](src/Sorts/counting-sort.cs) - [Merge Sort](src/Sorts/merge-sort.cs) +- [Quick Sort](src/Sorts/quick-sort.cs) ## Strings + - [Palindrome](src/Strings/palindrome.cs) - [Trie](src/Strings/trie.cs) - [Character Limit](src/Strings/character-limit.cs) ## Search + - [Binary Search](src/Search/binary-search.cs) - [Linear Search](src/Search/linear-search.cs) - [Minima Maxima](src/Search/minima-maxima.cs) ## Maths + - [Abundant Number](src/Maths/abundant-number.cs) - [Naismith's Rule](src/Maths/naismith-rule.cs) ## Queues + - [Queue Implementation Using Two Stacks](src/Queues/queue-implementation-using-two-stacks.cs) ## Recursion + - [Factorial](src/Recursion/factorial.cs) ## Graph + - [Breadth First Search](src/Graph/breadth-first-search.cs) - [Depth First Search](src/Graph/depth-first-search.cs) - [Kruskals Algorithm to Find Minimum Spanning Tree](src/Graph/kruskals-algorithm.cs) diff --git a/algorithms/CSharp/src/Sorts/quick-sort.cs b/algorithms/CSharp/src/Sorts/quick-sort.cs new file mode 100644 index 00000000..0c95ee59 --- /dev/null +++ b/algorithms/CSharp/src/Sorts/quick-sort.cs @@ -0,0 +1,93 @@ +using System; + +namespace Algorithms.Sorts +{ + public class QuickSort + { + public static void Main() + { + int[] array = { 10, 7, 8, 9, 1, 5 }; + + Sort(array, 0, array.Length - 1); + PrintArray(array); + } + + /// + /// Sorts an array. + /// + /// Array to be sorted. + /// Starting index. + /// Ending index. + public static int[] Sort(int[] array, int low, int high) + { + if (low < high) + { + // Select a pivot + int pivot = Partition(array, low, high); + + // Sort each subarray + Sort(array, low, pivot - 1); + Sort(array, pivot + 1, high); + } + + return array; + } + + /// + /// This method takes the last element as pivot, places + /// it at its correct position in sorted array, and + /// places all smaller (smaller than pivot) + /// to left of it and all greater elements to its right. + /// + /// Array to be sorted. + /// Starting index. + /// Ending index. + /// + private static int Partition(int[] array, int low, int high) + { + int pivot = array[high]; + int i = low - 1; + + for (int j = low; j <= high - 1; j++) + { + // If current element is smaller than the pivot + if (array[j] < pivot) + { + // Increment index of smaller element and swap them + i++; + Swap(array, i, j); + } + } + + Swap(array, i + 1, high); + + return (i + 1); + } + + /// + /// Swaps two elements. + /// + /// Array to be sorted. + /// An index. + /// Another index. + private static void Swap(int[] array, int i, int j) + { + int temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + + static void PrintArray(int[] array) + { + Console.Write("Sorted array: "); + + for (int i = 0; i < array.Length; i++) + { + Console.Write($"{array[i]} "); + } + + Console.WriteLine(); + } + } +} + diff --git a/algorithms/CSharp/test/Sorts/quick-sort.cs b/algorithms/CSharp/test/Sorts/quick-sort.cs new file mode 100644 index 00000000..ade0bcf9 --- /dev/null +++ b/algorithms/CSharp/test/Sorts/quick-sort.cs @@ -0,0 +1,39 @@ +using NUnit.Framework; + +namespace Algorithms.Tests.Sorts +{ + [TestFixture] + public class QuickSort + { + static readonly object[] TestCasesForQuickSort = + { + new object[] { + new int[] { 0, 19, 12, 22, 107, 118, 0, 1, 2}, + "0, 0, 1, 2, 12, 19, 22, 107, 118" + }, + + new object[] { + new int[] { 10, 11, 19, 0, -1, -19, -12, 1, 2, 1, 16, -100}, + "-100, -19, -12, -1, 0, 1, 1, 2, 10, 11, 16, 19" + }, + + new object[] { + new int[] { -1, -2, -3, -4, -5, -10}, + "-10, -5, -4, -3, -2, -1" + }, + + new object[] { + new int[] { -1 }, + "-1" + } + }; + + [TestCaseSource(nameof(TestCasesForQuickSort))] + public void TestQuickSort_ShouldGetExpected(int[] array, string expected) + { + var results = Algorithms.Sorts.QuickSort.Sort(array, 0, array.Length - 1); + + Assert.That(expected, Is.EqualTo(string.Join(", ", results))); + } + } +} From d14ef693953bafcf65baf95fa69b373baf2d6d83 Mon Sep 17 00:00:00 2001 From: Mohit Chakraverty <79406819+mohitchakraverty@users.noreply.github.com> Date: Sat, 13 Aug 2022 00:50:58 +0530 Subject: [PATCH 12/63] docs(en): add cycle sort (#799) --- docs/en/README.md | 1 + docs/en/Sorting/Cycle-Sort.md | 91 +++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 docs/en/Sorting/Cycle-Sort.md diff --git a/docs/en/README.md b/docs/en/README.md index aa1b5fd4..57254776 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -8,6 +8,7 @@ - [Insertion Sort](./Sorting/Insertion-Sort.md) - [Heap Sort](./Sorting/Heap-Sort.md) - [Quick Sort](./Sorting/Quick-Sort.md) +- [Cycle Sort](./Sorting/Cycle-Sort.md) ## Strings diff --git a/docs/en/Sorting/Cycle-Sort.md b/docs/en/Sorting/Cycle-Sort.md new file mode 100644 index 00000000..e589c2ae --- /dev/null +++ b/docs/en/Sorting/Cycle-Sort.md @@ -0,0 +1,91 @@ +# Cycle Sort + +Cycle sort is a comparison sorting algorithm that forces array to be factored into the number of cycles where each of them can be rotated to produce a sorted array. It is theoretically optimal in the sense that it reduces the number of writes to the original array. +It is an in-place and unstable sorting algorithm. + +Time Complexity : O(n^2) +- Worst Case : O(n^2) +- Average Case: O(n^2) +- Best Case : O(n^2) + +Space complexity : +The space complexity is constant cause this algorithm is in place so it does not use any extra memory to sort. +Auxiliary space: O(1) + +## Steps + +Suppose there is an array **arr** with **n** distinct elements. Given an element **A**, we can find its index by counting the number of elements smaller than **A**. + +1. If the element is at its correct position, simply leave it as it is. +2. Else, we have to find the correct position of **A** by counting the number of elements smaller than it. Another element **B** is replaced to be moved to its correct position. This process continues until we get an element at the original position of **A**. + +The above-illustrated process constitutes a cycle. Repeat this cycle for every element of the list until the list is sorted. + +## Example + +arr[] = {10, 5, 2, 3} + + index = 0 1 2 3 + +cycle_start = 0 + +item = 10 = arr[0] + +Find position where we put the item + +pos = cycle_start + +i=pos+1 + +while(i < n) + +if (arr[i] < item) + + pos++; + +We put 10 at arr[3] and change item to +old value of arr[3]. + +arr[] = {10, 5, 2, 10} + +item = 3 + +Again rotate rest cycle that start with index '0' + +Find position where we put the item = 3 + +we swap item with element at arr[1] now + +arr[] = {10, 3, 2, 10} + +item = 5 + +Again rotate rest cycle that start with index '0' and item = 5 + +we swap item with element at arr[2]. + +arr[] = {10, 3, 5, 10 } + +item = 2 + +Again rotate rest cycle that start with index '0' and item = 2 + +arr[] = {2, 3, 5, 10} + +Above is one iteration for cycle_stat = 0. + +Repeat above steps for cycle_start = 1, 2, ..n-2 + +## Implementation + +- [C++](../../../algorithms/CPlusPlus/Sorting/cycle-sort.cpp) +- [Java](../../../algorithms/Java/sorting/cyclic-sort.java) +- [Python](../../../algorithms/Python/sorting/count-sort.py) + +## Video URL + +[Youtube Video about Cycle Sort](https://youtu.be/gZNOM_yMdSQ) + +## Other + +[Wikipedia](https://en.wikipedia.org/wiki/Cycle_sort) \ No newline at end of file From 6f19b452ea07ab70348ed76dd479dc7d9693be38 Mon Sep 17 00:00:00 2001 From: Hridyansh Pareek Date: Mon, 15 Aug 2022 19:33:38 +0530 Subject: [PATCH 13/63] chore(Python) : add GCD using recursion following Euclid's Algorithm (#797) --- algorithms/Python/README.md | 1 + .../Python/recursion/gcd_using_recursion.py | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 algorithms/Python/recursion/gcd_using_recursion.py diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index b73323e6..b2be029d 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -26,6 +26,7 @@ - [n-th Fibonacci number](recursion/nth_fibonacci_number.py) - [Recursive Insertion Sort](recursion/recursive_insertion_sort.py) - [Recursive Sum of n numbers](recursion/recursive-sum-of-n-numbers.py) +- [GCD by Euclid's Algorithm](recursion/gcd_using_recursion.py) ## Scheduling diff --git a/algorithms/Python/recursion/gcd_using_recursion.py b/algorithms/Python/recursion/gcd_using_recursion.py new file mode 100644 index 00000000..092d65d8 --- /dev/null +++ b/algorithms/Python/recursion/gcd_using_recursion.py @@ -0,0 +1,23 @@ +#EUCLIDS ALGORITHM + +def gcd(a, b): + if a<0: + a = -a + if b<0: + b = -b + if b==0: + return a + else: + return gcd(b, a%b) + + +#TIME COMPLEXITY - O(log(min(a, b))) +#EXAMPLES +#print(gcd(10, 2)) -> 2 +#print(gcd(30, 15)) -> 3 +#print(gcd(-30, 15)) -> 3 +#WORKING +#We are using the Euclidean Algorithm to calculate the GCD of a number +#it states that if a and b are two positive integers then GCD or greatest common +#divisors of these two numbers will be equal to the GCD of b and a%b or +#gcd(a, b) = gcd(b, a%b) till b reaches 0 From 6e39b2bc6063d1033600d04412ee4e82baf49207 Mon Sep 17 00:00:00 2001 From: Mohit Chakraverty <79406819+mohitchakraverty@users.noreply.github.com> Date: Wed, 17 Aug 2022 20:50:07 +0530 Subject: [PATCH 14/63] enh(Java): binary search (#800) * add Cycle-Sort.md * corrected documentation * add Cycle-Sort.md * Fixed the broken link * Added the file index for Cycle-Sort * Fixed typo * created new file for iterative binary search * created binary-search.java --- algorithms/Java/searching/binary-search.java | 112 +++++++++++-------- 1 file changed, 63 insertions(+), 49 deletions(-) diff --git a/algorithms/Java/searching/binary-search.java b/algorithms/Java/searching/binary-search.java index db5442bf..21e24a1b 100644 --- a/algorithms/Java/searching/binary-search.java +++ b/algorithms/Java/searching/binary-search.java @@ -1,50 +1,64 @@ -// Java implementation of recursive Binary Search -class BinarySearch { - // Returns index of x if it is present in arr[l..r], - // else return -1 - int binarySearch(int arr[], int l, int r, int x) - { - if (r >= l) { - int mid = l + (r - l) / 2; - //We use (l + (r - l)) rather than using (l - r) to avoid arithmetic overflow. - //Arithmetic overflow is the situation when the value of a variable increases - //beyond the maximum value of the memory location, and wraps around. - - // If the element is present at the - // middle itself - if (arr[mid] == x) - return mid; - - // If element is smaller than mid, then - // it can only be present in left subarray - if (arr[mid] > x) - return binarySearch(arr, l, mid - 1, x); - - // Else the element can only be present - // in right subarray - return binarySearch(arr, mid + 1, r, x); - } - - // We reach here when element is not present - // in array - return -1; - } - - // Driver method to test above - public static void main(String args[]) - { - BinarySearch ob = new BinarySearch(); - int arr[] = { 2, 3, 4, 10, 40 }; - int n = arr.length; - int x = 10; - int result = ob.binarySearch(arr, 0, n - 1, x); - if (result == -1) - System.out.println("Element not present"); - else - System.out.println("Element found at index " + result); - } -} +// Algorithm BinarySearch Iterative method +/*binarySearch(arr, x, low, high) + repeat till low = high + mid = (low + high)/2 + if (x == arr[mid]) + return mid + + else if (x > arr[mid]) // x is on the right side + low = mid + 1 + + else // x is on the left side + high = mid - 1 + */ +// Time Complexity : O(log(n)) -// For running in terminal rename this file to BinarySearch.java -//then run the commands followed by -//It will generate and a BinarySearch.class file which is a file containing java bytecode that is executed by JVM. +public class BinarySearch { + + static int binarySearch(int arr[], int key) + { + int start = 0; + int end = arr.length - 1; + + while (start <= end) { + // We use (start + (end - start)/2) rather than using (start + end)/2 to avoid + // arithmetic overflow. + // Arithmetic overflow is the situation when the value of a variable increases + // beyond the maximum value of the memory location, and wraps around. + int mid = start + (end - start) / 2; // optimised way + + if (arr[mid] == key)// key element is found at the middle of the array + return mid; + + else if (arr[mid] < key) {// so the key lies in the right hand side of array + start = mid + 1; + } + + else {// so the key lies in the left subarray + end = mid - 1; + } + } + // we reach here when the key element is not present + return -1; + } + + public static void main(String[] args) + { + + int arr[] = { 1, 3, 4, 5, 6 }; + + /* + * List> arr = new ArrayList<>(); + * arr.add(new ArrayList(Arrays.asList( 1, 3, 4, 5, 6 ))); + */ + int key = 4; // element to search + int index = binarySearch(arr, key); + if (index == -1) { + System.out.println("key element not found"); + } + else { + System.out.println("key element found at index :" + index); + } + + } +} From 1d1a3468e7af883fd4c9657cc4e8b8a02811285a Mon Sep 17 00:00:00 2001 From: Hridyansh Pareek Date: Thu, 18 Aug 2022 18:53:20 +0530 Subject: [PATCH 15/63] chore(Python) : add prime number check (#802) * Added Prime Number checker alorithm * Added Prime Number Checker Algorithm: * Update prime_number.py --- algorithms/Python/README.md | 4 ++++ .../Python/number_theory/prime_number.py | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 algorithms/Python/number_theory/prime_number.py diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index b2be029d..7cfd6fa9 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -83,3 +83,7 @@ ## Queues - [First in First out Queue](queues/fifo-queue.py) + + +##Number Theory +- [Prime Number Checker][number_theory/prime_number.py] \ No newline at end of file diff --git a/algorithms/Python/number_theory/prime_number.py b/algorithms/Python/number_theory/prime_number.py new file mode 100644 index 00000000..aca81cfe --- /dev/null +++ b/algorithms/Python/number_theory/prime_number.py @@ -0,0 +1,22 @@ +#TO CHECK WHETHER A NUMBER IS PRIME OR NOT + + +def isPrime(N): + if N<=1: + return False + + for i in range(2, int(N**0.5) + 1): + if N%i==0: + return False + + return True + +# TIME COMPLEXITY - O(sqrt(N)) + +# EXAMPLES +# print(isPrime(3)) -> True +# print(isPrime(15)) -> False + +# We are just checking till sqrt(N) as if their is any factor of a number +# greater than sqrt(N) then it's partner will be less than sqrt(N) as if a*b>N +# and a>=sqrt(N) then b<=sqrt(N) as if b>sqrt(N) then a*b>N. From 9a74c3e8571faf80d4231366d03bdde04a731701 Mon Sep 17 00:00:00 2001 From: Ming Tsai Date: Sat, 20 Aug 2022 11:48:10 -0400 Subject: [PATCH 16/63] chore(codespell): add ignore for the Turkish folder --- .github/workflows/codespell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 745b104f..3db88c38 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -11,4 +11,4 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - run: pip install codespell - - run: codespell --ignore-words-list="ans,nnumber,nin,Hel" --quiet-level=2 --skip="**/**/package-lock.json,./docs/pt,./docs/es,./.github,./algorithms/CSharp/test" + - run: codespell --ignore-words-list="ans,nnumber,nin,Hel" --quiet-level=2 --skip="**/**/package-lock.json,./docs/pt,./docs/es,./docs/tr,./.github,./algorithms/CSharp/test" From d34acc78b07146b42e43bc485fc6facc5218bf2b Mon Sep 17 00:00:00 2001 From: Ming Tsai Date: Sat, 20 Aug 2022 11:48:26 -0400 Subject: [PATCH 17/63] docs: fix typos --- algorithms/C/maths/fibonacci-number/README.md | 2 +- algorithms/CPlusPlus/Maths/factorial.cpp | 4 ++-- algorithms/CPlusPlus/Recursion/first-uppercase-letter.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/algorithms/C/maths/fibonacci-number/README.md b/algorithms/C/maths/fibonacci-number/README.md index 7d5101c1..2af27e9a 100644 --- a/algorithms/C/maths/fibonacci-number/README.md +++ b/algorithms/C/maths/fibonacci-number/README.md @@ -1,5 +1,5 @@ # Fibonacci Number -Fibonacci numbers form a Fibonacci sequence where given any number (excluding first 2 terms) is a sum of its two preceding numbers. Usually, the sequence is either start with 0 and 1 or 1 and 1. Below is a Fibonacci sequnce starting from 0 and 1: +Fibonacci numbers form a Fibonacci sequence where given any number (excluding first 2 terms) is a sum of its two preceding numbers. Usually, the sequence is either start with 0 and 1 or 1 and 1. Below is a Fibonacci sequence starting from 0 and 1: $$ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, \dots diff --git a/algorithms/CPlusPlus/Maths/factorial.cpp b/algorithms/CPlusPlus/Maths/factorial.cpp index 11ad4773..a97f98c1 100644 --- a/algorithms/CPlusPlus/Maths/factorial.cpp +++ b/algorithms/CPlusPlus/Maths/factorial.cpp @@ -4,8 +4,8 @@ A factorial of number 4 is calculated as: 4 X 3 X 2 X 1 = 24 Approach: Calculating factorial using for loop. -Declaring the f varialbe to 1 (not initialising it to zero because any number multiplied by 0 will be 0) -Multiplying the f variable to 1,2,3...n and storing it in the f varialbe. +Declaring the f variable to 1 (not initialising it to zero because any number multiplied by 0 will be 0) +Multiplying the f variable to 1,2,3...n and storing it in the f variable. The same factorial can be calculated using while loop, recursion. Time Complexity: O(number) diff --git a/algorithms/CPlusPlus/Recursion/first-uppercase-letter.cpp b/algorithms/CPlusPlus/Recursion/first-uppercase-letter.cpp index 2be87827..40315a35 100644 --- a/algorithms/CPlusPlus/Recursion/first-uppercase-letter.cpp +++ b/algorithms/CPlusPlus/Recursion/first-uppercase-letter.cpp @@ -1,7 +1,7 @@ /* Description: Program to print the first uppercase letter in a string -Approach: Use a varialbe to iterate over the string +Approach: Use a variable to iterate over the string Increment the iterator by 1 at every recursive call If the value of iterator reaches till the length of the string, return '\0 From f4353ff2a46715825461ec11d64eaab7d6af6665 Mon Sep 17 00:00:00 2001 From: Mohnish Deshpande <77594965+mohnishdeshpande@users.noreply.github.com> Date: Sun, 21 Aug 2022 01:50:26 +1000 Subject: [PATCH 18/63] enh(CPlusPlus): update comment of binary search (#807) --- algorithms/CPlusPlus/Searching/binary-search.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/algorithms/CPlusPlus/Searching/binary-search.cpp b/algorithms/CPlusPlus/Searching/binary-search.cpp index 0603d02e..c07771de 100644 --- a/algorithms/CPlusPlus/Searching/binary-search.cpp +++ b/algorithms/CPlusPlus/Searching/binary-search.cpp @@ -7,7 +7,7 @@ int binarySearch(int arr[], int l, int r, int x) { if (r >= l) { int mid = l + (r - l) / 2; - //We use (l + (r - l)) rather than using (l - r) to avoid arithmetic overflow. + //We use (l + (r - l)) rather than using (l + r) to avoid arithmetic overflow. //Arithmetic overflow is the situation when the value of a variable increases //beyond the maximum value of the memory location, and wraps around. @@ -15,7 +15,7 @@ int binarySearch(int arr[], int l, int r, int x) if (arr[mid] == x) return mid; - // If element is smaller than mid, then it can only be present in left subarray + // If mid is greater than element, then it can only be present in left subarray if (arr[mid] > x) return binarySearch(arr, l, mid - 1, x); From 8649eda4b1547729fcf5219e036a63b5eff176dd Mon Sep 17 00:00:00 2001 From: Akashdeep Tickoo Date: Sat, 20 Aug 2022 21:24:06 +0530 Subject: [PATCH 19/63] docs(Python): add missing space on README (#809) --- algorithms/Python/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index 7cfd6fa9..b7c82fd7 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -84,6 +84,5 @@ ## Queues - [First in First out Queue](queues/fifo-queue.py) - -##Number Theory -- [Prime Number Checker][number_theory/prime_number.py] \ No newline at end of file +## Number Theory +- [Prime Number Checker](number_theory/prime_number.py) From 005af5d471a878e35dc07ae227fa4782d9bc776f Mon Sep 17 00:00:00 2001 From: Sandra Date: Thu, 25 Aug 2022 11:54:32 +0530 Subject: [PATCH 20/63] add-new-file --- algorithms/CPlusPlus/Arrays/sparse_matrix.cpp | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 algorithms/CPlusPlus/Arrays/sparse_matrix.cpp diff --git a/algorithms/CPlusPlus/Arrays/sparse_matrix.cpp b/algorithms/CPlusPlus/Arrays/sparse_matrix.cpp new file mode 100644 index 00000000..a7526beb --- /dev/null +++ b/algorithms/CPlusPlus/Arrays/sparse_matrix.cpp @@ -0,0 +1,40 @@ +/*Description :c++ solution to check if a given matrix is sparse matrix. +If the count of zeroes present in the mmatrix is more than half the elements of the matrix, +it is flagged as a sparse matrix.*/ + + +#include +using namespace std; +int main () { + int a[10][10] = { {0, 0, 9} , {5, 0, 8} , {7, 0, 0} }; + int i, j, count = 0; + int row = 3, col = 3; + for (i = 0; i < row; ++i) { + for (j = 0; j < col; ++j){ + if (a[i][j] == 0) + count++; + } + } + cout<<"The matrix is:"< ((row * col)/ 2)) + cout<<"This is a sparse matrix"< Date: Sat, 27 Aug 2022 16:45:55 +0000 Subject: [PATCH 21/63] docs(en): add doubly linked list (#813) Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> --- docs/en/Lists/doubly-linked-list.md | 71 +++++++++++++++++++++++++++++ docs/en/README.md | 4 ++ 2 files changed, 75 insertions(+) create mode 100644 docs/en/Lists/doubly-linked-list.md diff --git a/docs/en/Lists/doubly-linked-list.md b/docs/en/Lists/doubly-linked-list.md new file mode 100644 index 00000000..1bb753cc --- /dev/null +++ b/docs/en/Lists/doubly-linked-list.md @@ -0,0 +1,71 @@ +# Doubly Linked List + +A doubly linked list is a type of linked data structure that allows traversal in both directions (forward and backward directions). +It differs from singly linked list in that, singly linked list does not support backward traversal. +Every node in a doubly linked list contains a **data** part and two pointers; **next pointer** that points to the next node and the **prev pointer** that points to the previous node in the list. +A doubly linked list also has two dummy nodes (head and tail) known as **sentinels** (guard nodes) that contains no data of the sequence. +The first element of a doubly linked list has its prev pointer pointing to head and the last element has its next node pointing to tail. + +Without a tail pointer, you cannot directly access the last element without having to first traverse the entire list all the way from the beginning. + +## Steps to create a doubly linked list +To create an empty list, +- create head and tail nodes (nodes without data) first +- let the **next pointer** of the head point to the tail node +- let the **prev pointer** of the tail point to the head node. + +For a non-empty list, +- let the next pointer of the head point to the first real element of the sequence +- let the prev pointer of the tail point to the last real element of the sequence + +## Key operations +- Insertion (insert at the beginning, at the end or anywhere in the middle) +- deletion (delete from beginning, end or anywhere in the middle) + +To add an element(node) at the beginning of the list, let the; +- *next pointer* of the new element (node) point to the first element (the one the *head* currently points to) +- *next pointer* of the *head* point to this new element you want to add +- *prev pointer* of the element (node) you want to add point to *head*. + +To add an alement (node) to the end of the list, let the; +- *prev pointer* of the new element you want to add point to the last element (the one before the *tail*) +- *next pointer* of the last element (the one before the *tail*) point to the new element you want to add +- *prev pointer* of the *tail* point to the new element. + +To delete an element from the beginning, let the; +- *next pointer* of the *head* point to the second element in the list (node after the one *head* pointers to). +- *prev pointer* of the second element point to the *head* + + +To delete from the end of the list, let the; +- *prev pointer* of the *tail* point to the element before the last node +- *next pointer* of the element before the last node point to the *tail* + +Note: If there is only one element in the list, deletion from both directions happens by pointing the *next pointer* of *head* to *tail* and *prev pointer* of *tail* to *head*. + +Deletion anywhere in the middle happens by letting the *prev pointer* and the *next pointer* of the node after and before the one you want to delete point to each other respectively. + +To insert anywhere in the middle, let the; +- *next pointer* of the element you want to insert point to the node at the position you want to insert it +- *prev pointer* of the element you want to insert point to node before the position you want to insert it +- *prev pointer* of the node at the position you want to insert point to the new element +- *next pointer* of the node before the position you want to insert point to the new element. + +Deletion and insertion at the beginning or end of the list is a constant operation and has a O(1) runtime. Deletion or insertion anywhere in the middle however has a O(n) runtime. + + +## Implementation + +- [C++](../../../algorithms/C/linked-lists/doubly-linked-list.c) +- [Java](../../../algorithms/CPlusPlus/Linked-Lists/doubly.cpp) +- [JavaScript](../../../algorithms/Java/linked-lists/doubly.java) +- [Python](../../../algorithms/Python/linked_lists/doubly.py) + +## Video URL + +[Doubly linked list](https://www.youtube.com/watch?v=nquQ_fYGGA4) + + +## References + +[Goodrich, T. M., Tamassia, R., Goldwasser, M.H.(2014). *Data Structures & Algorithms in Java* (6th ed.). Wiley](https://www.wiley.com/en-us/Data+Structures+and+Algorithms+in+Java,+6th+Edition-p-9781118771334) diff --git a/docs/en/README.md b/docs/en/README.md index 57254776..65b4a7cf 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -1,5 +1,9 @@ # Algorithms +## Lists +- [Singly linked list](./Lists/singly-linked-list.md) +- [Doubly linked list](./Lists/doubly-linked-list.md) + ## Sorting - [Bubble Sort](./Sorting/Bubble-Sort.md) From b0f8c38565cb8c15db78c409cb4a5993cc338da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=20Karina=20Vergara=20Guzm=C3=A1n?= <37852043+anver-dev@users.noreply.github.com> Date: Sat, 27 Aug 2022 12:01:29 -0500 Subject: [PATCH 22/63] docs(Spanish): add merge sort (#819) --- docs/es/Ordenamiento/Merge-Sort.md | 35 ++++++++++++++++++++++++++++++ docs/es/README.md | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 docs/es/Ordenamiento/Merge-Sort.md diff --git a/docs/es/Ordenamiento/Merge-Sort.md b/docs/es/Ordenamiento/Merge-Sort.md new file mode 100644 index 00000000..808b7d6b --- /dev/null +++ b/docs/es/Ordenamiento/Merge-Sort.md @@ -0,0 +1,35 @@ +# Merge Sort + +Merge Sort es un algoritmo "Divide y venceras". Divide la matriz de entrada en dos mitades, se llama a sí mismo para cada una de ellas y luego fusiona las dos mitades ordenadas. + +## Pasos + +1. Encuentra el punto medio para dividir la matriz en dos mitades. +2. Llama a mergeSort para la primera mitad. +3. Llama a mergeSort para la segunda mitad. +4. Combina las dos mitades ordenadas en los pasos 2 y 3. + +## Ejemplo + +Dado el arreglo: +**12 11 13 5 6 7** + +El arreglo ordenado es +**5 6 7 11 12 13** + +## Implementación + +- [Java](../../../algorithms/Java/sorting/merge-sort.java) +- [C](../../../algorithms/C/sorting/merge-sort.c) +- [C++](../../../algorithms/CPlusPlus/Sorting/merge-sort.cpp) +- [JavaScript](../../../algorithms/JavaScript/src/sorting/merge-sort.js) +- [Python](../../../algorithms/Python/sorting/merge_sort.py) +- [C#](../../../algorithms/CSharp/src/Sorts/merge-sort.cs) + +## URL del video + +[Video de Youtube acerca de Merge Sort](https://www.youtube.com/watch?v=jlHkDBEumP0) + +## Otros + +[Wikipedia](https://en.wikipedia.org/wiki/Merge_sort) \ No newline at end of file diff --git a/docs/es/README.md b/docs/es/README.md index fcd7d5f8..cb97cd86 100644 --- a/docs/es/README.md +++ b/docs/es/README.md @@ -1,7 +1,7 @@ # Algoritmos ## Ordenamiento - +- [Merge Sort](./Ordenamiento/Merge-Sort.md) - [Quick Sort](./Ordenamiento/Quick-Sort.md) ## Otro From 7d0f490e7b0a69d3f3c140dacac51ea9004be47f Mon Sep 17 00:00:00 2001 From: Ayomide AJAYI <70599813+ayo-ajayi@users.noreply.github.com> Date: Sat, 27 Aug 2022 19:24:44 +0200 Subject: [PATCH 23/63] chore(Go): add selection sort (#820) --- algorithms/Go/README.md | 3 +- algorithms/Go/sorting/selection-sort.go | 62 +++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 algorithms/Go/sorting/selection-sort.go diff --git a/algorithms/Go/README.md b/algorithms/Go/README.md index 0e12c10e..febe548e 100644 --- a/algorithms/Go/README.md +++ b/algorithms/Go/README.md @@ -19,7 +19,8 @@ ## Sorting - [Bubble Sort](sorting/bubble-sort.go) - [Insertion Sort](sorting/insertion-sort.go) -- [Quicksort](sorting/quicksort.go) +- [Quick Sort](sorting/quicksort.go) +- [Selection Sort](sorting/selection-sort.go) ## Recursion - [Fibonacci](recursion/fibonacci.go) diff --git a/algorithms/Go/sorting/selection-sort.go b/algorithms/Go/sorting/selection-sort.go new file mode 100644 index 00000000..4975ce34 --- /dev/null +++ b/algorithms/Go/sorting/selection-sort.go @@ -0,0 +1,62 @@ +/* + Selection sort algorithm sorts an array by repeatedly finding the minimum element (considering ascending order) from unsorted part and putting it at the beginning. + The algorithm maintains two subarrays in a given array: + The subarray which is already sorted. + Remaining subarray which is unsorted. + Average Time Complexity: O(n^2) + + Link for reference: https://www.geeksforgeeks.org/selection-sort/ + +*/ + +package sorting + +import "fmt" + +func RunSelectionSortRec() { + arr := []int{7, 4, 7, 3, 2} + selSortRec(arr, len(arr)-1) //using recursion + fmt.Println(arr) // 2, 3, 4, 7, 7 +} +func RunSelectionSortIter() { + arr := []int{7, 4, 7, 3, 1} + selSort(arr) //using iteration + fmt.Println(arr) // 1, 3, 4, 7, 7 +} + +//sort using iterative method +func selSort(arr []int) { + for arrIndex := range arr { + minVal := arr[arrIndex] + minIndex := arrIndex + for subIndex := arrIndex + 1; subIndex < len(arr); subIndex++ { + if arr[subIndex] < minVal { + minVal = arr[subIndex] + minIndex = subIndex + } + } + arr[minIndex], arr[arrIndex] = arr[arrIndex], arr[minIndex] + } +} + +//sort using recursive method +func selSortRec(arr []int, i int) { + if i < 0 { + return + } + maxIn := maxSel(arr, i) + //i = len(arr)-1 + if i != maxIn { + arr[i], arr[maxIn] = arr[maxIn], arr[i] + } + selSortRec(arr, i-1) +} +func maxSel(arr []int, i int) int { + if i > 0 { + maxIn := maxSel(arr, i-1) + if arr[i] < arr[maxIn] { + return maxIn + } + } + return i +} From b5aaf761e3c62aa4f5282cc1a8fda281f857b86f Mon Sep 17 00:00:00 2001 From: Sandra Date: Sun, 28 Aug 2022 23:12:51 +0530 Subject: [PATCH 24/63] add tupple form --- algorithms/CPlusPlus/Arrays/sparse_matrix.cpp | 76 ++++++++++++++++--- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/algorithms/CPlusPlus/Arrays/sparse_matrix.cpp b/algorithms/CPlusPlus/Arrays/sparse_matrix.cpp index a7526beb..786c5a76 100644 --- a/algorithms/CPlusPlus/Arrays/sparse_matrix.cpp +++ b/algorithms/CPlusPlus/Arrays/sparse_matrix.cpp @@ -1,40 +1,96 @@ /*Description :c++ solution to check if a given matrix is sparse matrix. If the count of zeroes present in the mmatrix is more than half the elements of the matrix, -it is flagged as a sparse matrix.*/ +it is flagged as a sparse matrix. +Also the tuple form of the matrix(if the said matrix is sparse) is displayed.*/ #include using namespace std; + +int compactMatrix(int sparseMatrix[4][5]) +{ + int size = 0; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 5; j++) + if (sparseMatrix[i][j] != 0) + size++; + + /* number of columns in compactMatrix (size) must be + equal to number of non - zero elements in sparseMatrix */ + int compactMatrix[size][3]; + + // Making of new matrix + int k = 0; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 5; j++) + if (sparseMatrix[i][j] != 0) + { + compactMatrix[k][0] = i; + compactMatrix[k][1] = j; + compactMatrix[k][2] = sparseMatrix[i][j]; + k++; + } + cout<<"The tuple form is:"< ((row * col)/ 2)) - cout<<"This is a sparse matrix"< Date: Sun, 28 Aug 2022 16:59:58 -0400 Subject: [PATCH 25/63] docs(reviewers): add go reviewer Add ayo-ajayi --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ecb02edb..a9b61fc2 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ The programming should keep the naming convention rule of each programming langu | C or C++ | @Arsenic-ATG, @UG-SEP, @aayushjain7, @Ashborn-SM | | Java | @TawfikYasser, @aayushjain7 | | C# | @ming-tsai, @Waqar-107 | -| Go | | +| Go | @ayo-ajayi | | Python | @Arsenic-ATG, @sridhar-5 | | JavaScript | @ming-tsai | From 710d7bfbf61d57ae84609f27a2964309b960f7e5 Mon Sep 17 00:00:00 2001 From: Prashant Bhapkar Date: Mon, 29 Aug 2022 20:39:31 +0530 Subject: [PATCH 26/63] Find Second largest element in the array --- algorithms/C/arrays/secondLargestElement.c | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 algorithms/C/arrays/secondLargestElement.c diff --git a/algorithms/C/arrays/secondLargestElement.c b/algorithms/C/arrays/secondLargestElement.c new file mode 100644 index 00000000..04263d26 --- /dev/null +++ b/algorithms/C/arrays/secondLargestElement.c @@ -0,0 +1,30 @@ +//Second largest element in the array + +#include +#include + +int second(int arr[],int size) +{ + int max1=arr[0],max2; + for(int i=0;imax1) //Find largest element in the array + { + max2=max1; + max1=arr[i]; + } + else if (arr[i]>max2 && arr[i] Date: Wed, 31 Aug 2022 02:31:17 +0300 Subject: [PATCH 27/63] Open chore(CPlusPlus): add Floyd Warshall algorithm (#791) --- .../CPlusPlus/Graphs/floyd-warshall.cpp | 106 ++++++++++++++++++ algorithms/CPlusPlus/README.md | 1 + 2 files changed, 107 insertions(+) create mode 100644 algorithms/CPlusPlus/Graphs/floyd-warshall.cpp diff --git a/algorithms/CPlusPlus/Graphs/floyd-warshall.cpp b/algorithms/CPlusPlus/Graphs/floyd-warshall.cpp new file mode 100644 index 00000000..4f064f0b --- /dev/null +++ b/algorithms/CPlusPlus/Graphs/floyd-warshall.cpp @@ -0,0 +1,106 @@ +#include + +using namespace std; +const int N = 500, OO = 1e9; + +int dist[N][N]; + +//Initialize the distance matrix with infinities to indicate that there is no edge between nodes +void initialize_dist(int n) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + dist[i][j] = OO; + if (i == j) { + dist[i][j] = 0; + } + } + } +} + +//Take Edge input and update the distance matrix +void input(int m) { + for (int i = 0; i < m; i++) { + int a, b, c; + cin >> a >> b >> c; + dist[a][b] = c; + dist[b][a] = c; + } +} + +//Perform Floyd-Warshall algorithm to calculate all shortest paths +int floyd(int n) { + for (int k = 0; k < n; k++) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (dist[i][j] > dist[i][k] + dist[k][j]) { + dist[i][j] = dist[i][k] + dist[k][j]; + } + } + } + } +} + +//Take queries and output the shortest distance for each query +void output(int q) { + for (int i = 0; i < q; i++) { + int x, y; + cin >> x >> y; + cout << dist[x][y] << endl; + } +} + +int main() { + int n, m, q; + cin >> n; // Number of nodes + initialize_dist(n); + cin >> m; // Number of edges + input(m); + floyd(n); + cin >> q; // Number of queries + output(q); + return 0; +} + +/* +Time Complexity: O(n^3) +Memory Complexity: O(n^2) +*/ + +/* +Example: + 5 // Number of nodes + 10 // Number of edges + 0 1 5 // Edge from Node 0 to Node 1 with Weight 5 + 0 2 3 + 0 3 4 + 0 4 1 + 1 2 4 + 1 3 1 + 1 4 1 + 2 3 1 + 2 4 2 + 3 4 4 + 10 // Number of Queries + 0 1 // Print Minimum Path between Nodes 0 and 1 + 0 2 + 0 3 + 0 4 + 1 2 + 1 3 + 1 4 + 2 3 + 2 4 + 3 4 + +Output: + 2 //Minimum path from 0 to 1 + 3 //Minimum path from 0 to 2 + 3 //Minimum path from 0 to 3 + 1 //Minimum path from 0 to 4 + 2 //Minimum path from 1 to 2 + 1 //Minimum path from 1 to 3 + 1 //Minimum path from 1 to 4 + 1 //Minimum path from 2 to 3 + 2 //Minimum path from 2 to 4 + 2 //Minimum path from 3 to 4 + */ diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index 0350073e..1dd328c6 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -51,6 +51,7 @@ - [Connected Components](Graphs/total-connected-components.cpp) - [Dijkstra's Algorithm](Graphs/dijkstra.cpp) - [Cycle Detection](Graphs/cycle-detection.cpp) +- [Floyd Warshall](Graphs/floyd-warshall.cpp) ## Multiplication From 4a7eba4d2bad217c8f76ceb25c04efd2daeadf27 Mon Sep 17 00:00:00 2001 From: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> Date: Tue, 30 Aug 2022 19:38:25 -0400 Subject: [PATCH 28/63] docs(readme): add C/C++ reviewer --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a9b61fc2..239d8e04 100644 --- a/README.md +++ b/README.md @@ -119,14 +119,14 @@ The programming should keep the naming convention rule of each programming langu ## Reviewers -| Programming Language | Users | -| -------------------- | ------------------------------------------------ | -| C or C++ | @Arsenic-ATG, @UG-SEP, @aayushjain7, @Ashborn-SM | -| Java | @TawfikYasser, @aayushjain7 | -| C# | @ming-tsai, @Waqar-107 | -| Go | @ayo-ajayi | -| Python | @Arsenic-ATG, @sridhar-5 | -| JavaScript | @ming-tsai | +| Programming Language | Users | +| -------------------- | ----------------------------------------------------------- | +| C or C++ | @Arsenic-ATG, @UG-SEP, @aayushjain7, @Ashborn-SM, @Ashad001 | +| Java | @TawfikYasser, @aayushjain7 | +| C# | @ming-tsai, @Waqar-107 | +| Go | @ayo-ajayi | +| Python | @Arsenic-ATG, @sridhar-5 | +| JavaScript | @ming-tsai | ## Contributors From 41ace4231f75646983f53a086b107a54f689246e Mon Sep 17 00:00:00 2001 From: Prashant Bhapkar Date: Wed, 31 Aug 2022 16:30:53 +0530 Subject: [PATCH 29/63] Added running time of algorithm and update readme.md file --- algorithms/C/README.md | 1 + algorithms/C/arrays/secondLargestElement.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/algorithms/C/README.md b/algorithms/C/README.md index 9e241b51..50a7eb55 100644 --- a/algorithms/C/README.md +++ b/algorithms/C/README.md @@ -7,6 +7,7 @@ - [Reverse an array](arrays/reverse-array.c) - [Maximum difference](arrays/maximum-difference.c) - [Largest Element](arrays/largestElement.c) +- [Second Largest Element](arrays/secondLargestElement.c) - [Sieve of Eratosthenes](arrays/sieve-of-eratosthenes.c) ## Bit Manipulation diff --git a/algorithms/C/arrays/secondLargestElement.c b/algorithms/C/arrays/secondLargestElement.c index 04263d26..34b81d12 100644 --- a/algorithms/C/arrays/secondLargestElement.c +++ b/algorithms/C/arrays/secondLargestElement.c @@ -28,3 +28,11 @@ int main() second(arr,size); return 0; } + +/* +----------------Sample Output---------------- +> 88 45 + +Time Compexity: O(n) +Space compexity: O(1) +*/ From 3a657980245f49c5ee4ff68a094882f2ab0dfb67 Mon Sep 17 00:00:00 2001 From: Sandra Date: Thu, 1 Sep 2022 16:40:53 +0530 Subject: [PATCH 30/63] updated readme --- algorithms/CPlusPlus/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index 0350073e..40c98abb 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -30,6 +30,8 @@ - [All unique triplet that sum up to given value](Arrays/three-sum.cpp) - [Next permutation](Arrays/next-permutation.cpp) - [Maximum Minimum Average of numbers](Arrays/max-min-avg.cpp) +- [Sparse Matrix](Arrays/sparse_matrix.cpp) + ## Dynamic-Programming From 28ff13a2a4ebdd8c04165c328b7ef310be94dc29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ana=20Karina=20Vergara=20Guzm=C3=A1n?= <37852043+anver-dev@users.noreply.github.com> Date: Thu, 1 Sep 2022 10:38:36 -0500 Subject: [PATCH 31/63] docs(Spanish): add bubble sort (#825) Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> --- docs/es/Ordenamiento/Bubble-Sort.md | 60 +++++++++++++++++++++++++++++ docs/es/README.md | 5 ++- 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 docs/es/Ordenamiento/Bubble-Sort.md diff --git a/docs/es/Ordenamiento/Bubble-Sort.md b/docs/es/Ordenamiento/Bubble-Sort.md new file mode 100644 index 00000000..4fe94d70 --- /dev/null +++ b/docs/es/Ordenamiento/Bubble-Sort.md @@ -0,0 +1,60 @@ +# Ordenamiento de Burbuja + +Bubble Sort, también conocido como Sinking Sort, es el algoritmo de clasificación más simple. Intercambia los números si no están en el orden correcto. La complejidad del tiempo en el peor de los casos es O(n^2) + +## Pasos + +1. Compara el primer elemento con el siguiente elemento. +2. Si el primer elemento es más grande que el siguiente, los elementos se intercambian. +3. Se realiza el paso 2 hasta que el número seleccionado se coloca en su posición correcta y luego se compara el siguiente elemento. +4. Se realizan varias pasadas hasta que se completa la clasificación. + +## Ejemplo + +Dado el arreglo: +**5 1 4 2 8** + +La arreglo ordenado es +**1 2 4 5 8** + +Pasos +**Primer vuelta** + +- ( **5 1** 4 2 8 ) → ( **1 5** 4 2 8 ), Aquí, el algoritmo compara los dos primeros elementos y los intercambia desde 5 > 1. +- ( 1 **5 4** 2 8 ) → ( 1 **4 5** 2 8 ), Intercambia desde 5 > 4 +- ( 1 4 **5 2** 8 ) → ( 1 4 **2 5** 8 ), Intercambia desde 5 > 2 +- ( 1 4 2 **5 8** ) → ( 1 4 2 **5 8** ), Ahora, dado que estos elementos ya están en orden (8 > 5), el algoritmo no los intercambia. + +**Segunda vuelta** + +- ( **1 4** 2 5 8 ) → ( **1 4** 2 5 8 ) +- ( 1 **4 2** 5 8 ) → ( 1 **2 4** 5 8 ), Intercambia desde 4 > 2 +- ( 1 2 **4 5** 8 ) → ( 1 2 **4 5** 8 ) +- ( 1 2 4 **5 8** ) → ( 1 2 4 **5 8** ) + +Ahora, el arreglo ya está ordenado, pero el algoritmo no sabe si está completo. El algoritmo necesita una vuelta completa adicional sin ningún intercambio para saber que está ordenado. + +**Tercera vuelta** + +- ( **1 2** 4 5 8 ) → ( **1 2** 4 5 8 ) +- ( 1 **2 4** 5 8 ) → ( 1 **2 4** 5 8 ) +- ( 1 2 **4 5** 8 ) → ( 1 2 **4 5** 8 ) +- ( 1 2 4 **5 8** ) → ( 1 2 4 **5 8** ) + +## Implementación + +- [C](../../../algorithms/C/sorting/bubble-sort.c) +- [C++](../../../algorithms/CPlusPlus/Sorting/bubble-sort.cpp) +- [CSharp](../../../algorithms/CSharp/src/Sorts/bubble-sort.cs) +- [Go](../../../algorithms/Go/sorting/bubble-sort.go) +- [Java](../../../algorithms/Java/sorting/bubble-sort.java) +- [JavaScript](../../../algorithms/JavaScript/src/sorting/bubble-sort.js) +- [Python](../../../algorithms/Python/sorting/bubble_sort.py) + +## URL del video + +[Video de Youtube acerca de Bubble Sort](https://www.youtube.com/watch?v=vnnL17I7pIY) + +## Otros + +[Wikipedia](https://es.wikipedia.org/wiki/Ordenamiento_de_burbuja) diff --git a/docs/es/README.md b/docs/es/README.md index cb97cd86..b144a2c8 100644 --- a/docs/es/README.md +++ b/docs/es/README.md @@ -1,8 +1,9 @@ # Algoritmos ## Ordenamiento -- [Merge Sort](./Ordenamiento/Merge-Sort.md) -- [Quick Sort](./Ordenamiento/Quick-Sort.md) +- [Ordenamiento de burbuja](./Ordenamiento/Bubble-Sort.md) +- [Ordenar por fusión](./Ordenamiento/Merge-Sort.md) +- [Ordenación rápida](./Ordenamiento/Quick-Sort.md) ## Otro From a68c012fea6ddf8097124a612b4f2eed97d3ab17 Mon Sep 17 00:00:00 2001 From: angshudas <110800802+angshudas@users.noreply.github.com> Date: Thu, 1 Sep 2022 21:09:18 +0530 Subject: [PATCH 32/63] chore(CPlusPlus): add prim's graph algorithm (#816) Co-authored-by: angshudas Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> --- .../CPlusPlus/Graphs/prim's_algorithm.cpp | 96 +++++++++++++++++++ algorithms/CPlusPlus/README.md | 1 + 2 files changed, 97 insertions(+) create mode 100644 algorithms/CPlusPlus/Graphs/prim's_algorithm.cpp diff --git a/algorithms/CPlusPlus/Graphs/prim's_algorithm.cpp b/algorithms/CPlusPlus/Graphs/prim's_algorithm.cpp new file mode 100644 index 00000000..613ac71d --- /dev/null +++ b/algorithms/CPlusPlus/Graphs/prim's_algorithm.cpp @@ -0,0 +1,96 @@ +/* + PREREQUISITE --> + 1. GRAPH + 2. PRIORITY QUEUE +*/ + +#include +using namespace std; + +vector>> graph; +vector vis; + +int primAlgorithm(){ + int totalCost = 0; + // totalCost will store the minimum spanning tree + set> pq; + /* + here pq -> priority queue ( it sorts all elements ) + it takes two value + 1. weight + 2. vertex + + Here, priority queue will be sorted according to weight + */ + + + pq.insert({0,1}); + /* + initialising the priority queue with {0,1} + Since, vertex 1 is the first vertex so we don't have to travel through a + edge to reach vertex 1 + */ + + while( !pq.empty() ){ + // taking the values of first elements from priority queue + int wt = (*pq.begin()).first; // weight of first vertex in priority queue + int v = (*pq.begin()).second; // first vertex + pq.erase(pq.begin()); + + if( vis[v] ) continue; + // if the vertex 'v' is visited then continue and don't proceed + vis[v] = true; + totalCost += wt; + // if the vertex is not visited then mark it visited + // and add the weight to total cost + + + // traverse all the child of vertex 'v' + for( auto elem : graph[v] ){ + + if( vis[elem.first] ) continue; + + // if child is visited then don't insert in priority queue + // else insert in priority queue + pq.insert({elem.second,elem.first}); + } + } + + graph.clear(); // clearing all values in graph + return totalCost; +} + +int main() +{ + int n,e; cin>>n>>e; + // n -> number of vertex in graph + // e -> number of edges in graph + + // initialising the graph + graph = vector>> (n+1); + + // initialising the visited vector to false + // it represent if the vertex is visited or not + vis = vector(n+1,false); + + + // taking the input of 'e' edges + for(int i=0; i>a>>b>>wt; + /* + a,b -> vertexs of graph + wt -> weight of edge between vertex 'a' and 'b' + */ + + graph[a].push_back({b,wt}); + graph[b].push_back({a,wt}); + // it creates adjcency list by pushing all + // the vertexs(with weight) which are directly connected by edges. + + } + + cout< Date: Fri, 2 Sep 2022 01:40:21 +1000 Subject: [PATCH 33/63] chore(CPlusPlus): add binary power on maths algorithm (#810) Co-authored-by: angshudas Co-authored-by: Mohnish Deshpande --- algorithms/CPlusPlus/Maths/binary-power.cpp | 56 +++++++++++++++++++++ algorithms/CPlusPlus/README.md | 1 + 2 files changed, 57 insertions(+) create mode 100644 algorithms/CPlusPlus/Maths/binary-power.cpp diff --git a/algorithms/CPlusPlus/Maths/binary-power.cpp b/algorithms/CPlusPlus/Maths/binary-power.cpp new file mode 100644 index 00000000..4362dfa0 --- /dev/null +++ b/algorithms/CPlusPlus/Maths/binary-power.cpp @@ -0,0 +1,56 @@ +#include +using namespace std; + +/* +The idea is to half the power on every iteration +Computes the power in log(n) operations + +On every iteration: +Square the base, half the power + +Special case - if power is odd: +Multiply the ans with a +Because the ODD-NUMBER % 2 == 1 + +Note: There will always be one iteration where power is odd +*/ + +long binpow(long a, long b){ + long ans=1; + // while b is greater than zero, we continue the binary exponentiation + while(b>0){ + // if b is odd, multiply result with base + if(b&1) + ans *= a; + // square the base + a *= a; + // half the power + b /= 2; + } + return ans; +} + +// source: @angshudas +long binpow_rec(long a, long b){ + // a^0 = 1 [for any a] + if(b==0) + return 1; + // recursive call for a^(b/2) + long ans = binpow_rec(a, b/2); + // square the result + ans *= ans; + // if b is odd, times by a + // to cover for + if(b&1) + ans *= a; + + return ans; +} + +int main(){ + long base, power; + cout<<"Enter the base and power: "<>base>>power; + cout< Date: Sun, 4 Sep 2022 15:08:24 +0530 Subject: [PATCH 35/63] chore(Java): add isomorphic strings (#828) * chore(Java): added isomorphic strings * added Time and space complexity * update algorithms/Java/README.md * update algorithms/Java/README.md file * spelling Correct README.md file --- algorithms/Java/README.md | 1 + .../Java/strings/isomorphic_strings.java | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 algorithms/Java/strings/isomorphic_strings.java diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index 70c32fad..09ffeb53 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -88,6 +88,7 @@ - [Boyer Moore Search](strings/Boyer_Moore.java) - [Reverse String](strings/reverse-string.java) - [First Non Repeating Character](strings/first-non-repeating-char.java) +- [Isomorphic Strings](strings/isomorphic_strings.java) ## Trees diff --git a/algorithms/Java/strings/isomorphic_strings.java b/algorithms/Java/strings/isomorphic_strings.java new file mode 100644 index 00000000..5079c21c --- /dev/null +++ b/algorithms/Java/strings/isomorphic_strings.java @@ -0,0 +1,61 @@ +/** + problem statement: + Given two strings- str1 and str2, check both are isomorphic or not + Isomorphic strings: Two strings are called isomorphic, + if there is a one to one mapping possible for every character of str1 to every character of str2 while preserving the order. + */ + + /*** + Example 1 => Input: str1="aab", str2="xxy" + Output: 1 + Example 2 => Input: str1="aab", str2="xyz" + Output: 0 + */ +/** + * + * Time Complexity: O(N) + Space Complexity: O(1) +*/ + + import java.util.Arrays; +import java.util.Scanner; + public class isomorphic_strings{ + public static void main(String[] args){ + Scanner input=new Scanner(System.in); + String str1=input.next(); + String str2=input.next(); + if(strings_are_isomorphic(str1,str2)){ + System.out.println("1"); + }else{ + System.out.println("0"); + } + } + public static boolean strings_are_isomorphic(String s1,String s2){ + int n=s1.length(); + int m=s2.length(); + //check length of both strings + if(n!=m){ + return false; + } + // array, make for mark visited characters of s2. + boolean visited[]=new boolean[256]; + //array, store mapping of every character from s1 to s2 + int map[]=new int[256]; + Arrays.fill(map,-1); + for (int i=0;i Date: Mon, 5 Sep 2022 06:25:17 +0530 Subject: [PATCH 36/63] chore(Java): add square root using binary search (#826) --- algorithms/Java/Maths/square-root.java | 49 ++++++++++++++++++++++++++ algorithms/Java/README.md | 1 + 2 files changed, 50 insertions(+) create mode 100644 algorithms/Java/Maths/square-root.java diff --git a/algorithms/Java/Maths/square-root.java b/algorithms/Java/Maths/square-root.java new file mode 100644 index 00000000..2c229a4e --- /dev/null +++ b/algorithms/Java/Maths/square-root.java @@ -0,0 +1,49 @@ +// Calculating Square root of a number which is not necessarily perfect square +// using Binary Search i.e. is using decrease and conquer approach +// Time: O(log(n)) +public class BinarySearchSQRT { + public static void main(String[] args) { + int n = 40; // number whose square root is to be calculated + int p = 3; // decimal precision required + + System.out.printf("%.3f", sqrt(n, p)); + } + static double sqrt(int n, int p) { + int s = 0; + int e = n; + + double root = 0.0; + + while (s <= e) { + int m = s + (e - s) / 2; //this method of calculating middle element avoids integer overflow + + if (m * m == n) { //the middle element is the required sqrt + return m; + } + else if (m * m > n) { //sqrt lies on the left part + e = m - 1; + } + else { // sqrt lies in the right part + s = m + 1; + root = m; + } + } + //now the root contains the nearest integer to the required square root + //now we need to add decimal precision to the root so that we can get as close to the exact sqrt + double incr = 0.1; //initialise + for (int i = 0; i < p; i++) { + while (root * root <= n) { //if the square of the root we have is less than the number + root += incr; //we will add incr decimal point each time + } + root -= incr; + incr /= 10; //here we increase the decimal point + } + + return root; //here we have root up to p decimal point + } +} + +/* +Output - +6.324 +*/ diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index 09ffeb53..07a3d1c8 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -33,6 +33,7 @@ - [Catalan Numbers](Maths/catalan-numbers.java) - [Nth Geek Onacci Number](Maths/nth-geek-onacci-number.java) - [Random Node in Linked List](Maths/algorithms_random_node.java) +- [Square Root using BinarySearch](Maths/square-root.java) ## Queues From 033fbe1503c0b55f32a7f1584c9aba6b94ab98c8 Mon Sep 17 00:00:00 2001 From: Ivan Kirspu <69795291+luneyune@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:31:56 +0700 Subject: [PATCH 37/63] chore(C): add bogo sort algorithm (#829) * Add bogo sort algorithm * Add bogo sort to README.md * Fix typo Co-authored-by: Ivan Kirspu --- algorithms/C/README.md | 1 + algorithms/C/sorting/bogo-sort.c | 83 ++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 algorithms/C/sorting/bogo-sort.c diff --git a/algorithms/C/README.md b/algorithms/C/README.md index 95c7796c..f2391b1a 100644 --- a/algorithms/C/README.md +++ b/algorithms/C/README.md @@ -59,6 +59,7 @@ - [Quick Sort](sorting/quick-sort.c) - [Shell Sort](sorting/shell-sort.c) - [Radix Sort](sorting/radix-sort.c) +- [Bogo Sort](sorting/bogo-sort.c) ## Strings diff --git a/algorithms/C/sorting/bogo-sort.c b/algorithms/C/sorting/bogo-sort.c new file mode 100644 index 00000000..cb56f60e --- /dev/null +++ b/algorithms/C/sorting/bogo-sort.c @@ -0,0 +1,83 @@ +/* +[ALGORITHM]: Bogo sort - one of the most inefficient sorting algorithm + +[PROBLEM]: Given an array, of size n, sort it. + +[TIME COMPLEXITY]: O(N * N!) + +[SAMPLE OF OUTPUT]: + +Before sorting: +8 3 7 4 6 2 1 9 5 10 +After sorting: +1 2 3 4 5 6 7 8 9 10 +*/ + +#include +#include +#include +#include + +void swap(int *a, int *b) // Swap values between *a and *b +{ + int tmp = *a; + *a = *b; + *b = tmp; +} + +void shuffle(int *array, int size) // Randomly shuffles given array for further info check DSA/algorithms/C/arrays/shuffle_array.c +{ + for (int i = 0; i < size; i++) { + swap(array + i, array + (rand() % size)); + } +} + +bool is_sorted(int *array, int size) // If array is sorted (by non-reduction) return true, else false +{ + for (int i = 1; i < size; i++) { + if (array[i] < array[i - 1]) + return false; + } + return true; +} + +void bogo_sort(int *array, int size) // Until array is sorted randomly shuffles an array. +{ + while (!is_sorted(array, size)) + shuffle(array, size); +} + +void print_array(int *array, int size) // Printing array +{ + for (int i = 0; i < size; i++) { + printf("%d ", array[i]); + } + putchar('\n'); +} + +int main() +{ + srand(time(NULL)); // Setup of random seed for random generation + int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + /* + Be accurate with size of array, sorting an array with 15 (for example) elements could + take unexpected amount of time. + + For example: + Sorting 15 elements is 36036 times longer than sorting 10 elements. + So, if sorting 10 elements take half a second, + then sorting 15 elements approximately take 5 hours (in real could longer). + */ + + shuffle(array, 10); // Shuffling an array before sorting + + printf("Before sorting:\n"); + print_array(array, 10); + + bogo_sort(array, 10); + printf("After sorting:\n"); + print_array(array, 10); + + return 0; +} + From e1bbc8b3020e607cd13c8fc5f2194c95a3c5995e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Mart=C3=ADnez?= <44838230+amartinez1224@users.noreply.github.com> Date: Tue, 6 Sep 2022 14:15:28 -0400 Subject: [PATCH 38/63] chore(Python): add find all permutations (#831) * added find_all_permutations * added test case for find_all_permutations * updated README with find all permutations * Added desc and time complexity of find_all_permutations * PR comment spelling correction --- algorithms/Python/README.md | 1 + .../Python/strings/find_all_permutations.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 algorithms/Python/strings/find_all_permutations.py diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index b7c82fd7..9bcc929b 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -63,6 +63,7 @@ - [Unique Character](strings/unique_character.py) - [Add String](strings/add_string.py) - [Rabin Karp algorithm](strings/rabin-karp-algorithm.py) +- [Find all permutations](strings/find_all_permutations.py) ## Dynamic Programming - [Print Fibonacci Series Up To N-th Term](dynamic_programming/fibonacci_series.py) diff --git a/algorithms/Python/strings/find_all_permutations.py b/algorithms/Python/strings/find_all_permutations.py new file mode 100644 index 00000000..cffb75d7 --- /dev/null +++ b/algorithms/Python/strings/find_all_permutations.py @@ -0,0 +1,28 @@ +""" +Find all the permutations of a given string +Sample input: 'ABC' +Expected output: ['ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA'] +Description: The algorithm is recursive. In each recursion, each element of the string (left) is removed and added to the beginning (head). This process is repeated until left is empty. +Time complexity: (n!) +""" + +def permutation(head, left, permutations): + if len(left) == 0: + permutations.append(head) + else: + for i in range(len(left)): + permutation(head+left[i], left[:i]+left[i+1:], permutations) + +def find_all_permutations(string): + permutations = [] + permutation('', string, permutations) + return permutations + +if __name__ == "__main__": + input = 'ABC' + output = find_all_permutations(input) + + expected = ['ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA'] + assert len(output) == len(expected), f"Expected 6 permutations, got: {len(expected)}" + for perm in expected: + assert perm in output, f"Expected permutation {perm} to be in output, missing" From a5ae1dc09165600857b3d5ca32aa402a63aa01c1 Mon Sep 17 00:00:00 2001 From: Ishantgarg-web <57170623+Ishantgarg-web@users.noreply.github.com> Date: Sun, 11 Sep 2022 19:02:36 +0530 Subject: [PATCH 39/63] chore(Java): add next greater element (#833) * chore(Java): added Next Greater Element * Update Next_Greater_Element.java file --- algorithms/Java/README.md | 1 + .../Java/stacks/Next_Greater_Element.java | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 algorithms/Java/stacks/Next_Greater_Element.java diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index 07a3d1c8..1f658016 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -75,6 +75,7 @@ - [Celebrity Problem](stacks/celebrity-problem.java) - [Sliding Window Maximum](stacks/sliding-window-maximum.java) - [Min Stack](stacks/Min-Stack.java) +- [Next Greater Element](stacks/Next_Greater_Element.java) ## Strings diff --git a/algorithms/Java/stacks/Next_Greater_Element.java b/algorithms/Java/stacks/Next_Greater_Element.java new file mode 100644 index 00000000..887025f9 --- /dev/null +++ b/algorithms/Java/stacks/Next_Greater_Element.java @@ -0,0 +1,79 @@ +/*** + * Problem Statement: + * Given an array arr[] of size N having distinct elements, the task is to find the next greater element for each element of the array in order of their appearance in the array. + * Next greater element means nearest element on right side which is greater than current element, + * if there is no suxh element, then put -1 for that. + * + */ + + + /*** + * Example 1: Input: arr=[1,3,2,4] n=4 + Output: 3 4 4 -1 + + Example 2: Input: arr=[6 8 0 1 3] n=5 + Output: 8 -1 1 3 -1 + */ + + /*** + * Time Complexity: O(N) + * Space Complexity: O(N) + */ + import java.util.Scanner; +import java.util.Stack; + + public class Next_Greater_Element { + public static void main(String[] args){ + Scanner input=new Scanner(System.in); + int n=input.nextInt(); + long arr[]=new long[n]; + for (int i=0;i st=new Stack<>(); + st.push(arr[n-1]); + for (int i=n-2;i>=0;i--) + { + if(st.isEmpty()) + { + st.push(arr[i]); + ans[i]=-1; + } + else + { + while(st.isEmpty()==false && arr[i]>=st.peek()) + { + st.pop(); + } + if(st.size()==0){ + ans[i]=-1; + }else{ + ans[i]=st.peek(); + } + st.push(arr[i]); + } + } + return ans; + } + } + \ No newline at end of file From 7db2f01de77bb19641983b39f2c14c538f5c53dd Mon Sep 17 00:00:00 2001 From: Mohit Chakraverty <79406819+mohitchakraverty@users.noreply.github.com> Date: Mon, 12 Sep 2022 01:12:18 +0530 Subject: [PATCH 40/63] docs(readme): add Java reviewer (#836) Added myself in the reviewer's list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 239d8e04..3a653dde 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ The programming should keep the naming convention rule of each programming langu | Programming Language | Users | | -------------------- | ----------------------------------------------------------- | | C or C++ | @Arsenic-ATG, @UG-SEP, @aayushjain7, @Ashborn-SM, @Ashad001 | -| Java | @TawfikYasser, @aayushjain7 | +| Java | @TawfikYasser, @aayushjain7, @mohitchakraverty | | C# | @ming-tsai, @Waqar-107 | | Go | @ayo-ajayi | | Python | @Arsenic-ATG, @sridhar-5 | From 7f85abfa3176ec3dcffad0fb295ab2129c3056b0 Mon Sep 17 00:00:00 2001 From: Ishantgarg-web <57170623+Ishantgarg-web@users.noreply.github.com> Date: Mon, 12 Sep 2022 01:15:00 +0530 Subject: [PATCH 41/63] chore(Go): add anagram (#834) --- algorithms/Go/README.md | 1 + algorithms/Go/strings/anagram.go | 55 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 algorithms/Go/strings/anagram.go diff --git a/algorithms/Go/README.md b/algorithms/Go/README.md index febe548e..680a3d30 100644 --- a/algorithms/Go/README.md +++ b/algorithms/Go/README.md @@ -27,4 +27,5 @@ ## String - [Palindrome Permutation](strings/palindrome-permutation.go) +- [Anagram](strings/anagram.go) diff --git a/algorithms/Go/strings/anagram.go b/algorithms/Go/strings/anagram.go new file mode 100644 index 00000000..6ae30240 --- /dev/null +++ b/algorithms/Go/strings/anagram.go @@ -0,0 +1,55 @@ +package main + +/** +Problem Statement: Given two strings s and t, find they are anagrams or not +An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once. + +**/ + +/*** +Example 1: Input: s="anagram" t="nagaram" + Output: true + +Example 2: Input: s="rat" t="car" + Output: false + +***/ + +/*** +Time complexity: O(n), n=length of string s +Space complexity: O(1) + +**/ + +import "fmt" + +func main() { + fmt.Println("Enter first string") + var first string + fmt.Scanln(&first) + fmt.Println("Enter second string") + var second string + fmt.Scanln(&second) + ans := isAnagram(first, second) + if ans == true { + fmt.Println("They are anagrams") + } else { + fmt.Println("They are not anagrams") + } +} +func isAnagram(s string, t string) bool { + var count [256]int + //var i int + for i := 0; i < len(s); i++ { + count[s[i]]++ + } + for i := 0; i < len(t); i++ { + count[t[i]]-- + } + for i := 0; i < len(count); i++ { + if count[i] != 0 { + return false + } + } + return true +} From daa8be12a492bf152fb903da76419e302f1e08da Mon Sep 17 00:00:00 2001 From: Ayomide AJAYI <70599813+ayo-ajayi@users.noreply.github.com> Date: Mon, 12 Sep 2022 02:44:32 +0200 Subject: [PATCH 42/63] enh(Go): import the string package on anagram (#838) --- algorithms/Go/strings/anagram.go | 15 +++++---------- algorithms/Go/strings/palindrome-permutation.go | 14 ++++++++------ 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/algorithms/Go/strings/anagram.go b/algorithms/Go/strings/anagram.go index 6ae30240..ca290e8d 100644 --- a/algorithms/Go/strings/anagram.go +++ b/algorithms/Go/strings/anagram.go @@ -1,29 +1,23 @@ -package main - /** Problem Statement: Given two strings s and t, find they are anagrams or not An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once. -**/ - -/*** Example 1: Input: s="anagram" t="nagaram" Output: true Example 2: Input: s="rat" t="car" Output: false -***/ - -/*** Time complexity: O(n), n=length of string s Space complexity: O(1) **/ +package strings + import "fmt" -func main() { +func RunIsAnagram() { fmt.Println("Enter first string") var first string fmt.Scanln(&first) @@ -37,9 +31,10 @@ func main() { fmt.Println("They are not anagrams") } } + func isAnagram(s string, t string) bool { var count [256]int - //var i int + for i := 0; i < len(s); i++ { count[s[i]]++ } diff --git a/algorithms/Go/strings/palindrome-permutation.go b/algorithms/Go/strings/palindrome-permutation.go index 779f8660..62b158a9 100644 --- a/algorithms/Go/strings/palindrome-permutation.go +++ b/algorithms/Go/strings/palindrome-permutation.go @@ -1,3 +1,10 @@ +/* +Given a string s, return true if we can have a palindrome from the permutation of the input +A palindrome is a word, number, phrase, or other sequence of characters which reads the same backward as forward, such as madam or racecar. + + Time: O(n) + Space: O(n) +*/ package strings import( @@ -5,12 +12,7 @@ import( "fmt" ) -/* -Given a string s, return true if we can have a palindrome from the permutation of the input - Time: O(n) - Space: O(n) -*/ func canPermutePalindrome(s string) bool { a := strings.Split(s,"") dictionary := make(map[string] int) @@ -29,7 +31,7 @@ func canPermutePalindrome(s string) bool { //You are welcome to play around with the test cases -func runPermutationCheck(){ +func RunPermutationCheck(){ input1 := "carerac" fmt.Printf("%t for input %s \n", canPermutePalindrome(input1), input1) //should print true From eb3d410c092d40ca0cee18e0039f57751821bc9b Mon Sep 17 00:00:00 2001 From: Hemant Sharma <101392754+hemant097@users.noreply.github.com> Date: Thu, 15 Sep 2022 02:14:31 +0530 Subject: [PATCH 43/63] chore(Java): add left leaf sum binary tree (#839) --- algorithms/Java/README.md | 1 + algorithms/Java/trees/Left-Leaf-Sum.java | 95 ++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 algorithms/Java/trees/Left-Leaf-Sum.java diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index 1f658016..ce60dd93 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -101,6 +101,7 @@ - [Min Heap](trees/MinHeap.java) - [Check Tree Traversal](trees/check-tree-traversal.java) - [Random Node of a binary tree](tree-random-node.java) +- [Left Leaf Sum of a Binary tree](trees/Left-Leaf-Sum.java) ## Backtracking diff --git a/algorithms/Java/trees/Left-Leaf-Sum.java b/algorithms/Java/trees/Left-Leaf-Sum.java new file mode 100644 index 00000000..2e4299aa --- /dev/null +++ b/algorithms/Java/trees/Left-Leaf-Sum.java @@ -0,0 +1,95 @@ +package Trees.Left_Leaf_Sum; +/* Problem Statement: Given the root of a binary tree, return the sum of all left leaves. */ + +//class to create Tree +class TreeNode{ + int data; + TreeNode left,right; + + TreeNode(int data){ + this.data = data; + this.left = this.right = null; + } + } +class Tree{ + TreeNode root; + + public Tree() { + root=null; + } +} +public class LeftLeafSum { + + //method to check if a node is leaf or not + static boolean isLeaf(TreeNode root) + { + if (root == null) return false; + if (root.left == null && root.right == null) + return true; + + return false; + } + + //returns the sum of left leaves + public static int leftsum(TreeNode root){ + + int leftLeavesSum=0; + + //to avoid null pointer exception + if(root!=null) + { + + //if a node's left is a leaf then add its value + if( isLeaf(root.left) ) + leftLeavesSum+=root.left.data; + + //else go to left + else + leftLeavesSum+=leftsum(root.left); + + //and finally go to right + leftLeavesSum+=leftsum(root.right); + } + + return leftLeavesSum; + + + + + } + +public static void main(String[] args) { + Tree tree = new Tree(); + tree.root = new TreeNode(1); + tree.root.left = new TreeNode(2); + tree.root.right = new TreeNode(3); + tree.root.left.left = new TreeNode(7); + tree.root.left.right = new TreeNode(8); + tree.root.right.left = new TreeNode(81); + tree.root.right.right= new TreeNode(75); + + + int sumOfLeftLeaves = leftsum(tree.root); + System.out.println("sum of left leaves is "+sumOfLeftLeaves); +} +} + +/* + +Eg. Input:- + 1 + / \ + 2 3 + / \ / \ + 7 8 81 75 +Output:- 88 + +Explanation:-there are two left leaves(nodes which have no child) 7 and 81 respectively in the tree and their sum is 88 + +Time Complexity:- O(N), where n is number of nodes in Binary Tree. + + +Code Description:- A method isLeaf() which returns a boolean, is created to check if a node is leaf or not, is yes then add its +left.data, if not then recursively go to its left and then its right. + +*/ From 368ec2e1dbfdd6129801a025540839f0b2458341 Mon Sep 17 00:00:00 2001 From: Chris Morin <78628697+christophermorin@users.noreply.github.com> Date: Wed, 14 Sep 2022 17:48:19 -0300 Subject: [PATCH 44/63] fix (Java): random node of a binary tree link (#841) Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> --- algorithms/Java/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index ce60dd93..91f5c09e 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -100,7 +100,7 @@ - [Zig-Zag Traversal of a Tree](trees/zig-zag-traversal.java) - [Min Heap](trees/MinHeap.java) - [Check Tree Traversal](trees/check-tree-traversal.java) -- [Random Node of a binary tree](tree-random-node.java) +- [Random Node of a binary tree](trees/tree-random-node.java) - [Left Leaf Sum of a Binary tree](trees/Left-Leaf-Sum.java) ## Backtracking From 8072446b24c70789b88d99910ea4c2783322bb18 Mon Sep 17 00:00:00 2001 From: Adelinked <95980174+Adelinked@users.noreply.github.com> Date: Sun, 25 Sep 2022 02:47:06 +0100 Subject: [PATCH 45/63] chore(JavaScript): add max heap (#842) --- algorithms/JavaScript/README.md | 4 + algorithms/JavaScript/src/heaps/max-heap.js | 155 ++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 algorithms/JavaScript/src/heaps/max-heap.js diff --git a/algorithms/JavaScript/README.md b/algorithms/JavaScript/README.md index f20b4faa..705c22d0 100644 --- a/algorithms/JavaScript/README.md +++ b/algorithms/JavaScript/README.md @@ -44,3 +44,7 @@ ## Recursion - [Factorial](src/recursion/factorial.js) + +## Heaps + +- [Max Heap](src/heaps/max-heap.js) \ No newline at end of file diff --git a/algorithms/JavaScript/src/heaps/max-heap.js b/algorithms/JavaScript/src/heaps/max-heap.js new file mode 100644 index 00000000..c1a4a915 --- /dev/null +++ b/algorithms/JavaScript/src/heaps/max-heap.js @@ -0,0 +1,155 @@ + +// A binary heap is a partially ordered binary tree +// that satisfies the heap property. +// The heap property specifies a relationship between parent and child nodes. +// In a max heap, all parent nodes are greater than +// or equal to their child nodes. +// Heaps are represented using arrays because +// it is faster to determine elements position and it needs +// less memory space as we don't need to maintain references to child nodes. +// An example: +// consider this max heap: [null, 47, 15, 35, 10, 3, 0, 25, 1]. +// The root node is the first element 47. its children are 15 and 35. +// The general indexes formula for an element of index i are: +// the parent is at: Math.floor(i / 2) +// the left child is at: i * 2 +// the right child is at: i * 2 + 1 + +const isDefined = (value) => value !== undefined && value !== null; + +class MaxHeap { + constructor() { + this.heap = [null]; + } + + // Insert a new element method + // this is a recursive method, the algorithm is: + // 1. Add the new element to the end of the array. + // 2. If the element is larger than its parent, switch them. + // 3. Continue switching until the new element is either + // smaller than its parent or you reach the root of the tree. + + insert(value) { + // add the new element to the end of the array + this.heap.push(value); + const place = (index) => { + const parentIndex = Math.floor(index / 2); + if (parentIndex <= 0) return; + if (this.heap[index] > this.heap[parentIndex]) { + // the switch is made here + [this.heap[parentIndex], this.heap[index]] = [ + this.heap[index], + this.heap[parentIndex], + ]; + place(parentIndex); + } + }; + // we begin the tests from the new element we added + place(this.heap.length - 1); + }; + + // Print heap content method + print() { + return this.heap; + }; + + // Remove an element from the heap + // it's also a recursive method, the algorithm will reestablish + // the heap property after removing the root: + // 1. Move the last element in the heap into the root position. + // 2. If either child of the root is greater than it, + // swap the root with the child of greater value. + // 3. Continue swapping until the parent is greater than both + // children or you reach the last level in the tree. + + remove() { + // save the root value element because this method will return it + const removed = this.heap[1]; + // the last element of the array is moved to the root position + this.heap[1] = this.heap[this.heap.length - 1]; + // the last element is removed from the array + this.heap.splice(this.heap.length - 1, 1); + + const place = (index) => { + if (index === this.heap.length - 1) return; + const child1Index = 2 * index; + const child2Index = child1Index + 1; + const child1 = this.heap[child1Index]; + const child2 = this.heap[child2Index]; + let newIndex = index; + // if the parent is greater than its two children + // then the heap property is respected + if ( + (!isDefined(child1) || this.heap[newIndex] >= child1) && + (!isDefined(child2) || this.heap[newIndex] >= child2) + ) { + return; + } + // test if the parent is less than its left child + if (isDefined(child1) && this.heap[newIndex] < child1) { + newIndex = child1Index; + } + // test if the parent is less than its right child + if (isDefined(child2) && this.heap[newIndex] < child2) { + newIndex = child2Index; + } + // the parent is switched with the child of the biggest value + if (index !== newIndex) { + [this.heap[index], this.heap[newIndex]] = [ + this.heap[newIndex], + this.heap[index], + ]; + place(newIndex); + } + }; + // start tests from the beginning of the array + place(1); + return removed; + }; + + // Sort an array using a max heap + // the elements of the array to sort were previously added one by one + // to the heap using the insert method + // the sorted array is the result of removing the heap's elements one by one + // using the remove method until it is empty + sort() { + const arr = []; + while (this.heap.length > 1) { + arr.push(this.remove()); + } + return arr; + }; + // Verify the heap property of a given max heap + verifyHeap() { + const explore = (index) => { + if (index === this.heap.length - 1) return true; + const child1Index = 2 * index; + const child2Index = 2 * index + 1; + const child1 = this.heap[child1Index]; + const child2 = this.heap[child2Index]; + return ( + (!isDefined(child1) || + (this.heap[index] >= child1 && explore(child1Index))) && + (!isDefined(child2) || + (this.heap[index] >= child2 && explore(child2Index))) + ); + }; + return explore(1); + }; +} + +const test = new MaxHeap(); +test.insert(1); +test.insert(3); +test.insert(0); +test.insert(10); +test.insert(35); +test.insert(25); +test.insert(47); +test.insert(15); +// display heap elements +console.log(test.print()); +// verify heap property +console.log(test.verifyHeap()); +// display the sorted array +console.log(test.sort()); From 478a8c80c07aeff625eed3f611e1087e3b186361 Mon Sep 17 00:00:00 2001 From: Ahmed Silat <105588821+ahmedsilat44@users.noreply.github.com> Date: Tue, 27 Sep 2022 19:15:50 +0500 Subject: [PATCH 46/63] Fixed typos in MinHeap (#851) --- docs/en/Tree/min-heap.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Tree/min-heap.md b/docs/en/Tree/min-heap.md index 307021ab..789e54dc 100644 --- a/docs/en/Tree/min-heap.md +++ b/docs/en/Tree/min-heap.md @@ -27,19 +27,19 @@ 3. If the parent is greater than the element, swap them (move the element one level up), then go to step two. 4. Stop if the parent is less or equal. -> **Note:** second and third steps sift the element up the tree, until correct order of elements is achieved. +> **Note:** second and third steps shift the element up the tree, until correct order of elements is achieved. **remove min** 1. Replace the root with the rightmost element on the deepest level. The new root is now current element. 2. Compare the current element with its smallest child. 3. If the element is greater than its smallest child, swap the element with its smallest child (move the element one level deeper), and go to step 2. 4. If both children are greater or equal to the current element, stop. -> **Note:** second and third steps sift the element down the tree until correct order of elements is achieved. +> **Note:** second and third steps shift the element down the tree until correct order of elements is achieved. ## Example - **Inserting** elements 4, 10, 2, 22, 45, 18
Output: 2 10 4 22 45 18
Explanation: The numbers are stored subsequently. 2 is the root, 10 and 4 are its children. The children of 10 are 22 and 45. The only child of 4 is 18. -- **Deleting** the minimum in 2 10 4 22 45 18
Output: 4 10 18 22 45
Explanation: First, 2 is swapped with 18. Then, 18 is sifted down the tree, until the elements are in correct order. The size of the heap is reduced by 1. +- **Deleting** the minimum in 2 10 4 22 45 18
Output: 4 10 18 22 45
Explanation: First, 2 is swapped with 18. Then, 18 is shifted down the tree, until the elements are in correct order. The size of the heap is reduced by 1. ## Implementation From b67f5e1786781bb3a9330cccd5b2dc4422c9dfb9 Mon Sep 17 00:00:00 2001 From: Devang-Shah-49 <80088008+Devang-Shah-49@users.noreply.github.com> Date: Thu, 29 Sep 2022 03:44:20 +0530 Subject: [PATCH 47/63] chore(CPlusPlus): add n-queens backtracking algorithm (#812) Co-authored-by: Arsenic <54987647+Arsenic-ATG@users.noreply.github.com> --- .../CPlusPlus/Backtracking/n-queens.cpp | 81 +++++++++++++++++++ algorithms/CPlusPlus/README.md | 3 + docs/en/Backtracking/N-Queens.md | 37 +++++++++ 3 files changed, 121 insertions(+) create mode 100644 algorithms/CPlusPlus/Backtracking/n-queens.cpp create mode 100644 docs/en/Backtracking/N-Queens.md diff --git a/algorithms/CPlusPlus/Backtracking/n-queens.cpp b/algorithms/CPlusPlus/Backtracking/n-queens.cpp new file mode 100644 index 00000000..aa05c1e6 --- /dev/null +++ b/algorithms/CPlusPlus/Backtracking/n-queens.cpp @@ -0,0 +1,81 @@ +/* Code contributed by Devang Shah to MakeContributions/DSA GitHub repository + +Below CPlusPlus code displays all possible solutions for a N-Queens problem. +Problem: Given a N x N chess board, arrange N queens in a way such that no two queens attack each other. Two queens are attacking each other if they are in same row, same column or diagonal +Input: N +Output: All solutions ( in grid format {Q - Queen, * - empty cell} ) of the N-queens problem +Time Complexity: O(N!) +*/ + +#include +using namespace std; + +int a[30]; + +int place(int pos) +{ + int i; + for (i = 1; i < pos; i++) + { + if ((a[i] == a[pos]) || ((abs(a[i] - a[pos]) == abs(i - pos)))) + return 0; + } + return 1; +} + +void print_sol(int n) +{ + int i, j; + for (i = 1; i <= n; i++) + { + for (j = 1; j <= n; j++) + { + if (a[i] == j) + cout << "Q\t"; + else + cout << "*\t"; + } + cout << "\n"; + } +} + +void queen(int n) +{ + int k = 1; + a[k] = 0; + int count = 0; + while (k != 0) + { + a[k] = a[k] + 1; + while ((a[k] <= n) && !place(k)) + a[k]++; + if (a[k] <= n) + { + if (k == n) + { + count++; + cout << "Solution #" << count << "\n"; + print_sol(n); + } + else + { + k++; + a[k] = 0; + } + } + else + k--; + } + cout << "\nTotal solutions=" << count; +} + +int main() +{ + unsigned int n; + cin >> n; + if (n < 15) + queen(n); + else + cout << "Invalid input. Program crashed"; + return 0; +} diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index 772d3b38..6a713e39 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -203,3 +203,6 @@ - [Decimal To Octal](Number-system/decimal_to_octal.cpp) - [Octal To Decimal](Number-system/octal_to_decimal.cpp) +## Backtracking + +- [N-Queens Problem](Backtracking/n-queens.cpp) \ No newline at end of file diff --git a/docs/en/Backtracking/N-Queens.md b/docs/en/Backtracking/N-Queens.md new file mode 100644 index 00000000..72a62b21 --- /dev/null +++ b/docs/en/Backtracking/N-Queens.md @@ -0,0 +1,37 @@ +# N-Queens Problem + +N-Queens is a backtracking problem. Given a N x N chess board, our task is to arrange N queens in a way such that no two queens attack each other. Two queens are attacking each other if they are in same row, same column or diagonal. Minimum chess board size should be 4x4. + +## Steps + +1. Each row contains 1 queen +2. For each row, keep track of the valid columns for queen placement. # (NOTE in a clever way) +3. DFS, start from the first row, try each valid column and backtrack if necessary. +4. Note that we can encode left/right diagonals as indexes in the following way: +For any (r, c), + - its top-left to the bottom-right diagonal index is r – c, ∈ (-n, n) + - its bottom-left to the top-right diagonal index is r + c, ∈ [0, 2n) +5. Each (r, c) takes the r-th row, c-th column, and the two diagonal indexes encoded above. +6. Now we can use 4 sets to indicate whether those row/col/diagonal have been taken, if yes, a queen cannot be placed at (r, c). +7. Moreover, if we search via dfs, proceeding row by row, we can avoid keeping # the row set, getting away with 3 sets only (column, and 2 diagonals). +8. Each set indicates whether the column/diagonal with the specified index has been taken. + +## Example + +Given size of Chessboard: **N=4** + +2 solutions exists. They are: +![4-Queens solution image](https://tse3.mm.bing.net/th?id=OIP.9CG0udqpuL95M7-dksk1ZwHaDc&pid=Api&P=0) + +## Time Complexity + +O(N!) + +## Implementation + +- [C++](../../../algorithms/CPlusPlus/Backtracking/n-queens.cpp) + +## Video URL + +[Youtube Video explaining N-queens problem](https://youtu.be/xFv_Hl4B83A) + From b4cd97f55a898f1c228476bbf225fb7c119a9fba Mon Sep 17 00:00:00 2001 From: Vishnu Rai Date: Sat, 1 Oct 2022 02:37:07 +0530 Subject: [PATCH 48/63] chore(Java) : add ternery search (#850) * Add Ternery-search in java * Updated Ternery Search Added Time compleities and iterative method of the ternery search. * Updated Ternery-Search * Updated Ternery Search Updated Again. --- algorithms/Java/README.md | 1 + algorithms/Java/searching/ternery-search.java | 142 ++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 algorithms/Java/searching/ternery-search.java diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index 91f5c09e..12f58878 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -54,6 +54,7 @@ - [Allocate minimum number of pages](searching/allocate-min-pages.java) - [Exponential Search](searching/Exponential-search.java) - [Interpolation Search](searching/interpolation-search.java) +- [Ternery Search](searching/ternery-search.java) ## Sorting diff --git a/algorithms/Java/searching/ternery-search.java b/algorithms/Java/searching/ternery-search.java new file mode 100644 index 00000000..be33d131 --- /dev/null +++ b/algorithms/Java/searching/ternery-search.java @@ -0,0 +1,142 @@ +// Java program to illustrate +// the iterative approach to ternary search +// + +class main { + + // Function to perform Ternary Search + // recursive Function + // Time Complexity: O(log3n) + // Auxiliary Space: O(log3n) + + static int ternarySearchRecursive(int l, int r, int key, int ar[]) + + { + while (r >= l) { + + // Find the mid1 mid2 + int mid1 = l + (r - l) / 3; + int mid2 = r - (r - l) / 3; + + // Check if key is present at any mid + if (ar[mid1] == key) { + return mid1; + } + if (ar[mid2] == key) { + return mid2; + } + + // Since key is not present at mid, + // check in which region it is present + // then repeat the Search operation + // in that region + + if (key < ar[mid1]) { + + // The key lies in between l and mid1 + r = mid1 - 1; + } + else if (key > ar[mid2]) { + + // The key lies in between mid2 and r + l = mid2 + 1; + } + else { + + // The key lies in between mid1 and mid2 + l = mid1 + 1; + r = mid2 - 1; + } + } + + // Key not found + return -1; + } + + // Function to perform Iterative Ternary Search + // Time Complexity: O(log3n), where n is the size of the array. + // Auxiliary Space: O(1) + + static int ternarySearchIterative(int l, int r, int key, int ar[]) + + { + while (r >= l) { + + // Find the mid1 mid2 + int mid1 = l + (r - l) / 3; + int mid2 = r - (r - l) / 3; + + // Check if key is present at any mid + if (ar[mid1] == key) { + return mid1; + } + if (ar[mid2] == key) { + return mid2; + } + + // Since key is not present at mid, + // check in which region it is present + // then repeat the Search operation + // in that region + + if (key < ar[mid1]) { + + // The key lies in between l and mid1 + r = mid1 - 1; + } + else if (key > ar[mid2]) { + + // The key lies in between mid2 and r + l = mid2 + 1; + } + else { + + // The key lies in between mid1 and mid2 + l = mid1 + 1; + r = mid2 - 1; + } + } + + // Key not found + return -1; + } + + + // Driver code + public static void main(String args[]) + { + int l, r, p, key; + + // Get the array + // Sort the array if not sorted + int ar[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + // Starting index + l = 0; + + // length of array + r = 9; + + // Checking for 5 + + // Key to be searched in the array + key = 5; + + // Search the key using ternarySearch + p = ternarySearchRecursive(l, r, key, ar); + + // Print the result + System.out.println("Index of " + key + " is " + p); + + // Checking for 50 + + // Key to be searched in the array + key = 50; + + // Search the key using ternarySearch + p = ternarySearchIterative(l, r, key, ar); + + // Print the result + System.out.println("Index of " + key + " is " + p); + } +} From 62907b69ec74e2bff1195a1e0973970c231b5924 Mon Sep 17 00:00:00 2001 From: Vivi Koutsoumanidou <72651591+kparaske@users.noreply.github.com> Date: Sat, 1 Oct 2022 00:11:58 +0300 Subject: [PATCH 49/63] chore(Java) : add roman numerals conversion (#849) * Add Roman Numerals Conversion * roman numerals conversion, expanded description * roman numerals conversion, expanded description --- algorithms/Java/Maths/roman-numerals.java | 154 ++++++++++++++++++++++ algorithms/Java/README.md | 1 + 2 files changed, 155 insertions(+) create mode 100644 algorithms/Java/Maths/roman-numerals.java diff --git a/algorithms/Java/Maths/roman-numerals.java b/algorithms/Java/Maths/roman-numerals.java new file mode 100644 index 00000000..55dda0fc --- /dev/null +++ b/algorithms/Java/Maths/roman-numerals.java @@ -0,0 +1,154 @@ +import java.util.HashMap; + +/** + * Problem: To convert an integer to its Roman numeral equivalent and vice versa. + * ---------------------------------------------------------------------------------------------------------------- + * + * Time Complexity: O(n) + * Space Complexity: O(1) + * + * ---------------------------------------------------------------------------------------------------------------- + * + * Constraints: + * The input sting should contain only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M'). + * It is guaranteed that the input is a valid roman numeral in the range [1, 3999]. + * + * ---------------------------------------------------------------------------------------------------------------- + * + * Description: + * There are seven basic different symbols to represent roman numerals: I, V, X, L, C, D and M. + * Those being: + * Symbol Value + * I 1 + * V 5 + * X 10 + * L 50 + * C 100 + * D 500 + * M 1000 + * + * Roman numerals are usually written from largest to smallest, from left to right. + * There are six instances where this rule does not apply and subtraction is used instead: + * I can be placed before V (5) and X (10) to make 4 (IV) and 9 (IX). (5 - 1 and 10 - 1, respectively) + * X can be placed before L (50) and C (100) to make 40 (XL) and 90 (XC). (50 - 10 and 100 - 10, respectively) + * C can be placed before D (500) and M (1000) to make 400 (CD) and 900 (CM). (500 - 100 and 1000 - 100, respectively) + * + * ---------------------------------------------------------------------------------------------------------------- + * + * Examples: + * 1) Input: s = "II" + * Output: 2 + * Explanation: 2 = 1 + 1 = I + I. + * + * 2) Input: s = 31 + * Output: "XXXI" + * Explanation: 31 = 30 + 1 = XXX + I. + * + * 3) Input: s = "CMXLI" + * Output: 941 + * Explanation: 941 = 900 + 40 + 1 = CM + XL + I. + * +**/ + +public class RomanNumeralConverter { + + /** + * This method converts a roman numeral to its integer equivalent. + * @param s The input roman numeral to be converted. + * @return The integer equivalent of the roman numeral. + */ + public int romanToInt(String s){ + int result = 0; + int prev = 0; + + // for each character in the given string + for (int i = s.length() - 1; i >= 0; i--) { + // get the integer value of the character + int current = switch (s.charAt(i)) { + case 'I' -> 1; + case 'V' -> 5; + case 'X' -> 10; + case 'L' -> 50; + case 'C' -> 100; + case 'D' -> 500; + case 'M' -> 1000; + default -> throw new IllegalArgumentException("Invalid roman number"); + }; + + // check if the right number is greater than the left number (previous character) in the given string (case of subtraction) + if (current < prev) { + result -= current; // subtract the right number from the result + } else { + result += current; + } + prev = current; // update the previous number + } + return result; + } + + /** + * This method converts an integer to its roman numeral equivalent. + * @param num The input integer to be converted. + * @return The roman numeral equivalent of the integer. + */ + public String intToRoman(int num) { + // Create a hashmap to store the 7 basic roman numerals and the six special cases of subtraction + HashMap map = new HashMap<>(); + map.put(1,"I"); + map.put(4,"IV"); + map.put(5,"V"); + map.put(9,"IX"); + map.put(10,"X"); + map.put(40,"XL"); + map.put(50,"L"); + map.put(90,"XC"); + map.put(100,"C"); + map.put(400,"CD"); + map.put(500,"D"); + map.put(900,"CM"); + map.put(1000,"M"); + + int[] arr = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; // store the keys of the hashmap in an array + int len = arr.length; + + StringBuilder result = new StringBuilder(); + while(num > 0){ + int i; + // find the largest number in the array that is less than or equal to the given number + for(i = 0; i < len; i++) { + if (arr[i] <= num) break; + } + + result.append(map.get(arr[i])); // append the equivalent roman numeral to the result + num = num - arr[i]; // subtract the found key from the given number + } + return result.toString(); + } + + public static void main(String[] args) { + RomanNumeralConverter converter = new RomanNumeralConverter(); + // Roman to Integer + System.out.println("Roman to Integer Conversion Examples:"); + System.out.println("DCXXI = " + converter.romanToInt("DCXXI")); + System.out.println("II = " + converter.romanToInt("II")); + System.out.println("CCXCIV = " + converter.romanToInt("CCXCIV")); + System.out.println("IX = " + converter.romanToInt("IX")); + System.out.println("XXXI = " + converter.romanToInt("XXXI")); + System.out.println("CMXLI = " + converter.romanToInt("CMXLI")); + System.out.println("MCCXXVI = " + converter.romanToInt("MCCXXVI")); + System.out.println("CXLVIII = " + converter.romanToInt("CXLVIII")); + + System.out.println("<------------------------------------------------------------------->"); + + // Integer to Roman + System.out.println("Integer to Roman Conversion Examples:"); + System.out.println(621 + " = " + converter.intToRoman(621)); + System.out.println(2 + " = " + converter.intToRoman(2)); + System.out.println(294 + " = " + converter.intToRoman(294)); + System.out.println(9 + " = " + converter.intToRoman(9)); + System.out.println(31 + " = " + converter.intToRoman(31)); + System.out.println(941 + " = " + converter.intToRoman(941)); + System.out.println(1226 + " = " + converter.intToRoman(1226)); + System.out.println(148 + " = " + converter.intToRoman(148)); + } +} diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index 12f58878..c3d90e94 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -34,6 +34,7 @@ - [Nth Geek Onacci Number](Maths/nth-geek-onacci-number.java) - [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) ## Queues From 5d18a66cd80a3dfb87f65e7b5d835b8d6df1f935 Mon Sep 17 00:00:00 2001 From: AMIT KUSHWAHA Date: Mon, 3 Oct 2022 19:14:29 +0530 Subject: [PATCH 50/63] Update roman-numerals.java (#901) corrected the spelling mistake because of which my pull request failed the spell check --- algorithms/Java/Maths/roman-numerals.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/Java/Maths/roman-numerals.java b/algorithms/Java/Maths/roman-numerals.java index 55dda0fc..3f907f41 100644 --- a/algorithms/Java/Maths/roman-numerals.java +++ b/algorithms/Java/Maths/roman-numerals.java @@ -10,7 +10,7 @@ import java.util.HashMap; * ---------------------------------------------------------------------------------------------------------------- * * Constraints: - * The input sting should contain only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M'). + * The input string should contain only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M'). * It is guaranteed that the input is a valid roman numeral in the range [1, 3999]. * * ---------------------------------------------------------------------------------------------------------------- From fe130ddc4f6183bb97f0addbac7eb15d35d3b6a7 Mon Sep 17 00:00:00 2001 From: Adelinked <95980174+Adelinked@users.noreply.github.com> Date: Tue, 4 Oct 2022 21:01:15 +0100 Subject: [PATCH 51/63] chore(JavaScript): add min heap (#897) --- algorithms/JavaScript/README.md | 3 +- algorithms/JavaScript/src/heaps/min-heap.js | 155 ++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 algorithms/JavaScript/src/heaps/min-heap.js diff --git a/algorithms/JavaScript/README.md b/algorithms/JavaScript/README.md index 705c22d0..11c9b934 100644 --- a/algorithms/JavaScript/README.md +++ b/algorithms/JavaScript/README.md @@ -47,4 +47,5 @@ ## Heaps -- [Max Heap](src/heaps/max-heap.js) \ No newline at end of file +- [Max Heap](src/heaps/max-heap.js) +- [Min Heap](src/heaps/min-heap.js) diff --git a/algorithms/JavaScript/src/heaps/min-heap.js b/algorithms/JavaScript/src/heaps/min-heap.js new file mode 100644 index 00000000..a78b190f --- /dev/null +++ b/algorithms/JavaScript/src/heaps/min-heap.js @@ -0,0 +1,155 @@ + +// A binary heap is a partially ordered binary tree +// that satisfies the heap property. +// The heap property specifies a relationship between parent and child nodes. +// In a min heap, all child nodes are larger than +// or equal to their parent nodes. +// Heaps are represented using arrays because +// it is faster to determine elements position and it needs +// less memory space as we don't need to maintain references to child nodes. +// An example: +// consider this min heap: [null, 0, 3, 1, 10, 35, 25, 47, 15]. +// The root node is the first element 0. its children are 3 and 1. +// The general indexes formula for an element of index i are: +// the parent is at: Math.floor(i / 2) +// the left child is at: i * 2 +// the right child is at: i * 2 + 1 + +const isDefined = (value) => value !== undefined && value !== null; + +class MinHeap { + constructor() { + this.heap = [null]; + } + + // Insert a new element method + // this is a recursive method, the algorithm is: + // 1. Add the new element to the end of the array. + // 2. If the element is less large than its parent, switch them. + // 3. Continue switching until the new element is either + // larger than its parent or you reach the root of the tree. + + insert(value) { + // add the new element to the end of the array + this.heap.push(value); + const place = (index) => { + const parentIndex = Math.floor(index / 2); + if (parentIndex <= 0) return; + if (this.heap[index] < this.heap[parentIndex]) { + // the switch is made here + [this.heap[parentIndex], this.heap[index]] = [ + this.heap[index], + this.heap[parentIndex], + ]; + place(parentIndex); + } + }; + // we begin the tests from the new element we added + place(this.heap.length - 1); + }; + + // Print heap content method + print() { + return this.heap; + }; + + // Remove an element from the heap + // it's also a recursive method, the algorithm will reestablish + // the heap property after removing the root: + // 1. Move the last element in the heap into the root position. + // 2. If either child of the root is less large than it, + // swap the root with the child of the least large value. + // 3. Continue swapping until the parent is less great than both + // children or you reach the last level in the tree. + + remove() { + // save the root value element because this method will return it + const removed = this.heap[1]; + // the last element of the array is moved to the root position + this.heap[1] = this.heap[this.heap.length - 1]; + // the last element is removed from the array + this.heap.splice(this.heap.length - 1, 1); + + const place = (index) => { + if (index === this.heap.length - 1) return; + const child1Index = 2 * index; + const child2Index = child1Index + 1; + const child1 = this.heap[child1Index]; + const child2 = this.heap[child2Index]; + let newIndex = index; + // if the parent is greater than its two children + // then the heap property is respected + if ( + (!isDefined(child1) || this.heap[newIndex] <= child1) && + (!isDefined(child2) || this.heap[newIndex] <= child2) + ) { + return; + } + // test if the parent is larger than its left child + if (isDefined(child1) && this.heap[newIndex] > child1) { + newIndex = child1Index; + } + // test if the parent is larger than its right child + if (isDefined(child2) && this.heap[newIndex] > child2) { + newIndex = child2Index; + } + // the parent is switched with the child of the least value + if (index !== newIndex) { + [this.heap[index], this.heap[newIndex]] = [ + this.heap[newIndex], + this.heap[index], + ]; + place(newIndex); + } + }; + // start tests from the beginning of the array + place(1); + return removed; + }; + + // Sort an array using a min heap + // the elements of the array to sort were previously added one by one + // to the heap using the insert method + // the sorted array is the result of removing the heap's elements one by one + // using the remove method until it is empty + sort() { + const arr = []; + while (this.heap.length > 1) { + arr.push(this.remove()); + } + return arr; + }; + // Verify the heap property of a given max heap + verifyHeap() { + const explore = (index) => { + if (index === this.heap.length - 1) return true; + const child1Index = 2 * index; + const child2Index = 2 * index + 1; + const child1 = this.heap[child1Index]; + const child2 = this.heap[child2Index]; + return ( + (!isDefined(child1) || + (this.heap[index] <= child1 && explore(child1Index))) && + (!isDefined(child2) || + (this.heap[index] <= child2 && explore(child2Index))) + ); + }; + return explore(1); + }; +} + +const test = new MinHeap(); +test.insert(1); +test.insert(3); +test.insert(0); +test.insert(10); +test.insert(35); +test.insert(25); +test.insert(47); +test.insert(15); +// display heap elements +console.log(test.print()); +// verify heap property +console.log(test.verifyHeap()); +// display the sorted array +console.log(test.sort()); From c6a454590da4ce86b0f61fac4b567824d46d9752 Mon Sep 17 00:00:00 2001 From: AMIT KUSHWAHA Date: Wed, 5 Oct 2022 01:35:38 +0530 Subject: [PATCH 52/63] chore(CPlusPlus): add sliding windows (#853) --- algorithms/CPlusPlus/README.md | 2 + .../CPlusPlus/Strings/sliding-window.cpp | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 algorithms/CPlusPlus/Strings/sliding-window.cpp diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index 6a713e39..13139d2d 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -33,6 +33,7 @@ - [Sparse Matrix](Arrays/sparse_matrix.cpp) + ## Dynamic-Programming - [Longest Common Subsequence](Dynamic-Programming/longest-common-subsequence.cpp) @@ -128,6 +129,7 @@ - [Boyer Moore pattern search](Strings/Boyer_Moore.cpp) - [Longest common prefix](Strings/longest-common-prefix.cpp) - [First unique character in the string](Strings/first-unique-character.cpp) +- [Sliding Window to match target string](Strings/sliding-window.cpp) ## Trees diff --git a/algorithms/CPlusPlus/Strings/sliding-window.cpp b/algorithms/CPlusPlus/Strings/sliding-window.cpp new file mode 100644 index 00000000..a5f60cd4 --- /dev/null +++ b/algorithms/CPlusPlus/Strings/sliding-window.cpp @@ -0,0 +1,42 @@ +/* +Description: A program to find target sub string in given string + +Approach: Using sliding window technique to compare every possible substring with the target string. +It also supports variable length target inputs since we are initialising window size with size of target + +Time complexity: O(n) +*/ + +#include +#include + +using namespace std; + +void sliding(string s,string target){ + int window_size=target.size(); + bool notfound=true; + for(int i=0;i>target; + + sliding(s,target); + + return 0; +} \ No newline at end of file From 25f3e9dcae81d584748e1971f2f91a0a61a960dc Mon Sep 17 00:00:00 2001 From: Ankit Gupta Date: Wed, 5 Oct 2022 14:06:04 +0530 Subject: [PATCH 53/63] chore(CPlusPlus): add even odd algorithm (#876) * Added Check-Even-Odd Algo * Spell-Check Failed error fixed Co-authored-by: en1gm479 --- algorithms/CPlusPlus/Maths/Check-Even_Odd.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 algorithms/CPlusPlus/Maths/Check-Even_Odd.cpp diff --git a/algorithms/CPlusPlus/Maths/Check-Even_Odd.cpp b/algorithms/CPlusPlus/Maths/Check-Even_Odd.cpp new file mode 100644 index 00000000..6bae63f2 --- /dev/null +++ b/algorithms/CPlusPlus/Maths/Check-Even_Odd.cpp @@ -0,0 +1,33 @@ +#include +using namespace std; + +//Function to check whether a number is Odd or not. +//We use a single Odd function to check for Even-Odd, If it return true then it is Odd else it is Even. +bool isOddBin(int num){ + //We compare the last bit of the number to decide for Even or Odd + //If the last bit of the num is set (i.e. 1) then number is odd and its "Binary And (&)" with the 1 will return true(1). + //Similarly in case of even num last bit is unset/off (i.e. 0) and its "Binary And (&)" with the 1 will return false(0). + return (num&1); +} + +bool isOddN(int num){ + //In this we use the Mod(%) operator to check for Even-Odd. + //If the num is Odd then (num%2) will give 1 and function will return true. + //If the num is Even then (num%2) will give 0 and function will return false. + return (num%2==1); +} + +int main() { + int num; + cin >> num; //Taking input from the user + string result; + result = isOddBin(num) ? "Odd" : "Even"; //Evaluating string based on result from isOdd function + cout << result< Date: Thu, 6 Oct 2022 04:43:23 +0530 Subject: [PATCH 54/63] enh(en): documentation in bubble sort (#868) I add the space Complexity also --- docs/en/Sorting/Bubble-Sort.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/en/Sorting/Bubble-Sort.md b/docs/en/Sorting/Bubble-Sort.md index a917c6af..43fd563f 100644 --- a/docs/en/Sorting/Bubble-Sort.md +++ b/docs/en/Sorting/Bubble-Sort.md @@ -1,7 +1,9 @@ # Bubble Sort -Bubble Sort also known as Sinking Sort is the simplest sorting algorithm. It swaps the numbers if they are not in correct order. The Worst Case Time Complexity is O(n^2) - +Bubble Sort also known as Sinking Sort is the simplest sorting algorithm. It swaps the numbers if they are not in correct order. +The Worst Case - +Time Complexity : O(n^2) +Space Compldxity : O(1) i.e it use constant space. ## Steps 1. Compares the first element with the next element. From 6b7530c58775faf6ac06baa84e9667572fea69dc Mon Sep 17 00:00:00 2001 From: robotboyfriend <56538508+robotboyfriend@users.noreply.github.com> Date: Thu, 6 Oct 2022 11:16:14 +1100 Subject: [PATCH 55/63] docs(readme): remove duplicated contribution (#929) Spelling mistake - double word. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a653dde..c8d8263b 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ The file should conform to the `problem` specification, and the extension (**Eg. #### Project/Folder-based Contributions -The project and folder-based contributions have a bit more stricter contribution contribution specifications. +The project and folder-based contributions have a bit more stricter contribution specifications. The folder should conform to the `problem` specification, along with the following specifications From 75e93fd88521cc57723ab0d62550db3f7ddafde7 Mon Sep 17 00:00:00 2001 From: Katherine Hambley Date: Thu, 6 Oct 2022 08:01:48 -0500 Subject: [PATCH 56/63] Added CSharp Fibonacci Checker program (#913) --- algorithms/CSharp/README.md | 1 + .../CSharp/src/Maths/fibonacci-checker.cs | 32 +++++++++++++++++++ .../test/Maths/fibonacci-checker-tests.cs | 20 ++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 algorithms/CSharp/src/Maths/fibonacci-checker.cs create mode 100644 algorithms/CSharp/test/Maths/fibonacci-checker-tests.cs diff --git a/algorithms/CSharp/README.md b/algorithms/CSharp/README.md index 5f17d0b7..edee912a 100644 --- a/algorithms/CSharp/README.md +++ b/algorithms/CSharp/README.md @@ -40,6 +40,7 @@ To run the `.cs` file, kindly use [.Net Finddle](https://dotnetfiddle.net/) ## Maths - [Abundant Number](src/Maths/abundant-number.cs) +- [Fibonacci Checker](src/Maths/fibonacci-checker.cs) - [Naismith's Rule](src/Maths/naismith-rule.cs) ## Queues diff --git a/algorithms/CSharp/src/Maths/fibonacci-checker.cs b/algorithms/CSharp/src/Maths/fibonacci-checker.cs new file mode 100644 index 00000000..61cc94a8 --- /dev/null +++ b/algorithms/CSharp/src/Maths/fibonacci-checker.cs @@ -0,0 +1,32 @@ +/* Fibonacci Checker - A program to check whether a number is in the Fibonacci sequence. +This sequence is defined by: Fn = Fn-1 + Fn-2 (to find Fn, you add the previous two numbers. The program calculates the Fibonacci sequence up to and including the given number. */ +using System; + +namespace Algorithms.Maths +{ + public class Fibonacci + { + public static bool Checker(int num) + { + if (num == 2 || num == 3) + { + return true; + } + var num1 = 0; + var num2 = 1; + var num3 = 1; + + for (var i = 0; i <= num; i++) + { + if (num1 == num) + { + return true; + } + num1 = num2; + num2 = num3; + num3 = num1 + num2; + } + return false; + } + } +} diff --git a/algorithms/CSharp/test/Maths/fibonacci-checker-tests.cs b/algorithms/CSharp/test/Maths/fibonacci-checker-tests.cs new file mode 100644 index 00000000..25a2c58b --- /dev/null +++ b/algorithms/CSharp/test/Maths/fibonacci-checker-tests.cs @@ -0,0 +1,20 @@ +using NUnit.Framework; + +namespace Algorithms.Tests.Maths +{ + [TestFixture] + internal class Checker + { + [TestCase(1, true)] + [TestCase(3, true)] + [TestCase(4, false)] + [TestCase(34, true)] + [TestCase(70, false)] + [TestCase(110, false)] + public void FibonacciChecker_ShouldGetExpectedResult(int num, bool expected) + { + var result = Algorithms.Maths.Fibonacci.Checker(num); + Assert.AreEqual(expected, result); + } + } +} From 9b6d8e0b77345547346d3853f4b93033dfa5eae8 Mon Sep 17 00:00:00 2001 From: KARTIKEY SINGH <91819372+kartik-ey1@users.noreply.github.com> Date: Thu, 6 Oct 2022 18:45:10 +0530 Subject: [PATCH 57/63] chore(CPlusPlus): add detecting a cycle in a graph (#862) * Add files via upload * Delete Detecting a cycle in a graph (Using three color mechanism).cpp * Create detecting-cycle-in-a-graph-using-three-color-mechanism.cpp * Update detecting-cycle-in-a-graph-using-three-color-mechanism.cpp * Update detecting-cycle-in-a-graph-using-three-color-mechanism.cpp * Update README.md --- ...in-a-graph-using-three-color-mechanism.cpp | 127 ++++++++++++++++++ algorithms/CPlusPlus/README.md | 5 +- 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 algorithms/CPlusPlus/Graphs/detecting-cycle-in-a-graph-using-three-color-mechanism.cpp diff --git a/algorithms/CPlusPlus/Graphs/detecting-cycle-in-a-graph-using-three-color-mechanism.cpp b/algorithms/CPlusPlus/Graphs/detecting-cycle-in-a-graph-using-three-color-mechanism.cpp new file mode 100644 index 00000000..c052e031 --- /dev/null +++ b/algorithms/CPlusPlus/Graphs/detecting-cycle-in-a-graph-using-three-color-mechanism.cpp @@ -0,0 +1,127 @@ +// A DFS based approach to find if there is a cycle +// in a directed graph. + +#include + +using namespace std; + +// Declaring an enum of three colors +enum Color {WHITE, GRAY, BLACK}; + +// Class Graph +// Graph class represents a directed graph using +// adjacency list representation + +class Graph +{ + int V; // No. of vertices + list* adj; // adjacency list + + // DFS traversal of the vertices reachable from v + bool DFSUtil(int v, int color[]); + +public: + + Graph(int V); // The Constructor + + // Function to add an edge to graph + void addEdge(int v, int w); + // Function to check whether graph is cyclic or not + bool isCyclic(); +}; + +// Constructor +Graph::Graph(int V) +{ + this->V = V; + adj = new list[V]; +} + +// Utility function to add an edge +void Graph::addEdge(int v, int w) +{ + adj[v].push_back(w); // Add w to v's list. +} + +// Recursive function to find if there is back edge +// in DFS subtree tree rooted with 'u' + +bool Graph::DFSUtil(int u, int color[]) +{ + // GRAY : This vertex is being processed (DFS + // for this vertex has started, but not + // ended (or this vertex is in function + // call stack) + + color[u] = GRAY; + + // Iterate through all adjacent vertices + + list::iterator i; + for (i = adj[u].begin(); i != adj[u].end(); ++i) + { + int v = *i; // An adjacent of u + + // If there is Gray + if (color[v] == GRAY) + return true; + + // If v is not processed and there is a back + // edge in subtree rooted with v Call DFSUtil and check accordingly + if (color[v] == WHITE && DFSUtil(v, color)) + return true; + } + + // Mark this vertex as processed + color[u] = BLACK; + + return false; +} + +// Returns true if there is a cycle in graph +bool Graph::isCyclic() +{ + // Initialize color of all vertices as WHITE + int *color = new int[V]; + for (int i = 0; i < V; i++) + color[i] = WHITE; + + // Do a DFS traversal beginning with all + // vertices + for (int i = 0; i < V; i++) + if (color[i] == WHITE) + if (DFSUtil(i, color) == true) + return true; + + return false; +} + +// Driver code to test above +int main() +{ + /* + + 0--->1--->2--->3--->3 + + 2<---->0 + + total 6 edges + + */ + + // Create a graph given in the above diagram + Graph g(4); + g.addEdge(0, 1); + g.addEdge(0, 2); + g.addEdge(1, 2); + g.addEdge(2, 0); + g.addEdge(2, 3); + g.addEdge(3, 3); + + if (g.isCyclic()) + cout << "Graph contains cycle"; + else + cout << "Graph doesn't contain cycle"; + + return 0; +} diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index 13139d2d..b9b71156 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -56,6 +56,9 @@ - [Cycle Detection](Graphs/cycle-detection.cpp) - [Prim's Algorithm](Graphs/prim's_algorithm.cpp) - [Floyd Warshall](Graphs/floyd-warshall.cpp) +- [Detecting Cycle in Directed graph using three colors](Graphs/detecting-cycle-in-a-graph-using-three-color-mechanism.cpp) + + ## Multiplication @@ -207,4 +210,4 @@ ## Backtracking -- [N-Queens Problem](Backtracking/n-queens.cpp) \ No newline at end of file +- [N-Queens Problem](Backtracking/n-queens.cpp) From 684d69de08997f4f70c8ed7ebb4b9e225f9d5839 Mon Sep 17 00:00:00 2001 From: Gaurav Bhardwaj Date: Thu, 6 Oct 2022 20:53:19 +0530 Subject: [PATCH 58/63] chore(JavaScript): add trie implementations algorithm (#863) Co-authored-by: Ming Tsai <37890026+ming-tsai@users.noreply.github.com> --- algorithms/JavaScript/README.md | 4 + .../src/trie/trie-implementation.js | 79 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 algorithms/JavaScript/src/trie/trie-implementation.js diff --git a/algorithms/JavaScript/README.md b/algorithms/JavaScript/README.md index 11c9b934..9835c2cb 100644 --- a/algorithms/JavaScript/README.md +++ b/algorithms/JavaScript/README.md @@ -49,3 +49,7 @@ - [Max Heap](src/heaps/max-heap.js) - [Min Heap](src/heaps/min-heap.js) + +## Trie + +- [Trie Implementation](src/trie/trie-implementation.js) diff --git a/algorithms/JavaScript/src/trie/trie-implementation.js b/algorithms/JavaScript/src/trie/trie-implementation.js new file mode 100644 index 00000000..b166aba2 --- /dev/null +++ b/algorithms/JavaScript/src/trie/trie-implementation.js @@ -0,0 +1,79 @@ +/* +A trie (pronounced as "try") or prefix tree is a tree data structure +used to efficiently store and retrieve keys in a dataset of strings. +There are various applications of this data structure, +such as autocomplete and spellchecker. + +Insertion: +Average Case: O(N) +Worst Case: O(N) +Best Case: O(N) + +Deletion: +Average Case: O(N) +Worst Case: O(N) +Best Case: O(N) + +Searching: +Average Case: O(N) +Worst Case: O(N) +Best Case: O(1) + +Space complexity: O(alphabet_size * average key length * N) +*/ + +/* +Create a node that will have two properties — +one is the hash map for storing children. +the other one is for keeping track of the end of the word. +*/ + +class Node { + constructor() { + this.children = {}; + this.isEndWord = false; + } +} + +class Trie { + constructor() { + this.root = new Node(); + } + insert(word) { + let node = this.root; + for (const char of word) { + if (!node.children[char]) { + node.children[char] = new Node(); + } + node = node.children[char]; + } + node.isEndWord = true; + } + search(word) { + let node = this.root; + for (const char of word) { + if (!node.children[char]) { + return false; + } + node = node.children[char]; + } + return node.isEndWord ? true : false; + } + startsWith(prefix) { + let node = this.root; + for (const char of prefix) { + if (!node.children[char]) { + return false; + } + node = node.children[char]; + } + return true; + } +} + +const trie = new Trie(); +trie.insert('datastructures'); +trie.insert('datablock'); +console.log(trie.search('dsa')); // false +console.log(trie.search('datablock')); // true +console.log(trie.startsWith('data')); // true From 31fae0cfdc343895a5379a13745a39e9627d23e2 Mon Sep 17 00:00:00 2001 From: Dakshit Chopra Date: Thu, 6 Oct 2022 20:53:44 +0530 Subject: [PATCH 59/63] chore(CPlusPlus): add infix to prefix (#858) --- .../CPlusPlus/Stacks/infix-to-prefix.cpp | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 algorithms/CPlusPlus/Stacks/infix-to-prefix.cpp diff --git a/algorithms/CPlusPlus/Stacks/infix-to-prefix.cpp b/algorithms/CPlusPlus/Stacks/infix-to-prefix.cpp new file mode 100644 index 00000000..627ac875 --- /dev/null +++ b/algorithms/CPlusPlus/Stacks/infix-to-prefix.cpp @@ -0,0 +1,148 @@ +/* + Program to convert a infix expression to prefix expression a.k.a Polish Notation. + Infix expression : An expression in which the operator appears between the two operands. + Prefix expression : An expression in which the operator appears before the operands. +*/ + +/* + LOGIC + 1. Initialize the Stack. + 2. Scan the operator from left to right in the infix expression. + 3. Reverse the infix expression i.e A+B*C will become C*B+A. Note while reversing each ‘(‘ will become ‘)’ and each ‘)’ becomes ‘(‘. + 4. Obtain the “nearly” postfix expression of the modified expression i.e CB*A+. + 5. Reverse the postfix expression. Hence in our example prefix is +A*BC. +*/ + +#include +using namespace std; + +bool isOperator(char c) +{ + return (!isalpha(c) && !isdigit(c)); +} + +int getPriority(char C) +{ + if (C == '-' || C == '+') + return 1; + else if (C == '*' || C == '/') + return 2; + else if (C == '^') + return 3; + return 0; +} + +string infixToPostfix(string infix) +{ + infix = '(' + infix + ')'; + int l = infix.size(); + stack char_stack; + string output; + + for (int i = 0; i < l; i++) { + + // If the scanned character is an operand, add it to output. + if (isalpha(infix[i]) || isdigit(infix[i])) + output += infix[i]; + + // If the scanned character is an ‘(‘, push it to the stack. + else if (infix[i] == '(') + char_stack.push('('); + + // If the scanned character is an‘)’, pop and output from the stack until an ‘(‘ is encountered. + else if (infix[i] == ')') { + while (char_stack.top() != '(') { + output += char_stack.top(); + char_stack.pop(); + } + // Remove '(' from the stack + char_stack.pop(); + } + + // Operator found + else + { + if (isOperator(char_stack.top())) + { + if(infix[i] == '^') + { + while (getPriority(infix[i]) <= getPriority(char_stack.top())) + { + output += char_stack.top(); + char_stack.pop(); + } + + } + else + { + while (getPriority(infix[i]) < getPriority(char_stack.top())) + { + output += char_stack.top(); + char_stack.pop(); + } + + } + // Push current Operator on stack + char_stack.push(infix[i]); + } + } + } + while(!char_stack.empty()){ + output += char_stack.top(); + char_stack.pop(); + } + return output; +} + +string infixToPrefix(string infix) +{ + /* Reverse String + * Replace ( with ) and vice versa + * Get Postfix + * Reverse Postfix * */ + + int l = infix.size(); + + // Reverse infix + reverse(infix.begin(), infix.end()); + + // Replace ( with ) and vice versa + for (int i = 0; i < l; i++) { + + if (infix[i] == '(') { + infix[i] = ')'; + } + else if (infix[i] == ')') { + infix[i] = '('; + } + } + + string prefix = infixToPostfix(infix); + + // Reverse postfix + reverse(prefix.begin(), prefix.end()); + + return prefix; +} + +int main() +{ + int n; + string infix; + cout << "Enter the number of test cases: "; + cin >> n; + while(n--) + { + cout << "Enter the Infix expression: "; + cin >> infix; + cout << "Prefix Expression of " << infix << " is: " << infixToPrefix(infix) << endl; + } + +} +/* +infixToPrefix("A*B+C/D") // Should return "+*AB/CD " +infixToPrefix("(A-B/C)*(A/K-L)"") // Should return "*-A/BC-/AKL" + +time complexity : T(n) +space complexity : O(n) +*/ From c63a39519a53f9e42487093f68507ba167569e3a Mon Sep 17 00:00:00 2001 From: Mohit Chakraverty <79406819+mohitchakraverty@users.noreply.github.com> Date: Thu, 6 Oct 2022 20:55:43 +0530 Subject: [PATCH 60/63] chore(Java) : add prims algorithm (#945) --- algorithms/Java/README.md | 1 + algorithms/Java/graphs/Prims.java | 81 +++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 algorithms/Java/graphs/Prims.java diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index c3d90e94..be49b667 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -16,6 +16,7 @@ ## Graphs - [Dijkstras](graphs/Dijkstras.java) +- [Prims](graphs/Prims.java) ## Linked Lists diff --git a/algorithms/Java/graphs/Prims.java b/algorithms/Java/graphs/Prims.java new file mode 100644 index 00000000..58330f6c --- /dev/null +++ b/algorithms/Java/graphs/Prims.java @@ -0,0 +1,81 @@ +/** +Approach- +It starts with an empty spanning tree. The idea is to maintain two sets of vertices. +The first set contains the vertices already included in the MST, the other set contains the vertices not yet included. +At every step, it considers all the edges that connect the two sets and picks the minimum weight edge from these edges. +After picking the edge, it moves the other endpoint of the edge to the set containing MST. +*/ + +/* +Time complexity - +Time Complexity: O(V^2) +If the input graph is represented using an adjacency list, then the time complexity of Prim’s algorithm can be reduced to O(E log V) with the help of a binary heap. +In this implementation, we are always considering the spanning tree to start from the root of the graph. + +Auxiliary Space: O(V) +*/ + +import java.util.Scanner; +public class Prims{ + public static void main(String[] args) { + int w[][]=new int[10][10]; + int min,mincost=0, u, v, flag=0; + int sol[]=new int[10]; + System.out.println("Enter the number of vertices"); + Scanner sc=new Scanner(System.in); + int n=sc.nextInt(); + System.out.println("Enter the weighted graph"); + for(int i=1;i<=n;i++) + for(int j=1;j<=n;j++) + w[i][j]=sc.nextInt(); + System.out.println("Enter the source vertex"); + int s=sc.nextInt(); + for(int i=1;i<=n;i++) // Initialise the solution matrix with 0 + sol[i]=0; + sol[s]=1; // mark the source vertex + int count=1; + while (count<=n-1) + { + min=99; // If there is no edger between any two vertex its cost is assumed to be 99 + for(int i=1;i<=n;i++) + for(int j=1;j<=n;j++) + if(sol[i]==1&&sol[j]==0) //this will check the edge if not already traversed will be considered + if(i!=j && w[i][j]"+v+"="+min); + } + + for(i=1;i<=n;i++) + if(sol[i]==0) + flag=1; + if(flag==1) + System.out.println("No spanning tree"); + else + System.out.println("The cost of minimum spanning tree is"+mincost); + sc.close(); + } +} + +/* Let us create the following graph + 2 3 + (0)--(1)--(2) + | / \ | + 6| 8/ \5 |7 + | / \ | + (3)-------(4) + 9 + { + { 99, 2, 99, 6, 99 }, + { 2, 99, 3, 8, 5 }, + { 99, 3, 99, 99, 7 }, + { 6, 8, 99, 99, 9 }, + { 99, 5, 7, 9, 99 } + }; +*/ From 07c44c1843fa695874e97a66692b134c3feeba5b Mon Sep 17 00:00:00 2001 From: Pravar Anu <63355747+PravarAnu@users.noreply.github.com> Date: Thu, 6 Oct 2022 23:01:13 +0530 Subject: [PATCH 61/63] chore(CPlusPlus) : add reverse linked list (#942) --- .../reverse-the-list-using-stack.cpp | 97 +++++++++++++++++++ algorithms/CPlusPlus/README.md | 2 +- .../recursion/recursive-sum-of-n-numbers.py | 0 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 algorithms/CPlusPlus/Linked-Lists/reverse-the-list-using-stack.cpp rename recursive-sum-of-n-numbers.py => algorithms/Python/recursion/recursive-sum-of-n-numbers.py (100%) diff --git a/algorithms/CPlusPlus/Linked-Lists/reverse-the-list-using-stack.cpp b/algorithms/CPlusPlus/Linked-Lists/reverse-the-list-using-stack.cpp new file mode 100644 index 00000000..33121e63 --- /dev/null +++ b/algorithms/CPlusPlus/Linked-Lists/reverse-the-list-using-stack.cpp @@ -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 +#include + +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<data<<" "; + Print(n->next); +} +void RevList() { + if(head == NULL) return; + stack 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; +} diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index b9b71156..66505d55 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -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) diff --git a/recursive-sum-of-n-numbers.py b/algorithms/Python/recursion/recursive-sum-of-n-numbers.py similarity index 100% rename from recursive-sum-of-n-numbers.py rename to algorithms/Python/recursion/recursive-sum-of-n-numbers.py From 999530431b892117cfddbebe0853ae27d97479b9 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar <72486443+Abhishek109062@users.noreply.github.com> Date: Fri, 7 Oct 2022 20:14:41 +0530 Subject: [PATCH 62/63] chore(Java): add permutation sequences (#872) * Algorithms/Java/Maths/permutation_sequences.java Added a new java file in Algorithms/Java/Maths/permutation_sequences.java * Update algorithms/Java/Maths/permutation_sequence.java Co-authored-by: Mohit Chakraverty <79406819+mohitchakraverty@users.noreply.github.com> * Update algorithms/Java/Maths/permutation_sequence.java Co-authored-by: Mohit Chakraverty <79406819+mohitchakraverty@users.noreply.github.com> * Done Co-authored-by: Mohit Chakraverty <79406819+mohitchakraverty@users.noreply.github.com> --- .../Java/Maths/permutation_sequence.java | 178 ++++++++++++++++++ algorithms/Java/README.md | 1 + 2 files changed, 179 insertions(+) create mode 100644 algorithms/Java/Maths/permutation_sequence.java diff --git a/algorithms/Java/Maths/permutation_sequence.java b/algorithms/Java/Maths/permutation_sequence.java new file mode 100644 index 00000000..aee8c72d --- /dev/null +++ b/algorithms/Java/Maths/permutation_sequence.java @@ -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> 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, List 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 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(); + } +} + + diff --git a/algorithms/Java/README.md b/algorithms/Java/README.md index be49b667..5e1670cf 100644 --- a/algorithms/Java/README.md +++ b/algorithms/Java/README.md @@ -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 From 3c7339e59c915ed92dc414bc580b10cc07b7d445 Mon Sep 17 00:00:00 2001 From: Jyoti Singh <98025162+dev24il@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:49:57 +0530 Subject: [PATCH 63/63] chore(CPlusPlus): add redundant parenthesis (#946) * Redundant parenthesis in cpp completed * Update README.md --- algorithms/CPlusPlus/README.md | 1 + .../Stacks/redundant-parenthesis.cpp | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 algorithms/CPlusPlus/Stacks/redundant-parenthesis.cpp diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index 66505d55..1de7183a 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -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 diff --git a/algorithms/CPlusPlus/Stacks/redundant-parenthesis.cpp b/algorithms/CPlusPlus/Stacks/redundant-parenthesis.cpp new file mode 100644 index 00000000..293ca19b --- /dev/null +++ b/algorithms/CPlusPlus/Stacks/redundant-parenthesis.cpp @@ -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 +using namespace std; + +int main() +{ + cout << "Enter the string:" << endl; + string s; + cin >> s; + // create a stack of characters + stack 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