最少交换次数 置换环 LeetCode 2471. 逐层排序二叉树所需的最少操作数目
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; } }