深度优先搜索解题算法1

本文介绍了使用深度优先搜索(DFS)解决五个不同的算法问题:字典序排数、递增子序列、岛屿数量、阵中的路径和机器人的运动路径。针对每个问题,详细阐述了解题思路并提供了C++版本的DFS实现,探讨了如何优化时间复杂度和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、字典序排数

给定一个整数 n, 返回从 1 到 n 的字典顺序

例如
给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 。

请尽可能的优化算法的时间复杂度和空间复杂度。 输入的数据 n 小于等于 5,000,000

方法一:python 库函数 sorted 带有按照字典序排列的功能

    def lexicalOrder(self, n: int) -> List[int]:
        res = range(1,n+1)
        # key=str 就是按照字典序排序的方法
        return sorted(res,key=str)

方法二:C++ 版本

深度优先搜索序列思想

class Solution {
   
   
public:
    vector<int>res;
    void calOrder(int cur,int n){
   
   
        if(cur>n){
   
   
            return;
        }
        res.push_back(cur);
        cur*=10;
        for(int i =0;i<10;++i){
   
   
            calOrder(cur+i,n);
        }
    }
    vector<int> lexicalOrder(int n) {
   
   
        for(int i = 1;i<10;++i){
   
   
            calOrder(i,n);
        }
        return res;
    }
};

2、递增子序列

给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2

示例
输入: [4, 6, 7, 7]
输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]

思路:深度优先搜索序列
两个条件:(1)在添加一个元素时,只需考虑它是否大于等于当前子序列的最后一个值,(2)子序列长度大于2

记录用过的数字,避免重复

def findSubsequences(nums):
    res, n = [], len(nums)
    def dfs(index, path):
        if len(path) >= 2:
            res.append(path)
        if index >= n:
            return
        used = []
        for i in range(index, n):
            if nums[i] in used:
                continue
            used.append(nums[i])
            if not path or nums[i] >= path[-1]:
                dfs(i+1, path+[nums[i]])
    dfs(0, [])
    return res

3、岛屿数量

给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例1
输入:
1 1 1 1 0
1 1 0 1 0
1 1 0 0 0
0 0 0 0 0
输出: 1

示例2
输入:
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1
输出: 3

方法一:遍历这个网格,当有一格内是‘1’时,以此为起点,向四个方向进行深度优先搜索,找到所有能到达的‘1’,搜索过的地方用‘#’标记,以免重复搜索,无法及继续搜索时代表已经找到一个完整的岛屿

继续遍历网格,重复第 1 步,直到网格遍历完

    def numIslands(self, grid: List[List[str]]) -> int:
        rows = len(grid)
        if not rows:
            return 0
        cols = len(grid[0])
        def IsExpend(grid,row,col):
            if row<0 or col <0 or row>=len(grid) or col>=len(grid[0]) or grid[row][col]!='1':
                return
            grid[row][col] = '#'
            IsExpend(grid,row+1,col)
            IsExpend(grid,row-1,col)
            IsExpend(grid,row,col+1)
            IsExpend(grid,row,col-1)
            
        num = 0
        for row in range(rows):
            for col in range(cols):
                if grid[row][col]=='1':
                    IsExpend(grid, row,col)
                    # 只要函数出来后就一定是一个岛屿
                    num+=1
        return num

简化代码

    def numIslands(self, grid: List[List[str]]) -> int:
        def IsExpend(grid,row,col):
            if row<0 or col <0 or row>=len(grid) or col>=len(grid[0]) or grid[row][col]!='1':
                return False;
            grid[row][col] = '#'
            return IsExpend(grid,row+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序猿的温柔香

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

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

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

打赏作者

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

抵扣说明:

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

余额充值