40. Combination Sum II -Medium

本文介绍了一种解决组合求和问题的方法,通过回溯算法找到候选数字集合中所有可能的组合,使这些数字之和等于目标值。文章提供了一个具体的示例,并给出了详细的解决方案及代码实现。

Question

Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

给出一个候选数字集合C和目标值T,请你找出所有C中元素相加得到T的组合。(每个元素只能使用一次,且C中有相同元素)

Example

given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8,

A solution set is:

[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

Solution

  • 回溯解。因为元素不能多次使用,所以在回溯过程中,每次从下个元素的索引开始,而又因为C中有相同元素,所以我们需要先对数组进行排序,然后每当遇到第二个相同元素作为起始点时则跳过不做计算

    public class Solution {
        public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            Arrays.sort(candidates);
            List<List<Integer>> res = new ArrayList<>();
            backtracking(candidates, 0, target, res, new ArrayList<>());
            return res;
        }
    
        public void backtracking(int[] candidates, int start, int target, List<List<Integer>> res, List<Integer> temp){
            if(target < 0) return;
            if(target == 0){
                res.add(new ArrayList<>(temp));
                return;
            }
            for(int i = start; i < candidates.length; i++){
                // 如果出现重复元素,第二个元素直接跳过
                if(i > start && candidates[i] == candidates[i - 1]) continue;
                // 仅当当前元素小于目标值时选择
                if(candidates[i] <= target) {
                    temp.add(candidates[i]);
                    // 每次指向下一个元素的索引
                    backtracking(candidates, i + 1, target - candidates[i], res, temp);
                    temp.remove(temp.size() - 1);
                }
            }
        }
    }
