线段树解法,线段树结构:{Min, Max, Value, Small, Big} = TreeData。
Min数据段最小值,Max数据段最大值,Value数据段数据个数,Small左子树,Big右子树。
左右子树的划分值Mid = Min + (Max-Min) div 2, Small为{Min,Mid},Big为{Mid+1,Max}。
每插入一个数Num的时候,更新所有Num属于{Min,Max}的节点的Value+1,时间复杂度O(lgN)。同样计算所有{Min,Num-1}的个数,遍历线段树的时间复杂度也在O(lgN)。
给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
示例 1:
输入:nums = [5,2,6,1]
输出:[2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素
示例 2:
输入:nums = [-1]
输出:[0]
示例 3:
输入:nums = [-1,-1]
输出:[0,0]
提示:
1 <= nums.length <= 10^5
-10^4 <= nums[i] <= 10^4
-spec count_smaller(Nums :: [integer()]) -> [integer()].
count_smaller(Nums) ->
Min = lists:min(Nums),
Max = lists:max(Nums),
TreeData = {Min, Max, 0, nil, nil},
do_count(lists:reverse(Nums), Min, Max, TreeData, []).
do_count([], Min, Max, Tree, Ans) ->
Ans;
do_count([N | Nums], Min, Max, Tree, Ans) ->
NewTree = insert_to_tree(Min, Max, N, Tree),
Count = get_small_num(Min, Max, N, Tree),
do_count(Nums, Min, Max, NewTree, [Count | Ans]).
insert_to_tree(Min, Min, N, TreeData) ->
case TreeData of
{Min, Min, Value, nil, nil} ->
{Min, Min, Value + 1, nil, nil};
_ ->
{Min, Min, 1, nil, nil}
end;
insert_to_tree(Min, Max, N, TreeData) ->
if
TreeData =:= nil ->
Value = 0, Small = nil, Big = nil;
true ->
{Min, Max, Value, Small, Big} = TreeData
end,
Mid = Min + (Max-Min) div 2,
if
Mid >= N ->
{Min, Max, Value + 1, insert_to_tree(Min, Mid, N, Small), Big};
true ->
{Min, Max, Value + 1, Small, insert_to_tree(Mid + 1, Max, N, Big)}
end.
get_small_num(Min, Min, N, TreeData) ->
case TreeData of
{Min, Min, Value, nil, nil} ->
if
N > Min ->
Value;
true ->
0
end;
_ ->
0
end;
get_small_num(Min, Max, N, TreeData) ->
if
TreeData =:= nil ->
0;
true ->
{Min, Max, Value, Small, Big} = TreeData,
if
N > Max ->
Value;
Min > N ->
0;
true ->
Mid = Min + (Max-Min) div 2,
if
Mid >= N ->
get_small_num(Min, Mid, N, Small);
true ->
get_small_num(Min, Mid, N, Small) + get_small_num(Mid + 1, Max, N, Big)
end
end
end.