回溯算法之深度优先搜索

news2024/11/27 17:35:38

目录

放牌

员工的重要性

图像渲染

岛屿的周长

被围绕的区域

岛屿的数量

岛屿的最大面积 

 电话号码的字母组合

二进制手表 

组合总和

活字印刷

N皇后



深度优先搜索(Depth First Search)------ 一条道走到黑

放牌

假如有编号为1~3的3张扑克牌和编号为1~3的3个盒子,现在需要将3张牌分别放到3个盒子中去,且每个盒子只能放一张牌,一共有多少种不同的放法。

步骤:

        1.边界,如果遍历到了最后一个,输出遍历结果

        2.遍历每一个牌

                1.如果没有使用过,放入牌,盒子标记为1

                2.进入下一个遍历

                3.回溯,取出最后一个放入的牌

public static void Dfs(int index, int n, int[] boxs, int[] book){
    if(index==n+1){//边界:最后一个-->此时牌都放入了,直接输出结果
        //输出这一次的遍历结果
        for (int i = 1; i <=n ; i++) {
            System.out.print(boxs[i]+" ");
        }
        //一次结果输出后,回车
            System.out.println();
            return;

    }
    for(int i=1;i<=n;i++){
        //判断当前牌是否用过
        if(book[i]==0){
            //没有使用过,放入牌,盒子标记为1
            boxs[index]=i;
            book[i]=1;//i号牌已经使用
            //处理下一个盒子
            Dfs(index+1,n,boxs,book);
            //从下一个盒子回退到当前盒子,取出当前盒子的牌
            book[i]=0;
        }
    }
}

public static void main(String[] args) {
    int n;
    Scanner sc = new Scanner(System.in);
    n = sc.nextInt();//盒子和牌个数
    int[] boxs = new int[n + 1];//盒子
    int[] books = new int[n + 1];//牌
    Dfs(1, n, boxs, books);
}

员工的重要性

class Solution {
    public int DFS(Map<Integer,Employee> info, int id){
        //当前员工的import和他所有下属的import
        Employee curE=info.get(id);//得到id
        int sum=curE.importance;//通过id,得到import和
        for (int subId: curE.subordinates) {//遍历下属,得到总和
            sum+=DFS(info,subId);
        }
        return sum;
    }
    public int getImportance(List<Employee> employees, int id) {
        if(employees.isEmpty()){
            return 0;
        }
        Map<Integer,Employee> info=new HashMap<>();
        //信息放入info中
        for(Employee e:employees){
            info.put(e.id,e);//从list中取出list中的元素,放入info中
        }
        //遍历总和
        return DFS(info,id);

    }
}

图像渲染

 步骤:

floodFill

        1.得到矩阵的长宽,指定位置原本的颜色

        2.创建数组book,判断该位置是否遍历过        

        3.进入dfs

        4.输出结果image

dfs

        1.把当前位置颜色改变,标记为遍历过

        2.遍历四个方向

        3.得到新的位置

        4.判断位置是否合法

        5.判断是否和原颜色相同,是否标记过

        5.满足要求,进行递归

class Solution {
    public int[][] floodFill(int[][] image, int sr, int sc, int color) {
        int oldcolor=image[sr][sc];
        int row=image.length;
        int col=image[0].length;
        int[][] book=new int[row][col];
        dfs(image,sr,sc,book,row,col,oldcolor,color);
        return image;
    }
    int[][] next={{1,0},{-1,0},{0,1},{0,-1}};
    public void dfs(int[][] image,int curx,int cury,int[][] book,int row,int col,int oldcolor,int color){
        image[curx][cury]=color;
        book[curx][cury]=1;
        for(int i=0;i<4;i++){
            int newx=curx+next[i][0];
            int newy=cury+next[i][1];

            if(newx>=row || newx<0 || newy>=col || newy<0){
                continue;
            }
            if(image[newx][newy]==oldcolor && book[newx][newy]==0){
                dfs(image,newx,newy,book,row,col,oldcolor,color);
            }
        }
    }

   
}

岛屿的周长

 遍历,判断是不是陆地,如果是进入dfs

  • 判断位置是否合法
  • 判断是否是水域,返回1
  • 判断不是陆地或标记过,返回0
  • 进入四个方向遍历
class Solution {
     public int islandPerimeter(int[][] grid) {
         for(int i=0;i<grid.length;i++){
             for(int j=0;j<grid[0].length;j++){
                 if(grid[i][j]==1){
                     return dfs(grid,i,j);
                 }
             }
         }
         return 0;
    }
    public int dfs(int[][] grid,int i,int j){
        //边界+1
        if(i<0 || i>=grid.length || j<0 || j>=grid[0].length){
            return 1;
        }
        //水域+1
        if(grid[i][j]==0){
            return 1;
        }
        //遍历过 在内部,周长不增加
        if(grid[i][j]!=1){
            return 0;
        }
        //遍历过,防止再次遍历
        grid[i][j]=2;
        return dfs(grid,i-1,j)+dfs(grid,i+1,j)+dfs(grid,i,j+1)+dfs(grid,i,j-1);
    }
}

被围绕的区域

 从四个边遍历,把边上的O变为A,把剩下的O(此时的O都是被包围的)变为X,把A变为O

步骤:

  • solve
    • 找到第一行,第一列,最后一行,最后一列,进入dfs,直到不为O
  • dfs
    • 标记当前位置
    • 遍历四个方向
    • 得到新的坐标]
    • 判断坐标是否合法
    • 如果是O,并且没有标记过,进入下一个
class Solution {
   
    public void solve(char[][] board) {
        if(board==null){
            return ;
        }
     int row=board.length;
     int col=board[0].length;
     int[][] book=new int[row][col];
     for(int i=0;i<row;i++){
         if(book[i][0]==0 && board[i][0]=='O'){
             dfs(board,i,0,row,col,book);
         }

         if(book[i][col-1]==0 && board[i][col-1]=='O'){
             dfs(board,i,col-1,row,col,book);
         }
     }

     for(int i=0;i<col;i++){
         if(book[0][i]==0 && board[0][i]=='O'){
             dfs(board,0,i,row,col,book);
         }
         if(book[row-1][i]==0  && board[row-1][i]=='O'){
             dfs(board,row-1,i,row,col,book);
         }
     }
     for(int i=0;i<row;i++){
         for(int j=0;j<col;j++){
             if(board[i][j]=='O'){
                 board[i][j]='X';
             }else if(board[i][j]=='A'){
                 board[i][j]='O';
             }
         }
     }
    }
    int[][] next={{1,0},{-1,0},{0,1},{0,-1}};
    public void dfs(char[][] board,int x,int y,int row,int col,int[][] book){
        book[x][y]=1;
        board[x][y]='A';
        for(int i=0;i<4;i++){
            int nx=x+next[i][0];
            int ny=y+next[i][1];

            if(nx<0 || nx>=row || ny<0 || ny>=col){
                continue;
            }

            if(board[nx][ny]=='O'){
                dfs(board,nx,ny,row,col,book);
            }
        }
    }
}

岛屿的数量

步骤

  •  遍历矩阵,如果是陆地没有遍历过
  • ret++,进入dfs
  • dfs
    • 标记当前位置
    • 遍历四个方向
    • 得到新的坐标
    • 判断坐标是否合法
    • 如果是陆地没有遍历过
    • 进入下一个判断

class Solution {
    public int numIslands(char[][] grid) {
        int ret=0;
         int row=grid.length;
         int col=grid[0].length;
         int[][] book=new int[row][col];
         for(int i=0;i<row;i++){
             for(int j=0;j<col;j++){
                 if(grid[i][j]=='1' && book[i][j]==0){
                     ret++;
                      dfs(grid,book,row,col,i,j);
                 }
                 
             }
         }
         return ret;
       }
       int[][] next={{0,1},{0,-1},{1,0},{-1,0}};
       public void dfs(char[][] grid,int[][] book,int row,int col,int x,int y){
           book[x][y]=1;
           for(int i=0;i<4;i++){
               int nx=x+next[i][0];
               int ny=y+next[i][1];

               if(nx>=row || nx<0 || ny>=col || ny<0){
                   continue;
               }

               if(grid[nx][ny]=='1' && book[nx][ny]==0){
                   dfs(grid,book,row,col,nx,ny);
               }
           }
       }
}

