Skip to content

Commit

Permalink
Added erlang
Browse files Browse the repository at this point in the history
  • Loading branch information
javadev committed Jan 23, 2025
1 parent 2ca4468 commit 17cac9a
Show file tree
Hide file tree
Showing 62 changed files with 2,131 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/main/erlang/g0101_0200/s0139_word_break/Solution.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
% #Medium #Top_100_Liked_Questions #Top_Interview_Questions #String #Hash_Table
% #Dynamic_Programming #Trie #Memoization #Algorithm_II_Day_15_Dynamic_Programming
% #Dynamic_Programming_I_Day_9 #Udemy_Dynamic_Programming #Big_O_Time_O(M+max*N)_Space_O(M+N+max)
% #2025_01_18_Time_1_(100.00%)_Space_60.03_(100.00%)

-spec word_break(S :: unicode:unicode_binary(), WordDict :: [unicode:unicode_binary()]) -> boolean().
word_break(S, WordDict) ->
% Initialize ETS table for memoization
ets:new(memo, [set, named_table]),
% Process word dict to include sizes
Words = [{Word, byte_size(Word)} || Word <- WordDict],
% Get result
Result = breakable(S, Words),
% Clean up
ets:delete(memo),
Result.

-spec breakable(binary(), [{binary(), integer()}]) -> boolean().
breakable(<<>>, _Words) ->
true;
breakable(S, Words) ->
case ets:lookup(memo, S) of
[{_, Result}] ->
Result;
[] ->
Result = try_words(S, Words, Words),
ets:insert(memo, {S, Result}),
Result
end.

try_words(_S, [], _AllWords) ->
false;
try_words(S, [{Word, Len} | Rest], AllWords) ->
case S of
<<Prefix:Len/binary, Remaining/binary>> when Prefix =:= Word ->
case breakable(Remaining, AllWords) of
true -> true;
false -> try_words(S, Rest, AllWords)
end;
_ ->
try_words(S, Rest, AllWords)
end.
39 changes: 39 additions & 0 deletions src/main/erlang/g0101_0200/s0139_word_break/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
139\. Word Break

Medium

Given a string `s` and a dictionary of strings `wordDict`, return `true` if `s` can be segmented into a space-separated sequence of one or more dictionary words.

**Note** that the same word in the dictionary may be reused multiple times in the segmentation.

**Example 1:**

**Input:** s = "leetcode", wordDict = ["leet","code"]

**Output:** true

**Explanation:** Return true because "leetcode" can be segmented as "leet code".

**Example 2:**

**Input:** s = "applepenapple", wordDict = ["apple","pen"]

**Output:** true

**Explanation:** Return true because "applepenapple" can be segmented as "apple pen apple".

Note that you are allowed to reuse a dictionary word.

**Example 3:**

**Input:** s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]

**Output:** false

**Constraints:**

* `1 <= s.length <= 300`
* `1 <= wordDict.length <= 1000`
* `1 <= wordDict[i].length <= 20`
* `s` and `wordDict[i]` consist of only lowercase English letters.
* All the strings of `wordDict` are **unique**.
77 changes: 77 additions & 0 deletions src/main/erlang/g0101_0200/s0146_lru_cache/LRUCache.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
% #Medium #Top_100_Liked_Questions #Top_Interview_Questions #Hash_Table #Design #Linked_List
% #Doubly_Linked_List #Udemy_Linked_List #Big_O_Time_O(1)_Space_O(capacity)
% #2025_01_18_Time_312_(100.00%)_Space_273.78_(100.00%)

%% Persistent Term Keys
-define(CAPACITY_KEY, {lru_cache, capacity}).
-define(CACHE_TABLE, lru_cache_cache_table).
-define(TTL_TABLE, lru_cache_ttl_table).

%% API Specifications
-spec lru_cache_init_(Capacity :: integer()) -> ok.
lru_cache_init_(Capacity) ->
persistent_term:put(?CAPACITY_KEY, Capacity),
case ets:info(?CACHE_TABLE) of
undefined ->
ets:new(?CACHE_TABLE, [set, public, named_table]),
ets:new(?TTL_TABLE, [ordered_set, public, named_table]);
_ ->
ets:delete_all_objects(?CACHE_TABLE),
ets:delete_all_objects(?TTL_TABLE)
end,
ok.

-spec lru_cache_get(Key :: integer()) -> integer().
lru_cache_get(Key) ->
case extract(Key) of
{Key, Value} ->
insert(Key, Value),
Value;
-1 ->
-1
end.

-spec lru_cache_put(Key :: integer(), Value :: integer()) -> ok.
lru_cache_put(Key, Value) ->
_ = extract(Key),
insert(Key, Value),
evict(),
ok.

