我们有 n
栋楼,编号从 0
到 n - 1
。每栋楼有若干员工。由于现在是换楼的季节,部分员工想要换一栋楼居住。
给你一个数组 requests
,其中 requests[i] = [fromi, toi]
,表示一个员工请求从编号为 fromi
的楼搬到编号为 toi
的楼。
一开始 所有楼都是满的,所以从请求列表中选出的若干个请求是可行的需要满足 每栋楼员工净变化为 0 。意思是每栋楼 离开 的员工数目 等于 该楼 搬入 的员工数数目。比方说 n = 3
且两个员工要离开楼 0
,一个员工要离开楼 1
,一个员工要离开楼 2
,如果该请求列表可行,应该要有两个员工搬入楼 0
,一个员工搬入楼 1
,一个员工搬入楼 2
。
请你从原请求列表中选出若干个请求,使得它们是一个可行的请求列表,并返回所有可行列表中最大请求数目。
示例 1:
输入:n = 5, requests = [[0,1],[1,0],[0,1],[1,2],[2,0],[3,4]] 输出:5 解释:请求列表如下: 从楼 0 离开的员工为 x 和 y ,且他们都想要搬到楼 1 。 从楼 1 离开的员工为 a 和 b ,且他们分别想要搬到楼 2 和 0 。 从楼 2 离开的员工为 z ,且他想要搬到楼 0 。 从楼 3 离开的员工为 c ,且他想要搬到楼 4 。 没有员工从楼 4 离开。 我们可以让 x 和 b 交换他们的楼,以满足他们的请求。 我们可以让 y,a 和 z 三人在三栋楼间交换位置,满足他们的要求。 所以最多可以满足 5 个请求。
示例 2:
输入:n = 3, requests = [[0,0],[1,2],[2,1]] 输出:3 解释:请求列表如下: 从楼 0 离开的员工为 x ,且他想要回到原来的楼 0 。 从楼 1 离开的员工为 y ,且他想要搬到楼 2 。 从楼 2 离开的员工为 z ,且他想要搬到楼 1 。 我们可以满足所有的请求。
示例 3:
输入:n = 4, requests = [[0,3],[3,1],[1,2],[2,0]] 输出:4
提示:
1 <= n <= 20
1 <= requests.length <= 16
requests[i].length == 2
0 <= fromi, toi < n
方法一:二进制枚举
我们注意到,换楼请求列表长度不超过
我们在
时间复杂度
class Solution:
def maximumRequests(self, n: int, requests: List[List[int]]) -> int:
def check(mask: int) -> bool:
cnt = [0] * n
for i, (f, t) in enumerate(requests):
if mask >> i & 1:
cnt[f] -= 1
cnt[t] += 1
return all(v == 0 for v in cnt)
ans = 0
for mask in range(1 << len(requests)):
cnt = mask.bit_count()
if ans < cnt and check(mask):
ans = cnt
return ans
class Solution {
private int m;
private int n;
private int[][] requests;
public int maximumRequests(int n, int[][] requests) {
m = requests.length;
this.n = n;
this.requests = requests;
int ans = 0;
for (int mask = 0; mask < 1 << m; ++mask) {
int cnt = Integer.bitCount(mask);
if (ans < cnt && check(mask)) {
ans = cnt;
}
}
return ans;
}
private boolean check(int mask) {
int[] cnt = new int[n];
for (int i = 0; i < m; ++i) {
if ((mask >> i & 1) == 1) {
int f = requests[i][0], t = requests[i][1];
--cnt[f];
++cnt[t];
}
}
for (int v : cnt) {
if (v != 0) {
return false;
}
}
return true;
}
}
class Solution {
public:
int maximumRequests(int n, vector<vector<int>>& requests) {
int m = requests.size();
int ans = 0;
auto check = [&](int mask) -> bool {
int cnt[n];
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < m; ++i) {
if (mask >> i & 1) {
int f = requests[i][0], t = requests[i][1];
--cnt[f];
++cnt[t];
}
}
for (int v : cnt) {
if (v) {
return false;
}
}
return true;
};
for (int mask = 0; mask < 1 << m; ++mask) {
int cnt = __builtin_popcount(mask);
if (ans < cnt && check(mask)) {
ans = cnt;
}
}
return ans;
}
};
func maximumRequests(n int, requests [][]int) (ans int) {
m := len(requests)
check := func(mask int) bool {
cnt := make([]int, n)
for i, r := range requests {
if mask>>i&1 == 1 {
f, t := r[0], r[1]
cnt[f]--
cnt[t]++
}
}
for _, v := range cnt {
if v != 0 {
return false
}
}
return true
}
for mask := 0; mask < 1<<m; mask++ {
cnt := bits.OnesCount(uint(mask))
if ans < cnt && check(mask) {
ans = cnt
}
}
return
}
function maximumRequests(n: number, requests: number[][]): number {
const m = requests.length;
let ans = 0;
const check = (mask: number): boolean => {
const cnt = new Array(n).fill(0);
for (let i = 0; i < m; ++i) {
if ((mask >> i) & 1) {
const [f, t] = requests[i];
--cnt[f];
++cnt[t];
}
}
return cnt.every(v => v === 0);
};
for (let mask = 0; mask < 1 << m; ++mask) {
const cnt = bitCount(mask);
if (ans < cnt && check(mask)) {
ans = cnt;
}
}
return ans;
}
function bitCount(i: number): number {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
/**
* @param {number} n
* @param {number[][]} requests
* @return {number}
*/
var maximumRequests = function (n, requests) {
const m = requests.length;
let ans = 0;
const check = mask => {
const cnt = new Array(n).fill(0);
for (let i = 0; i < m; ++i) {
if ((mask >> i) & 1) {
const [f, t] = requests[i];
--cnt[f];
++cnt[t];
}
}
return cnt.every(v => v === 0);
};
for (let mask = 0; mask < 1 << m; ++mask) {
const cnt = bitCount(mask);
if (ans < cnt && check(mask)) {
ans = cnt;
}
}
return ans;
};
function bitCount(i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}