public class Solution { private class Node { public Dictionary Next { get; set; } = new(); public bool Has { get; set; } = false; public Node() { } } private static Node MakeTrie(string[] dictionary) { var root = new Node(); foreach (var word in dictionary) { var node = root; foreach (var c in word) { if (!node.Next.ContainsKey(c)) { node.Next[c] = new(); } node = node.Next[c]; } node.Has = true; } return root; } public int MinExtraChar(string s, string[] dictionary) { var trie = MakeTrie(dictionary); var length = s.Length; var dp = new int[length + 1]; for (var start = length - 1; start >= 0; --start) { dp[start] = 1 + dp[start + 1]; var node = trie; for (var end = start; end < length; ++end) { if (!node.Next.ContainsKey(s[end])) { break; } node = node.Next[s[end]]; if (node.Has) { dp[start] = Math.Min(dp[start], dp[end + 1]); } } } return dp[0]; } }