搜索算法思想

DFS

常规DFS:

(1)二叉树前序,中序,后序遍历-CSDN博客

void postorderTraversal(root)
    初始化一个空列表 arr
    find访问总树(root,arr)
    return arr

void find(temp, arr)
    if temp 为空
        return 

// 调用顺序由前中后序决定

    find递归访问左子树

    find递归访问右子树

    arr加入当前节点

(2)P1030 [NOIP2001 普及组] 求先序排列_用java实现p1030 [noip2001 普及组] 求先序排列-CSDN博客

 找先序遍历
// mid中序,after后序
void finds(string mid, string after)
{
	if (mid.size() > 0)
	{   // 打印前序
		char ch = after[after.size() - 1];
		int root = mid.find(ch);
		cout << ch;
 
		// 分为第一棵树,中序(左根右) 后序(左右根)
		finds(mid.substr(0, root), after.substr(0, root));
 
		// 第二棵树 中序 后序
		// substr(pos(起始),len(从起始遍历的长度))
		finds(mid.substr(root + 1), after.substr(root,mid.size()-1-root  ));
	}
}

DFS+回溯:

模板:

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

 全排列:

问题 A: 求全排列(1)(DFS(排列类))-CSDN博客

全排列的伪代码(标记,向深搜索,回溯):

void dfs(Node* node) {
    if (node 是已访问) {
        return;
    }
    标记 node 为已访问;
    temp.push_back(nums[i]);
    dfs(nextNode);  //对于 node 的每一个未访问的邻接节点 nextNode 
    temp.pop_back(nums[i]);
    标记 node 为未访问;
}

 多层嵌套:

 P8650 [蓝桥杯 2017 省 A] 正则问题(dfs )-CSDN博客

def calculate_expression_length():
    length = 0
    while True:
        ch = read_next_character()
        
        if ch is None:  # 结束条件,适用于字符串结束
            return length
        
        if ch == 'x':
            length += 1
        elif ch == '(':
            length += calculate_expression_length()  # 进入子表达式的递归计算
        elif ch == ')':
            return length  # 结束当前递归层次
        elif ch == '|':
            length = max(length, calculate_expression_length())  # 开始新的选项计算,并与之前的长度比较

搜索查找可能性:

P9241 [蓝桥杯 2023 省 B] 飞机降落(DFS)-CSDN博客

Note: 

 1.每架飞机都能在其最晚开始降落时间之前降落

2.当前飞机最早何时可以开始降落(planes[i].t),并确保这不会早于上一架飞机降落完成的时间(endtime

3.找到了一种可行的飞机降落顺序,就不需要继续尝试其他顺序

二维回溯

17. 电话号码的字母组合(回溯)-CSDN博客

Note:

  • 以二维数组判断每个字母的访问情况(也解决了重复字母出现的情况)
  • 用查找深度(也是当前排列长度),判断当前的具体元素

DFS+并查集: 

问题 C: Oil Deposits(DFS+类并查集)-CSDN博客

统计油田数量伪代码:

void dfs(x,y){
    for i in range(next[i][]):
        (x,y)向周围八个位置延伸(x1,y1)
        
        if (x1,y1) == @:
            (x1,y1) == *      // 标记
            dfs(x1,y1)
}

P1141 01迷宫(dfs+染色联通块)-CSDN博客

main()
    对于每个矩阵中的点 (i, j)
        如果 visit[i][j] 未标记
            标记 visit[i][j] 为当前联通块 k
            DFS探索(i, j)
            更新联通块 k 的大小为 n        // item[k]对应k个联通块大小
            k++, 重置 n 为 1
   

void DFS(x, y)
    (x,y)->四个方向延伸(nx,ny)
        如果 (nx, ny) 在矩阵范围内 且 map[x][y] ≠ map[nx][ny] 且 visit[nx][ny] 未标记
            标记 (nx,ny) 为当前联通块 k
            增加当前联通块的大小 n++
            DFS(nx, ny)

DFS+断点划分:

P8599 [蓝桥杯 2013 省 B] 带分数(dfs+全排列+断点判断)_洛谷p8599 [蓝桥杯 2013 省 b] 带分数java-CSDN博客 Note:        target=a+b/c        (a,b,c分别由1~9的不同数字组成)

function dfs(position):
    if position == 9:  # 如果已经填完所有位置
        # 根据当前排列更新答案
        return
    
    for i from 1 to 9:  # 尝试每一个数字
        if not visited[i]:  # 如果数字i没有被访问过
            # 标记数字i为已访问
            arr[position] = i  # 在当前位置放置数字i
            dfs(position + 1)  # 移动到下一个位置
            # 回溯,标记数字i为未访问

function check_condition():
    # 将arr数组的不同段转换成数字并检查是否满足(l - a) * c == b的条件
    # 如果条件满足,则增加ans的值

BFS:

保证最短路径:在寻找最短路径问题中,BFS 能够保证一旦找到目标节点,该路径就是最短的。层级遍历:这意味着首先访问距离起点最近的节点,然后依次访问距离逐渐增加的节点。

所以:首次到达任一节点的路径肯定是从起点到该节点的最短路径。

常规BFS:

问题 R: 胜利大逃亡(bfs)-CSDN博客

问题 N: A strange lift(BFS)-CSDN博客

病毒感染时间(字节青训营)-CSDN博客 

function bfs(x, y, z, T):
    初始化队列arr
    将起点{0,0,0,0}加入队列
    标记起点为已访问

    while 队列不为空:
        取出队列首节点为current
        if current是终点且val <= T:
            清空队列
            输出current.val并返回

        for 每个可能的移动方向:
            计算新位置new_pos
            if new_pos有效且未访问且不是墙:
                标记new_pos为已访问
                new_pos.val = current.val + 1
                将new_pos加入队列

    输出-1  # 没有找到有效路径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值