101. Symmetric Tree

问题描述

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

1
/
2 2
/ \ /
3 4 4 3

But the following [1,2,2,null,3,null,3] is not:

1
/
2 2
\
3 3

Note:
Bonus points if you could solve it both recursively and iteratively.

题目链接:

思路分析

给出一棵二叉树,判断这颗二叉树是否是对称的。对称的条件是以root所在的位置为对称轴,左右子树的结构和值都相同。一开始想用100. Same Tree的中序遍历树然后对比头尾是否相同的方式解决, 发现这样做会有一些结构上的不同无法发现。

然后现在使用的是递归的方式,检查每一个点是否相同,然后在比较左子结点的左子树与右子结点的右子树,左子结点的右子树与右子结点的左子树是否相同就可以了。

代码

java

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root != null){
            return compare(root.left, root.right);
        }
        else{
            return true;
        }
    }
    
    private boolean compare(TreeNode p, TreeNode q){
        if (p == null && q == null){
            return true;
        }
        else if (p == null || q == null){
            return false;
        }
        else if (p.val != q.val){
            return false;
        }
        else{
            return compare(p.left, q.right) && compare(p.right, q.left);
        }
    }
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root)
            return compare(root->left, root->right);
        else
            return true;
            
    }
    
    bool compare(TreeNode* p, TreeNode* q){
        if (!p && !q)
            return true;
        else if (!p || !q)
            return false;
        else if (p->val != q->val)
            return false;
        else
            return (compare(p->left, q->right) && compare(p->right, q->left));
    }
};

时间复杂度:O(n) // n为树的结点数


####反思
还是没有掌握递归的精髓,不要总是想着把所有结点都处理完再进行比较,错误代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        string s = inorderVisitTree(root);
        int n = s.length();
        for(int i = 0; i < (n/2 + 1); i++){
            if(s[i] != s[n-1-i])
                return false;
        }
        return true;
    }
    
     string inorderVisitTree(TreeNode* p){
        string s = "";
        if(p){
            if (p->left == NULL && p->right == NULL)
                return s += p->val;
            if (p->left != NULL)
                s += inorderVisitTree(p->left);
            else
                s += "n";
            s += p->val;
            if(p->right != NULL)
                s += inorderVisitTree(p->right);
            else
                s += "n";
        }
        else
            return "";
        return s;
    }
    
};

