题目描述
出处 https://leetcode.com/problems/couples-holding-hands/description/
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.
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).
The couples’ initial seating is given by row[i] being the value of the person who is initially sitting in the i-th seat.
Example 1:
Input: row = [0, 2, 1, 3]
Output: 1
Explanation: We only need to swap the second (row[1]) and third (row[2]) person.
Example 2:
Input: row = [3, 2, 0, 1]
Output: 0
Explanation: All couples are already seated side by side.
分析
- 方法一:
这道题可以直接通过暴力求解的方式,遍历整个vector,若相邻的两人不是夫妇,则寻找其对应夫妇的位置,并进行交换,最终求得交换次数。但这种方法时间复杂度为O(n^2),比较高。 - 方法二:
为了优化方法一中的寻找部分,可以在开始时用单独的vector记录每个数字对应的位置,从而快速找到对应夫妇,将时间复杂度降为O(n);
最终结果
方法一:
class Solution {
public:
int minSwapsCouples(vector<int>& row) {
int count = 0, flag = 0, num = 0;
int size = row.size();
for (int i = 0; i < size; i+=2) {
if (row[i] % 2 == 0 && row[i]+1 == row[i+1]) {
flag = 0;
} else if (row[i] % 2 == 1 && row[i]-1 == row[i+1]) {
flag = 0;
} else {
flag = 1;
num = row[i];
}
if (num % 2 == 0){
num += 1;
} else {
num -= 1;
}
if (flag == 1) {
count ++;
cout << num << endl;
for (int j = i+2; j < size; j++) {
if(row[j] == num) {
row[j] = row[i+1];
row[i+1] = num;
break;
}
}
}
}
return count;
}
};
方法二:
class Solution {
public:
int minSwapsCouples(vector<int>& row) {
int count = 0;
vector<int> pos(row.size(), 0);
for(int i = 0; i < row.size(); i++) {
pos[row[i]] = i;
}
for (int i = 0; i < row.size(); i+=2) {
if (row[i]/2 == row[i+1]/2) continue;
if (row[i]%2 == 0) {
pos[row[i+1]] = pos[row[i]+1];
swap(row[pos[row[i]+1]], row[i+1]);
} else {
pos[row[i+1]] = pos[row[i]-1];
swap(row[pos[row[i]-1]], row[i+1]);
}
count ++;
}
return count;
}
};