class Solution:
def unhappyFriends(self, n, preferences, pairs):
# Build a ranking matrix for quick lookup
rank = [[0]*n for _ in range(n)]
for i in range(n):
for j, friend in enumerate(preferences[i]):
rank[i][friend] = j
# Pair mapping: person -> their pair
pair_map = {}
for x, y in pairs:
pair_map[x] = y
pair_map[y] = x
unhappy = set()
for x in range(n):
y = pair_map[x]
# All people x prefers over y
for u in preferences[x]:
if u == y:
break
v = pair_map[u]
# If u prefers x over their own pair v
if rank[u][x] < rank[u][v]:
unhappy.add(x)
break
return len(unhappy)
class Solution {
public:
int unhappyFriends(int n, vector<vector<int>>& preferences, vector<vector<int>>& pairs) {
vector<vector<int>> rank(n, vector<int>(n));
for (int i = 0; i < n; ++i)
for (int j = 0; j < n - 1; ++j)
rank[i][preferences[i][j]] = j;
vector<int> pair_map(n);
for (auto& p : pairs) {
pair_map[p[0]] = p[1];
pair_map[p[1]] = p[0];
}
int unhappy = 0;
for (int x = 0; x < n; ++x) {
int y = pair_map[x];
for (int i = 0; preferences[x][i] != y; ++i) {
int u = preferences[x][i];
int v = pair_map[u];
if (rank[u][x] < rank[u][v]) {
++unhappy;
break;
}
}
}
return unhappy;
}
};
class Solution {
public int unhappyFriends(int n, int[][] preferences, int[][] pairs) {
int[][] rank = new int[n][n];
for (int i = 0; i < n; ++i)
for (int j = 0; j < n - 1; ++j)
rank[i][preferences[i][j]] = j;
int[] pair_map = new int[n];
for (int[] p : pairs) {
pair_map[p[0]] = p[1];
pair_map[p[1]] = p[0];
}
int unhappy = 0;
for (int x = 0; x < n; ++x) {
int y = pair_map[x];
for (int i = 0; preferences[x][i] != y; ++i) {
int u = preferences[x][i];
int v = pair_map[u];
if (rank[u][x] < rank[u][v]) {
unhappy++;
break;
}
}
}
return unhappy;
}
}
var unhappyFriends = function(n, preferences, pairs) {
const rank = Array.from({length: n}, () => Array(n).fill(0));
for (let i = 0; i < n; ++i)
for (let j = 0; j < n - 1; ++j)
rank[i][preferences[i][j]] = j;
const pair_map = Array(n);
for (const [x, y] of pairs) {
pair_map[x] = y;
pair_map[y] = x;
}
let unhappy = new Set();
for (let x = 0; x < n; ++x) {
let y = pair_map[x];
for (const u of preferences[x]) {
if (u === y) break;
let v = pair_map[u];
if (rank[u][x] < rank[u][v]) {
unhappy.add(x);
break;
}
}
}
return unhappy.size;
};
The "Count Unhappy Friends" problem involves a group of n
people, each with a list of preferences ranking all other people. These people are paired up into n/2
pairs. A person x
is considered unhappy if there exists another person u
such that:
x
prefers u
over their current pair y
, andu
prefers x
over their own pair v
.Inputs:
n
: Number of people (even integer).preferences
: List of lists, where preferences[i]
is the list of people ranked by person i
.pairs
: List of pairs, where each pair is a list of two people.The problem is about identifying people who are "unhappy" with their assigned pair based on mutual preferences. At first glance, it may seem like we need to check every possible pair of people to see if the unhappiness condition is met, which could be time-consuming for larger groups.
The brute-force approach would involve, for each person, checking every other person to see if the conditions for being unhappy are met. However, since each person only cares about those they prefer over their assigned partner, we can optimize by only considering those people.
To make the checking efficient, we can precompute each person's ranking of others for O(1) lookups and quickly find whether a mutual preference exists. This avoids redundant checks and improves performance.
rank[x][u]
gives the index of person u
in x
's preference list. This allows us to check how much x
likes u
in constant time.
x
, look at everyone they prefer over their assigned partner y
. For each such person u
, check if u
prefers x
over their own assigned pair v
(using the ranking matrix).
x
as unhappy. To avoid counting duplicates, use a set or increment a count only once per person.
This approach ensures that each check is efficient, and we only consider relevant people for each person.
Sample Input:
n = 4
preferences = [[1,2,3],[3,2,0],[3,1,0],[1,2,0]]
pairs = [[0,1],[2,3]]
Step-by-step:
The key insight in solving the "Count Unhappy Friends" problem is to recognize that each person only needs to check those they prefer over their assigned pair, and that mutual preference can be checked efficiently using a ranking matrix. By mapping each person to their pair and using quick lookups, we reduce the problem from a potentially cubic brute-force approach to a quadratic solution. This efficient design ensures the solution is both fast and easy to understand, making it suitable for larger inputs and demonstrating the power of precomputation and smart data structures.