最少交换次数 置换环 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;
	}
}

  

posted @ 2024-01-20 17:55  热敷哥  阅读(15)  评论(0编辑  收藏  举报