Last active
November 26, 2020 07:15
-
-
Save sumew/2f8948d7459e3130bb1cf886f148668c to your computer and use it in GitHub Desktop.
A generic representation of a sliding window problem
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
def lengthOfLongestSubstring(in: String): Int = { | |
//A type alias to simplify the syntax | |
type CounterContainer[T] = Map[T, Int] | |
//The elements are Chars and our container, a map with the Char as key and the frequence as value holds the elements within the current window | |
val longest = new SlidingWindow[Char, CounterContainer[Char]] { | |
override val input: Seq[Char] = in | |
//The initial state consists of windows of 0 width at the beginning of the sequence and an empty container | |
override def initialize() = State(Window(0, 0), Window(0, 0), Map.empty[Char, Int]) | |
//We terminate when the current window's right edge reaches the last element of the input | |
override def terminate(s: State[CounterContainer[Char]]): Boolean = input.length == s.current.r | |
//When expanding, we increment frequency of element at the right edge of our current window to our container and expand the window | |
override def expand(s: State[CounterContainer[Char]]): State[CounterContainer[Char]] = | |
s.copy( | |
contained = s.contained.updatedWith(input(s.lastIndex()))(opt => Some(opt.fold(1)(count => count + 1))), | |
current = s.current ||-> 1 | |
) | |
//When shrinking we decrement the element at the left edge of our current window and move that edge to the right | |
override def shrink(s: State[CounterContainer[Char]]): State[CounterContainer[Char]] = | |
s.copy( | |
contained = s.contained | |
.get(input(s.firstIndex())) | |
.fold(s.contained)(count => s.contained.updated(input(s.firstIndex()), count - 1)), | |
current = s.current |->| 1 | |
) | |
override def better(b: Window, c: Window) = if (c.size < b.size) b else c //the problem asks for the longest | |
override def shouldExpand(s: State[CounterContainer[Char]]) = !s.contained.values.exists(_ > 1)// expand only when there are no repeated characters | |
override def satisfied(s: State[CounterContainer[Char]]): Boolean = shouldExpand(s) //The condition (without repeated characters) holds | |
} | |
val s: State[CounterContainer[Char]] = longest.run() | |
s.best.size | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment