当前位置: 首页 > wzjs >正文

渭南网站建设与维护国家政务服务平台官网入口

渭南网站建设与维护,国家政务服务平台官网入口,网站 做 专家问答,wordpress 防调用解锁回溯与遍历的核心能力!今日深入解析深度优先搜索(DFS)的实现原理与优化技巧,结合排列组合、路径搜索等高频场景,彻底掌握递归与剪枝的底层逻辑。 一、DFS 核心思想 深度优先搜索(DFS) 是一…

解锁回溯与遍历的核心能力!今日深入解析深度优先搜索(DFS)的实现原理与优化技巧,结合排列组合、路径搜索等高频场景,彻底掌握递归与剪枝的底层逻辑。

一、DFS 核心思想

深度优先搜索(DFS) 是一种优先探索分支路径到底层的算法,核心特性:

  1. 递归/栈驱动:通过递归调用栈或显式栈实现深度遍历

  2. 路径探索:适合寻找所有可能解或连通性检测

  3. 回溯机制:通过状态重置实现多路径搜索

适用场景:

  • 排列组合问题(全排列、子集)

  • 矩阵/图中的路径搜索(岛屿问题、迷宫问题)

  • 树形结构遍历(路径总和、二叉树操作)


二、DFS 算法模板

1. 递归模板(隐式栈)
void dfs(参数列表) {if (终止条件) { 记录结果; return; }for (选择 in 选择列表) {处理选择;    // 前序操作dfs(新参数); // 递归进入下一层撤销选择;    // 后序操作(回溯)}
}
2. 迭代模板(显式栈)
void dfsIterative(Node* root) {stack<Node*> stk;unordered_set<Node*> visited;stk.push(root);while (!stk.empty()) {Node* curr = stk.top(); stk.pop();if (visited.count(curr)) continue;visited.insert(curr);// 处理当前节点for (auto& neighbor : curr->neighbors) {stk.push(neighbor); // 按逆序入栈保证顺序}}
}

三、四大高频应用场景

场景1:全排列问题(LeetCode 46)
vector<vector<int>> permute(vector<int>& nums) {vector<vector<int>> res;function<void(int)> dfs = [&](int start) {if (start == nums.size()) {res.push_back(nums);return;}for (int i = start; i < nums.size(); ++i) {swap(nums[start], nums[i]); // 选择当前位dfs(start + 1);             // 递归后续位swap(nums[start], nums[i]); // 撤销选择}};dfs(0);return res;
}
场景2:岛屿数量(LeetCode 200)
int numIslands(vector<vector<char>>& grid) {int count = 0;for (int i = 0; i < grid.size(); ++i) {for (int j = 0; j < grid[0].size(); ++j) {if (grid[i][j] == '1') {dfs(grid, i, j);count++;}}}return count;
}void dfs(vector<vector<char>>& grid, int x, int y) {if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] != '1') return;grid[x][y] = '0'; // 标记为已访问dfs(grid, x + 1, y);dfs(grid, x - 1, y);dfs(grid, x, y + 1);dfs(grid, x, y - 1);
}
场景3:路径总和 III(LeetCode 437)
int pathSum(TreeNode* root, int targetSum) {unordered_map<long, int> prefix; // 前缀和计数prefix[0] = 1; // 初始前缀和为0出现1次int count = 0;function<void(TreeNode*, long)> dfs = [&](TreeNode* node, long currSum) {if (!node) return;currSum += node->val;// 查找当前路径是否存在前缀和满足 currSum - targetSumcount += prefix[currSum - targetSum];prefix[currSum]++; // 记录当前前缀和dfs(node->left, currSum);dfs(node->right, currSum);prefix[currSum]--; // 回溯};dfs(root, 0);return count;
}
场景4:组合总和(LeetCode 39)
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {vector<vector<int>> res;vector<int> path;sort(candidates.begin(), candidates.end());function<void(int, int)> dfs = [&](int start, int sum) {if (sum == target) {res.push_back(path);return;}for (int i = start; i < candidates.size(); ++i) {if (sum + candidates[i] > target) break; // 排序后剪枝path.push_back(candidates[i]);dfs(i, sum + candidates[i]); // 允许重复选择path.pop_back();}};dfs(0, 0);return res;
}

四、DFS 优化技巧

优化方法应用场景优化效果
记忆化搜索重复子问题(如斐波那契)时间复杂度降为O(n)
剪枝策略排列组合问题减少无效递归路径
前缀和+哈希表路径总和问题时间复杂度降为O(n)
双向DFS状态空间较大问题减少搜索空间

五、大厂真题实战

真题1:单词搜索(某大厂2024面试)

题目描述:
在二维字符矩阵中搜索给定单词是否存在(相邻字母连接)
DFS解法:

bool exist(vector<vector<char>>& board, string word) {for (int i = 0; i < board.size(); ++i) {for (int j = 0; j < board[0].size(); ++j) {if (dfs(board, word, i, j, 0)) return true;}}return false;
}bool dfs(vector<vector<char>>& board, string& word, int x, int y, int idx) {if (idx == word.size()) return true;if (x < 0 || x >= board.size() || y < 0 || y >= board[0].size() || board[x][y] != word[idx]) return false;char tmp = board[x][y];board[x][y] = '#'; // 标记已访问bool found = dfs(board, word, x+1, y, idx+1)|| dfs(board, word, x-1, y, idx+1)|| dfs(board, word, x, y+1, idx+1)|| dfs(board, word, x, y-1, idx+1);board[x][y] = tmp; // 回溯return found;
}
真题2:N皇后问题(某大厂2023笔试)

题目描述:
在N×N棋盘放置N个皇后,使其互不攻击
DFS+位运算优化:

vector<vector<string>> solveNQueens(int n) {vector<vector<string>> res;vector<string> board(n, string(n, '.'));function<void(int, int, int, int)> dfs = [&](int row, int cols, int diag1, int diag2) {if (row == n) {res.push_back(board);return;}int available = ((1 << n) - 1) & ~(cols | diag1 | diag2);while (available) {int pos = available & -available; // 取最低位的1int col = __builtin_ctz(pos); // 计算列索引board[row][col] = 'Q';dfs(row + 1, cols | pos, (diag1 | pos) << 1, (diag2 | pos) >> 1);board[row][col] = '.';available &= available - 1; // 移除最低位的1}};dfs(0, 0, 0, 0);return res;
}

六、复杂度分析

问题类型时间复杂度空间复杂度示例
全排列O(n×n!)O(n)排列问题
组合问题O(C(n,k)×k)O(k)组合总和
矩阵路径搜索O(3^k)(k为路径长度)O(k)单词搜索
树形遍历O(n)O(h)二叉树路径总和

七、常见误区与调试技巧

  1. 栈溢出:递归层数过深(Python默认递归深度约1000层)

    • 解决方案:改用迭代DFS或增大递归限制

  2. 状态污染:忘记回溯时恢复共享状态

  3. 剪枝错误:错误剪枝导致漏解

  4. 调试技巧

    • 打印递归树路径

    • 使用条件断点跟踪特定路径

    • 可视化中间状态


LeetCode真题训练:

  • 17. 电话号码的字母组合

  • 79. 单词搜索

  • 113. 路径总和 II

http://www.dtcms.com/wzjs/562032.html

相关文章:

  • 手机做任务的网站有哪些怎么制作一个网站内容
  • 外贸网站如何做推广电话个人二级网站怎么做
  • 重庆没建网站的企业网站主机 分为
  • 山东网站建设方案制作网站建设怎么上传数据
  • 做电子杂志用什么网站深圳市建筑人才网
  • 企业管理咨询网站模板创意型网站
  • 南山商城网站建设哪家便宜店面设计师是什么
  • 注册网站需要多少钱运用asp做购物网站的心得
  • 怎么自己创建一个网站手机做uml图网站
  • 免费 flash网站源码定制软件开发流程
  • 添加网站栏目的步骤建设网站前台费用
  • 企业网站备案号密码忘记wordpress 关键词获取
  • 优惠建设网站龙岩做网站多少钱
  • 营销型网站建设tfx88手机网站制作吧
  • php企业网站源码蓝色做安全题目是哪个网站
  • 公司 网站建设 会计科目找项目
  • 分享代码的网站做短视频的软件
  • 个人网站命名的要求在线游戏网站
  • 什么网站做蜘蛛池app开发定制外包26
  • 做影视网站不备案网站备案完才能建站吗
  • 平面素材网站排名活动宣传推广的形式有哪些
  • 网站数据库搬家seo关键词优化怎么收费
  • 蚂蚁中国网站建设动漫网站开发研究内容
  • 网站是否需要备案视频网站开发流程
  • 手机网站建设要注意哪些问题站长工具海角
  • 深圳网站建设icxun网站源码在哪里
  • 建网站需要几程序员wordpress建企业网站
  • 手机精品网站建设网站 配色
  • 兰州网站设计公司有哪些南宁市建设工程造价信息网
  • s什么网站可以接单做设计赚钱野花高清中文免费观看视频