分析代码为什么不能够跑起来::;main_window.py 2025-09-22 22:12:01 - core.base_module - INFO - Utils module initialized 2025-09-22 22:12:01 - core.base_module - INFO - Project root: C:\Users\Administrator\Desktop\project 2025-09-22 22:12:01 - core - INFO - 核心模块导入成功 [模块状态] input_analysis.InputAnalysisModule: ✅ 已加载 2025-09-22 22:12:01 - DLT_Analysis - INFO - 主窗口初始化完成 2025-09-22 22:12:01 - InputAnalysis - INFO - 成功导入核心事件中心 2025-09-22 22:12:01 - InputAnalysis - INFO - 模块 input_analysis 已订阅 module_run 事件 2025-09-22 22:12:01 - root - INFO - 输入分析模块初始化完成: input_analysis [模块状态] combination_analysis.CombinationAnalysisModule: ✅ 已加载 2025-09-22 22:12:01 - modules.combination_analysis.combination_analysis - INFO - 组合分析模块初始化完成 [combination_analysis] 2025-09-22 22:12:01 - TrendAnalysis.trend_analysis - INFO - 初始化数据... 2025-09-22 22:12:01 - TrendAnalysis.trend_analysis - INFO - 开始读取文件: F:\超级\历史数据\历史数据.csv [模块状态] trend_analysis.TrendAnalysisModule: ✅ 已加载 [模块状态] number_generation.NumberGenerator: ✅ 已加载 2025-09-22 22:12:02 - TrendAnalysis.trend_analysis - INFO - 数据初始化完成,使用 2701 期数据 2025-09-22 22:12:02 - FollowAnalysisSystem.follow_analysis_engine - INFO - 模块 'follow_analysis_engine' 已订阅 module_run 事件 2025-09-22 22:12:02 - FollowAnalysisSystem.follow_analysis_engine - INFO - 初始化分析器... 2025-09-22 22:12:03 - FollowAnalysisSystem - INFO - 检测到文件编码: GB2312 (置信度: 99.0%) 2025-09-22 22:12:03 - FollowAnalysisSystem - INFO - 成功使用 GB2312 编码加载数据 2025-09-22 22:12:03 - FollowAnalysisSystem - INFO - 数据预处理完成,共 2701 期数据 2025-09-22 22:12:03 - FollowAnalysisSystem - INFO - 初始化分析器,使用 500 期数据 2025-09-22 22:12:03 - FollowAnalysisSystem.follow_analysis_engine - INFO - 分析器初始化完成,使用 2701 期数据 2025-09-22 22:12:03 - FollowAnalysisSystem.follow_analysis_engine - INFO - 模块 'follow_analysis_engine' 已注册,等待指令... 2025-09-22 22:12:03 - FollowAnalysisSystem.follow_analysis_engine - INFO - 数据文件路径: F:\超级\历史数据\历史数据.csv 2025-09-22 22:12:03 - InputAnalysis - INFO - 模块 input_analysis 已订阅 module_run 事件 2025-09-22 22:12:03 - root - INFO - 输入分析模块初始化完成: input_analysis 2025-09-22 22:12:03 - root - INFO - 成功创建模块: input_analysis (外部模块) 2025-09-22 22:12:03 - DLT_Analysis - INFO - 输入分析模块数据加载成功 2025-09-22 22:12:03 - DLT_Analysis - INFO - 收到数据提交 from main_ui: [] [模块状态] follow_analysis.FollowAnalysisModule: ✅ 已加载 2025-09-22 22:12:08 - DLT_Analysis - INFO - 输入分析模块数据加载成功 2025-09-22 22:12:08 - DLT_Analysis - INFO - 收到数据提交 from main_ui: [] 2025-09-22 22:12:10 - DLT_Analysis - INFO - Token已更新: 494e4b45-c80c-48f9-8ec9-df8ae5aed60f 2025-09-22 22:12:10 - root - ERROR - [号码池] 处理模块运行事件失败: 'dict' object has no attribute 'target' 2025-09-22 22:12:10 - root - INFO - 模块 input_analysis 分析执行成功 2025-09-22 22:12:10 - InputAnalysis - INFO - 收到运行指令: module_run 2025-09-22 22:12:10 - modules.number_generation - INFO - 收到运行指令: module_run 2025-09-22 22:12:10 - DLT_Analysis - WARNING - Token不匹配,忽略结果 2025-09-22 22:12:10 - InputAnalysis - INFO - 收到运行指令: module_run 2025-09-22 22:12:10 - InputAnalysis - INFO - 分析完成,结果已发布 2025-09-22 22:12:10 - DLT_Analysis - WARNING - Token不匹配,忽略结果 2025-09-22 22:12:10 - InputAnalysis - INFO - 分析完成,结果已发布 2025-09-22 22:12:12 - modules.combination_analysis.combination_analysis - INFO - 组合分析模块初始化完成 [combination_analysis] 2025-09-22 22:12:12 - root - INFO - 成功创建模块: combination_analysis (外部模块) 2025-09-22 22:12:13 - DLT_Analysis - INFO - Token已更新: bbc353cc-ee39-44f7-a5cc-c48b4e944e36 2025-09-22 22:12:13 - root - ERROR - [号码池] 处理模块运行事件失败: 'dict' object has no attribute 'target' 2025-09-22 22:12:13 - root - ERROR - 处理模块运行事件失败: not enough values to unpack (expected 2, got 1) 2025-09-22 22:12:13 - modules.number_generation - INFO - 收到运行指令: module_run 2025-09-22 22:12:14 - FollowAnalysisSystem.follow_analysis - INFO - 模块 'follow_analysis' 已订阅 module_run 事件 2025-09-22 22:12:14 - FollowAnalysisSystem.follow_analysis - INFO - 初始化分析器... 2025-09-22 22:12:15 - FollowAnalysisSystem - INFO - 检测到文件编码: GB2312 (置信度: 99.0%) 2025-09-22 22:12:15 - FollowAnalysisSystem - INFO - 成功使用 GB2312 编码加载数据 2025-09-22 22:12:15 - FollowAnalysisSystem - INFO - 数据预处理完成,共 2701 期数据 2025-09-22 22:12:15 - FollowAnalysisSystem - INFO - 初始化分析器,使用 500 期数据 2025-09-22 22:12:15 - FollowAnalysisSystem.follow_analysis - INFO - 分析器初始化完成,使用 2701 期数据 2025-09-22 22:12:15 - FollowAnalysisSystem.follow_analysis - INFO - 模块 'follow_analysis' 已注册,等待指令... 2025-09-22 22:12:15 - FollowAnalysisSystem.follow_analysis - INFO - 数据文件路径: F:\超级\历史数据\历史数据.csv 2025-09-22 22:12:15 - root - INFO - 成功创建模块: follow_analysis (外部模块) 2025-09-22 22:12:16 - DLT_Analysis - INFO - Token已更新: 7c6bbeb0-ff4b-408a-b869-770418fad0eb 2025-09-22 22:12:16 - root - ERROR - [号码池] 处理模块运行事件失败: 'dict' object has no attribute 'target' 2025-09-22 22:12:16 - root - WARNING - 模块 follow_analysis 没有可执行的方法 2025-09-22 22:12:16 - modules.number_generation - INFO - 收到运行指令: module_run 2025-09-22 22:12:16 - FollowAnalysisSystem.follow_analysis - INFO - 收到来自 main_ui 的运行指令,token=7c6bbeb0-ff4b-408a-b869-770418fad0eb 2025-09-22 22:12:16 - FollowAnalysisSystem - INFO - 初始化分析器,使用 500 期数据 2025-09-22 22:12:16 - FollowAnalysisSystem - INFO - 跟随分析完成,前区 35 种,后区 12 种跟随关系 2025-09-22 22:12:16 - FollowAnalysisSystem - INFO - 跟随分析完成,前区 35 种,后区 12 种跟随关系 2025-09-22 22:12:17 - FollowAnalysisSystem - INFO - 跟随分析完成,前区 35 种,后区 12 种跟随关系 2025-09-22 22:12:17 - FollowAnalysisSystem - INFO - 跟随分析完成,前区 35 种,后区 12 种跟随关系 2025-09-22 22:12:17 - FollowAnalysisSystem.follow_analysis - INFO - 发送分析结果... 2025-09-22 22:12:17 - DLT_Analysis - WARNING - Token不匹配,忽略结果 2025-09-22 22:12:17 - FollowAnalysisSystem.follow_analysis - INFO - 结果已发送到: main_ui 2025-09-22 22:12:17 - FollowAnalysisSystem.follow_analysis - INFO - 分析完成,结果已发送 2025-09-22 22:12:18 - TrendAnalysis.trend_analysis - INFO - 初始化数据... 2025-09-22 22:12:18 - TrendAnalysis.trend_analysis - INFO - 开始读取文件: F:\超级\历史数据\历史数据.csv 2025-09-22 22:12:18 - TrendAnalysis.trend_analysis - INFO - 数据初始化完成,使用 2701 期数据 2025-09-22 22:12:18 - root - INFO - 成功创建模块: trend_analysis (外部模块) 2025-09-22 22:12:19 - DLT_Analysis - INFO - Token已更新: 16968b10-35ea-4f2e-9f25-3505e1ad4cb8 2025-09-22 22:12:19 - root - ERROR - [号码池] 处理模块运行事件失败: 'dict' object has no attribute 'target' 2025-09-22 22:12:19 - root - ERROR - 处理模块运行事件失败: TrendAnalysisModule.run_analysis() takes 1 positional argument but 2 were given 2025-09-22 22:12:19 - modules.number_generation - INFO - 收到运行指令: module_run 2025-09-22 22:12:21 - root - INFO - 成功创建模块: number_generation (外部模块) 2025-09-22 22:12:22 - DLT_Analysis - INFO - Token已更新: bbb93eb3-6f6b-4916-be3f-32f2d7eca4a0 2025-09-22 22:12:22 - root - ERROR - [号码池] 处理模块运行事件失败: 'dict' object has no attribute 'target' 2025-09-22 22:12:22 - root - WARNING - 模块 number_generation 没有可执行的方法 2025-09-22 22:12:22 - modules.number_generation - INFO - 收到运行指令: module_run 2025-09-22 22:12:22 - modules.number_generation - INFO - 收到运行指令: module_run 进程已结束,退出代码为 0
最新发布
09-24
从你提供的日志信息来看,程序 **看似运行了**(进程没有崩溃,退出码为 0),但实际上存在多个关键错误导致模块无法正常执行功能。我们来逐条分析为什么这个系统“不能跑起来”——即虽然启动成功,但核心逻辑未正确执行。 --- ### 🔍 核心问题分析 #### ❌ 错误1:`'dict' object has no attribute 'target'` ```log 2025-09-22 22:12:10 - root - ERROR - [号码池] 处理模块运行事件失败: 'dict' object has no attribute 'target' ``` 这说明你在某个地方尝试访问一个对象的 `.target` 属性,但传入的是一个字典(`dict`),而不是预期的对象实例或事件对象。 > 常见于事件驱动架构中,比如使用了类似 `Event(target='xxx')` 的类结构,但在实际调用时却传了一个 `{'target': 'xxx'}` 字典。 📌 **原因推测**: - 模块通信通过“事件中心”进行。 - 发送事件时可能误将字典当作事件对象发送,例如: ```python event_center.publish({'target': 'module_run'}) # ❌ 错误!应是 Event 类实例 ``` - 而接收方代码期望的是: ```python if event.target == 'module_run': ... ``` 👉 当 `event` 是 dict 时,它没有 `.target` 属性,只有键 `'target'`,所以抛出异常。 --- #### ❌ 错误2:`not enough values to unpack (expected 2, got 1)` ```log 2025-09-22 22:12:13 - root - ERROR - 处理模块运行事件失败: not enough values to unpack (expected 2, got 1) ``` 这是典型的解包错误,常见于: ```python a, b = some_value # 如果 some_value 只有一个元素就会报错 ``` 📌 **可能场景**: 在处理事件回调注册时,可能是这样写的: ```python for module_name, callback in self.callbacks: ... ``` 但如果 `self.callbacks` 中某一项是单个值而非元组(如 `('input_analysis', func)`),就会炸。 👉 表示事件订阅机制的数据结构不一致,某些模块注册方式错误。 --- #### ❌ 错误3:`TrendAnalysisModule.run_analysis() takes 1 positional argument but 2 were given` ```log 2025-09-22 22:12:19 - root - ERROR - 处理模块运行事件失败: TrendAnalysisModule.run_analysis() takes 1 positional argument but 2 were given ``` 这是 Python 面向对象的经典错误。 📌 **原因**: 你定义的方法缺少 `self` 参数,或者调用方式错误。 ✅ 正确写法应该是: ```python class TrendAnalysisModule: def run_analysis(self): # 必须有 self ... ``` ❌ 错误写法: ```python class TrendAnalysisModule: def run_analysis(): # 没有 self ... ``` 当你用 `instance.run_analysis()` 调用时,Python 实际上传了 `self` 作为第一个参数,变成 `run_analysis(instance)`,而函数没声明参数 → 报错:“多给了一个参数”。 --- #### ⚠️ 警告:模块没有可执行方法 ```log WARNING - 模块 follow_analysis 没有可执行的方法 WARNING - 模块 number_generation 没有可执行的方法 ``` 这说明这些模块被加载了,但没有实现 `.run()` 或 `.execute()` 这样的入口方法,导致事件来了也无法执行。 👉 架构设计上要求所有模块必须提供统一执行接口,否则调度器不知道怎么运行它们。 --- #### 🔄 Token 不匹配,结果被忽略 ```log DLT_Analysis - WARNING - Token不匹配,忽略结果 ``` 说明主控模块(`DLT_Analysis`)和子模块之间使用 token 同步任务批次,但由于并发或延迟响应,token 已更新,旧的结果被丢弃。 👉 这意味着: - 子模块处理太慢; - 或者事件广播/监听不同步; - 或 token 管理机制有问题(全局共享?线程安全?) --- #### ✅ 日志显示部分模块初始化成功 - 所有模块都显示 `[模块状态] xxx: ✅ 已加载` - 数据文件读取成功(GB2312 编码) - 分析完成、结果发布等日志也出现 ➡️ 所以程序能“启动”,但 **不能“运行”** —— 即初始化 OK,执行失败。 --- ## ✅ 解决方案与修复建议 ### ✅ 修复1:确保事件对象是类实例而非字典 假设你有一个事件系统: ```python # events.py class ModuleEvent: def __init__(self, target, data=None): self.target = target self.data = data ``` 发送事件时: ```python # 正确 ✅ event_center.publish(ModuleEvent(target="module_run", data={})) ``` 不要这样做 ❌: ```python event_center.publish({"target": "module_run"}) # dict 没有 .target 属性 ``` 接收端才能安全使用: ```python def on_event(event): if event.target == "module_run": ... ``` --- ### ✅ 修复2:检查解包逻辑,避免 `a, b = x` 查找类似代码: ```python for item in callback_list: name, func = item # 可能 item 是字符串或单元素 tuple ``` 改为更安全的方式: ```python for item in callback_list: if isinstance(item, tuple) and len(item) == 2: name, func = item else: continue ``` 或者统一注册格式: ```python callbacks.append(('module_name', callback_func)) ``` --- ### ✅ 修复3:为模块方法添加 `self` 确保每个模块的运行方法都有 `self`: ```python # trend_analysis/trend_analysis.py class TrendAnalysisModule: def run_analysis(self): # 注意 self logger.info("开始趋势分析...") # ...分析逻辑... return result ``` 如果要用函数式风格,可以封装一层: ```python def create_module(): def run(): pass return type('TrendAnalysisModule', (), {'run_analysis': run})() ``` 但推荐标准 OOP 写法。 --- ### ✅ 修复4:为所有模块实现统一执行接口 约定所有模块必须实现 `.run()` 方法: ```python class NumberGenerator: def run(self): # 统一入口 logger.info("生成号码...") ``` 主控模块调用: ```python if hasattr(module, 'run') and callable(getattr(module, 'run')): module.run() else: logger.warning(f"模块 {name} 没有可执行的方法") ``` --- ### ✅ 修复5:同步 Token 机制 考虑引入任务 ID + 回调机制,而不是依赖全局 token 匹配。 例如: ```python task_id = str(uuid.uuid4()) event_center.publish(ModuleEvent("module_run", task_id=task_id)) # 子模块返回时带上 task_id result_event = ResultEvent(module="trend_analysis", data=result, task_id=task_id) ``` 主控只接受对应 task_id 的结果。 --- ### ✅ 示例修复代码片段(事件系统) ```python # core/event_center.py import logging from typing import Callable, Any logger = logging.getLogger(__name__) class Event: def __init__(self, target: str, **kwargs): self.target = target for k, v in kwargs.items(): setattr(self, k, v) class EventCenter: def __init__(self): self._listeners = {} def subscribe(self, event_type: str, listener: Callable): if event_type not in self._listeners: self._listeners[event_type] = [] self._listeners[event_type].append(listener) def publish(self, event: Event): if event.target in self._listeners: for listener in self._listeners[event.target]: try: listener(event) except Exception as e: logger.error(f"处理事件失败: {e}", exc_info=True) else: logger.debug(f"无监听者处理事件: {event.target}") ``` 使用方式: ```python ec = EventCenter() def on_run(event): print(f"收到指令: {event.target}") ec.subscribe("module_run", on_run) ec.publish(Event("module_run", token="abc")) ``` --- ## ✅ 总结:为什么不能跑起来? | 问题 | 原因 | 修复方案 | |------|------|---------| | `'dict' object has no attribute 'target'` | 事件传的是 dict 而非对象 | 使用 `Event` 类封装事件 | | `not enough values to unpack` | 注册回调结构不一致 | 统一 `(name, func)` 元组格式 | | `takes 1 argument but 2 given` | 方法缺 `self` | 添加 `self` 参数 | | “没有可执行方法” | 模块缺少 `.run()` | 实现统一执行接口 | | “Token不匹配” | 异步结果过期 | 改用 task_id + 回调 | --- ##
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值