计算2d子数组中True的数量

如何解决计算2d子数组中True的数量

给出2d布尔数组

{{false,false,true,false,true}

{true,false,true,false,false}

{false,true,false,false,false}

{假,假,假,假,假}

{true,true,true,true,true}}

您不能直接访问该数组,它必须通过现成的函数hasTrue 来获取上述2d Array的subArray的起点和终点,如果返回则返回一个布尔值此子数组至少具有1个真

boolean hasTrue(int startX,int startY,int endX,int endY)

例如,如果我们要检查从索引(0,0)到(1,1)的区域,我们将调用hasTrue(0,1,1),并且从索引(1,0开始,它将返回true )的值为true。 我们可以给它一个起点。例如,hasOnes(0,0)只会检查数组中包含值false并返回false的单个索引。

我需要实现一个计算给定子数组中True数量的函数,并且必须使用hasTrue函数

int countTrues(int startX,int endY)

一种解决方案是从起始索引到末尾进行蛮力计算,并计算具有true的索引的数量。但在最佳情况下,复杂度为n * m。

我正在考虑的另一种解决方案是实现一个递归函数,该函数立即将整个subArray传递给hasOnes(),如果整个subArray返回false,那么我就不需要遍历所有索引,我只需返回0,最好的情况是O(1)。

如果返回True,我将拆分数组并检查每半,并继续这样做并计算True的数量。 我需要实施第二种解决方案的帮助

解决方法

我会以忘记Java的身份编写C ++代码(对不起),但仍然可以为您提供帮助。当然,转换为Java并不困难。它实现了递归地分成两半的想法,实际上它分为四个几乎相等的象限(子矩形)。

>>> [el.get_attribute('innerHTML') for el in wd.find_elements_by_css_selector(".bt__media__content b")]
,

countTrues函数可以使用递归来实现,基本上,您首先将数组水平分成两半,当剩下的行不多时,将数组垂直分成两半,这很容易理解:

int countTrues(int startX,int startY,int endX,int endY) {
        if (!hasTrue(startX,startY,endX,endY)) return 0;

        if (startX < endX) {
            //split horizontally
            return countTrues(startX,(startX + endX) / 2,endY) +
                    countTrues((startX + endX) / 2 + 1,endY);
        } else if (startY < endY) {
            //split vertically
            return countTrues(startX,(startY + endY) / 2) +
                    countTrues(startX,(startY + endY) / 2 + 1,endY);
        }

        //only one value left and is true
        return 1;

    }

这是一个完整的解决方案:


public class Main {

    static boolean array[][] =
            {{false,false,true,true},{true,false},{false,true}};

    public static void main(String[] args) {

        int rowLen = array.length,colLen = array[0].length;

        int res = countTrues(0,rowLen - 1,colLen - 1);

        System.out.println("number of Trues: " + res);

    }


    static boolean hasTrue(int startX,int endY) {
        while (startX <= endX) {
            int indexY = startY;
            while (indexY <= endY) {
                if (array[startX][indexY]) return true;
                indexY++;
            }
            startX++;
        }
        return false;
    }


    static int countTrues(int startX,endY);
        }

        //only one value left and is true
        return 1;

    }

}

,

为了以最有效的方式解决此问题,我们必须考虑到hasTrue返回true时,我们不知道有多少true存在;但是,当它返回false时,我们知道可以丢弃整个区域,因为它的计数(以及任何子区域的计数)始终为0。因此,我们应该在最大区域上以hasTrue开始,如果它返回true ,然后分裂并继续;如果返回false,我们可以丢弃整个区域。递归实现:

int countTrues(int startX,int endY) {
  int count = 0;
  if (endX >= startX && endY >= startY) {
    int midX = (endX + startX) / 2;
    int midY = (endY + startY) / 2;
    // top-left
    if (hasTrue(startX,midX,midY)) {
      count += countTrues(startX,midY);
    }
    // top-right
    if (hasTrue(midX + 1,midY)) {
      count += countTrues(midX + 1,midY);
    }
    // bottom-left
    if (hasTrue(startX,midY + 1,endY)) {
      count += countTrues(startX,endY);
    }
    // bottom-right
    if (hasTrue(midX + 1,endY)) {
      count += countTrues(midX + 1,endY);
    }
  }
  return count;
}

此实现中的重要元素是仅当hasTrue在特定子区域上返回true时,才对countTrues进行递归调用。没有这一点,递归实现并不比暴力迭代实现更好。

,

由于你不能直接访问数组,而只能通过一个hasTrue方法,你可以使用半除法构建递归countTrues方法> 方法。您可以使用 IntStream 进行迭代:

static boolean[][] arr = {
        {false,true}};
static boolean hasTrue(int startX,int endY) {
    // invalid syntax
    if (startX > endX || startY > endY)
        return false;

    return IntStream
            // iterate over specified
            // range of the rows
            .rangeClosed(startX,endX)
            // get row by index
            // Stream<boolean[]>
            .mapToObj(i -> arr[i])
            // at least one true in any row
            .anyMatch(row -> IntStream
                    // iterate over specified
                    // range of the elements
                    .rangeClosed(startY,endY)
                    // at least one true in the row
                    .anyMatch(j -> row[j]));
}
static int countTrues(int startX,int endY) {
    // no trues on this iteration
    if (!hasTrue(startX,endY))
        return 0;

    // recursive calls
    int lengthX = endX - startX;
    int lengthY = endY - startY;
    int middleX = lengthX / 2;
    int middleY = lengthY / 2;
    if (lengthX > 0 || lengthY > 0)
        return IntStream
                // if 'lengthX > 0' then two iterations X:
                // from beginning to middle and from
                // middle to end,otherwise one iteration
                .rangeClosed(0,lengthX > 0 ? 1 : 0)
                .map(i -> i == 0 ? 0 : middleX + 1)
                .map(i -> IntStream
                        // if 'lengthY > 0' then two iterations Y:
                        // from beginning to middle and from
                        // middle to end,otherwise one iteration
                        .rangeClosed(0,lengthY > 0 ? 1 : 0)
                        .map(j -> j == 0 ? 0 : middleY + 1)
                        // recursive calls,if it is necessary for
                        // top-left,top-right,bottom-left,bottom-right
                        .map(j -> countTrues(startX + i,startY + j,i == 0 ? startX + middleX : endX,j == 0 ? startY + middleY : endY))
                        .sum())
                .sum();

    // if it reached this point,this point is true
    return 1;
}
public static void main(String[] args) {
    System.out.println(hasTrue(1,1,3,3)); // true
    System.out.println(countTrues(1,3)); // 2
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-