扑克牌 、员工重要性、图像渲染、岛屿的周长(DFS)

一、扑克牌

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

在这里插入图片描述

static int count = 0;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int parperNums = scanner.nextInt();
        //盒子
        int[] boxArray = new int[parperNums + 1];
        //标记数组,标记牌有没有被放
        boolean[] book = new boolean[parperNums + 1];
        getNums(1,book,boxArray,parperNums + 1);
        System.out.println(count);
    }

    public static void getNums(int boxIndex, boolean[] book, int[] boxArray, int n){
        if(boxIndex >= n){
            count++;
            return;
        }
        for (int i = 1; i < n; i++) {
            if(!book[i]){                  //看看这个牌 有没有放
                boxArray[boxIndex] = i;    //放入此牌  
                book[i] = true;            //标记这个牌 已经放了
                //放下一个箱子
                getNums(boxIndex + 1, book, boxArray, n);
                book[i] = false;           //回溯,标记这个牌是自由的
            }
        }
    }

二、员工重要性

员工的重要性

给定一个保存员工信息的数据结构,它包含了员工 唯一的 id ,重要度 和 直系下属的 id 。
比如,员工 1 是员工 2 的领导,员工 2 是员工 3 的领导。他们相应的重要度为 15 , 10 , 5 。那么员工 1 的数据结构是 [1, 15, [2]] ,员工 2的 数据结构是 [2, 10, [3]] ,员工 3 的数据结构是 [3, 5, []] 。注意虽然员工 3 也是员工 1 的一个下属,但是由于 并不是直系 下属,因此没有体现在员工 1 的数据结构中。
现在输入一个公司的所有员工信息,以及单个员工 id ,返回这个员工和他所有下属的重要度之和。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/employee-importance
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 通过id找到员工对象
  • sum表示重要度 sum = 员工自己的重要度 + 每一个直系下属的重要度
  • 遍历每一个直系下属,通过DFS求得每个直系下属的重要度,一直递归到没有下属的员工
    public int getImportance(List<Employee> employees, int id) {
        // 有没有这个员工
        Employee e = null;
        for (Employee employee : employees) {
            if(employee.id == id){
                e = employee;
                break;
            }
        }
        if(e == null){
            return 0;
        }

        // 员工的直系
        List<Integer> list = e.subordinates;
        if(list == null){
            return e.importance;
        }

        // 员工的 下属的 价值
        int value = 0;
        for (int i = 0; i < list.size(); i++) {
            value += getImportance(employees, list.get(i));
        }

        // 员工 + 其下属的价值
        return value + e.importance;
    }
public int getImportance(List<Employee> employees, int id) {
        int sum = 0;
        for (Employee employee : employees) {
            if(employee.id == id){
                sum += employee.importance;
                for (int childId : employee.subordinates) {
                    sum += getImportance(employees, childId);
                }
            }
        }
        return sum;
    }
  • 由于每次查找id对应的员工时,都要遍历一遍List< Employee >,可以通过map简化这一操作 key放id,value放Employee
public int getImportance(List<Employee> employees, int id) {
        HashMap<Integer, Employee> map = new HashMap<>();
        for (Employee employee : employees) {
            map.put(employee.id, employee);
        }
        return Import(map, id);
    }

    public int Import(HashMap<Integer, Employee> map, int id){
        if(map.get(id) == null){
            return 0;
        }

        Employee employee = map.get(id);
        List<Integer> list = employee.subordinates;
        if(list == null){
            return employee.importance;
        }

        int value = 0;
        for (int e : list) {
            value += Import(map, e);
        }

        return value + employee.importance;
    }

三、图像渲染

图像渲染

有一幅以 m x n 的二维整数数组表示的图画 image ,其中 image[i][j] 表示该图画的像素值大小。
你也被给予三个整数 sr , sc 和 newColor 。你应该从像素 image[sr][sc] 开始对图像进行 上色填充 。
为了完成 上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应 四个方向上 像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 newColor 。
最后返回 经过上色渲染后的图像 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flood-fill
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    static int[][] nextP = {{-1,0},{1,0},{0,-1},{0,1}};
    public static int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
        int row = image.length;
        int col = image[0].length;
        int oldColor = image[sr][sc];
        DFS(image, sr, sc, oldColor, newColor, row, col);
        return image;
    }

    public static void DFS(int[][] image, int sr, int sc, int oldColor, int newColor, int row, int col){
        // 超出界限
        if(newSr < 0 || newSr >= row || newSc < 0 || newSc >= col){
                continue;
        }
        // 已经 涂色  或者不用涂色的
        if(image[newSr][newSc] != oldColor ){
                continue;
        }            
        // 涂色
        image[sr][sc] = newColor;

        // 上下左右方向分别搜索
        for (int[] next : nextP) {
            int newSr = sr + next[0];
            int newSc = sc + next[1];
            DFS(image, newSr, newSc, oldColor, newColor, row, col);
        }
    }

四、岛屿的周长

岛屿的周长

这里是引用
给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/island-perimeter
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
在这里插入图片描述

  • 计算一个岛屿的周长,要看它的四周(上下左右)是什么,四周的边长加到一起
  • 如果他靠近 边界、海水,周长+1,如果靠近另一块岛屿,需要搜索另一块岛屿的四周
  • 标记一下搜索过的岛屿块,靠近搜索过的岛屿,周长+0
    public int islandPerimeter(int[][] grid) {
        int row = grid.length;
        int col = grid[0].length;
        boolean[][] book = new boolean[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if(grid[i][j] == 1){
                    return isLand(grid, row, col, book, i, j);
                }
            }
        }
        return 0;
    }

    public int isLand(int[][] grid, int row, int col, boolean[][] book, int x, int y){
        if(x < 0 || x >= row || y < 0 || y >= col){
            return 1;
        }
        if(grid[x][y] == 0){
            return 1;
        }
        if(book[x][y]){
            return 0;
        }
        book[x][y] = true;

        return isLand(grid,row,col,book,x-1,y) +
                isLand(grid,row,col,book,x+1,y) +
                isLand(grid,row,col,book,x,y-1) +
                isLand(grid,row,col,book,x,y+1);
    }
  • 一个位置一个位置的看,如果此岛屿块四周没有岛屿 它提供的边长为4;如果有1块,提供3;如果有2块,提供2;如果有3块,提供1;如果有4块,提供0;
class Solution {
    public int islandPerimeter(int[][] grid) {
        int[][] nextP = {{-1,0},{1,0},{0,-1},{0,1}};
        int len = 0;
        int row = grid.length;
        int col = grid[0].length;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if(grid[i][j] == 1){
                    int C = 4;
                    for (int[] next : nextP) {
                        int nx = i + next[0];
                        int ny = j + next[1];
                        if(nx >= row || nx < 0 || ny >= col || ny < 0){
                            continue;
                        }
                        if(grid[nx][ny] == 1){
                            C--;
                        }
                    }
                    len += C;
                }
            }
        }
        return len;
    }
}

中华泰山,天下泰安

山东泰安
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

威少总冠军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值