Question We have n
buildings numbered from 0
to n - 1
. Each building has a number of employees. It’s transfer season, and some employees want to change the building they reside in.
You are given an array requests
where requests[i] = [fromi, toi]
represents an employee’s request to transfer from building fromi
to building toi
.
All buildings are full , so a list of requests is achievable only if for each building, the net change in employee transfers is zero . This means the number of employees leaving is equal to the number of employees moving in . For example if n = 3
and two employees are leaving building 0
, one is leaving building 1
, and one is leaving building 2
, there should be two employees moving to building 0
, one employee moving to building 1
, and one employee moving to building 2
.
Return the maximum number of achievable requests .
Solution 我的思路:根据人员流动建立有向图,然后回溯求所有的环。再用回溯求边数允许的最多环。
更好的思路:直接回溯,用一个数组记录节点的流出及流入。
当回溯到最后时,如果所有节点流出流入平衡(为0)时,则可以将其长度计入。
Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public int maximumRequests (int n, int [][] requests) { return backtrack(new int [n], requests, 0 , 0 ); } private int backtrack (int [] count, int [][] requests, int i, int len) { if (i >= requests.length) { if (isAcceptable(count)) return len; return 0 ; } int not = backtrack(count, requests, i+1 , len); count[requests[i][0 ]]--; count[requests[i][1 ]]++; int select = backtrack(count, requests, i+1 , len+1 ); count[requests[i][0 ]]++; count[requests[i][1 ]]--; return Math.max(not, select); } private boolean isAcceptable (int [] count) { for (int i : count){ if (i != 0 ) return false ; } return true ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 class Solution { boolean [] visited; boolean [] inCycle; int len; int [][] g; List<Integer> tempCycle; int res; List<List<Integer>> cycles; public int maximumRequests (int n, int [][] requests) { visited = new boolean [n]; inCycle = new boolean [n]; len = n; g = new int [n][n]; tempCycle = new ArrayList <Integer>(); res = 0 ; cycles = new ArrayList <>(); for (int i = 0 ; i < requests.length; i++){ int from = requests[i][0 ]; int to = requests[i][1 ]; g[from][to]++; } for (int i = 0 ; i < n; i++){ if (!visited[i]) getCycles(i, tempCycle); } res = getLongestCycle(0 , 0 ); return res; } private int getLongestCycle (int c, int length) { if (c >= cycles.size()) return length; boolean isSelect = true ; int select = Integer.MIN_VALUE; List<Integer> cycle = cycles.get(c); for (int i = 0 ; i < cycle.size()-1 ; i++){ if (g[cycle.get(i)][cycle.get(i+1 )] <= 0 ){ isSelect = false ; break ; } } if (isSelect){ for (int i = 0 ; i < cycle.size()-1 ; i++){ g[cycle.get(i)][cycle.get(i+1 )]--; } select = getLongestCycle(c+1 , length + cycle.size()-1 ); for (int i = 0 ; i < cycle.size()-1 ; i++){ g[cycle.get(i)][cycle.get(i+1 )]++; } } int not = getLongestCycle(c+1 , length); return Math.max(not, select); } private void getCycles (int from, List<Integer> tempCycle) { inCycle[from] = true ; visited[from] = true ; tempCycle.add(from); for (int to = 0 ; to < len; to++){ if (g[from][to] > 0 ){ for (int i = 0 ; i <g[from][to]; i++){ if (!inCycle[to]){ getCycles(to, tempCycle); } else { int start = tempCycle.indexOf(to); List<Integer> cycle = new ArrayList <Integer>(); for (int j = start; j < tempCycle.size(); j++) { cycle.add(tempCycle.get(j)); } cycle.add(tempCycle.get(start)); cycles.add(cycle); } } } } inCycle[from] = false ; tempCycle.remove(tempCycle.size()-1 ); } }