岛屿的最大面积 

步骤

  •  遍历数组,找到是陆地并且没有标记过的进入dfs
  • dfs
    • 把当前位置标记
    • 遍历四个方向
    • 得到新的坐标
    • 判断坐标是否合法
    • 判断是否是陆地,是否遍历过-->进入递归,得到和
    • 返回和
  • 得到每一次和的最大值,返回
class Solution {
      public int maxAreaOfIsland(int[][] grid) {
        if(grid.length==0){
            return 0;
        }
        int row=grid.length;
        int col=grid[0].length;
        int[][] book=new int[row][col];
        int max=0;
        int ret=0;
        for(int i=0;i<row;i++){
            for(int j=0;j<col;j++){
                if(book[i][j]==0 && grid[i][j]==1){
                    ret=dfs(grid,book,row,col,i,j);
                    max=Math.max(max,ret);
                }
            }
        }
        return  max;
    }

    int[][] nextP={{0,1},{0,-1},{1,0},{-1,0}};

    private int dfs(int[][] grid, int[][] book, int row, int col, int x, int y) {
        book[x][y]=1;
        int r=1;
        for(int i=0;i<4;i++){
            int nx=x+nextP[i][0];
            int ny=y+nextP[i][1];


            if(nx>=row || nx<0 || ny>=col || ny<0){
                continue;
            }

            if(grid[nx][ny]==1 && book[nx][ny]==0){
                r+=dfs(grid,book,row,col,nx,ny);
            }
        }
        return r;
        
    }
}

 电话号码的字母组合

步骤 

  • 把信息存放到字符串数组中,下标对应得到的数字
  • 边界:当前位置下标和字符串长度相等(遍历完),把字符串放入list中
  • 找到对应位置:通过当前下标,得到对应下标的数字,通过数字得到字符串数组中对应的字符串
  • 遍历字符串,进行下一个新的判断
public List<String> letterCombinations(String digits) {
    List<String> ret=new ArrayList<>();
    StringBuilder curStr=new StringBuilder("");
    dfs(digits,ret,curStr,0);
    //  数组 结果存放 当前字符串    遍历的长度
    return ret;

}

String[] mapString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
private void dfs(String digits, List<String> ret, StringBuilder curStr, int curDepth) {
   //边界
    if(curDepth==digits.length()){
        if(curStr.length()!=0){
            ret.add(curStr.toString());
        }
        return;
    }
    //找到对应位置
    int curMapIndex=digits.charAt(curDepth)-'0';//得到当前的数字
    String curMap=mapString[curMapIndex];//通过数字找到该下标的所有字母
    for (int i = 0; i < curMap.length(); i++) {
        //当前字符串加入新的字母(得到的字符串的每个元素依次遍历)
        dfs(digits, ret, curStr.append(curMap.charAt(i)), curDepth+1);
        //结束后,去掉新加的字母,为下一个字母的加入做准备
        curStr.deleteCharAt(curStr.length()-1);
    }
}

二进制手表 

步骤:

        1. 判断边界  h>11 m>59  不满足

        2.如果在边界上,还需要的灯的个数为0   时间放入list中

        3.把十个灯遍历,得到对应的时间  

class Solution {
    int[] hs={1,2,4,8,0,0,0,0,0,0};
    int[] ms={0,0,0,0,1,2,4,8,16,32};
    List<String> list=new ArrayList<>();
    public List<String> readBinaryWatch(int turnedOn) {
             dfs(turnedOn,0,0,0);
             return list;
    }
    public void dfs(int turnedOn,int index,int h,int m){
        if(h>11 || m>59){
            return ;
        }
        if(turnedOn==0){
            list.add(h+":"+(m<10?"0":"")+m);
        }
        for(int i=index;i<10;i++){
            dfs(turnedOn-1,i+1,h+hs[i],m+ms[i]);
        }
    }
}

