我们有 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
方法一:二进制枚举
二进制枚举所有方案,找出满足条件的最大请求数方案即可。
时间复杂度 O(m*2^m),其中 m 表示 requests 的长度。
class Solution:
def maximumRequests(self, n: int, requests: List[List[int]]) -> int:
def check(x):
d = [0] * n
for i, (f, t) in enumerate(requests):
if (x >> i) & 1:
d[f] -= 1
d[t] += 1
return all(v == 0 for v in d)
ans, m = 0, len(requests)
for mask in range(1 << m):
cnt = mask.bit_count()
if cnt > ans and check(mask):
ans = cnt
return ans
class Solution {
public int maximumRequests(int n, int[][] requests) {
int ans = 0;
for (int mask = 1; mask < 1 << requests.length; ++mask) {
int cnt = Integer.bitCount(mask);
if (ans < cnt && check(mask, requests)) {
ans = cnt;
}
}
return ans;
}
private boolean check(int x, int[][] requests) {
int[] d = new int[21];
for (int i = 0; i < requests.length; ++i) {
if (((x >> i) & 1) == 1) {
int f = requests[i][0];
int t = requests[i][1];
--d[f];
++d[t];
}
}
for (int v : d) {
if (v != 0) {
return false;
}
}
return true;
}
}
class Solution {
public:
int maximumRequests(int n, vector<vector<int>>& requests) {
int ans = 0, m = requests.size();
for (int mask = 0; mask < 1 << m; ++mask) {
int cnt = __builtin_popcount(mask);
if (ans < cnt && check(mask, requests)) ans = cnt;
}
return ans;
}
bool check(int x, vector<vector<int>>& requests) {
vector<int> d(21);
for (int i = 0; i < requests.size(); ++i) {
if ((x >> i) & 1) {
--d[requests[i][0]];
++d[requests[i][1]];
}
}
for (int& v : d)
if (v) return 0;
return 1;
}
};
func maximumRequests(n int, requests [][]int) int {
check := func(x int) bool {
d := make([]int, n)
for i, r := range requests {
if (x>>i)&1 == 1 {
d[r[0]]--
d[r[1]]++
}
}
for _, v := range d {
if v != 0 {
return false
}
}
return true
}
ans, m := 0, len(requests)
for mask := 0; mask < 1<<m; mask++ {
cnt := bits.OnesCount(uint(mask))
if ans < cnt && check(mask) {
ans = cnt
}
}
return ans
}
/**
* @param {number} n
* @param {number[][]} requests
* @return {number}
*/
var maximumRequests = function (n, requests) {
function check(x) {
let d = new Array(n).fill(0);
for (let i = 0; i < m; ++i) {
if ((x >> i) & 1) {
const [f, t] = requests[i];
d[f]--;
d[t]++;
}
}
for (const v of d) {
if (v) {
return false;
}
}
return true;
}
let ans = 0;
let m = requests.length;
for (let mask = 1; mask < 1 << m; ++mask) {
let cnt = mask.toString(2).split('0').join('').length;
if (ans < cnt && check(mask)) {
ans = cnt;
}
}
return ans;
};