474.Ones and Zeroes

本文针对LeetCode上的474题 Ones and Zeroes 提供了解题思路及Java实现代码。该问题属于0-1背包问题的变种,通过动态规划的方法求解在给定0和1数量限制下能组成的最大字符串数量。

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

474.Ones and Zeroes

  • 题目描述:In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.

    For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there is an array with strings consisting of only 0s and 1s.

    Now your task is to find the maximum number of strings that you can form with given m 0s and n 1s. Each 0 and 1 can be used at most once.

    Note:

    1. The given numbers of 0s and 1s will both not exceed 100
    2. The size of given string array won’t exceed 600.
  • Example 1:

    Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3
    Output: 4
    
    Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0
  • Example 2:

    Input: Array = {"10", "0", "1"}, m = 1, n = 1
    Output: 2
    
    Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1".
  • 题目大意:给定一个只包含0与1的字符数组array,给定m表述0最多出现的次数,给定n表示1最多出现的次数,问在给定的m与n的范围内,可以从array中选出的最多字符的个数。

  • 思路:DP,0,1背包的变种,dp[i][j]表示m为i,n为j能找出的最多字符串的个数。

  • 代码

    package DP;
    
    /**
    * @author OovEver
    * 2017/12/25 9:59
    */
    public class LeetCode474 {
      public int findMaxForm(String[] strs, int m, int n) {
          int[][] dp = new int[m + 1][n + 1];
          for (String s : strs) {
              int[] count = count(s);
              for(int i=m;i>=count[0];i--) {
                  for(int j=n;j>=count[1];j--) {
                      dp[i][j] = Math.max(dp[i][j], 1 + dp[i - count[0]][j - count[1]]);
                  }
              }
          }
          return dp[m][n];
      }
    
      /**
       * 统计s中0与1的数量
       * @param s 要统计的字符串
       * @return 字符串中0与1的数量
       */
      private int[] count(String s) {
          int[] res = new int[2];
          for(int i=0;i<s.length();i++) {
              res[s.charAt(i) - '0']++;
          }
          return res;
      }
    }
    
