列表

详情


765. 情侣牵手

n 对情侣坐在连续排列的 2n 个座位上,想要牵到对方的手。

人和座位由一个整数数组 row 表示,其中 row[i] 是坐在第 i 个座位上的人的 ID。情侣们按顺序编号,第一对是 (0, 1),第二对是 (2, 3),以此类推,最后一对是 (2n-2, 2n-1)

返回 最少交换座位的次数,以便每对情侣可以并肩坐在一起每次交换可选择任意两人,让他们站起来交换座位。

 

示例 1:

输入: row = [0,2,1,3]
输出: 1
解释: 只需要交换row[1]和row[2]的位置即可。

示例 2:

输入: row = [3,2,0,1]
输出: 0
解释: 无需交换座位,所有的情侣都已经可以手牵手了。

 

提示:

相似题目

缺失的第一个正数

丢失的数字

相似度为 K 的字符串

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int minSwapsCouples(vector<int>& row) { } };

cpp 解法, 执行用时: 4 ms, 内存消耗: 7.9 MB, 提交时间: 2023-11-11 00:23:28

class Solution {
public:
    int minSwapsCouples(vector<int>& row) {
        int n = row.size();
        int tot = n / 2;
        
        vector<vector<int>> graph(tot);
        for (int i = 0; i < n; i += 2) {
            int l = row[i] / 2;
            int r = row[i + 1] / 2;
            if (l != r) {
                graph[l].push_back(r);
                graph[r].push_back(l);
            }
        }
        vector<int> visited(tot, 0);
        int ret = 0;
        for (int i = 0; i < tot; i++) {
            if (visited[i] == 0) {
                queue<int> q;
                visited[i] = 1;
                q.push(i);
                int cnt = 0;

                while (!q.empty()) {
                    int x = q.front();
                    q.pop();
                    cnt += 1;

                    for (int y: graph[x]) {
                        if (visited[y] == 0) {
                            visited[y] = 1;
                            q.push(y);
                        }
                    }
                }
                ret += cnt - 1;
            }
        }
        return ret;
    }
};

cpp 解法, 执行用时: 4 ms, 内存消耗: 7.7 MB, 提交时间: 2023-11-11 00:23:17

class Solution {
public:
    int getf(vector<int>& f, int x) {
        if (f[x] == x) {
            return x;
        }
        int newf = getf(f, f[x]);
        f[x] = newf;
        return newf;
    }

    void add(vector<int>& f, int x, int y) {
        int fx = getf(f, x);
        int fy = getf(f, y);
        f[fx] = fy;
    }

    int minSwapsCouples(vector<int>& row) {
        int n = row.size();
        int tot = n / 2;
        vector<int> f(tot, 0);
        for (int i = 0; i < tot; i++) {
            f[i] = i;
        }

        for (int i = 0; i < n; i += 2) {
            int l = row[i] / 2;
            int r = row[i + 1] / 2;
            add(f, l, r);
        }

        unordered_map<int, int> m;
        for (int i = 0; i < tot; i++) {
            int fx = getf(f, i);
            m[fx]++;
        }
        
        int ret = 0;
        for (const auto& [f, sz]: m) {
            ret += sz - 1;
        }
        return ret;
    }
};

python3 解法, 执行用时: 40 ms, 内存消耗: 15 MB, 提交时间: 2023-01-11 10:19:18