组合总和

 dfs:

等于目标返回

从当前位置到最后一个位置,遍历

如果当前位置的值大于目标值,continue

深度搜索

去掉最后一个元素

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
       List<List<Integer>> solutions=new ArrayList<>();
       List<Integer> solution=new ArrayList<>();
       if(candidates.length==0){
           return solutions;
       }
       int curSum=0;
       dfs(solutions,solution,candidates,target,curSum,0);
       return solutions;
    }
    public static void dfs(List<List<Integer>> solutions,List<Integer> solution,int[] candidates,int target,int curSum,int index){
        if(curSum>=target){
            if(curSum==target){
                List<Integer> newS=new ArrayList<>();
                for(int e:solution){
                    newS.add(e);
                }
                solutions.add(newS);
            }
            return;
        }
        for(int i=index;i<candidates.length;i++){
            if(candidates[i]>target){
                continue;
            }
            solution.add(candidates[i]);
            dfs(solutions,solution,candidates,target,curSum+candidates[i],i);
            solution.remove(solution.size()-1);
        }

    }
    
}

活字印刷

因为每个只能使用一次,所有要标记是否使用过,如果没有使用过标记为0,进入遍历

 dfs:

如果curStr长度不为0,放入set中

从0开始遍历titles

如果没有遍历过,标记为遍历,进入dfs,去到新加的,标记为没有遍历过

class Solution {
   public int numTilePossibilities(String tiles) {
        if(tiles.length()==0){
            return 0;
        }
        int[] book=new int[tiles.length()];
        Set<String> total=new HashSet<>();
        StringBuilder curStr=new StringBuilder();
        dfs(tiles,curStr,book,total);
        return total.size();
    }

    private void dfs(String tiles, StringBuilder curStr, int[] book, Set<String> total) {
        if(curStr.length()!=0){
            total.add(curStr.toString());
        }
        for(int i=0;i<tiles.length();i++){
            if(book[i]==0){
                book[i]=1;
                dfs(tiles,curStr.append(tiles.charAt(i)),book,total);
                curStr.deleteCharAt(curStr.length()-1);
                book[i]=0;
            }
        }
       
    }
}

N皇后

dfs:

  1. 判断是否遍历完,如果完成把结果存入solutions中
  2. 遍历
    1. 判断是否冲突,不冲突,继续
    2. 把当前元素的位置存入solution中
    3. 进入下一个判断
    4. 回溯 去掉新加的元素

isVaild:判断列,行列和,行列差知否冲突,

transResult:

  1. 遍历每一种方案
  2. 创建一个List> ret
  3. 把每一个都设置为.
  4. 通过solution把对应位置设置为Q
  5. 存入ret中