%% Internal Functions
extract(Key) ->
case ets:lookup(?CACHE_TABLE, Key) of
[{Key, Uniq, Value}] ->
ets:delete(?TTL_TABLE, Uniq),
{Key, Value};
[] ->
-1
end.

insert(Key, Value) ->
Uniq = unique_integer(),
ets:insert(?CACHE_TABLE, {Key, Uniq, Value}),
ets:insert(?TTL_TABLE, {Uniq, Key}).

evict() ->
Capacity = persistent_term:get(?CAPACITY_KEY),
CurrentSize = ets:info(?CACHE_TABLE, size),
if
CurrentSize > Capacity ->
Uniq = ets:first(?TTL_TABLE),
[{_, Key}] = ets:lookup(?TTL_TABLE, Uniq),
ets:delete(?TTL_TABLE, Uniq),
ets:delete(?CACHE_TABLE, Key);
true ->
ok
end.

unique_integer() ->
erlang:unique_integer([monotonic]).

%% Your functions will be called as such:
%% lru_cache_init_(Capacity),
%% Param_1 = lru_cache_get(Key),
%% lru_cache_put(Key, Value),

%% lru_cache_init_ will be called before every test case, in which you can do some necessary initializations.
48 changes: 48 additions & 0 deletions src/main/erlang/g0101_0200/s0146_lru_cache/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
146\. LRU Cache

Medium

Design a data structure that follows the constraints of a **[Least Recently Used (LRU) cache](https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU)**.

Implement the `LRUCache` class:

* `LRUCache(int capacity)` Initialize the LRU cache with **positive** size `capacity`.
* `int get(int key)` Return the value of the `key` if the key exists, otherwise return `-1`.
* `void put(int key, int value)` Update the value of the `key` if the `key` exists. Otherwise, add the `key-value` pair to the cache. If the number of keys exceeds the `capacity` from this operation, **evict** the least recently used key.

The functions `get` and `put` must each run in `O(1)` average time complexity.

**Example 1:**

**Input** ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]

**Output:** [null, null, null, 1, null, -1, null, -1, 3, 4]

**Explanation:**

LRUCache lRUCache = new LRUCache(2);

lRUCache.put(1, 1); // cache is {1=1}

lRUCache.put(2, 2); // cache is {1=1, 2=2}

lRUCache.get(1); // return 1

lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3}

lRUCache.get(2); // returns -1 (not found)

lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3}

lRUCache.get(1); // return -1 (not found)

lRUCache.get(3); // return 3

lRUCache.get(4); // return 4

**Constraints:**

* `1 <= capacity <= 3000`
* <code>0 <= key <= 10<sup>4</sup></code>
* <code>0 <= value <= 10<sup>5</sup></code>
* At most <code>2 * 10<sup>5</sup></code> calls will be made to `get` and `put`.
29 changes: 29 additions & 0 deletions src/main/erlang/g0101_0200/s0148_sort_list/Solution.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
% #Medium #Top_100_Liked_Questions #Top_Interview_Questions #Sorting #Two_Pointers #Linked_List
% #Divide_and_Conquer #Merge_Sort #Level_2_Day_4_Linked_List #Big_O_Time_O(log(N))_Space_O(log(N))
% #2025_01_18_Time_43_(100.00%)_Space_102.77_(100.00%)

