大数加法大数乘法岛屿问题dfs

116 篇文章 1 订阅
109 篇文章 1 订阅

大数相加

在这里插入图片描述

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 计算两个数之和
# @param s string字符串 表示第一个整数
# @param t string字符串 表示第二个整数
# @return string字符串
#
class Solution:
    def solve(self , s: str, t: str) -> str:
        # write code here
        # 进位
        carry = 0
        lens = len(s)
        lent = len(t)
        max_len =  max(lens, lent)
        res = ''
        
        for i in range(max_len):
            # 逆序相加x1 x2 carry
            if i < lens:
                x1 = int(s[lens - i -1])
            # 说明s是短的则 前面补0对齐
            else:
                x1 = 0
            
            if i < lent:
                x2 = int(t[lent - i -1])
            # 说明s是短的则 前面补0对齐
            else:
                x2 = 0
                
            temp = x1 + x2 + carry
            res += str(temp % 10)
            carry = temp // 10# 注意// 才是整数除余
        # 说明首位是进位
        if carry == 1:
            res += '1'
        # 逆序输出
        return res[::-1]

大数相乘

在这里插入图片描述
在这里插入图片描述

不进位的长乘法
在这里插入图片描述

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param s string字符串 第一个整数
# @param t string字符串 第二个整数
# @return string字符串
#
class Solution:
    def solve(self , s: str, t: str) -> str:
        # write code here
        if s == '0' or t == '0':
            return '0'
        s = list(s)
        t = list(t)
        
        # 因为是从最后一位开始相乘 所以需要逆转一下
        s.reverse()
        t.reverse()
        res = [0] * (len(s) + len(t))
        print(s, t)
        
        for i in range(len(s)):
            for j in range(len(t)):
                #结果是 18 25 8 0  
                res[i + j ] += int(s[i])*int(t[j]) 
        “”“
        ['2', '1'] ['9', '8']
		
        ”“”
        print(res)
      
        carry = 0 # 进位
        for k in range(len(res)):
            res[k] += carry
            carry = res[k] // 10
            res[k] = res [k] % 10
        # res是int的列表 且是逆序所以需要逆转 且最后一位是0 说明逆转后高位是0 所以去除最后一位 
        if res[-1] == 0:
            res.pop()
            
        res.reverse()
        ans = ''
        
        for x in res:
            ans += str(x)
        
        return ans

岛屿数量

在这里插入图片描述
思路参考:https://leetcode-cn.com/problems/number-of-islands/solution/dao-yu-lei-wen-ti-de-tong-yong-jie-fa-dfs-bian-li-/
简单来说:就是由二叉树的前序遍历推广到网格的dfs,二叉树是左右两个孩子,网格是上下左右四个孩子。

在这里插入图片描述

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        
        def dfs(grid, i, j):
            # 边界出口 
            if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]):return
            # 不是岛屿 返回
            if grid[i][j] == '0':return 

            # 访问过的陆地记为0 海洋
            grid[i][j] = '0'
            
            #遍历 分别是上下左右 
            dfs(grid, i-1, j)
            dfs(grid, i+1, j)
            dfs(grid, i, j-1)
            dfs(grid, i, j+1)

        count = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                # 取出所有陆地
                if grid[i][j] == '1':
                    dfs(grid, i, j)
                    count += 1
        return count

695. 岛屿的最大面积

在这里插入图片描述

思路:先求岛屿面积,每遍历一个格子就面积加1

class Solution(object):
    def maxAreaOfIsland(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        def dfs(grid, i, j):
            # 边界
            if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]):return 0
            # 不是岛屿 返回
            if grid[i][j] != 1 :return 0

            # 标记已访问的结点 赋值为2
            grid[i][j] = 2
             
            num = 1

            # 遍历上下左右的陆地 每遍历一次陆地就加1
            num += dfs(grid, i-1, j)
            num += dfs(grid, i+1, j)
            num += dfs(grid, i, j-1) 
            num += dfs(grid, i, j+1)
            
            return num
        
        res = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    res = max(res, dfs(grid, i, j))
                  
        return res

