当前位置: 代码迷 >> 综合 >> leetcode 1298. 你能从盒子里获得的最大糖果数(javascript)
  详细解决方案

leetcode 1298. 你能从盒子里获得的最大糖果数(javascript)

热度:18   发布时间:2023-12-06 12:59:06.0

给你 n 个盒子,每个盒子的格式为 [status, candies, keys, containedBoxes] ,其中:

  • 状态字 status[i]:整数,如果 box[i] 是开的,那么是 1 ,否则是 0 。 糖果数 candies[i]: 整数,表示
    box[i] 中糖果的数目。
  • 钥匙 keys[i]:数组,表示你打开 box[i] 后,可以得到一些盒子的钥匙,每个元素分别为该钥匙对应盒子的下标。
  • 内含的盒子 containedBoxes[i]:整数,表示放在 box[i] 里的盒子所对应的下标。
  • 给你一个 initialBoxes
    数组,表示你现在得到的盒子,你可以获得里面的糖果,也可以用盒子里的钥匙打开新的盒子,还可以继续探索从这个盒子里找到的其他盒子。

请你按照上述规则,返回可以获得糖果的 最大数目 。

初看此题,就打算用bfs解。这道既然属于困难题,那么肯定不能用常规bfs方法套。首先看开盒条件:

  • 盒子序号在initialBoxes数组中(手中有这个盒子)
  • 盒子序号在keys数组中(手中有盒子的钥匙)

那么可以先尝试写出来bfs的模板:

var maxCandies = function(status, candies, keys, containedBoxes, initialBoxes) {
    var ans=0;while(initialBoxes.length){
    let temp=initialBoxes.shift();if(status[temp]==1){
    ans+=candies[temp];for(let i=0;i<keys[temp].length;i++){
    status[keys[temp][i]]=1;}for(let i=0;i<containedBoxes[temp].length;i++){
    initialBoxes.push(containedBoxes[temp][i]);}}}return ans;
};

写出来模板问题就清晰多了。我发现这道题的关键在于,遍历时可能当前拥有的盒子刚好此刻没有钥匙。但这并不代表此后不会从其他盒子中开出当前盒子的钥匙,如果只是让当前拥有的盒子简单出队,那么必然会少开很多盒子。
那么很简单,当当前没有钥匙时,我们不要让他出队。

else{
    initialBoxes.push(temp);
}

成功解决可能会错过钥匙的问题后,新的问题来了。当题目所给的数据可能无法开完所有盒子时,这段代码将进入死循环。

那么我们需要找到一个跳出循环的办法。我一开始认为,当死循环时,剩余没拿到的钥匙数等于当前拥有盒子数,那么我就用这个条件。然后我就发现这只是死循环的必要不充分条件。

那么怎么样才会算进入死循环呢?其实,只要钥匙集合与拥有盒子的集合没有交集,那么就肯定无法继续开盒子了。那么,最终代码就来了。

var maxCandies = function(status, candies, keys, containedBoxes, initialBoxes) {
    var ans=0;while(initialBoxes.length){
    let flag=initialBoxes.some(function(item,index,arr){
    return status[item]==1;})if(!flag)   return ans;let temp=initialBoxes.shift();if(status[temp]==1){
    ans+=candies[temp];for(let i=0;i<keys[temp].length;i++){
    status[keys[temp][i]]=1;}for(let i=0;i<containedBoxes[temp].length;i++){
    initialBoxes.push(containedBoxes[temp][i]);}}else{
    initialBoxes.push(temp);}}return ans;
};
  相关解决方案