Middle-题目66:236. Lowest Common Ancestor of a Binary Tree

本文介绍了一种寻找二叉树中两个指定节点最低公共祖先的有效算法。通过递归地检查左右子树来确定公共祖先的位置,巧妙地利用了二叉树的特性。

题目原文:
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
题目大意:
寻找普通二叉树中两个节点的公共祖先。
题目分析:
看到了discuss中的一个极为巧妙的算法,先在左子树中找p或q,记为left,再到右子树中找,记为right,如果找到了(p或q都行),就把root往上传,没找到记为null,再判断返回的left和right哪个不是null,公共祖先就在哪里。
如果没有理解的话,看以下两种情况:
(1) p是q的祖先或者q是p的祖先,那么一定会搜索到root==p或root==q的情况,这样返回root,然后root的父节点上递归的两个函数一个为空一个为root,根据第5行则返回root,以此类推把root传到整个树的根节点。
(2) p和q分别位于某节点的左子树和右子树中,那么该节点上递归返回的left和right都不为空,第四行会返回这个root(即公共祖先),再依次往上传。
源码:(language:java)

public class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == p || root == q || root == null) return root;
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left != null && right != null) return root;
        return left != null ? left : right;
    }
}

成绩:
13ms,beats 28.45%,众数13ms,45.40%
cmershen的碎碎念:
朴素解法是记录下p和q的路径,再求公共部分的最后一个节点,此解法的设计是基于p和q的第一次出现,既简洁又易于理解,堪称妙绝!

2025-03-25 23:27:14.228 ERROR 21008 --- [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)] with root cause javax.servlet.ServletException: Circular view path [login]: would dispatch back to the current handler URL [/login] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.) at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:148) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1405) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1149) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.24.jar:5.3.24] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.24.jar:5.3.24] at javax.servlet.http.HttpServlet.service(HttpServlet.java:670) ~[tomcat-embed-core-9.0.69.jar:4.0.FR] at org.springframework.web.servl
03-26
<think>嗯,用户遇到了Spring MVC中的Circular view path问题,特别是在登录页面。这个问题通常发生在视图解析器配置不正确的时候。我需要先理解这个错误的原因。根据用户的描述,可能是InternalResourceView和ViewResolver的配置有问题。 首先,用户提到了引用[1],里面有关于视图解析器的配置,前缀和后缀分别是/WEB-INF/views/和.jsp。如果控制器返回的视图名和实际JSP路径组合后导致循环,比如视图名是"login",而JSP文件也是login.jsp,那么DispatcherServlet可能会陷入无限循环,试图转发到同一个路径,从而引发错误。 接下来,用户提供的引用[3]中有一个控制器的例子,返回的ModelAndView可能设置了视图名为"login",而如果视图解析器配置了前缀和后缀,组合后的路径就是/WEB-INF/views/login.jsp,这应该是正确的。但为什么会出现循环呢?可能是在没有明确配置视图解析器的情况下,Spring MVC默认的行为导致的问题。 另外,引用[4]提到了@EnableWebMvc注解,这个注解会导入DelegatingWebMvcConfiguration,可能会覆盖一些默认配置。如果用户同时使用了XML配置和注解配置,可能会有冲突,导致视图解析器没有被正确配置。 可能的解决方案包括检查视图解析器的配置是否正确,避免视图名和URL路径重复,或者在控制器方法中返回重定向而不是转发,以避免循环。例如,登录成功后应该重定向到主页,而不是再次转发到登录页面。 还需要检查是否有多个视图解析器被注册,导致优先级混乱。InternalResourceViewResolver应该设置为最低优先级,避免拦截其他视图解析器的处理。 此外,用户可能没有在Spring配置中启用MVC注解驱动,或者视图解析器的Bean没有被正确创建。需要确保配置类上有@Configuration和@EnableWebMvc,或者在XML中有<mvc:annotation-driven/>。 总结一下,解决这个问题的步骤应该是:1. 确认视图解析器配置正确,前缀和后缀没有导致循环;2. 检查控制器返回的视图名是否与URL路径冲突;3. 使用重定向避免循环转发;4. 确保视图解析器的优先级正确;5. 验证配置是否正确加载。</think>### 解决Spring MVC中Circular view path问题的分步指南 #### 1. **问题分析** 当Spring MVC的视图解析器配置不当时,可能触发`Circular view path`错误。例如: - 视图解析器前缀和后缀组合后与请求路径重复(如视图名`login`解析为`/WEB-INF/views/login.jsp`,但控制器映射的URL也是`/login`)。 - 控制器返回的视图名未正确指向物理文件路径。 #### 2. **配置视图解析器** 通过以下配置确保视图解析逻辑清晰: ```properties # application.properties spring.mvc.view.prefix=/WEB-INF/views/ spring.mvc.view.suffix=.jsp ``` 或XML配置(需结合`<mvc:annotation-driven/>`[^2]): ```xml <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> ``` **关键点**:验证生成的完整路径是否与物理文件匹配,避免路径循环。 #### 3. **调整控制器逻辑** 避免视图名与请求路径重复: ```java @Controller public class LoginController { @GetMapping("/login") public String showLoginPage() { return "loginPage"; // 确保视图名与URL路径不同 } } ``` 若需重定向到其他页面(如登录成功): ```java @PostMapping("/login") public String handleLogin() { return "redirect:/home"; // 使用重定向打破循环 } ``` #### 4. **检查视图解析器优先级** 若存在多个`ViewResolver`,需设置`order`属性确保`InternalResourceViewResolver`最后执行: ```java @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setOrder(Ordered.LOWEST_PRECEDENCE); // 最低优先级 return resolver; } ``` #### 5. **验证注解配置** 确保启用MVC注解驱动(通过`@EnableWebMvc`或XML配置[^4]): ```java @Configuration @EnableWebMvc // 关键注解 @ComponentScan("com.example.controller") public class WebConfig implements WebMvcConfigurer { // 其他配置 } ``` #### 6. **排查隐藏配置冲突** - **禁用默认Servlet处理**:在配置类中添加`registry.enable();`可能覆盖默认行为。 - **检查静态资源映射**:避免静态资源路径与视图名冲突。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值