Skip to content

Instantly share code, notes, and snippets.

@rugyoga
Created January 30, 2024 09:48
Show Gist options
  • Save rugyoga/7d65ee8c9071fd034169b1128a2f9c72 to your computer and use it in GitHub Desktop.
Save rugyoga/7d65ee8c9071fd034169b1128a2f9c72 to your computer and use it in GitHub Desktop.
003 Longest string without repeated character using a Queue and char_list
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