执行 java -Djava.security.debug=provider -jar tks-shop-test.jar 报错[traceId:] 2025-06-03T09:48:27.798+08:00 WARN 311663 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tokenAes' defined in class path resource [com/yami/shop/common/config/ShopBeanConfig.class]: Failed to instantiate [cn.hutool.crypto.symmetric.AES]: Factory method 'tokenAes' threw exception with message: SecurityException: JCE cannot authenticate the provider BC [traceId:] 2025-06-03T09:48:27.810+08:00 DEBUG 311663 --- [ main] c.y.s.c.t.TraceThreadPoolTaskExceutor : Shutting down ExecutorService 'taskExecutor' [traceId:] 2025-06-03T09:48:27.841+08:00 INFO 311663 --- [lientSelector_1] RocketmqRemoting : closeChannel: close the connection to remote address[47.115.51.7:10911] result: true [traceId:] 2025-06-03T09:48:27.845+08:00 INFO 311663 --- [lientSelector_1] RocketmqRemoting : closeChannel: close the connection to remote address[47.115.51.7:9876] result: true [traceId:] 2025-06-03T09:48:27.911+08:00 INFO 311663 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat] [traceId:] 2025-06-03T09:48:27.960+08:00 INFO 311663 --- [ main] .s.b.a.l.ConditionEvaluationReportLogger : Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. [traceId:] 2025-06-03T09:48:28.016+08:00 ERROR 311663 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tokenAes' defined in class path resource [com/yami/shop/common/config/ShopBeanConfig.class]: Failed to instantiate [cn.hutool.crypto.symmetric.AES]: Factory method 'tokenAes' threw exception with message: SecurityException: JCE cannot authenticate the provider BC at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:659) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:493) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:941) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) at com.yami.shop.admin.WebApplication.main(WebApplication.java:25) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) at org.springframework.boot.loader.Launcher.launch(Launcher.java:95) at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [cn.hutool.crypto.symmetric.AES]: Factory method 'tokenAes' threw exception with message: SecurityException: JCE cannot authenticate the provider BC at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) ... 27 common frames omitted Caused by: cn.hutool.crypto.CryptoException: SecurityException: JCE cannot authenticate the provider BC at cn.hutool.crypto.SecureUtil.createCipher(SecureUtil.java:1034) at cn.hutool.crypto.CipherWrapper.<init>(CipherWrapper.java:39) at cn.hutool.crypto.symmetric.SymmetricCrypto.init(SymmetricCrypto.java:150) at cn.hutool.crypto.symmetric.SymmetricCrypto.<init>(SymmetricCrypto.java:127) at cn.hutool.crypto.symmetric.SymmetricCrypto.<init>(SymmetricCrypto.java:115) at cn.hutool.crypto.symmetric.SymmetricCrypto.<init>(SymmetricCrypto.java:104) at cn.hutool.crypto.symmetric.SymmetricCrypto.<init>(SymmetricCrypto.java:83) at cn.hutool.crypto.symmetric.AES.<init>(AES.java:50) at com.yami.shop.common.config.ShopBeanConfig.tokenAes(ShopBeanConfig.java:27) at com.yami.shop.common.config.ShopBeanConfig$$SpringCGLIB$$0.CGLIB$tokenAes$3(<generated>) at com.yami.shop.common.config.ShopBeanConfig$$SpringCGLIB$$2.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) at com.yami.shop.common.config.ShopBeanConfig$$SpringCGLIB$$0.tokenAes(<generated>) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ... 28 common frames omitted Caused by: java.lang.SecurityException: JCE cannot authenticate the provider BC at java.base/javax.crypto.Cipher.getInstance(Cipher.java:722) at cn.hutool.crypto.SecureUtil.createCipher(SecureUtil.java:1032) ... 46 common frames omitted Caused by: java.lang.IllegalStateException: zip file closed at java.base/java.util.zip.ZipFile.ensureOpen(ZipFile.java:839) at java.base/java.util.zip.ZipFile.getManifestName(ZipFile.java:1065) at java.base/java.util.zip.ZipFile$1.getManifestName(ZipFile.java:1108) at java.base/javax.crypto.JarVerifier.verifySingleJar(JarVerifier.java:464) at java.base/javax.crypto.JarVerifier.verifyJars(JarVerifier.java:320) at java.base/javax.crypto.JarVerifier.verify(JarVerifier.java:263) at java.base/javax.crypto.ProviderVerifier.verify(ProviderVerifier.java:130) at java.base/javax.crypto.JceSecurity.verifyProvider(JceSecurity.java:190) at java.base/javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:218) at java.base/javax.crypto.Cipher.getInstance(Cipher.java:718) ... 47 common frames omitted
06-04
<think>嗯,用户遇到了JavaSpringBoot启动时的BeanCreationException错误,具体是JCE无法验证BC(Bouncy Castle)加密提供程序。我需要先理解这个问题的根本原因。根据提供的引用,问题可能出在JDK版本与BouncyCastle的兼容性上,特别是JDK17。之前JDK1.8也有类似问题,但解决方法可能不同。首先,JCE(JavaCryptographyExtension)是Java的加密框架,负责管理加密提供程序。当应用程序尝试加载BouncyCastle作为提供程序时,如果JCE无法验证其签名,就会抛出认证错误,导致Bean创建失败。这可能是因为Bouncy Castle的JAR没有正确签名,或者JDK的安全策略限制了未签名的提供程序。接下来,我需要考虑解决方案。用户用的是Spring Boot,可能需要检查依赖中的Bouncy Castle版本是否正确。可能的解决步骤包括:1.确认依赖项,使用正确版本的Bouncy Castle;2.配置安全策略文件,允许未认证的提供程序;3.调整JDK的安全设置,比如移除限制或添加例外;4.手动注册BouncyCastle提供程序,避免自动检测的问题。另外,用户可能混淆了不同JDK版本的解决方法。例如,JDK1.8可能需要修改java.security文件,而JDK17可能需要不同的配置。需要确保用户针对他们使用的JDK版本采取正确的措施。同时,Spring Boot的自动配置可能在某些情况下导致BouncyCastle被提前加载,从而触发验证问题,因此手动注册提供程序可能更可靠。 还需要检查是否有多个版本的BouncyCastle库冲突,这可能导致签名不一致。Maven或Gradle的依赖树分析可以帮助排除这种情况。此外,确保应用程序启动时正确初始化安全提供程序,可能需要通过代码动态添加BouncyCastle,而不是依赖配置文件。最后,提供具体的步骤示例,比如如何修改pom.xml,如何编辑java.security文件,以及如何在SpringBoot中手动注册提供程序。同时,提醒用户注意JDK版本对应的不同解决方法,并建议测试环境验证解决方案的有效性。</think>### 问题分析 Java应用程序启动时出现`JCE cannot authenticate the provider BC`错误,通常是因为Bouncy Castle(BC)加密提供程序未通过JCE(Java Cryptography Extension)的签名验证。在Spring Boot中,这会导致依赖BC的Bean初始化失败,抛出`BeanCreationException`。常见原因包括: 1. BC版本与JDK不兼容(如JDK 17对JCE策略更严格)[^1] 2. BC未正确配置为受信任的提供程序 3. 安全策略文件(如`java.security`)未允许BC的权限 --- ### 解决方案 #### 方法1:更新依赖并显式声明BC版本 在`pom.xml`中强制使用与JDK兼容的BC版本(如1.70+): ```xml <dependency> <groupId.org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> <version>1.76</version> </dependency> ``` 运行`mvn clean install`确保依赖冲突已解决。 #### 方法2:修改JCE安全策略(针对JDK 17) 1. 定位JDK的`java.security`文件(路径示例:`$JAVA_HOME/conf/security/java.security`) 2. 注释或删除以下行以禁用严格验证: ```plaintext # security.provider.1=SUN # security.provider.2=SunRsaSign ``` 3. 添加BC提供程序(示例): ```plaintext security.provider.3=org.bouncycastle.jce.provider.BouncyCastleProvider ``` #### 方法3:手动注册BC提供程序 在Spring Boot启动类中静态注册BC: ```java @SpringBootApplication public class Application { static { Security.addProvider(new BouncyCastleProvider()); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` #### 方法4:调整JVM参数(临时方案) 在启动命令中添加: ```bash -Dorg.bouncycastle.disable.jce.check=true ``` 此参数跳过JCE对BC的签名验证,但需评估安全风险[^1]。 --- ### 验证步骤 1. 检查BC是否成功注册: ```java Provider[] providers = Security.getProviders(); Arrays.stream(providers).filter(p -> p.getName().contains("Bouncy")).findFirst(); ``` 2. 确保无重复BC依赖: ```bash mvn dependency:tree | grep "bouncycastle" ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值