URL
https://leetcode.com/problems/minimum-number-of-operations-to-sort-a-binary-tree-by-level/description/?envType=daily-question&envId=2024-12-23
Code
https://github.com/syohex/dotnet-study/blob/master/fsharp/leetcode/challenge/202412/minimum_number_of_operations_to_sort_a_binary_tree_by_level/main.fsx
type Tree =
| Leaf
| Node of int * Tree * Tree
let minimumOperations (root: Tree) : int =
let countSwaps orig =
let rec countSwaps' sorted i (orig: int[]) origMap acc =
match sorted with
| [] -> acc
| h :: t ->
if h = orig.[i] then
countSwaps' t (i + 1) orig origMap acc
else
let origIndex = Map.find h origMap
let origMap = Map.add orig.[i] origIndex origMap
let tmp = orig.[i]
orig.[i] <- orig.[origIndex]
orig.[origIndex] <- tmp
countSwaps' t (i + 1) orig origMap (acc + 1)
let sorted = orig |> List.sort
let origMap =
orig |> List.indexed |> List.fold (fun acc (i, v) -> Map.add v i acc) Map.empty
countSwaps' sorted 0 (List.toArray orig) origMap 0
let rec minimumOperations' q acc =
match q with
| [] -> acc
| _ ->
let orig =
q
|> List.fold
(fun acc node ->
match node with
| Leaf -> acc
| Node(v, _, _) -> v :: acc)
[]
|> List.rev
let q =
q
|> List.fold
(fun acc node ->
match node with
| Leaf -> acc
| Node(_, left, Leaf) -> left :: acc
| Node(_, Leaf, right) -> right :: acc
| Node(v, left, right) -> right :: left :: acc)
[]
|> List.rev
let ops = countSwaps orig
minimumOperations' q (acc + ops)
minimumOperations' [ root ] 0