Last active
July 8, 2018 14:20
-
-
Save asethia/9c8b80f5188066c6361835e7b048adc5 to your computer and use it in GitHub Desktop.
Assume you have a method isSubstring which checks if one word is a substring of another.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.scalatest.{Matchers, WordSpec} | |
import scala.annotation.tailrec | |
/** | |
* Assume you have a method isSubstring which checks if one word is a substring of another. | |
* Given two strings, 51 and 52, write code to check if 52 is a rotation of 51 using only | |
* one call to isSubstring (e.g.,"waterbottle"is a rotation of"erbottlewat"). | |
* Time Complexity: O(n) | |
* Created by Arun Sethia on 7/7/18. | |
*/ | |
trait StringRotation { | |
/** | |
* this is using high order function contains | |
* | |
* @param s1 | |
* @param s2 | |
* @return | |
*/ | |
def isSubStringHighOrder(s1: String, s2: String): Boolean = { | |
if (s1.length != s2.length) | |
false | |
else { | |
val n = s1 + s1 | |
n.contains(s2) | |
} | |
} | |
/** | |
* this is without using any high order functions | |
* | |
* @param s1 | |
* @param s2 | |
* @return | |
*/ | |
def isSubString(s1: String, s2: String) = { | |
//convert to char list | |
val s1Chars: List[Char] = s1.toList | |
//length of s1 string | |
val s1Len = s1Chars.length | |
@tailrec | |
def isRotatedSubString(lastMatch: Boolean, mchars: List[Char], matchIndex: Int): Boolean = { | |
if (mchars == Nil) lastMatch | |
else { | |
val cChar = mchars.head | |
val nChar = mchars.tail | |
//current char from s1 is matching with s2 char | |
val matches = (s1Chars(matchIndex) == cChar) | |
val next = | |
if (matches) nChar | |
else { | |
//since last match was true and now it is not matching means wrong string | |
if ((matchIndex > 0 && lastMatch) || nChar == Nil) Nil | |
else mchars | |
} | |
if (matchIndex == (s1Len - 1)) { | |
//if last matched index was last one then move to zeroth index | |
isRotatedSubString(matches, next, 0) | |
} else { | |
//else increment by 1 | |
isRotatedSubString(matches, next, matchIndex + 1) | |
} | |
} | |
} | |
//if lengths are not equal | |
if (s1Len != s2.length) | |
false | |
else //start matching rotation | |
isRotatedSubString(false, s2.toList, 0) | |
} | |
} | |
class StringRotationSpec extends WordSpec | |
with Matchers | |
with StringRotation { | |
"erbottlewat" should { | |
"rotated string of waterbottle" in { | |
assert(isSubString("waterbottle", "erbottlewat")) | |
} | |
} | |
"waterbottle" should { | |
"rotated string of erbottlewat" in { | |
assert(isSubString("erbottlewat", "waterbottle")) | |
} | |
} | |
"a" should { | |
"not rotated string of b" in { | |
assert(!isSubString("a", "b")) | |
} | |
} | |
"abb" should { | |
"not rotated string of bb" in { | |
assert(!isSubString("abb", "bb")) | |
} | |
} | |
"abb" should { | |
"rotated string of bba" in { | |
assert(isSubString("abb", "bba")) | |
} | |
} | |
"erbottlewat" should { | |
"rotated string of waterbottle using high order fn" in { | |
assert(isSubStringHighOrder("waterbottle", "erbottlewat")) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment