Skip to content

Commit a91c636

Browse files
committed
Update GCD problem
1 parent d37ab2b commit a91c636

File tree

9 files changed

+178
-182
lines changed

9 files changed

+178
-182
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ List of Programs related to data structures and algorithms
9898

9999
9. Encode and decode strings: [Source](https://github.com/sudheerj/datastructures-algorithms/blob/master/src/javascript/algorithms/strings/9.encodeDecodeStrings/encodeDecodeStrings.js) [JavaScript](https://livecodes.io/?console&x=https://github.com/sudheerj/datastructures-algorithms/blob/master/src/javascript/algorithms/strings/9.encodeDecodeStrings/encodeDecodeStrings.js) [Documentation](https://github.com/sudheerj/datastructures-algorithms/blob/master/src/javascript/algorithms/strings/9.encodeDecodeStrings/encodeDecodeStrings.md)
100100

101-
10. Greatest common devisor of strings: [JavaScript](https://livecodes.io/?console&x=https://github.com/sudheerj/datastructures-algorithms/blob/master/src/javascript/algorithms/strings/greatestCommonDivisor.js)
101+
10. Greatest common devisor of strings: [Source](https://github.com/sudheerj/datastructures-algorithms/blob/master/src/javascript/algorithms/strings/10.greatestCommonDivisor/greatestCommonDivisor.js) [JavaScript](https://livecodes.io/?console&x=https://github.com/sudheerj/datastructures-algorithms/blob/master/src/javascript/algorithms/strings/10.greatestCommonDivisor/greatestCommonDivisor.js) [Documentation](https://github.com/sudheerj/datastructures-algorithms/blob/master/src/javascript/algorithms/strings/10.greatestCommonDivisor/greatestCommonDivisor.md)
102102

103103
### Dynamic programming
104104

src/java1/algorithms/strings/MinWindowSubstring.java

-54
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package java1.algorithms.strings.greatestCommonDivisor;
2+
3+
public class GreatestCommonDivisor {
4+
//1. GCD using Euclidean's algorithm TC: O(n+m)(i.e, O(n + m + log(min(n, m)))), SC: O(n+m)
5+
private static String gcdOfStrings1(String str1, String str2) {
6+
if(!((str1+str2).equals(str2+str1))) return "";
7+
8+
int gcdLength = gcd(str1.length(), str2.length());
9+
10+
return str1.substring(0, gcdLength);
11+
12+
}
13+
14+
private static int gcd(int a, int b){
15+
return b == 0 ? a : gcd(b, a%b);
16+
}
17+
18+
// 2. BrutForce (Time complexity: O(min(m,n) . (m+n)), Space complexity: O(min(m,n)))
19+
private static String gcdOfStrings2(String str1, String str2) {
20+
int l1 = str1.length(), l2 = str2.length();
21+
22+
for(int i = Math.min(l1, l2); i >=1; i++){
23+
if(hasGcdString(str1, str2, i)) {
24+
return str1.substring(0, i);
25+
}
26+
}
27+
28+
return "";
29+
}
30+
31+
private static boolean hasGcdString(String str1, String str2, int k){
32+
int l1 = str1.length(), l2 = str2.length();
33+
34+
if(l1%k > 0 || l2%k > 0){
35+
return false;
36+
}
37+
38+
int f1 = l1/k, f2 = l2/k;
39+
String base = str1.substring(0, k);
40+
41+
return base.repeat(f1) == str1 && base.repeat(f2) == str2;
42+
}
43+
44+
public static void main(String[] args) {
45+
System.out.println(gcdOfStrings1("AB", "AB"));
46+
System.out.println(gcdOfStrings1("ABCABCABC", "ABCABC"));
47+
System.out.println(gcdOfStrings1("ABABAB", "AB"));
48+
49+
System.out.println(gcdOfStrings2("AB", "AB"));
50+
System.out.println(gcdOfStrings2("ABCABCABC", "ABCABC"));
51+
System.out.println(gcdOfStrings2("ABABAB", "AB"));
52+
}
53+
}
54+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
**Description:**
2+
Given two strings `str1` and `str2`, return the largest string `x` such that it divides both `str1` and `str2`.
3+
4+
**Note:** For any two strings `a` and `b`, we say "b divides a" if and only if `a = b + b +... + a`.
5+
6+
### Examples
7+
Example 1:
8+
Input: ["AB", "AB"]
9+
Output: ["AB"]
10+
11+
Example 2:
12+
Input: ["ABCABCABC", "ABCABC"]
13+
Output: ["ABCABC"]
14+
15+
Example 3:
16+
Input: ["ABABAB", "AB"]
17+
Output: ["AB"]
18+
19+
20+
**Algorithmic Steps**
21+
This problem is solved with the help of basic string operations and **Euclidean's** algorithm. The algorithmic approach can be summarized as follows:
22+
23+
1. Add a preliminary check if the two strings can be constructed from a common substring. It can be verified by comparing `str1+str2` with `str2+str1`. If they are not equal, there is no chanced of GCD.
24+
25+
2. Implement a gcd of two string lengths using Euclidean's algorithm.
26+
27+
3. Invoke the method created in step2 and assign to a variable `gcdLength`.
28+
29+
4. Return a substring on either of strings( `str1` or `str2`) using 0 as first argument and `gcdLength` as second argument.
30+
31+
32+
**Time and Space complexity:**
33+
This algorithm has a time complexity of `O(n+m)` where `n` is the length of first string and `m` is the length of second string. This is because both the string concatenation and comparison takes will time complexity of `O(n+m)` individually. Also, Euclid's algorithm takes time complexity of `O(log(min(n, m)))`. So, the overall time complexity combining these operations resulting in `O(n + m + log(min(n, m))) ~= O(n+m)`.
34+
35+
Also, it takes space complexity of `O(n+m)` due to additional space required for concatenated strings.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//1. GCD using Euclidean's algorithm TC: O(n+m)(i.e, O(n + m + log(min(n, m)))), SC: O(n+m)
2+
function gcdOfStrings1(string1, string2){
3+
//Verify whether GCD strings exists or not
4+
if(!(string1+string2 === string2+string1)) {
5+
return false;
6+
}
7+
8+
let gcdLength = gcd(string1.length, string2.length);
9+
return string1.substring(0, gcdLength);
10+
}
11+
12+
function gcd(x, y) {
13+
if(y === 0) {
14+
return x;
15+
}
16+
return gcd(y, x%y);
17+
}
18+
19+
// 2. BrutForce (Time complexity: O(min(m,n) . (m+n)), Space complexity: O(min(m,n)))
20+
function gcdOfStrings2(string1, string2) {
21+
let l1 = string1.length;
22+
let l2 = string2.length;
23+
24+
for(let i= Math.min(l1,l2); i >= 1; i--) {
25+
if(hasGcdString(string1, string2, i)) {
26+
return string1.substring(0, i);
27+
}
28+
}
29+
30+
return "";
31+
}
32+
33+
function hasGcdString(string1, string2, k) {
34+
let l1 = string1.length;
35+
let l2 = string2.length;
36+
37+
if(l1%k > 0 || l2%k >0) {
38+
return false;
39+
}
40+
41+
let f1= l1/k, f2 = l2/k;
42+
let base = string1.substring(0, k);
43+
return base.repeat(f1) === string1 && base.repeat(f2) === string2;
44+
}
45+
46+
47+
console.log(gcdOfStrings1("AB", "AB"));
48+
console.log(gcdOfStrings1("ABCABCABC", "ABCABC"));
49+
console.log(gcdOfStrings1("ABABAB", "AB"));
50+
51+
console.log(gcdOfStrings2("AB", "AB"));
52+
console.log(gcdOfStrings2("ABCABCABC", "ABCABC"));
53+
console.log(gcdOfStrings2("ABABAB", "AB"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
**Description:**
2+
Given two strings `str1` and `str2`, return the largest string `x` such that it divides both `str1` and `str2`.
3+
4+
**Note:** For any two strings `a` and `b`, we say "b divides a" if and only if `a = b + b +... + a`.
5+
6+
### Examples
7+
Example 1:
8+
Input: ["AB", "AB"]
9+
Output: ["AB"]
10+
11+
Example 2:
12+
Input: ["ABCABCABC", "ABCABC"]
13+
Output: ["ABCABC"]
14+
15+
Example 3:
16+
Input: ["ABABAB", "AB"]
17+
Output: ["AB"]
18+
19+
20+
**Algorithmic Steps**
21+
This problem is solved with the help of basic string operations and **Euclidean's** algorithm. The algorithmic approach can be summarized as follows:
22+
23+
1. Add a preliminary check if the two strings can be constructed from a common substring. It can be verified by comparing `str1+str2` with `str2+str1`. If they are not equal, there is no chanced of GCD.
24+
25+
2. Implement a gcd of two string lengths using Euclidean's algorithm.
26+
27+
3. Invoke the method created in step2 and assign to a variable `gcdLength`.
28+
29+
4. Return a substring on either of strings( `str1` or `str2`) using 0 as first argument and `gcdLength` as second argument.
30+
31+
32+
**Time and Space complexity:**
33+
This algorithm has a time complexity of `O(n+m)` where `n` is the length of first string and `m` is the length of second string. This is because both the string concatenation and comparison takes will time complexity of `O(n+m)` individually. Also, Euclid's algorithm takes time complexity of `O(log(min(n, m)))`. So, the overall time complexity combining these operations resulting in `O(n + m + log(min(n, m))) ~= O(n+m)`.
34+
35+
Also, it takes space complexity of `O(n+m)` due to additional space required for concatenated strings.

src/javascript/algorithms/strings/greatestCommonDivisor.js

-48
This file was deleted.

src/javascript/algorithms/strings/minWindowSubstring.js

-49
This file was deleted.

src/javascript/algorithms/strings/palindromicStrings.js

-30
This file was deleted.

0 commit comments

Comments
 (0)