首页 > 其他分享 >Minimum Number of Operations to Sort a Binary Tree by Level

Minimum Number of Operations to Sort a Binary Tree by Level

时间:2022-11-14 20:25:04浏览次数:73  
标签:Operations Sort right TreeNode level int Binary 序列 left

Minimum Number of Operations to Sort a Binary Tree by Level

You are given the root of a binary tree with unique values.

In one operation, you can choose any two nodes at the same level and swap their values.

Return the minimum number of operations needed to make the values at each level sorted in a strictly increasing order.

The level of a node is the number of edges along the path between it and the root node.

Example 1:

Input: root = [1,4,3,7,6,8,5,null,null,null,null,9,null,10]
Output: 3
Explanation:
- Swap 4 and 3. The 2nd level becomes [3,4].
- Swap 7 and 5. The 3rd level becomes [5,6,8,7].
- Swap 8 and 7. The 3rd level becomes [5,6,7,8].
We used 3 operations so return 3.
It can be proven that 3 is the minimum number of operations needed.

Example 2:

Input: root = [1,3,2,7,6,5,4]
Output: 3
Explanation:
- Swap 3 and 2. The 2nd level becomes [2,3].
- Swap 7 and 4. The 3rd level becomes [4,6,5,7].
- Swap 6 and 5. The 3rd level becomes [4,5,6,7].
We used 3 operations so return 3.
It can be proven that 3 is the minimum number of operations needed.

Example 3:

Input: root = [1,2,3,4,5,6]
Output: 0
Explanation: Each level is already sorted in increasing order so return 0.

Constraints:

  • The number of nodes in the tree is in the range $[1, {10}^{5}]$.
  • $1 \leq \text{Node.val} \leq {10}^{5}$
  • All the values of the tree are unique.

 

解题思路

  先bfs找出每一层的值,然后问题就变成了给定一个序列,可以交换任意两个位置的元素,最少需要进行多少次交换使得序列变成升序。

  可把这个问题转换成一个环图。比如有原序列 2 1 4 5 3 ,这个序列对应的升序序列是 1 2 3 4 5 ,这时我们根据这两个序列进行建图,边$a \to b$表示升序序列的第$a$个位置的元素应该放到原序列的第$b$个位置,按照这种连边方式就会得到下图:

  因为每个数都是不同的,因此每个数在原数组中以及排序后的数组中的位置是唯一确定的,因此每个点的入度和出度都是$1$,因此这个图就是一个环图。

  如果交换的两个数不在同一个环里,那么会把这两个环合并成一个环。比如对原序列中第$2$个元素和第$3$个元素进行交换,原序列变成 2 4 1 5 3 ,就会得到下图:

  如果交换的两个数在同一个环里,那么会把这个环裂开成两个环。比如对原序列中第$4$个元素和第$5$个元素进行交换,原序列变成 2 1 4 3 5 ,就会得到下图:

  可以发现,对于一个升序序列,每一个数都是一个自环,一共有$n$个自环。因此为了实现最小的操作次数每次都应该把一个环裂开成两个环,直到变成$n$个环为止。因此一开始先统计环的个数,假设是$m$个环,由于每裂开一次最多增加一个环,因此至少要裂$n - m$次,即交换$n - m$次。

  求一开始环的个数可以用并查集,由于这个是一个环图,一个环就是一个连通块,统计连通块的数量等价于统计环的数量。

  AC代码如下:

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10  * };
11  */
12 class Solution {
13 public:
14     int minimumOperations(TreeNode* root) {
15         queue<TreeNode*> q({root});
16         int ret = 0;
17         while (!q.empty()) {
18             int sz = q.size();
19             vector<int> a, fa;
20             while (sz--) {
21                 auto t = q.front();
22                 q.pop();
23                 a.push_back(t->val);
24                 if (t->left) q.push(t->left);
25                 if (t->right) q.push(t->right);
26             }
27             
28             unordered_map<int, int> mp;
29             for (int i = 0; i < a.size(); i++) {
30                 fa.push_back(i);
31                 mp[a[i]] = i;   // 记录元素a[i]的下标位置
32             }
33             sort(a.begin(), a.end());
34             
35             function<int(int)> find = [&](int x) {
36                 return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
37             };
38             
39             int cnt = 0;    // 记录有多少个连通块被合并了,也就是需要破环的次数
40             for (int i = 0; i < a.size(); i++) {
41                 int x = find(i), y = find(mp[a[i]]);
42                 if (x != y) fa[x] = y, cnt++;
43             }
44             ret += cnt;
45         }
46         return ret;
47     }
48 };

  这题是问对于一个序列可以交换任意两个位置的元素使其变成升序所需要的最小交换次数,可以用并查集来求解。如果只能交换相邻两个元素,那么就是统计序列中逆序对的数量,可以用树状数组或归并排序来求解。

 

参考资料

  力扣第319场周赛:https://www.bilibili.com/video/BV1kY411Z7uE/

标签:Operations,Sort,right,TreeNode,level,int,Binary,序列,left
From: https://www.cnblogs.com/onlyblues/p/16890211.html

相关文章

  • C++中sort函数、1.4最长公共子串
    sort()即为用来排序的函数,它根据具体情况使用不同的排序方法,效率较高。sort在实现时避免了经典快速排序中可能出现的会导致实际复杂度退化到O(n2)的极端情况。使用sort()......
  • VMware Aria Operations for Networks 6.8 - 网络和应用监控工具
    请访问原文链接:VMwareAriaOperationsforNetworks6.8-网络和应用监控工具,查看最新版。原创作品,转载请保留出处。作者主页:www.sysin.orgVMwareAriaOperationsfo......
  • C++ 位运算Bitwise operations详解 ----- 重要的解题技巧
    什么是位运算:利用位运算符号进行二进制位计算的操作即为位运算维基百科:......
  • 75.Sort Colors
    Givenanarraywith n objectscoloredred,whiteorblue,sortthemsothatobjectsofthesamecolorareadjacent,withthecolorsintheorderred,white......
  • [oeasy]python0014_二进制_binary_bin
    ​ 二进制(binary)回忆上次内容上次我们了解了​​ASCII​​码表​ASCII​​码表就是​​A​​merican​​S​​tandard​​C​​odefor​​I​​nformat......
  • 791. 自定义字符串排序 ----- 自定义sort、权值排序、计数排序
    给定两个字符串order和s。order的所有单词都是唯一的,并且以前按照一些自定义的顺序排序。对s的字符进行置换,使其与排序的 order 相匹配。更具体地说,如果在 or......
  • Java:自定义排序与sort()函数
    自定义排序与Arrays.sort()本篇题目来源:2022/11/13Leetcode每日一题:https://leetcode.cn/problems/custom-sort-string给定两个字符串order和s。order的所有单词都......
  • AtCoder Beginner Contest 277 F Sorting a Matrix
    SortingaMatrix拓扑序首先可以明确无论怎么交换行列,原本在同一行或者同一列的元素,还是会处于同一行或者同一列条件一每行每行地看,如果能满足从小到大的条件,说明第......
  • Sort List
    SourceSortalinkedlistinO(nlogn)timeusingconstantspacecomplexity.题解1-归并排序(链表长度求中间节点)链表的排序操作,对于常用的排序算法,能达到O(n......
  • Redis有序集合Zset(sorted set)
    Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高......