DFS + visited 集合

小明站在一个无限大的坐标系上(比如从 (0, 0) 开始),每走一步可以:

向 左(x - 1)

向 右(x + 1)

向 上(y + 1)

但有两个限制:

不能往下走 ❌

不能走到以前去过的地方 ❌(每个格子只能走一次)

问:走 n 步,有多少种不同的走法?

✅ 举个例子来说明: 从 (0, 0) 出发

当 n = 1: 只走一步,有 3 种选择:

向右 → (1, 0)

向左 → (-1, 0)

向上 → (0, 1) 当 n = 2: 每一步都不能走重复点,比如:

第一步向右 (1,0),第二步可以向右 (2,0)、左回去 (0,0)❌、上 (1,1),但不能走 (0,0),因为已经走过了

我们必须用遍历的方法去试一遍所有不重复的走法,这就是用“递归”做的。

✅ 怎么做:用“递归 + 回溯” 我们可以用一个函数 dfs(x, y, step) 来表示:

“现在在 (x,y) 这个位置,已经走了 step 步,看看接下来怎么走”

✅ 用 JavaScript 写的完整代码(有中文注释):

function countWays(n) {
   const visited = new Set(); // 记录走过的点
   let count = 0; // 最后结果


   // 深度优先搜索
   function dfs(x, y, steps) {
       if (steps === n) { // 已经走完 n 步
           count++;
           return;
       }


       const key = `${x},${y}`;
       visited.add(key); // 当前点记为已访问


       // 三个方向:右、左、上
       const dirs = [
           [1, 0],  // 向右
           [-1, 0], // 向左
           [0, 1]   // 向上
       ];


       for (const [dx, dy] of dirs) {
           const nx = x + dx;
           const ny = y + dy;
           const nextKey = `${nx},${ny}`;


           // 没有访问过才能走
           if (!visited.has(nextKey)) {
               dfs(nx, ny, steps + 1); // 走一步
           }
       }


       visited.delete(key); // 回溯,把当前点从 visited 中移除
   }


   dfs(0, 0, 0); // 从 (0, 0) 开始走
   return count;
}

✅ 为什么用 Set 保存走过的点? 因为不能走重复的点,比如:

走了 (0, 0) → (1, 0) → (0, 0) ← 这样是不合法的(回到了走过的点)

所以我们用 Set 存每次走过的位置,在走下一步前先检查它有没有在 Set 中。

✅ 回溯是什么意思? 每次走一步之后,我们“试试看”,如果失败了(比如没法继续走),就“退回来”把这个点从 Set 中删掉(这叫“回溯”)。

全部评论
复杂度是否太高了
点赞 回复 分享
发布于 08-03 13:34 广东

相关推荐

得物 2026秋招【薪资】25K-31k *16-18【base地】上海、杭州、北京【岗位类型】技术类、供应链类、产品类、运营类、设计类、职能类、风控类、商品研究类等,每人两个【内推链接】https://poizon.jobs.feishu.cn/s/214DfkMeScY【内推码】7ZNTX5R【技术面试内容】手撕:中等hot1001布隆过滤器相关2redis主从同步的细节3 mysql的锁4共享协作文档如何同步5Java中的设计模式,至少四个(工厂模式和策略模式差异,为什么要用策略模式)6说说Spring中的AOP7在实习期间,最有挑战性的事情?担任的是什么角色? 遇到什么问题?怎么解决?8在微服务/分布式服务的场景下,怎么确保我在同一个方法内部调用多个服务时的一致性?9对账是个有时效的方法,如何用一些近乎实时的方式去确保一致性?10RPC远程调用幂等校验11你对分布式这块还有什么需要分享的么?比如说你对微服务还有哪些你个人的理解么?12一个网站怎么兼容到移动端13页面多请求,高并发如何解决14promise处理高并发的方法15生产过程中出现问题怎么定位16不能用原生方法17Java线程通信方式18谈谈你对AQS的理解19AQS中可重入锁和互斥锁怎么实现的20CMS和C1区别21JVM调优的手段22新生代频繁Minor GC原因,解决办法23频繁Full GC(老年代GC)的原因?解决办法24Java内存区域,内存模型25Java运行一个程序的过程26静态变量在什么阶段分配内存27Spring 循环依赖是什么?怎么解决28什么回表29一定发生回表操作吗用我的内推投递,有什么问题私聊我,联系hr,全程跟随解决!投递可以评论已投,听说点赞评论的人多拿offer偶投递的uu留下姓名缩写和岗位~我每一个都会跟进!作者:aabbbbb链接:https://www.nowcoder.com/feed/main/detail/27c0dca9af8b465fb8ef7f51ff3f0c0e?sourceSSR=users来源:牛客网
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务