Skip to content

Commit 0430798

Browse files
committed
添加 problem 765
1 parent ce6514a commit 0430798

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package leetcode
2+
3+
func minSwapsCouples(row []int) int {
4+
if len(row)&1 == 1 {
5+
return 0
6+
}
7+
uf := UnionFind{}
8+
uf.init(len(row))
9+
for i := 0; i < len(row)-1; i = i + 2 {
10+
uf.union(i, i+1)
11+
}
12+
for i := 0; i < len(row)-1; i = i + 2 {
13+
if uf.find(row[i]) != uf.find(row[i+1]) {
14+
uf.union(row[i], row[i+1])
15+
}
16+
}
17+
return len(row)/2 - uf.count
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
type question765 struct {
9+
para765
10+
ans765
11+
}
12+
13+
// para 是参数
14+
// one 代表第一个参数
15+
type para765 struct {
16+
one []int
17+
}
18+
19+
// ans 是答案
20+
// one 代表第一个答案
21+
type ans765 struct {
22+
one int
23+
}
24+
25+
func Test_Problem765(t *testing.T) {
26+
27+
qs := []question765{
28+
29+
question765{
30+
para765{[]int{0, 2, 1, 3}},
31+
ans765{1},
32+
},
33+
34+
question765{
35+
para765{[]int{3, 2, 0, 1}},
36+
ans765{0},
37+
},
38+
39+
question765{
40+
para765{[]int{3, 1, 4, 0, 2, 5}},
41+
ans765{2},
42+
},
43+
44+
question765{
45+
para765{[]int{10, 7, 4, 2, 3, 0, 9, 11, 1, 5, 6, 8}},
46+
ans765{4},
47+
},
48+
}
49+
50+
fmt.Printf("------------------------Leetcode Problem 765------------------------\n")
51+
52+
for _, q := range qs {
53+
_, p := q.ans765, q.para765
54+
fmt.Printf("【input】:%v 【output】:%v\n", p, minSwapsCouples(p.one))
55+
}
56+
fmt.Printf("\n\n\n")
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# [765. Couples Holding Hands](https://leetcode.com/problems/couples-holding-hands/)
2+
3+
4+
## 题目:
5+
6+
N couples sit in 2N seats arranged in a row and want to hold hands. We want to know the minimum number of swaps so that every couple is sitting side by side. A swap consists of choosing **any** two people, then they stand up and switch seats.
7+
8+
The people and seats are represented by an integer from `0` to `2N-1`, the couples are numbered in order, the first couple being `(0, 1)`, the second couple being `(2, 3)`, and so on with the last couple being `(2N-2, 2N-1)`.
9+
10+
The couples' initial seating is given by `row[i]` being the value of the person who is initially sitting in the i-th seat.
11+
12+
**Example 1:**
13+
14+
Input: row = [0, 2, 1, 3]
15+
Output: 1
16+
Explanation: We only need to swap the second (row[1]) and third (row[2]) person.
17+
18+
**Example 2:**
19+
20+
Input: row = [3, 2, 0, 1]
21+
Output: 0
22+
Explanation: All couples are already seated side by side.
23+
24+
**Note:**
25+
26+
1. `len(row)` is even and in the range of `[4, 60]`.
27+
2. `row` is guaranteed to be a permutation of `0...len(row)-1`.
28+
29+
30+
## 题目大意
31+
32+
N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手。 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起。 一次交换可选择任意两人,让他们站起来交换座位。人和座位用 0 到 2N-1 的整数表示,情侣们按顺序编号,第一对是 (0, 1),第二对是 (2, 3),以此类推,最后一对是 (2N-2, 2N-1)。这些情侣的初始座位 row[i] 是由最初始坐在第 i 个座位上的人决定的。
33+
34+
说明:
35+
36+
1. len(row) 是偶数且数值在 [4, 60]范围内。
37+
2. 可以保证 row 是序列 0...len(row)-1 的一个全排列。
38+
39+
40+
## 解题思路
41+
42+
- 给出一个数组,数组里面两两相邻的元素代表一对情侣。情侣编号是从 0 开始的:0 和 1 是情侣,2 和 3 是情侣……这些情侣坐在一排,但是并非成对坐着一起的,问如何用最小的次数交换座位以后,情侣能两两坐在一起。
43+
- 这道题的突破口是如何找到最小的交换次数。乍一想可能没有思路。直觉告诉我们,这种难题,很可能最后推出来的结论,或者公式是一个很简单的式子。(事实此题确实是这种情况)先不考虑最小交换次数,用正常的方法来处理这道题。举个例子:【3 1 4 0 2 5】,从数组 0 下标开始往后扫。
44+
45+
初始状态
46+
47+
集合 0:0,1
48+
集合 1:2,3
49+
集合 2:4,5
50+
51+
3 和 1 不是情侣,将 3 和 1 所在集合 `union()` 起来。3 所在集合是 1 ,1 所在集合是 0,将 0 和 1 号集合 `union()` 起来。因为情侣 0 和情侣 1 是集合 0 ,情侣 2 和情侣 3 是集合 1,以此类推。
52+
53+
集合 0 和 1:0,1,2,3
54+
集合 2:4,5
55+
56+
- 继续往后扫,4 和 0 不在同一个集合,4 在集合 3,0 在集合 0,那么把它们 `union()` 起来。
57+
58+
集合 0 和 1 和 2:0,1,2,3,4,5
59+
60+
在上面集合合并的过程中,合并了 2 次。那么就代表最少需要交换 2 次。也可以通过 `len(row)/2 - uf.count` 来计算。`len(row)/2` 是初始集合总数,`uf.count` 是最后剩下的集合数,两者相减就是中间交换的次数。
61+
62+
- 最后实现的代码非常简单。并查集先相邻的两两元素 `union()` 在一起。然后扫原数组,每次扫相邻的两个,通过这两个元素值所在集合,进行 `union()`。扫完以后就可以得到最后的答案。
63+
- 回过头来看这道题,为什么我们从数组开头往后依次调整每一对情侣,这样交换的次数是最少的呢?其实这个方法的思想是贪心思想。从头开始往后一对一对的调整,就是可以最终做到次数最少。(具体证明笔者不会)交换到最后,最后一对情侣一定是正确的,无须交换。(因为前面每一对都调整完了,最后一对一定是正确的)

0 commit comments

Comments
 (0)