双指针
解题思路
不断遍历匹配T的头部是否含有S的头部,匹配到时将S头部移除直到空列表即为true
代码
-spec is_subsequence(S :: unicode:unicode_binary(), T :: unicode:unicode_binary()) -> boolean().
is_subsequence(S, T) ->
TList = binary:bin_to_list(T),
SList = binary:bin_to_list(S),
do_is_subsequence(TList, SList).
do_is_subsequence([HeadT | T], S = [HeadS | _]) when HeadT =/= HeadS ->
do_is_subsequence(T, S);
do_is_subsequence([HeadT | T], [HeadS | S]) when HeadT =:= HeadS ->
do_is_subsequence(T, S);
do_is_subsequence(_, []) ->
true;
do_is_subsequence(_, _) ->
false.
动态规划
解题思路
首先用T建立缓存数据,遍历T并建立每个字母的索引列表
然后再遍历S,查询字母索引列表中是否存在合法索引,即索引值大于当前索引的新索引。
代码
-spec is_subsequence(S :: unicode:unicode_binary(), T :: unicode:unicode_binary()) -> boolean().
is_subsequence(S, T) ->
TList = binary:bin_to_list(T),
SList = binary:bin_to_list(S),
do_cache(TList, #{index => 1, list => SList, cache => #{}}).
do_cache([Word | T], Args = #{index := Index, cache := Cache}) ->
IndexList = maps:get(Word, Cache, []),
NewIndexList = IndexList ++ [Index],
do_cache(T, Args#{index := Index + 1, cache := Cache#{Word => NewIndexList}});
do_cache(_, #{list := SList, cache := Cache}) ->
do_is_subsequence(SList, #{index => 0, cache => Cache}).
do_is_subsequence([Word | S], Args = #{index := PreIndex, cache := Cache}) ->
IndexList = maps:get(Word, Cache, []),
%io:format("cache ~w\n", [Cache]),
%io:format("word ~w pre_index ~w\n", [Word, PreIndex]),
case [Index || Index <- IndexList, Index > PreIndex] of
NewIndexList = [NewPreIndex | _] ->
NewCache = Cache#{Word => NewIndexList},
do_is_subsequence(S, Args#{index := NewPreIndex, cache := NewCache});
_ ->
false
end;
do_is_subsequence([], _) ->
true.