%% Definition for singly-linked list.
%%
%% -record(list_node, {val = 0 :: integer(),
%% next = null :: 'null' | #list_node{}}).

%% @spec sort_list(Head :: #list_node{} | null) -> #list_node{} | null.
-spec sort_list(Head :: #list_node{} | null) -> #list_node{} | null.
sort_list(Head) ->
List = node_to_list(Head, []),
SortedList = lists:sort(fun(X, Y) -> X > Y end, List),
list_to_node(SortedList, null).

%% Converts a linked list to an Erlang list.
-spec node_to_list(Node :: #list_node{} | null, Acc :: [integer()]) -> [integer()].
node_to_list(null, Acc) ->
Acc;
node_to_list(#list_node{val = Val, next = Next}, Acc) ->
node_to_list(Next, [Val | Acc]).

%% Converts an Erlang list to a linked list.
-spec list_to_node(List :: [integer()], Node :: #list_node{} | null) -> #list_node{} | null.
list_to_node([], Node) ->
Node;
list_to_node([H | T], Node) ->
list_to_node(T, #list_node{val = H, next = Node}).
34 changes: 34 additions & 0 deletions src/main/erlang/g0101_0200/s0148_sort_list/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
148\. Sort List

Medium

Given the `head` of a linked list, return _the list after sorting it in **ascending order**_.

**Example 1:**

![](https://assets.leetcode.com/uploads/2020/09/14/sort_list_1.jpg)

**Input:** head = [4,2,1,3]

**Output:** [1,2,3,4]

**Example 2:**

![](https://assets.leetcode.com/uploads/2020/09/14/sort_list_2.jpg)

**Input:** head = [-1,5,3,4,0]

**Output:** [-1,0,3,4,5]

**Example 3:**

**Input:** head = []

**Output:** []

**Constraints:**

* The number of nodes in the list is in the range <code>[0, 5 * 10<sup>4</sup>]</code>.
* <code>-10<sup>5</sup> <= Node.val <= 10<sup>5</sup></code>

**Follow up:** Can you sort the linked list in `O(n logn)` time and `O(1)` memory (i.e. constant space)?
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
% #Medium #Top_100_Liked_Questions #Top_Interview_Questions #Array #Dynamic_Programming
% #Dynamic_Programming_I_Day_6 #Level_2_Day_13_Dynamic_Programming #Udemy_Dynamic_Programming
% #Big_O_Time_O(N)_Space_O(1) #2025_01_18_Time_0_(100.00%)_Space_63.79_(100.00%)

-spec max_product(Nums :: [integer()]) -> integer().
max_product(Nums) ->
max_product(Nums, 1, 1, -(1 bsl 31)).

-spec max_product(Nums :: [integer()], integer(), integer(), integer()) -> integer().
max_product([], _, _, MaxProduct) ->
MaxProduct;
max_product([H|T], MaxCurrent, MinCurrent, MaxProduct) ->
% The new maximum and minimum products are derived by comparing
% the current number, its product with the maximum so far, and its product with the minimum so far
NewMaxCurrent = max(max(H, H * MaxCurrent), H * MinCurrent),
NewMinCurrent = min(min(H, H * MaxCurrent), H * MinCurrent),
NewMaxProduct = max(MaxProduct, NewMaxCurrent),
max_product(T, NewMaxCurrent, NewMinCurrent, NewMaxProduct).
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
152\. Maximum Product Subarray

Medium

Given an integer array `nums`, find a contiguous non-empty subarray within the array that has the largest product, and return _the product_.

The test cases are generated so that the answer will fit in a **32-bit** integer.

A **subarray** is a contiguous subsequence of the array.

**Example 1:**

**Input:** nums = [2,3,-2,4]

**Output:** 6

**Explanation:** [2,3] has the largest product 6.

**Example 2:**

**Input:** nums = [-2,0,-1]

**Output:** 0

**Explanation:** The result cannot be 2, because [-2,-1] is not a subarray.

**Constraints:**

* <code>1 <= nums.length <= 2 * 10<sup>4</sup></code>
* `-10 <= nums[i] <= 10`
* The product of any prefix or suffix of `nums` is **guaranteed** to fit in a **32-bit** integer.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
% #Medium #Top_100_Liked_Questions #Array #Binary_Search #Algorithm_II_Day_2_Binary_Search
% #Binary_Search_I_Day_12 #Udemy_Binary_Search #Big_O_Time_O(log_N)_Space_O(log_N)
% #2025_01_18_Time_0_(100.00%)_Space_60.97_(100.00%)

-spec find_min(Nums :: [integer()]) -> integer().
find_min([N]) ->
N;
find_min(Nums) ->
Count = length(Nums),
Mid = Count div 2,
Left = lists:sublist(Nums, Mid),
Right = lists:nthtail(Mid, Nums),
MinLeft = find_min(Left),
MinRight = find_min(Right),
erlang:min(MinLeft, MinRight).
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
153\. Find Minimum in Rotated Sorted Array

Medium

Suppose an array of length `n` sorted in ascending order is **rotated** between `1` and `n` times. For example, the array `nums = [0,1,2,4,5,6,7]` might become:

* `[4,5,6,7,0,1,2]` if it was rotated `4` times.
* `[0,1,2,4,5,6,7]` if it was rotated `7` times.

Notice that **rotating** an array `[a[0], a[1], a[2], ..., a[n-1]]` 1 time results in the array `[a[n-1], a[0], a[1], a[2], ..., a[n-2]]`.

Given the sorted rotated array `nums` of **unique** elements, return _the minimum element of this array_.

You must write an algorithm that runs in `O(log n) time.`

**Example 1:**

**Input:** nums = [3,4,5,1,2]

**Output:** 1

**Explanation:** The original array was [1,2,3,4,5] rotated 3 times.

**Example 2:**

**Input:** nums = [4,5,6,7,0,1,2]

**Output:** 0

**Explanation:** The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.

**Example 3:**

**Input:** nums = [11,13,15,17]

**Output:** 11

**Explanation:** The original array was [11,13,15,17] and it was rotated 4 times.

**Constraints:**

* `n == nums.length`
* `1 <= n <= 5000`
* `-5000 <= nums[i] <= 5000`
* All the integers of `nums` are **unique**.
* `nums` is sorted and rotated between `1` and `n` times.
Loading

0 comments on commit 17cac9a

Please sign in to comment.