1601. 最多可达成的换楼请求数目
我们有 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
原站题解
python3 解法, 执行用时: 1788 ms, 内存消耗: 16.1 MB, 提交时间: 2023-06-20 09:38:08
class Solution: def maximumRequests(self, n: int, requests: List[List[int]]) -> int: ans = 0 for mask in range(1 << len(requests)): cnt = mask.bit_count() if cnt <= ans: continue delta = [0] * n for i, (x, y) in enumerate(requests): if mask & (1 << i): delta[x] += 1 delta[y] -= 1 if all(x == 0 for x in delta): ans = cnt return ans
java 解法, 执行用时: 66 ms, 内存消耗: 39 MB, 提交时间: 2023-06-20 09:37:46
class Solution { public int maximumRequests(int n, int[][] requests) { int[] delta = new int[n]; int ans = 0, m = requests.length; for (int mask = 0; mask < (1 << m); ++mask) { int cnt = Integer.bitCount(mask); if (cnt <= ans) { continue; } Arrays.fill(delta, 0); for (int i = 0; i < m; ++i) { if ((mask & (1 << i)) != 0) { ++delta[requests[i][0]]; --delta[requests[i][1]]; } } boolean flag = true; for (int x : delta) { if (x != 0) { flag = false; break; } } if (flag) { ans = cnt; } } return ans; } }
golang 解法, 执行用时: 76 ms, 内存消耗: 6.7 MB, 提交时间: 2023-06-20 09:37:21
// 二进制枚举 func maximumRequests(n int, requests [][]int) (ans int) { next: for mask := 0; mask < 1<<len(requests); mask++ { cnt := bits.OnesCount(uint(mask)) if cnt <= ans { continue } delta := make([]int, n) for i, r := range requests { if mask>>i&1 == 1 { delta[r[0]]++ delta[r[1]]-- } } for _, d := range delta { if d != 0 { continue next } } ans = cnt } return }
javascript 解法, 执行用时: 1304 ms, 内存消耗: 47 MB, 提交时间: 2023-06-20 09:36:47
/** * @param {number} n * @param {number[][]} requests * @return {number} */ var maximumRequests = function(n, requests) { const delta = new Array(n).fill(0); let ans = 0, m = requests.length; for (let mask = 0; mask < (1 << m); ++mask) { let cnt = mask.toString(2).split('0').join('').length; if (cnt <= ans) { continue; } delta.fill(0); for (let i = 0; i < m; ++i) { if ((mask & (1 << i)) !== 0) { ++delta[requests[i][0]]; --delta[requests[i][1]]; } } let flag = true; for (const x of delta) { if (x !== 0) { flag = false; break; } } if (flag) { ans = cnt; } } return ans; };
javascript 解法, 执行用时: 108 ms, 内存消耗: 41.3 MB, 提交时间: 2023-06-20 09:36:23
/** * @param {number} n * @param {number[][]} requests * @return {number} */ var maximumRequests = function(n, requests) { const delta = new Array(n).fill(0); let zero = n, ans = 0, cnt = 0; const dfs = (requests, pos) => { if (pos === requests.length) { if (zero === n) { ans = Math.max(ans, cnt); } return; } // 不选 requests[pos] dfs(requests, pos + 1); // 选 requests[pos] let z = zero; ++cnt; const r = requests[pos]; let x = r[0], y = r[1]; zero -= delta[x] == 0 ? 1 : 0; --delta[x]; zero += delta[x] == 0 ? 1 : 0; zero -= delta[y] == 0 ? 1 : 0; ++delta[y]; zero += delta[y] == 0 ? 1 : 0; dfs(requests, pos + 1); --delta[y]; ++delta[x]; --cnt; zero = z; } dfs(requests, 0); return ans; };
golang 解法, 执行用时: 24 ms, 内存消耗: 2.1 MB, 提交时间: 2023-06-20 09:36:05
// 回溯 + 枚举 func maximumRequests(n int, requests [][]int) (ans int) { delta := make([]int, n) cnt, zero := 0, n var dfs func(int) dfs = func(pos int) { if pos == len(requests) { if zero == n && cnt > ans { ans = cnt } return } // 不选 requests[pos] dfs(pos + 1) // 选 requests[pos] z := zero cnt++ r := requests[pos] x, y := r[0], r[1] if delta[x] == 0 { zero-- } delta[x]-- if delta[x] == 0 { zero++ } if delta[y] == 0 { zero-- } delta[y]++ if delta[y] == 0 { zero++ } dfs(pos + 1) delta[y]-- delta[x]++ cnt-- zero = z } dfs(0) return }
java 解法, 执行用时: 17 ms, 内存消耗: 39 MB, 提交时间: 2023-06-20 09:35:30
class Solution { int[] delta; int ans = 0, cnt = 0, zero, n; public int maximumRequests(int n, int[][] requests) { delta = new int[n]; zero = n; this.n = n; dfs(requests, 0); return ans; } public void dfs(int[][] requests, int pos) { if (pos == requests.length) { if (zero == n) { ans = Math.max(ans, cnt); } return; } // 不选 requests[pos] dfs(requests, pos + 1); // 选 requests[pos] int z = zero; ++cnt; int[] r = requests[pos]; int x = r[0], y = r[1]; zero -= delta[x] == 0 ? 1 : 0; --delta[x]; zero += delta[x] == 0 ? 1 : 0; zero -= delta[y] == 0 ? 1 : 0; ++delta[y]; zero += delta[y] == 0 ? 1 : 0; dfs(requests, pos + 1); --delta[y]; ++delta[x]; --cnt; zero = z; } }
python3 解法, 执行用时: 1060 ms, 内存消耗: 16.1 MB, 提交时间: 2023-06-20 09:35:07
# 回溯 + 枚举 class Solution: def maximumRequests(self, n: int, requests: List[List[int]]) -> int: delta = [0] * n # 每一栋楼的员工变化量 ans, cnt, zero = 0, 0, n # 枚举第pos个请求 def dfs(pos: int) -> None: nonlocal ans, cnt, zero if pos == len(requests): if zero == n: ans = max(ans, cnt) return # 不选 requests[pos] dfs(pos + 1) # 选 requests[pos] z = zero cnt += 1 x, y = requests[pos] zero -= delta[x] == 0 delta[x] -= 1 zero += delta[x] == 0 zero -= delta[y] == 0 delta[y] += 1 zero += delta[y] == 0 dfs(pos + 1) delta[y] -= 1 delta[x] += 1 cnt -= 1 zero = z dfs(0) return ans