<think>嗯,用户这次的问题是关于`ap_per_class`函数的第一个参数是否有问题。根据用户提供的代码片段,第一个参数是`np.concatenate((np.ones((len(pred_boxes), 1)), np.zeros((len(pred_boxes), 1))), axis=1)`。我需要仔细分析这个参数的结构和用途,判断是否存在问题。 首先,回忆一下目标检测评估中常用的指标计算,特别是AP(平均精度)的计算。通常,计算AP需要真实标签和预测结果的匹配情况,特别是需要知道每个预测框是否为真正例(True Positive,TP)或假正例(False Positive,FP)。在常见的实现中,比如YOLO或其他目标检测框架,`ap_per_class`函数的第一个参数应该是TP和FP的组合数组,通常是一个二维数组,其中每行代表一个预测框,第一列是TP标志(1表示TP,0表示FP),第二列是FP标志(可能相反)。但用户这里的代码却将两列分别设置为全1和全0,这显然有问题,因为这意味着所有的预测框都被标记为TP,而FP全部为0,这在实际情况中是不可能的。 接下来,分析这个参数的结构。`np.ones((len(pred_boxes), 1))`生成一个形状为(N,1)的全1数组,而`np.zeros((len(pred_boxes), 1))`生成同样形状的全0数组,然后用`np.concatenate`在axis=1方向拼接,得到一个形状为(N,2)的数组,其中第一列全1,第二列全0。这样构造的数组是否合理呢? 在正确的实现中,TP和FP应该是互斥的,即每个预测框只能是TP或FP中的一种,因此每行应该有一个1,另一个为0。例如,如果第一个元素是TP,则第二个元素是FP,或者反过来。但用户这里的代码将所有预测框都标记为TP,同时FP全为0,这显然不符合实际情况,因为不可能所有的预测都是正确的。这会导致计算出的精确度和召回率异常高,评估结果不可信。 进一步考虑,用户可能误解了`ap_per_class`函数的参数要求。正确的参数应该是根据预测框与真实框的匹配结果生成的TP/FP数组。例如,在YOLOv5的实现中,通常会通过计算IoU来判定每个预测框是否为TP,然后生成相应的标志数组。因此,用户这里的构造方式显然有问题,应该根据实际的匹配结果来生成正确的TP/FP数组,而不是简单地用全1和全0填充。 另外,检查其他参数是否正确。`pred_confs`是预测的置信度,`pred_clses`是预测的类别,`true_boxes_cls`是真实框的类别。这些参数看起来是合理的,但第一个参数的构造错误会影响整个计算结果。 总结,用户的问题在于错误地构造了`ap_per_class`的第一个参数,导致TP和FP的标志不正确,进而影响AP的计算结果。需要修正这个参数的正确生成方式,基于预测框与真实框的实际匹配情况来确定每个预测框是TP还是FP。</think>在目标检测评估中,`ap_per_class` 函数的第一个参数存在问题。以下是具体解析: --- ### **1. 问题定位** 你提供的代码片段中,第一个参数的构造方式为: ```python np.concatenate( (np.ones((len(pred_boxes), 1)), np.zeros((len(pred_boxes), 1))), axis=1 ) ``` 这会生成一个形状为 `(N, 2)` 的二维数组,其中: - 第一列全为 `1`(表示所有预测框都是 True Positive,TP) - 第二列全为 `0`(表示所有预测框都不是 False Positive,FP) **这是错误的**,因为实际场景中不可能所有预测框都是正确匹配的(TP)。 --- ### **2. 参数的正确含义** `ap_per_class` 的第一个参数应为 **TP/FP 标志矩阵**,其结构应为: - 每行对应一个预测框 - 第一列表示是否为 TP(1=是,0=否) - 第二列表示是否为 FP(1=是,0=否) **正确构造逻辑**: 根据预测框与真实框的 IoU(交并比)进行匹配: - 若 IoU ≥ 阈值且类别正确 → 标记为 TP(第一列=1,第二列=0) - 若 IoU < 阈值或类别错误 → 标记为 FP(第一列=0,第二列=1) --- ### **3. 错误后果** - **全 TP 的假设**:所有预测框都被视为正确检测,导致 **精度虚高(Precision=100%)** - **无 FP 的假设**:召回率(Recall)计算也会失真,因为分母(真实框总数)与分子(TP数)均异常 --- ### **4. 正确实现方法** 需基于 **预测框与真实框的实际匹配结果** 动态生成 TP/FP 矩阵。例如: ```python # 伪代码:根据 IoU 和类别匹配生成 tp_fp_matrix tp = [] # 存储每个预测框是否为 TP fp = [] # 存储每个预测框是否为 FP for pred_box in pred_boxes: matched = False for true_box in true_boxes: if calculate_iou(pred_box, true_box) >= iou_threshold and pred_cls == true_cls: tp.append(1) fp.append(0) matched = True break if not matched: tp.append(0) fp.append(1) tp_fp_matrix = np.column_stack((tp, fp)) # 正确的第一个参数 ``` --- ### **5. 验证示例** 假设: - `pred_boxes` 有 3 个预测框 - 其中 1 个匹配到真实框(TP),2 个未匹配(FP) 正确的第一个参数应为: ``` [[1, 0], # TP [0, 1], # FP [0, 1]] # FP ``` --- ### **6. 总结** - **错误原因**:手动填充全 TP 和全 FP,未基于实际匹配结果。 - **修复方法**:根据 IoU 和类别匹配动态生成 TP/FP 矩阵。 - **影响指标**:AP、Precision、Recall 等关键评估指标均会因错误参数失真。 建议参考目标检测框架(如 YOLO、MMDetection)中的匹配逻辑实现 TP/FP 矩阵生成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值