# 循环搜索
class Solution():
    def minSwapsCouples(self, row: List[int]) -> int:
        N = len(row) // 2

        #couples[x] = [i, j]:
        #x-th couple is at couches i and j
        couples = [[] for _ in range(N)]
        for i, x in enumerate(row):
            couples[x//2].append(i//2)
        #adj[x] = [i, j]
        #x-th couch connected to couches i, j by couples
        adj = [[] for _ in range(N)]
        for x, y in couples:
            adj[x].append(y)
            adj[y].append(x)
        #Answer is N minus the number of cycles in "adj"
        ans = N
        for start in range(N):
            if not adj[start]: continue
            ans -= 1
            x, y = start, adj[start].pop()
            while y != start:
                adj[y].remove(x)
                x, y = y, adj[y].pop()
        return ans

python3 解法, 执行用时: 36 ms, 内存消耗: 14.9 MB, 提交时间: 2023-01-11 10:17:28

# 贪心法,
class Solution():
    def minSwapsCouples(self, row: List[int]) -> int:
        ans = 0
        for i in range(0, len(row), 2):
            x = row[i]
            if row[i+1] == x^1: continue
            ans += 1
            for j in range(i+1, len(row)):
                if row[j] == x^1:
                    row[i+1], row[j] = row[j], row[i+1]
                    break
        return ans

java 解法, 执行用时: 1 ms, 内存消耗: 39.3 MB, 提交时间: 2023-01-11 10:15:40

class Solution {
    public int minSwapsCouples(int[] row) {
        int n = row.length;
        int tot = n / 2;
        
        List<Integer>[] graph = new List[tot];
        for (int i = 0; i < tot; i++) {
            graph[i] = new ArrayList<Integer>();
        }
        for (int i = 0; i < n; i += 2) {
            int l = row[i] / 2;
            int r = row[i + 1] / 2;
            if (l != r) {
                graph[l].add(r);
                graph[r].add(l);
            }
        }
        boolean[] visited = new boolean[tot];
        int ret = 0;
        for (int i = 0; i < tot; i++) {
            if (!visited[i]) {
                Queue<Integer> queue = new LinkedList<Integer>();
                visited[i] = true;
                queue.offer(i);
                int cnt = 0;

                while (!queue.isEmpty()) {
                    int x = queue.poll();
                    cnt += 1;

                    for (int y : graph[x]) {
                        if (!visited[y]) {
                            visited[y] = true;
                            queue.offer(y);
                        }
                    }
                }
                ret += cnt - 1;
            }
        }
        return ret;
    }
}

golang 解法, 执行用时: 0 ms, 内存消耗: 2 MB, 提交时间: 2023-01-11 10:14:58

func minSwapsCouples(row []int) (ans int) {
    n := len(row)
    graph := make([][]int, n/2)
    for i := 0; i < n; i += 2 {
        l, r := row[i]/2, row[i+1]/2
        if l != r {
            graph[l] = append(graph[l], r)
            graph[r] = append(graph[r], l)
        }
    }
    vis := make([]bool, n/2)
    for i, vs := range vis {
        if !vs {
            vis[i] = true
            cnt := 0
            q := []int{i}
            for len(q) > 0 {
                cnt++
                v := q[0]
                q = q[1:]
                for _, w := range graph[v] {
                    if !vis[w] {
                        vis[w] = true
                        q = append(q, w)
                    }
                }
            }
            ans += cnt - 1
        }
    }
    return
}

javascript 解法, 执行用时: 60 ms, 内存消耗: 41.3 MB, 提交时间: 2023-01-11 10:14:37

/**
 * @param {number[]} row
 * @return {number}
 */
var minSwapsCouples = function(row) {
    const n = row.length;
    const tot = n / 2;
    
    const graph = new Array(tot).fill(0).map(() => []);
    for (let i = 0; i < n; i += 2) {
        const l = Math.floor(row[i] / 2);
        const r = Math.floor(row[i + 1] / 2);
        if (l != r) {
            graph[l].push(r);
            graph[r].push(l);
        }
    }
    const visited = new Array(tot).fill(false);
    let ret = 0;
    for (let i = 0; i < tot; i++) {
        if (!visited[i]) {
            const queue = [];
            visited[i] = true;
            queue.push(i);
            let cnt = 0;

            while (queue.length) {
                const x = queue.shift();
                cnt += 1;

                for (const y of graph[x]) {
                    if (!visited[y]) {
                        visited[y] = true;
                        queue.push(y);
                    }
                }
            }
            ret += cnt - 1;
        }
    }
    return ret;
};

javascript 解法, 执行用时: 64 ms, 内存消耗: 41 MB, 提交时间: 2023-01-11 10:13:57

/**
 * @param {number[]} row
 * @return {number}
 */
var minSwapsCouples = function(row) {
    const n = row.length;
    const tot = n / 2;
    const f = new Array(tot).fill(0).map((element, index) => index);
    
    for (let i = 0; i < n; i += 2) {
        const l = Math.floor(row[i] / 2);
        const r = Math.floor(row[i + 1] / 2);
        add(f, l, r);
    }
    const map = new Map();
    for (let i = 0; i < tot; i++) {
        const fx = getf(f, i);
        if (map.has(fx)) {
            map.set(fx, map.get(fx) + 1);
        } else {
            map.set(fx, 1)
        }
    }
    
    let ret = 0;
    for (const [f, sz] of map.entries()) {
        ret += sz - 1;
    }
    return ret;
};  

const getf = (f, x) => {
    if (f[x] === x) {
        return x;
    }
    const newf = getf(f, f[x]);
    f[x] = newf;
    return newf;
}

const add = (f, x, y) => {
    const fx = getf(f, x);
    const fy = getf(f, y);
    f[fx] = fy;
}

golang 解法, 执行用时: 0 ms, 内存消耗: 1.9 MB, 提交时间: 2023-01-11 10:13:28

type unionFind struct {
    parent, size []int
    setCount     int // 当前连通分量数目
}

func newUnionFind(n int) *unionFind {
    parent := make([]int, n)
    size := make([]int, n)
    for i := range parent {
        parent[i] = i
        size[i] = 1
    }
    return &unionFind{parent, size, n}
}

func (uf *unionFind) find(x int) int {
    if uf.parent[x] != x {
        uf.parent[x] = uf.find(uf.parent[x])
    }
    return uf.parent[x]
}

func (uf *unionFind) union(x, y int) {
    fx, fy := uf.find(x), uf.find(y)
    if fx == fy {
        return
    }
    if uf.size[fx] < uf.size[fy] {
        fx, fy = fy, fx
    }
    uf.size[fx] += uf.size[fy]
    uf.parent[fy] = fx
    uf.setCount--
}

func minSwapsCouples(row []int) int {
    n := len(row)
    uf := newUnionFind(n / 2)
    for i := 0; i < n; i += 2 {
        uf.union(row[i]/2, row[i+1]/2)
    }
    return n/2 - uf.setCount
}

java 解法, 执行用时: 1 ms, 内存消耗: 39.2 MB, 提交时间: 2023-01-11 10:13:08

class Solution {
    public int minSwapsCouples(int[] row) {
        int n = row.length;
        int tot = n / 2;
        int[] f = new int[tot];
        for (int i = 0; i < tot; i++) {
            f[i] = i;
        }

        for (int i = 0; i < n; i += 2) {
            int l = row[i] / 2;
            int r = row[i + 1] / 2;
            add(f, l, r);
        }

        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i = 0; i < tot; i++) {
            int fx = getf(f, i);
            map.put(fx, map.getOrDefault(fx, 0) + 1);
        }
        
        int ret = 0;
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            ret += entry.getValue() - 1;
        }
        return ret;
    }

    public int getf(int[] f, int x) {
        if (f[x] == x) {
            return x;
        }
        int newf = getf(f, f[x]);
        f[x] = newf;
        return newf;
    }

    public void add(int[] f, int x, int y) {
        int fx = getf(f, x);
        int fy = getf(f, y);
        f[fx] = fy;
    }
}

java 解法, 执行用时: 0 ms, 内存消耗: 39.2 MB, 提交时间: 2023-01-11 10:12:36

class Solution {

    public int minSwapsCouples(int[] row) {
        int len = row.length;
        int N = len / 2;
        UnionFind unionFind = new UnionFind(N);
        for (int i = 0; i < len; i += 2) {
            unionFind.union(row[i] / 2, row[i + 1] / 2);
        }
        return N - unionFind.getCount();
    }

    private class UnionFind {

        private int[] parent;

        private int count;

        public int getCount() {
            return count;
        }

        public UnionFind(int n) {
            this.count = n;
            this.parent = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
            }
        }

        public int find(int x) {
            while (x != parent[x]) {
                parent[x] = parent[parent[x]];
                x = parent[x];
            }
            return x;
        }

        public void union(int x, int y) {
            int rootX = find(x);
            int rootY = find(y);
            if (rootX == rootY) {
                return;
            }

            parent[rootX] = rootY;
            count--;
        }
    }
}

上一题