问题:
给定n个box:
status[i]
: 1:box[i] 打开,0:box[i] 关闭candies[i]
: box[i]里装有的糖个数keys[i]
: 装有的其他box钥匙的index(数组)containedBoxes[i]
: 装有的其他box的index(数组)
关闭的box,只有持有钥匙key,才能打开。
打开的box,可以直接打开。
initialBoxes:表示目前手中的盒子。(不一定都可打开)
求打开所有能打开的box后,能得到多少糖。
Example 1: Input: status = [1,0,1,0], candies = [7,5,4,100], keys = [[],[],[1],[]], containedBoxes = [[1,2],[3],[],[]], initialBoxes = [0] Output: 16 Explanation: You will be initially given box 0. You will find 7 candies in it and boxes 1 and 2. Box 1 is closed and you don't have a key for it so you will open box 2. You will find 4 candies and a key to box 1 in box 2. In box 1, you will find 5 candies and box 3 but you will not find a key to box 3 so box 3 will remain closed. Total number of candies collected = 7 + 4 + 5 = 16 candy. Example 2: Input: status = [1,0,0,0,0,0], candies = [1,1,1,1,1,1], keys = [[1,2,3,4,5],[],[],[],[],[]], containedBoxes = [[1,2,3,4,5],[],[],[],[],[]], initialBoxes = [0] Output: 6 Explanation: You have initially box 0. Opening it you can find boxes 1,2,3,4 and 5 and their keys. The total number of candies will be 6. Example 3: Input: status = [1,1,1], candies = [100,1,100], keys = [[],[0,2],[]], containedBoxes = [[],[],[]], initialBoxes = [1] Output: 1 Example 4: Input: status = [1], candies = [100], keys = [[]], containedBoxes = [[]], initialBoxes = [] Output: 0 Example 5: Input: status = [1,1,1], candies = [2,3,2], keys = [[],[],[]], containedBoxes = [[],[],[]], initialBoxes = [2,1,0] Output: 7 Constraints: 1 <= status.length <= 1000 status.length == candies.length == keys.length == containedBoxes.length == n status[i] is 0 or 1. 1 <= candies[i] <= 1000 0 <= keys[i].length <= status.length 0 <= keys[i][j] < status.length All values in keys[i] are unique. 0 <= containedBoxes[i].length <= status.length 0 <= containedBoxes[i][j] < status.length All values in containedBoxes[i] are unique. Each box is contained in one box at most. 0 <= initialBoxes.length <= status.length 0 <= initialBoxes[i] < status.length
解法:BFS
- 状态:
- 当前入手的箱子(未打开):GotBoxes
- 当前手上的钥匙。
- 当前所有箱子的开闭状态。
- 选择:
- 当前箱子打开后得到的箱子(状态为开)
- 已经入手的箱子(且在本次开箱中,获得了key)
这里,BFS只是一个尝试持续,而非多种选择分叉不同情况,
因此,各个状态用已有的单独数组进行记录即可,不用将状态入队。
只需要入队当前箱子id即可。
我们规定:只有能够打开的box,才能入队,那么每次出队的箱子中的糖果都能累计。
对于已经计算过的箱子,箱子状态为打开状态&&并非此次获得的新箱子。
我们每次入队新箱子 or 还未打开的已入手箱子。则可保证每次出队的箱子都是未计算过的。
对于每次处理的箱子:
- 拿到该箱子中的keys,来开已经入手却没打开的箱子。
- 同时,将入手or未入手的箱子 状态都改为 open。
- 拿到该箱子中的新箱子,
- 如果箱子是open状态,直接入队。
- 否则,计入已经入手的箱子。
代码参考:
1 class Solution { 2 public: 3 int n; 4 int maxCandies(vector<int>& status, vector<int>& candies, vector<vector<int>>& keys, vector<vector<int>>& containedBoxes, vector<int>& initialBoxes) { 5 int res = 0; 6 n = status.size(); 7 vector<bool> GotBoxes(n,false); 8 queue<int> q; 9 //push Start box(opened) to queue. 10 //push all box gotten to GotBoxes 11 for(int iB:initialBoxes) { 12 if(status[iB]) { 13 q.push(iB); 14 }// else { 15 GotBoxes[iB] = true; 16 // } 17 } 18 //queue: boxes which 'can open' next time. 19 while(!q.empty()) { 20 int cur = q.front(); 21 q.pop(); 22 res += candies[cur]; 23 //use keys we got this time ,to open the box we got(but is closed) 24 for(int k_box:keys[cur]) { 25 if(status[k_box]==0 && GotBoxes[k_box]) { 26 q.push(k_box); 27 //boxes which we got already but closed. this time we get the key. 28 } 29 status[k_box] = 1;//once get the key, box status should be open. 30 } 31 for(int nextbox:containedBoxes[cur]) { 32 if(status[nextbox]==1) { 33 //if we get a box which we have the key before. we can open it. 34 q.push(nextbox); 35 } //else { 36 GotBoxes[nextbox] = true;//get a box closed. 37 //} 38 } 39 } 40 return res; 41 } 42 };