tips:注意题目给的是str还是int 是‘1’还是1

827. 最大人工岛

在这里插入图片描述
思路:

总体思路: 对网格做两遍 DFS:第一遍 DFS 遍历陆地格子,计算每个岛屿的面积并标记岛屿;这个题目见LeetCode 695. Max Area of Island ,

第二遍 DFS 遍历海洋格子,观察每个海洋格子相邻的岛屿格子。重点!!!把每个岛屿格子的值标为面积
0是海洋1是岛屿
在这里插入图片描述

在这里插入图片描述

class Solution(object):
    def largestIsland(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        # 第一步遍历陆地 求岛屿的面积area
        # 第二步遍历海洋 求海洋上下左右不同的岛屿的编号 才能联通 findneighbor
        
        # 边界函数
        def inbound(grid, i, j):
            return 0 <= i < len(grid) and  0 <= j < len(grid[0])

        #  求编号为index岛屿的面积
        def area(grid, i, j, index):
            if not inbound(grid, i, j):return 0 
            # 如果不是未访问过的陆地
            if grid[i][j] != 1 :return 0
            # 标记为index 表示访问过
            grid[i][j] = index

            return 1 + area(grid, i - 1, j, index) + area(grid, i + 1, j, index) + area(grid, i, j-1, index) + area(grid, i, j+1, index)
        
        # 将来遍历海洋时  需要找到每格海洋上下左右相邻的陆地编号 同时要保证陆地编号要是index
        def findneighbor(grid, i, j):
            PerOceacnNeighlan = set()
            if(inbound(grid, i - 1, j) and grid[i - 1][j] >= 2):
                PerOceacnNeighlan.add(grid[i - 1][j])
            if(inbound(grid, i + 1, j) and grid[i + 1][j] >= 2):
                PerOceacnNeighlan.add(grid[i + 1][j])
            if(inbound(grid, i, j - 1) and grid[i][j - 1] >= 2):
                PerOceacnNeighlan.add(grid[i][j - 1])
            if(inbound(grid, i, j + 1) and grid[i][j + 1] >= 2):
                PerOceacnNeighlan.add(grid[i][j + 1])

            return PerOceacnNeighlan

        
        # 主函数 分两步进行
        # 第一步遍历陆地 求岛屿的面积area
        # 第二步遍历海洋 求海洋上下左右不同的岛屿的编号 才能联通 findneighbor

        index = 2 # index从2开始 避免与陆地1和海洋0冲突
        res = 0 #最终连通的最大面积和
        PerIlanArea = {}# 计算不同编号岛屿的面积
        
        # 遍历没有访问的陆地
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    sum = area(grid, i, j, index) # 求岛屿面积
                    PerIlanArea[index] = sum # 存入岛屿编号、岛屿面积
                    index += 1 # 岛屿编号增加
                    res = max(res,sum)# 记录不同编号之间最大的岛屿面积

   

        if res == 0:return 1 # res =0 表示没有陆地 就造一块陆地

        # 遍历没有访问的海洋格子
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 0:
                    # 对于每个海洋格子求出他上下左右陆地的编号
                    OceanSet = findneighbor(grid, i, j)
                    if len(OceanSet) < 1 :continue # 说明这个海洋格子周围没有不同的陆地编号 联通不了
                    total = 1 # 这个海洋变陆地的格子,之后记录连通后的和
                    # print(OceanSet)
                    for index in OceanSet:
                        total += PerIlanArea[index]
                    
                    res = max(total,res) # 记录所有【连通后的】最大的岛屿面积
        return res

463. 岛屿的周长

在这里插入图片描述

class Solution(object):
    def islandPerimeter(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """

        # 当一个陆地格子分别走向边界和海洋时都会使周长加1  而陆地格子走向陆地格子不影响周长
        def dfs(grid, i, j):
            # 走向边界 加1
            if not 0 <= i < len(grid) or not 0 <= j < len(grid[0]):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)

        
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    res = dfs(grid, i, j)
        return res

1020. 飞地的数量

1254. 统计封闭岛屿的数目

130. 被围绕的区域

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值