From 4a195e965841387c4bf26b01eea897b15b48759f Mon Sep 17 00:00:00 2001 From: anebz Date: Fri, 5 Apr 2019 23:19:07 +0200 Subject: [PATCH] 1.9. string rotation --- .../1.9. string_rotation.java | 31 ++++++++++++++ .../1.9. string_rotation.md | 38 +++++++++++++++++ .../1.9. string_rotation.py | 42 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 Chapter 1 Arrays and strings/1.9. string_rotation.java create mode 100644 Chapter 1 Arrays and strings/1.9. string_rotation.md create mode 100644 Chapter 1 Arrays and strings/1.9. string_rotation.py diff --git a/Chapter 1 Arrays and strings/1.9. string_rotation.java b/Chapter 1 Arrays and strings/1.9. string_rotation.java new file mode 100644 index 0000000..f16cc8f --- /dev/null +++ b/Chapter 1 Arrays and strings/1.9. string_rotation.java @@ -0,0 +1,31 @@ +public class Question { + public static boolean isSubstring(String big, String small) { + if (big.indexOf(small) >= 0) { + return true; + } else { + return false; + } + } + + public static boolean isRotation(String s1, String s2) { + int len = s1.length(); + /* check that s1 and s2 are equal length and not empty */ + if (len == s2.length() && len > 0) { + /* concatenate s1 and s1 within new buffer */ + String s1s1 = s1 + s1; + return isSubstring(s1s1, s2); + } + return false; + } + + public static void main(String[] args) { + String[][] pairs = {{"apple", "pleap"}, {"waterbottle", "erbottlewat"}, {"camera", "macera"}}; + for (String[] pair : pairs) { + String word1 = pair[0]; + String word2 = pair[1]; + boolean is_rotation = isRotation(word1, word2); + System.out.println(word1 + ", " + word2 + ": " + is_rotation); + } + } + +} \ No newline at end of file diff --git a/Chapter 1 Arrays and strings/1.9. string_rotation.md b/Chapter 1 Arrays and strings/1.9. string_rotation.md new file mode 100644 index 0000000..1b11217 --- /dev/null +++ b/Chapter 1 Arrays and strings/1.9. string_rotation.md @@ -0,0 +1,38 @@ +# 1.9. String rotation + +## Given s1 and s2, calculate if s2 is a rotation of s1 using only one call to isSubstring, a function that checks if a string is a substring of another + +> example: 'waterbottle' is a rotation of 'erbottlewat' + +## First idea + +Need to have the same lengths and same count of characters. + +```python +from collections import Counter +if len(s1) != len(s2) or Counter(s1) != Counter(s2): + return 0 +if len(s1) < 3 or s1 == s2: + return 1 +``` + +Find s1[0] in s2, index `i`. Check that s2, from i to the end is equal to the substring of s1, and same with the first part. + +```python +indexes = [i for i, e in enumerate(s2) if e == s1[0]] +for idx in indexes: + offset = len(s1) - idx + if s2[idx:] == s1[:offset] and s2[:idx] == s1[offset:]: + return 1 +return 0 +``` + +Finds all occurences of s1[0] in s2, checks if 'wat' == 'wat', and then 'erbottle' == 'erbottle'. Takes O(n) time, O(1) space. No calls to isSubstring, either 2 calls or none. I don't see the point of just one. + +## Hints and solution + +Let s1 be divided into two parts, x and y. s1 = xy and s2 = yx. If we concatenate s2 with itself, s2 = yxxy. In which case s1 is a substring of s2s2. But this takes O(n) time in `isSubstring` and O(n) space. + +```python +return isSubstring(s1, s2 + s2) +``` \ No newline at end of file diff --git a/Chapter 1 Arrays and strings/1.9. string_rotation.py b/Chapter 1 Arrays and strings/1.9. string_rotation.py new file mode 100644 index 0000000..1f028b9 --- /dev/null +++ b/Chapter 1 Arrays and strings/1.9. string_rotation.py @@ -0,0 +1,42 @@ +import unittest +from collections import Counter + +def rotate_matrix(s1, s2): + + if len(s1) != len(s2) or Counter(s1) != Counter(s2): + return 0 + if len(s1) < 3 or s1 == s2: + return 1 + + indexes = [i for i, e in enumerate(s2) if e == s1[0]] + for idx in indexes: + offset = len(s1) - idx + if s2[idx:] == s1[:offset] and s2[:idx] == s1[offset:]: + return 1 + return 0 + + +class Test(unittest.TestCase): + '''Test Cases''' + dataT = [('', ''), + ('a', 'a'), + ('ab', 'ba'), + ('waterbottle', 'waterbottle'), + ('erbottlewat', 'waterbottle'), + ('qwerqwer', 'erqwerqw')] + + dataF = [('', 'a'), + ('a', 'b'), + ('qwerq', 'wreqq')] + + def test_rotate_matrix(self): + for test in self.dataT: + res = rotate_matrix(*test) + self.assertTrue(res) + + for test in self.dataF: + res = rotate_matrix(*test) + self.assertFalse(res) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file