数组的最少交换次数
排序之前的数组: 4 3 2 1
排好序之后的数组:1 2 3 4
两种方法指向:用排好序之前的数组指向之后的数组、排好序之后的数组指向之前的数组
这里用后者可以得到环图
排好序之后的数组应该是n个自环,数组交换的次数=元素的个数n - 未排序数组中环的个数k
或者等于:
将环变成自环需要的交换次数就是:cycle_size-1
int minSwaps(const vector<int> &nums){ //在这里并不需要对原数组进行修改
int n = nums.size();
pair<int, int> arrPos[n]; //记录数组元素的位置
for (int i = 0; i < n; i++) {
arrPos[i].first = nums[i];
arrPos[i].second = i;
}
sort(arrPos, arrPos + n); //按照元素值的大小进行排序
int res = 0; //存储元素的交换次数
vector<bool> visited(n, false); //元素是否被访问过
for (int i = 0; i < n; i++){
int j = i;
if (visited[j] || arrPos[j].second == j)//元素已经被访问过或是已经在正确的位置上
continue;
int cycle_size = 0;
while (!visited[j]){
visited[j] = true;
j = arrPos[j].second;
cycle_size++;
}
if (cycle_size > 0)
res += cycle_size - 1;
}
return res;
}
相关题目
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int minimumOperations(TreeNode* root) {
int res = 0;
queue<TreeNode* > q;
q.push(root);
TreeNode* last = root;
vector<int> nums;
while (q.size()){
TreeNode* p = q.front();
q.pop();
nums.push_back(p->val);
if (p->left) q.push(p->left);
if (p->right) q.push(p->right);
// cout << p->val << endl;
if (p == last){
if (q.size()) last = q.back();
res += minSwaps(nums);
nums.clear();
}
}
return res;
}
int minSwaps(vector<int> &nums){
if (nums.size() < 2) return 0;
int n = nums.size(), res = 0;
pair<int, int> temp[n];
for (int i = 0; i < n; i++){
temp[i].first = nums[i];
temp[i].second = i;
}
sort(temp, temp + n);
vector<bool> visited(n, false);
for (int i = 0; i < n; i++){
int j = i;
if (visited[j] || temp[j].second == j)
continue;
int cycle_size = 0;
while (!visited[j]){
visited[j] = true;
j = temp[j].second;
cycle_size++;
}
if (cycle_size > 0)
res += cycle_size - 1;
}
return res;
}
};