Created
January 30, 2024 09:48
-
-
Save rugyoga/7d65ee8c9071fd034169b1128a2f9c72 to your computer and use it in GitHub Desktop.
003 Longest string without repeated character using a Queue and char_list
This file contains 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
defmodule Solution do | |
defmodule Queue do | |
defstruct [front: [], back: [], size: 0] | |
def push(q, item), do: %Queue{ q | size: q.size+1, back: [item | q.back]} | |
def pop(%Queue{size: 0} = q), do: {:empty, q} | |
def pop(%Queue{front: [a | as]} = q), do: {a, %Queue{q | front: as, size: q.size-1}} | |
def pop(%Queue{front: []} = q), do: pop(%Queue{q | front: Enum.reverse(q.back), back: []}) | |
end | |
@spec length_of_longest_substring(s :: String.t) :: integer | |
def length_of_longest_substring(s) do | |
compute(String.to_charlist(s), {0, MapSet.new, %Queue{}}) | |
end | |
def compute([], {n, _, _}), do: n | |
def compute([a | as] = s, {_, seen, _} = x) do | |
if MapSet.member?(seen, a) do | |
compute(s, drop_until(x, a)) | |
else | |
compute(as, add(x, a)) | |
end | |
end | |
def add({n, seen, q}, item) do | |
{max(n, q.size+1), MapSet.put(seen, item), Queue.push(q, item)} | |
end | |
def drop({n, seen, q}) do | |
{front, q} = Queue.pop(q) | |
{front, {n, MapSet.delete(seen, front), q}} | |
end | |
def drop_until(window, item) do | |
{front, window} = drop(window) | |
if front == item do | |
window | |
else | |
drop_until(window, item) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment