leetcode刷题第20天——1342,200,547

第二十天

1342 将数字变成0的操作次数

给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

方法一

直接模拟。

class Solution {
    public int numberOfSteps(int num) {
        int count = 0;
        while (num != 0){
            ++count;
            if ((num & 1) == 1) --num;
            else num >>= 1;
        }
        return count;
    }
}
方法二 位运算优化

将减1操作转化成和0xfffffffe进行与运算。

class Solution {
    public int numberOfSteps(int num) {
        int count = 0;
        int ANDVALUE = Integer.MAX_VALUE - 1;
        while (num != 0){
            ++count;
            if ((num & 1) == 1) num &= ANDVALUE;
            else num >>= 1;
        }
        return count;
    }
}

200 岛屿数量

给你一个由 '1'(陆地)和'0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

方法 深度优先搜索

遍历整个图中的每一个节点,当遇到1时,对当前节点进行深搜,然后将访问过的节点都标记为已访问

class Solution {
public static boolean[][] isVisited;
    public static int xlength;
    public static int ylength;
    public static int[] dx = {0, 0, 1, -1};
    public static int[] dy = {1, -1, 0, 0};

    public int numIslands(char[][] grid) {
        int res = 0;
        xlength = grid.length;
        ylength = grid[0].length;
        isVisited = new boolean[xlength][ylength];
        for (int i = 0; i < xlength; ++i){
            for (int j = 0; j  < ylength; ++j){
                if (grid[i][j] == '1' && !isVisited[i][j]) {
                    depthFirstSearch(grid, i, j);
                    res++;
                }
            }
        }
        return res;
    }

    public static void depthFirstSearch(char[][] grid, int x, int y){
        if (isVisited[x][y]) return;
        isVisited[x][y] = true;
        for (int i = 0; i < 4; ++i){
            int newX = x + dx[i];
            int newY = y + dy[i];
            if (newX >= 0 && newX < xlength && newY >= 0 && newY < ylength &&
            grid[newX][newY] == '1' && !isVisited[newX][newY]){
                depthFirstSearch(grid, newX, newY);
            }
        }
    }
}

547 省份数量

n个城市,其中一些彼此相连,另一些没有相连。如果城市a与城市b直接相连,且城市 b与城市c直接相连,那么城市 a 与城市c间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个n x n的矩阵 isConnected ,其中 isConnected[i][j] = 1表示第i个城市和第j个城市直接相连,而 isConnected[i][j] = 0表示二者不直接相连。

返回矩阵中 省份 的数量。

方法 DFS

类比于地图的DFS,对DFS算法稍作修改,由于考虑的是城市之间的连通性,因此外层循环只需要从1遍历到n即可,内层调用DFS,对于已经访问过的节点i,将其标记为已访问即可。

class Solution {
    public static boolean[] isVisited;
    public int findCircleNum(int[][] isConnected) {
        int res = 0;
        isVisited = new boolean[isConnected.length];
        for (int i = 0; i < isConnected.length; ++i){
            if (!isVisited[i]){
                res++;
                depthFirstSearch(i, isConnected);
            }
        }
        return res;
    }
    
    public static void depthFirstSearch(int x, int[][] map){
        if (isVisited[x]) return;
        isVisited[x] = true;
        int length = map[x].length;
        for (int i = 0; i < length; ++i){
            if (map[x][i] == 1) depthFirstSearch(i, map); //城市i和联通 递归的去访问城市i的其他连通城市
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值