题目描述
给定一份 n
位朋友的亲近程度列表,其中 n
总是 偶数。
对每位朋友 i
,preferences[i]
包含一份 按亲近程度从高到低排列 的朋友列表。换句话说,排在列表前面的朋友与 i
的亲近程度比排在列表后面的朋友更高。每个列表中的朋友均以 0
到 n-1
之间的整数表示。
所有的朋友被分成几对,配对情况以列表 pairs
给出,其中 pairs[i] = [x_i, y_i]
表示 x_i
与 y_i
配对,且 y_i
与 x_i
配对。
但是,这样的配对情况可能会是其中部分朋友感到不开心。在 x
与 y
配对且 u
与 v
配对的情况下,如果同时满足下述两个条件,x
就会不开心:
x
与u
的亲近程度胜过x
与y
,且u
与x
的亲近程度胜过u
与v
返回 不开心的朋友的数目。
样例
输入:
n = 4
preferences = [[1, 2, 3], [3, 2, 0], [3, 1, 0], [1, 2, 0]]
pairs = [[0, 1], [2, 3]]
输出:2
解释:
朋友 1 不开心,因为:
- 1 与 0 配对,但 1 与 3 的亲近程度比 1 与 0 高,且
- 3 与 1 的亲近程度比 3 与 2 高。
朋友 3 不开心,因为:
- 3 与 2 配对,但 3 与 1 的亲近程度比 3 与 2 高,且
- 1 与 3 的亲近程度比 1 与 0 高。
朋友 0 和 2 都是开心的。
输入:
n = 2
preferences = [[1], [0]]
pairs = [[1, 0]]
输出:0
解释:朋友 0 和 1 都开心。
输入:
n = 4
preferences = [[1, 3, 2], [2, 3, 0], [1, 3, 0], [0, 2, 1]]
pairs = [[1, 3], [0, 2]]
输出:4
限制
2 <= n <= 500
n
是偶数。preferences.length == n
preferences[i].length == n - 1
0 <= preferences[i][j] <= n - 1
preferences[i]
不包含i
preferences[i]
中的所有值都是独一无二的。pairs.length == n/2
pairs[i].length == 2
x_i != y_i
0 <= x_i, y_i <= n - 1
- 每位朋友都 恰好 被包含在一对中。
算法
(暴力枚举) $O(n^2)$
- 求出每个人的对每个朋友的排名。
- 枚举所有不重复两对朋友,判断是否存在题目描述的情况。
时间复杂度
- 求出排名的时间复杂度为 $O(n^2)$。
- 共 $O(n^2)$ 对朋友,枚举判断的总时间复杂度为 $O(n^2)$。
空间复杂度
- 仅需要 $O(n^2)$ 的额外空间存储每个人对每个朋友的排名。
C++ 代码
class Solution {
private:
bool check(int x, int y, int u, int v, const vector<vector<int>> &rk) {
return rk[x][u] < rk[x][y] && rk[u][x] < rk[u][v];
}
public:
int unhappyFriends(int n, vector<vector<int>>& preferences,
vector<vector<int>>& pairs) {
vector<vector<int>> rk(n, vector<int>(n));
for (int i = 0; i < n; i++)
for (int j = 0; j < n - 1; j++)
rk[i][preferences[i][j]] = j;
int ans = 0;
for (int i = 0; i < pairs.size(); i++) {
int x = pairs[i][0], y = pairs[i][1];
bool unhappy_x = false, unhappy_y = false;
for (int j = 0; j < pairs.size(); j++) {
if (i == j) continue;
int u = pairs[j][0], v = pairs[j][1];
if (!unhappy_x && (check(x, y, u, v, rk) || check(x, y, v, u, rk))) {
unhappy_x = true;
ans++;
}
if (!unhappy_y && (check(y, x, u, v, rk) || check(y, x, v, u, rk))) {
unhappy_y = true;
ans++;
}
if (unhappy_x && unhappy_y) break;
}
}
return ans;
}
};