class pair{
    int x;
    int y;
    public pair(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Solution {
    public List<List<String>> solveNQueens(int n) {
       List<List<pair>> solutions=new ArrayList<>();
       List<pair> solution=new ArrayList();
       dfs(solutions,solution,0,n);
       return transResult(solutions,n);
    }

    private List<List<String>> transResult(List<List<pair>> solutions, int n) {
         //遍历每一个方案
        List<String> tmp=new ArrayList<>();
        //把每一种方案转换成string形式
        List<List<String>> ret=new ArrayList<>();
        for(List<pair> solution:solutions){
            List<StringBuilder> solutionString=new ArrayList<>();

            for(int i=0;i<n;i++) {
                StringBuilder s = new StringBuilder();
                //把所有的都设为.
                for (int j = 0; j < n; j++) {
                    s.append('.');
                }
                solutionString.add(s);
            }
                //通过solutions
                for(pair p:solution){
                    solutionString.get(p.x).setCharAt(p.y,'Q');
                }
                List<String> curRet=new ArrayList<>();
                for(StringBuilder s:solutionString){
                    curRet.add(s.toString());
                }
                ret.add(curRet);
            }
            return ret;
        }



    public void dfs(List<List<pair>> solutions,
                    List<pair> solution, int curRow, int n){
       if(curRow==n){
           List<pair> newS=new ArrayList<>();
           for(pair p:solution){
               newS.add(p);
           }
           solutions.add(newS);
       }

       for(int i=0;i<n;i++){
           if(isVaild(solution,curRow,i)){
               //判断列是否相同
               //行每次会增加,不会冲突
               solution.add(new pair(curRow,i));
               dfs(solutions,solution,curRow+1,n);
               solution.remove(solution.size()-1);
           }
       }
    }

    private boolean isVaild(List<pair> solution, int row, int col) {
       for(pair i:solution){
           if(i.y==col || i.x+i.y==row+col || i.x-i.y==row-col){
               return false;
           }
       }
       return true;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/620749.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

cpython编译与运行

一.配置环境 python 本身不能运行 cpython 的语法&#xff0c;需要 编译 后引用 需要 gcc 编译器 和 cython 编译器 gcc编译器 把 c语言 编译成扩展模块 Cython 编译器是一种源到源的编译器 python 语法编译成 c语法 1.安装gcc 编译器 gcc 编译器可以下载 Visual Studio 或者…

Android系统的启动流程(一):进入Zygote进程的初始化

Android系统的启动流程 概要 本篇文章主要是从Android系统启动电源开始介绍到程序运行到Java框架层并且完成Zygote进程的启动为止。下面先给出一张简单的概要图&#xff0c;本篇文章将会从源码进行分析Android的部分启动流程&#xff0c;这里的源码来自于AndroidCodeSearch,截…

基于RK3588的人工智能边缘计算大算力网关

智能运维系统从下至上分为终端层、边缘层、平台层和应用层&#xff0c;如图 1 所示。终端层 是整个系统的神经末梢&#xff0c;负责现场数据的采集&#xff0c;除摄像机外&#xff0c;还包括各类传感器、控制器 等物联网设备。边缘层汇总各个现场终端送来的非结构化视频数据和…

BERT(Transformer Encoder)详解和TensorFlow实现(附源码)

文章目录 一、BERT简介1. 模型2. 训练2.1 Masked Language Model2.2 Next Sentence Prediction2.3 BERT的输出 3. 微调 二、源码1. 加载BERT模型2. 加载预处理模型3. 加载BERT4. 构建BERT微调模型5. 训练6. 推理 一、BERT简介 1. 模型 BERT的全称为Bidirectional Encoder Repr…

java.time 时区详解

from: https://blog.zhjh.top/archives/MFTOJ-jorm4ISK9KXEYFE LocalDateTime 类是不包含时区信息的&#xff0c;可以通过 atZone 方法来设置 ZoneId&#xff0c;返回 ZonedDateTime 类实例&#xff0c;通过 atOffset 方法来设置 ZoneOffset&#xff0c;返回 OffsetDateTime 类…

攻防世界-web-supersqli

1. 题目描述&#xff1a; 2. 思路分析 这里尝试按照基本思路进行验证&#xff0c;先确定注入点&#xff0c;然后通过union查询依次确认数据库名&#xff0c;表名&#xff0c;字段名&#xff0c;最终获取到我们想要的字段信息。 这里只有一个输入框&#xff0c;所以注入点肯定…

【犀牛书】JavaScript 类型、值、变量章节读书笔记

本文为对《JavaScript权威指南》第三章&#xff1a;类型、值、变量精读的读书笔记&#xff0c;对重点进行了记录以及在一些地方添加了自己的理解。 JavaScript类型可以分为两类&#xff1a;原始类型和对象类型。Javascript的原始类型包括数值、文本字符串&#xff08;也称字符串…

驱动操作控制LED灯

控制LED灯&#xff1a; 驱动如何操作寄存器 rgb_led灯的寄存器是物理地址&#xff0c;在linux内核启动之后&#xff0c; 在使用地址的时候&#xff0c;操作的全是虚拟地址。需要将物理地址 转化为虚拟地址。在驱动代码中操作的虚拟地址就相当于 操作实际的物理地址。 物理地址&…

2023年5月榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩)发布!

飞瓜轻数发布2023年5月飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B站UP主。 飞…

Git—版本管理工具

作用&#xff1a;分布式版本控制 一句话&#xff1a;在开发的过程中用于管理对文件、目录或工程等内容的修改历史&#xff0c;方便查看历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术 官网下载安装&#xff1a;https://git-scm.com/ 命令大全&#xff1a;https://g…

OceanBase 4.1 全面测评及部署流程,看这篇就够了【建议收藏】

背景 测试 OceanBase 对比 MySQL&#xff0c;TiDB 的性能表现&#xff0c;数据存储压缩&#xff0c;探索多点内部项目一个数据库场景落地 Oceanbase&#xff08;MySQL->OceanBase&#xff09;。 单机测试 准备 OBD 方式部署单机 文件准备 wget https://obbusiness-pri…

Bilinear CNN:细粒度图像分类网络,对Bilinear CNN中矩阵外积的解释。

文章目录 一、Bilinear CNN 的网络结构二、矩阵外积&#xff08;outer product&#xff09;2.1 外积的计算方式2.2 外积的作用 三、PyTorch 网络代码实现 细粒度图像分类&#xff08;fine-grained image recognition&#xff09;的目的是区分类别的子类&#xff0c;如判别一只狗…

【web自动化测试】Web网页测试针对性的流程解析

前言 测试行业现在70%是以手工测试为主&#xff0c;那么只有20%是自动化测试&#xff0c;剩下的10%是性能测试。 有人可能会说&#xff0c;我现在做手工&#xff0c;我为什么要学自动化呢&#xff1f;我去学性能更好性能的人更少&#xff1f; 其实&#xff0c;性能的要求比自动…

蓝桥杯2022年第十三届决赛真题-齿轮

题目描述 这天&#xff0c;小明在组装齿轮。 他一共有 n 个齿轮&#xff0c;第 i 个齿轮的半径为 ri&#xff0c;他需要把这 n 个齿轮按一定顺序从左到右组装起来&#xff0c;这样最左边的齿轮转起来之后&#xff0c;可以传递到最右边的齿轮&#xff0c;并且这些齿轮能够起到提…

小程序容器与PWA是一回事吗?

PWA代表“渐进式网络应用”&#xff08;Progressive Web Application&#xff09;。它是一种结合了网页和移动应用程序功能的技术概念。PWA旨在提供类似于原生应用程序的用户体验&#xff0c;包括离线访问、推送通知、后台同步等功能&#xff0c;同时又具有网页的优势&#xff…

软件验收测试该怎么进行?权威的软件检测机构应该具备哪些资质?

软件测试是软件开发周期中非常重要的一个环节。软件测试的目的是发现软件在不同环境下的各种问题&#xff0c;保证软件在发布前能够达到用户的要求。软件验收测试是软件测试的最后一个环节&#xff0c;该环节主要验证软件是否满足用户需求。那么对于软件验收测试&#xff0c;该…

分布式事务二 Seata使用及其原理剖析

一 Seata 是什么 Seata 介绍 Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本…

【Spring源码】Spring源码导入Idea

1.基础环境准备 相关软件、依赖的版本号 Spring源码版本 5.3.x软件 ideaIU-2021.1.2.exeGradle gradle-7.2-bin.zip https://services.gradle.org/distributions/gradle-7.2-bin.zip - 网上说要单独下载gradle并配置环境变量&#xff0c;亲测当前5.3.X版本通过gradlew的方式进…

虚函数详解及应用场景

目录 概述1. 虚函数概述2. 虚函数的声明与重写3. 析构函数与虚函数的关系4. 虚函数的应用场景4.1. 多态性4.2. 接口定义与实现分离4.3. 运行时类型识别4.4. 多级继承与虚函数覆盖 结论 概述 虚函数是C中一种实现多态性的重要机制&#xff0c;它允许在基类中声明一个函数为虚函…

PDCCH monitoring capability

欢迎关注同名微信公众号“modem协议笔记”。 前段时间看search space set group (SSSG) switching相关内容时&#xff0c;注意到R17和R16的描述由于PDCCH monitoring capability的变化&#xff0c;内容有些不一样。于是就顺带看了下R16 R17PDCCH monitoring capability的内容。…