101. Symmetric Tree

本文介绍了一种用于判断二叉树是否为对称树的方法,包括递归和非递归两种实现方式。递归方法通过比较左右子树来确定整个树的对称性,而非递归方法则使用队列进行层次遍历来实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

101.Symmetric Tree

题目描述:
对称树
思路:
递归和非递归两种方法实现,递归要有出口,非递归采用depth-first-search遍历。

1. 递归解法

此解法参考他人。

/**
 * 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 judge(TreeNode *lchild, TreeNode *rchild) {
        if (lchild == 0 || rchild == 0) {
            if (lchild == 0 && rchild == 0)
                return true;
            else 
                return false;
        }
        if (lchild->val != rchild->val)
            return false;
        return judge(lchild->left, rchild->right) && judge(lchild->right, rchild->left);
    }
    bool isSymmetric(TreeNode* root) {
        if (root == 0)
            return true;
        bool res;
        res = judge(root->left, root->right);
        return res;
    }
};

2. 非递归解法

非递归解法。
二叉树层次遍历。

class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if (root == 0)
            return true;
        queue<TreeNode *> left;
        queue<TreeNode *> right;
        left.push(root->left);
        right.push(root->right);
        while (!left.empty() && !right.empty()) {
            TreeNode *node1 = left.front();
            TreeNode *node2 = right.front();
            left.pop();
            right.pop();
            if ((node1 && !node2) || (!node1 && node2))
                return false;
            if (node1 && node2) {
                if (node1->val != node2->val)
                    return false;
                left.push(node1->left);
                left.push(node1->right);
                right.push(node2->right);
                right.push(node2->left);
            }
        }
        return true;
    }
};
执行 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、付费专栏及课程。

余额充值