|
| 1 | +defmodule Solution do |
| 2 | + @spec three_sum(nums :: [integer]) :: [[integer]] |
| 3 | + def three_sum(nums) do |
| 4 | + length_of_nums = length nums |
| 5 | + num_index_map = nums |> Enum.with_index |> Map.new |
| 6 | + frequencies_of_num = nums |> Enum.frequencies() |
| 7 | + tuple_nums = nums |> List.to_tuple |
| 8 | + num_indexs_map = nums |> |
| 9 | + Enum.with_index() |> |
| 10 | + Enum.group_by(fn {v, _} -> v end, fn {_, i} -> i end) |
| 11 | + |
| 12 | + Stream.unfold({0, 1}, fn {i, j} -> |
| 13 | + if j < length_of_nums - 1, |
| 14 | + do: {{i, j}, {i, j + 1}}, |
| 15 | + else: {{i, j}, {i + 1, i + 2}} |
| 16 | + end) |> |
| 17 | + Stream.take_while(fn {i, _} -> |
| 18 | + i < length_of_nums - 1 |
| 19 | + end) |> |
| 20 | + Stream.map(fn {i, j} -> |
| 21 | + a = elem tuple_nums, i |
| 22 | + b = elem tuple_nums, j |
| 23 | + c = -(a + b) |
| 24 | + |
| 25 | + case frequencies_of_num[c] do |
| 26 | + nil -> nil |
| 27 | + count when count >= 3 -> [a, b, c] |> Enum.sort() |
| 28 | + _ -> |
| 29 | + if num_indexs_map[c] |> Enum.filter(& &1 != i && &1 != j) |> Enum.at(0), |
| 30 | + do: [a, b, c] |> Enum.sort(), |
| 31 | + else: nil |
| 32 | + end |
| 33 | + end) |> |
| 34 | + Stream.reject(& &1 == nil) |> |
| 35 | + Stream.uniq |> |
| 36 | + Enum.to_list |
| 37 | + end |
| 38 | +end |
0 commit comments