Problem: Count Unhappy Friends

You are given a list of `preferences` for `n` friends, where `n` is always
even.

For each person `i`, `preferences[i]` contains a list of friends sorted in the
order of preference. In other words, a friend earlier in the list is more
preferred than a friend later in the list. Friends in each list are denoted by
integers from `0` to `n-1`.

All the friends are divided into pairs. The pairings are given in a list
`pairs`, where `pairs[i] = [xi, yi]` denotes `xi` is paired with `yi` and `yi`
is paired with `xi`.

However, this pairing may cause some of the friends to be unhappy. A friend
`x` is unhappy if `x` is paired with `y` and there exists a friend `u` who is
paired with `v` but:

* `x` prefers `u` over `y`, and
* `u` prefers `x` over `v`.

Return the number of unhappy friends.


Python solution:
import math
import itertools
import bisect
import collections
import string
import heapq
import functools
import sortedcontainers
from typing import List, Dict, Tuple, Iterator

class Solution:
  def unhappyFriends(self, n: int, preferences: List[List[int]], pairs: List[List[int]]) -> int:
    ans = 0
    matches = [0] * n
    prefer = [{} for _ in range(n)]

    for x, y in pairs:
      matches[x] = y
      matches[y] = x

    for i in range(n):
      for j in range(n - 1):
        prefer[i][preferences[i][j]] = j

    for x in range(n):
      for u in prefer[x].keys():
        y = matches[x]
        v = matches[u]
        if prefer[x][u] < prefer[x][y] and prefer[u][x] < prefer[u][v]:
          ans += 1
          break

    return ans


Java solution:
class Solution {
  public int unhappyFriends(int n, int[][] preferences, int[][] pairs) {
    int ans = 0;
    int[] matches = new int[n];
    Map<Integer, Integer>[] prefer = new Map[n];

    for (int[] pair : pairs) {
      final int x = pair[0];
      final int y = pair[1];
      matches[x] = y;
      matches[y] = x;
    }

    for (int i = 0; i < n; ++i)
      prefer[i] = new HashMap<>();

    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n - 1; ++j)
        prefer[i].put(preferences[i][j], j);

    for (int x = 0; x < n; ++x)
      for (final int u : preferences[x]) {
        final int y = matches[x];
        final int v = matches[u];
        if (prefer[x].get(u) < prefer[x].get(y) && prefer[u].get(x) < prefer[u].get(v)) {
          ++ans;
          break;
        }
      }

    return ans;
  }
}


C++ solution:
class Solution {
 public:
  int unhappyFriends(int n, vector<vector<int>>& preferences,
                     vector<vector<int>>& pairs) {
    int ans = 0;
    vector<int> matches(n);
    vector<unordered_map<int, int>> prefer(n);

    for (const vector<int>& pair : pairs) {
      const int x = pair[0];
      const int y = pair[1];
      matches[x] = y;
      matches[y] = x;
    }

    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n - 1; ++j)
        prefer[i][preferences[i][j]] = j;

    for (int x = 0; x < n; ++x)
      for (const auto& [u, _] : prefer[x]) {
        const int y = matches[x];
        const int v = matches[u];
        if (prefer[x][u] < prefer[x][y] && prefer[u][x] < prefer[u][v]) {
          ++ans;
          break;
        }
      }

    return ans;
  }
};