BM55 没有重复项数字的全排列、BM57 岛屿数量、BM61 矩阵最长递增路径、NC345 城市群数量

 1. 给出一组数字,返回该组数字的所有排列

法一 #递归

BM55 没有重复项数字的全排列、BM57 岛屿数量、BM61 矩阵最长递增路径、NC345 城市群数量_第1张图片

class Solution:
    def permuteUnique(self , nums ):
        res = []
        nums.sort()
        def backtrack(nums,temp):
            if not nums:#当到num中最后一个元素时,则证明此时已经找到一种排列了res.append(temp)
                return
            for i in range(len(nums)):#遍历num数组
                if i > 0 and nums[i] == nums[i-1]:#若当前位置中的数已经添加过了则跳过
                    continue
                backtrack(nums[:i]+nums[i+1:],temp+[nums[i]])
        backtrack(nums,[])
        return res

 法二

解:大概是图中这个意思BM55 没有重复项数字的全排列、BM57 岛屿数量、BM61 矩阵最长递增路径、NC345 城市群数量_第2张图片

class Solution:
    def permute(self , num: List[int]) -> List[List[int]]:
        res=[[num[0]]]
        for i in range(1,len(num)):#遍历
            res=self.f(res,num[i])#新来一个num[i]在原先的基础上做插入
        return res
    def f(self,li,n):
        temp=[]
        for s in li:
            for j in range(len(s),-1,-1):#考虑的后来的优先级低,按倒着的顺序插入
                tmp=s.copy()
                tmp.insert(j,n)#在s的第j个位置插入n
                temp.extend([tmp])#以列表的形式更新并入结果
        return temp

2.BM57 岛屿数量

题:相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。

最简单的一种方式就是遍历数组中的每一个值,如果是1就说明是岛屿,然后把它置为0或者其他的字符都可以,只要不是1就行,然后再遍历他的上下左右4个位置。

class Solution:
    def solve(self , grid: List[List[str]]) -> int:
        # write code here
        def dfs(grid,i,j):
            if i<0 or i>=len(grid) or j<0 or j>=len(grid[0]) or grid[i][j]=="0":#如果出边界或者遇到海洋/已经遍历过 弹出一次dfs
                return 
            grid[i][j]="0"#标记 当前置为0
            dfs(grid,i-1,j)#查它的上下左右
            dfs(grid,i+1,j)
            dfs(grid,i,j+1)
            dfs(grid,i,j-1)
            
        if not grid:
            return 0
        num=0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j]=="1":
                    num+=1#多一块岛屿
                    dfs(grid,i,j)#进入一次dfs
        return num

# ACM模式要自己处理输入输出
# grid = []
# line = input().strip().split("],")
# for li in line:
#     li = li.strip("[").strip("]").split(",")
#     grid.append(li)
  
# s = Solution()
# print(s.solve(grid))

3. BM61 矩阵最长递增路径

题:给定一个 n 行 m 列矩阵 matrix ,矩阵内所有数均为非负整数。在矩阵中找到一条最长路径,使这条路径上的元素是递增的。并输出这条最长路径的长度。

 枚举某一个起点,然后进行递归操作,用一个递归函数表示从这个位置开始可以最多走多少步。然后由四个方向的位置进行转移过来。一旦发现在过程中不符合题目的条件,我们直接进行返回0即可

class Solution:
    def solve(self , matrix: List[List[int]]) -> int:
        # write code here
        dp = [[0]*len(matrix) for _ in range(len(matrix[0]))]
        def dfs(i,j,pre):
            if i<0 or i>=len(matrix) or j<0 or j>=len(matrix[0]) or matrix[i][j]<=pre:#到达边界或当前值小于上一个值
                return 0
            if dp[i][j]:#优化 记忆化搜索 此位置已经填过最大路径,直接返回,不重复计算
                return dp[i][j]
            ma=max(dfs(i+1,j,matrix[i][j]),dfs(i-1, j,matrix[i][j]),dfs(i, j-1,matrix[i][j]),dfs(i, j+1,matrix[i][j]))
            dp[i][j]=1+ma#更新这个位置的状态
            return dp[i][j]
        if not matrix:#特判矩阵为空的情况
            return 0
        res=0
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                res=max(res,dfs(i,j,-1))#枚举每个起点的位置
        return res
            

 4.NC345 城市群数量

题:给定一个 n 个节点的邻接矩阵 m。 节点定义为城市,如果 a 城市与 b 城市相连, b 与 c 城市相连,尽管 a 与 c 并不直接相连,但可以认为 a 与 c 相连,定义 a,b,c 是一个城市群。找出共有多少个城市群。

#注意行和列对应的一样 对称矩阵  因此按行搜索 (行若搜索过 则代表那列也搜索过)
class Solution:
    def citys(self ,grid: List[List[int]]) -> int:
        def dfs(grid,i):
            if re[i]:#已访问过这个城市,不必重复搜索
                return
            re[i]=1#标记访问过 
            # 继续搜索与i相连的城市
            for j in range(m):
                if grid[i][j] == 1:
                    dfs(grid,j)
        
        num,n,m=0,len(grid),len(grid[0])
        re=[0]*n#记录是否访问过此城市
        for i in range(n):#按行遍历
                if not re[i]:
                    num+=1#多一个城市群
                    dfs(grid,i)#进入一次dfs
        return num

你可能感兴趣的:(python,剑指offer,递归,算法,python)