Skip to content

Instantly share code, notes, and snippets.

@appgurueu
Created August 9, 2023 23:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save appgurueu/ef63b701e5a876039710ec1648d691f6 to your computer and use it in GitHub Desktop.
Save appgurueu/ef63b701e5a876039710ec1648d691f6 to your computer and use it in GitHub Desktop.
Longest common prefix of any two strings in a list of strings
-- Longest common prefix of any two strings in `strs`
local function lcp(strs)
assert(#strs >= 2)
local trie = {}
local max_cp_len = 0
local max_cp_node = trie
for i, str in ipairs(strs) do
local cp_len = 0
local cp_node = trie
while cp_len < #str do
local b = str:byte(cp_len + 1)
if cp_node[b] == nil then break end
cp_node = cp_node[b]
cp_len = cp_len + 1
end
if cp_len > max_cp_len then
max_cp_len = cp_len
max_cp_node = cp_node
end
local node = cp_node
for j = cp_len + 1, #str do
local b = str:byte(j)
node[b] = node[b] or {}
node = node[b]
end
node.idx = i
end
local i, j
local function dfs_idx(node)
if node.idx then
if i == nil then i = node.idx
elseif j == nil then j = node.idx end
end
for _, v in pairs(node) do
if i and j then break end
if type(v) == "table" then dfs_idx(v) end
end
end
dfs_idx(max_cp_node)
return max_cp_len, i, j
end
-- Test
do
local len, i, j = lcp{"pack", "packing", "banana", "banana pie", "banana smoothie"}
assert(len == #"banana " and math.min(i, j) == 4 and math.max(i, j) == 5)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment