leedcode:最大人工岛

题目:

给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。

返回执行此操作后,grid 中最大的岛屿面积是多少?

岛屿 由一组上、下、左、右四个方向相连的 1 形成

class Solution {
    public int largestIsland(int[][] grid) {
        
		
		Map<Integer,Integer> mapIndexLand=new HashMap<Integer, Integer>();
		//陆地的编号
		int index=2;
        //先标记出岛屿
		//循环行
        for(int i=0;i<grid.length;i++){
        	//循环列
        	for(int j=0;j<grid[0].length;j++) {
        		
        		if(grid[i][j]==1) {//说明是陆地
        			
        			//对其进行标记编号,并获取面积
        			int landArea = landArea(grid,i,j,index);
        			mapIndexLand.put(index, landArea);
        			index++;
        		}
        	}

        }
        
        int maxArea=0;
        //循环海洋 获取连接的最大面积
        for(int i=0;i<grid.length;i++){
        	//循环列
        	for(int j=0;j<grid[0].length;j++) {
        		
        		if(grid[i][j]==0) {//说明是海洋
        			
        			//对其进行标记编号,并获取面积
        			Set<Integer> indexSet = obtainNeighbourIndex(grid, i, j, mapIndexLand);
        			
        			Iterator<Integer> iterator = indexSet.iterator();
        			int area=1;
        			while(iterator.hasNext()) {
        				area+=mapIndexLand.getOrDefault(iterator.next(), 0);
        			}
        			
        			maxArea=Math.max(maxArea, area);
        		}
        	}

        }
        if(maxArea==0&&mapIndexLand.keySet().size()==1) {//说明全是陆地没有海洋
        	maxArea=mapIndexLand.get(index-1);
        }        
        return maxArea;
    }
	
	
	/**
	 * 标记并获取面积
	 * @param grid
	 * @param row
	 * @param cell
	 * @param index
	 * @return
	 */
	public int landArea(int[][] grid,int row,int cell,int index) {
		//校验,是否超出边界或者是海洋
		if(!inArea(grid,row,cell)) {
			return 0;
		}
		
		//判断是否访问过,防止进入死循环
		if(grid[row][cell]!=1) {
			return 0;
		}
		grid[row][cell]=index;
		
		return 1+
				landArea(grid,row-1,cell,index)+
				landArea(grid,row+1,cell,index)+
				landArea(grid,row,cell-1,index)+
				landArea(grid,row,cell+1,index);
		
	}
	
	/**
	 * 判断是否超界
	 * @param grid
	 * @param row
	 * @param cell
	 * @return
	 */
	public Boolean inArea(int[][] grid,int row,int cell) {
		
		return row>=0&&cell>=0&&row<grid.length&&cell<grid[0].length;
	}
	
	/**
	 * 获取相邻陆地面积,一个海洋有可能被同一块陆地块包围,所以获取的路地块标识是去重的
	 * @param grid
	 * @param row
	 * @param cell
	 * @param mapIndexLand
	 * @return
	 */
	public Set<Integer> obtainNeighbourIndex(int[][] grid,int row,int cell,Map<Integer,Integer> mapIndexLand) {
		
		Set<Integer> indexSet=new HashSet<Integer>();
		//校验,是否超出边界或者是海洋
		if(inArea(grid,row-1,cell)) {
			indexSet.add(grid[row-1][cell]);
		}
		if(inArea(grid,row+1,cell)) {
			indexSet.add(grid[row+1][cell]);
		}
		if(inArea(grid,row,cell-1)) {
			indexSet.add(grid[row][cell-1]);
		}
		if(inArea(grid,row,cell+1)) {
			indexSet.add(grid[row][cell+1]);
		}
		
		
		return indexSet;
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值