数组的最少交换次数

数组的最少交换次数

题目描述

排序之前的数组: 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;
}

相关题目

2471. 逐层排序二叉树所需的最少操作数目

/**
 * 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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值