void Main()
{
var root = new TreeNode(1)
{
left = new TreeNode(3)
{
left = new TreeNode(7),
right = new TreeNode(6)
},
right = new TreeNode(2)
{
left = new TreeNode(5),
right = new TreeNode(4)
}
};
var r = new Solution().MinimumOperations(root);
r.Dump();
}
public class Solution
{
public int MinimumOperations(TreeNode root)
{
var res = 0;
var queue = new Queue<TreeNode>();
queue.Enqueue(root);
while (queue.Count > 0)
{
var count = queue.Count;
var arr = new int[count];
var idx = new int[count];
for (int i = 0; i < count; i++)
{
root = queue.Dequeue();
arr[i] = root.val;
idx[i] = i;
if (root.left != null) queue.Enqueue(root.left);
if (root.right != null) queue.Enqueue(root.right);
}
if (count == 1)
{
continue;
}
Array.Sort(idx, (i, j) => arr[i] - arr[j]);
var k = 0;
for (int i = 0; i < count; i++)
{
while (idx[i] != i)
{
var val = idx[i];
idx[i] = idx[val];
idx[val] = val;
k++;
}
}
res += k;
//置换环:感觉比我自己的写法好不了多少,还多了个hash,
//上面我的写法,交换多了点,如果不交换,也需要建个hash。
/*
例如在数组 [2,0,1,4,3] 中,[2,0,1] 和 [4,3] 分别是两个置换环,
环与环之间是数字是不需要发生交换的,只会在环内发生交换。
怎么找到环呢?从第一个数开始,把这个数字当成下标去访问数组,不断循环直到回到这个数本身。
我们只需要计算每个环内需要多少次交换。对于每个环,交换次数为环的大小减一。
*/
//var hash = new HashSet<int>();
//for (int i = 0; i < count; i++)
//{
// if (hash.Contains(i)) continue;
// var k = 1;
// var val = idx[i];
// while (val != i)
// {
// hash.Add(val);
// k++;
// val = idx[val];
// }
// res += (k - 1);
//}
}
return res;
}
}