符号三角形问题(Java)

2023-05-16

符号三角形问题(Java)

文章目录

  • 符号三角形问题(Java)
    • 1、 前置介绍
    • 2、算法设计
    • 3、程序代码
    • 4、算法效率
    • 5、参考资料


在这里插入图片描述


1、 前置介绍

符号三角形定义

如下图所示,符号三角形是由14个“+” 号和14个"-"号组成的符号三角形。两个同号下面都是“+” 号, 两个异号下面都是”-“。

在一般情况下, 符号三角形的第一行有n个符号。符号三角形问题要求对于给定的n, 计算有多少
个不同的符号三角形,使其所含的"+ “和” - "的个数相同。

在这里插入图片描述

2、算法设计

对于符号三角形问题,用n元组X[l:n]表示符号三角形的第一行的n个符号。

x[i]=1 时,表示符号三角形的第一行的第t个符号为“+” ;当x[i]=0时,表示符号三角形的第一行的第t个号为"-"

由于x[i]是2值的, 所以在用回溯法解符号三角形问题时,可以用一棵完全二叉树来表示其解空间。

在符号三角形的第一行的前i个符号x[1:i]确定后, 就确定了一个由i*(i + 1)/2个符号组成的符号三角形。下一步确定x[i+l]的值后,只要在前面已确定的符号三角形的右边加一条边, 就可以扩展为x[1:i+l] 所相应的符号三角形。最终由x[l:n]所确定的符号三角形中包含的“+”个数与"-"个数同为n*(n+l)/4

  • 可行性约束条件

因此在回溯搜索过程中可用当前符号三角形所包含的“+”个数与"-"个数均不超过n*(n+l)/4 作为可行性约束, 用于剪去不满足约束的子树。

对于给定的n, 当n*(n+l)/2 为奇数时, 显然不存在所包含的“+” 个数与"-"个数相同的符号三角形。这种情况可以通过简单的判断加以处理。

3、程序代码

说明:

  • backtrack(level):搜索解空间中第level层子树

  • 主类的数据成员记录解空间中结点信息,以减少传给backtrack 的参数。

  • sum:记录当前已找到的“+”个数与"-"个数相同的符号三角形数。

  • 在算法backtrack中, 当i>n时,算法搜索至叶结点, 得到一个新的"+“个数与”-"个数相同的符号三角形,当前已找到符号三角形数sum增l

  • i<=n时, 当前扩展结点Z是解空间中的内部结点。该结点有x[i]=1 和x[i]=0共两个儿子结点。对当前扩展结点Z的每一个儿子结点, 计算其相应的符号三角形中“+”个数count与"-"个数,并以深度优先的方式递归地对可行子树搜索, 或剪去不可行子树。

public class Solution {

    static int n;           // 第一行符号个数
    static int half;        // n * (n+1) / 4        "+"/"-"符号个数
    static int count;       // 当前"+"个数
    static int[][] p;       // 符号三角形矩阵
    static long sum;        // 已找到的符号三角形数量

    public static void main(String[] args) {
        n = 4;
//        n = 7;
        count = 0;
        sum = 0;
        half = n * (n + 1) / 2;     // 先初始化为符号三角形中的符号总个数

        p = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                p[i][j] = 0;
            }
        }

        System.out.println("不同的符号三角形分别为:");
        compute(n);
        System.out.println("首行" + n + "个符号且符合题目要求的一共有" + sum + "种不同的符号三角形");
//        System.out.println("这" + sum + "种不同的符号三角形分别为:");

    }

    public static long compute(int firstCnt) {
        if (half % 2 == 1) {    // 符号总个数为奇数 不可能出现“+”、“-”个数相等的情况
            return 0;
        }
        half /= 2;             // 符号总个数为偶数   将 half设置为“+”(“-”)的个数
        backtrack(1);
        return sum;
    }

    private static void backtrack(int t) {
        // 当前“+”或者“-”符号个数已经达到n * (n + 1) / 4
        if ((count > half) || (t * (t - 1) / 2 - count > half)) {
            return;
        }
        // TODO 已经构造出一个符合要求的符号三角形,数量加1
        if (t > n) {
            sum++;
            // 打印符号三角形
            for (int i = 1; i <= n; i++) {
                for (int k = 1; k < i; k++) {
                    System.out.print(" ");
                }
                for (int j = 1; j <= n; j++) {
                    if (p[i][j] == 0 && j <= n - i + 1) {
                        System.out.print("+" + " ");
                    } else if (p[i][j] == 1 && j <= n - i + 1) {
                        System.out.print("-" + " ");
                    } else {
                        System.out.print("  ");
                    }
                }
                System.out.println();
            }
            System.out.println("----------------------------------");
        } else {
            // “+”、“-”用 0、1 代替(构造完全二叉树)
            for (int i = 0; i < 2; i++) {
                p[1][t] = i;
                count += i;
                // 上一行种只有大于等于2个符号才可以形成其下一行的一个符号
                for (int j = 2; j <= t; j++) {
                    // TODO 通过异或的方式求其余行数的放置方式
                    p[j][t - j + 1] = p[j - 1][t - j + 1] ^ p[j - 1][t - j + 2];
                    count += p[j][t - j + 1];
                }
                backtrack(t + 1);
                for (int j = 2; j <= t; j++) {
                    count -= p[j][t - j + 1];
                }
                count -= i;
            }
        }
    }
}

运行结果

在这里插入图片描述

4、算法效率

计算可行性约束需要O(n)时间,在最坏情况下有0(2n)个结点需要计算可行性约束,故解符号三角形问题的回溯算法backtrack所需的计算时间为O(n*2n)。

5、参考资料

  • 算法设计与分析(第四版)

结束!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

符号三角形问题(Java) 的相关文章

  • MapReduce报错:「MKDirs failed to create file」

    MapReduce报错 xff1a MKDirs failed to create file 文章目录 MapReduce报错 xff1a MKDirs failed to create file 0 写在前面1 程序代码及报错信息输入 输
  • Hive执行脚本: Return Code 2 from org.apache.hadoop.hive.ql.exec.MapRedTask

    Hive执行脚本 Return Code 2 from org apache hadoop hive ql exec MapRedTask 文章目录 Hive执行脚本 Return Code 2 from org apache hadoop
  • Hive on Tez 的安装配置

    Hive on Tez 的安装配置 文章目录 Hive on Tez 的安装配置0 写在前面1 起源2 Tez概述3 安装部署4 解决日志Jar包冲突 0 写在前面 Hadoop xff1a Hadoop 2 9 2Hive xff1a H
  • 执行Hive查询时出现OOM

    执行Hive查询时出现OOM 文章目录 执行Hive查询时出现OOM写在前面报错 xff1a Error Java heap space实验场景日志信息StckOverFlow的回答 写在前面 Hive执行引擎 xff1a Hive on
  • android 信息(mms)的故事(五)-- 发彩信

    发彩信和发短信一样 xff0c 在ComposeMessageActivity java界面都是从onclick xff08 xff09 sendMessage xff08 xff09 开始 xff0c 同样的发送前检查收件人是否有效 xf
  • flume----HDFS sink 启动时产生大量小文件处理办法

    flume HDFS sink 启动时产生大量小文件处理办法 转载自 xff1a https blog csdn net qq 37714755 article details 113243139 1 问题背景 通过flume直接上传实时数
  • Python3操作MongoDB数据库

    Python3操作MongoDB数据库 文章目录 Python3操作MongoDB数据库0 写在前面1 安装开源驱动库pymongo2 参考 0 写在前面 Linux xff1a Ubuntu Kylin 16 04MongoDB xff1
  • Linux好用的管道命令

    Linux好用的管道命令 文章目录 Linux好用的管道命令1 选取命令grepcut 分割 2 排序命令sortwcuniq 3 划分命令 split4 参数代换xargs5 数据处理工具awk 6 sed工具7 参考 1 选取命令 gr
  • 关于Hadoop集群物理及虚拟内存的检测的设置说明

    关于Hadoop集群物理及虚拟内存的检测的设置说明 文章目录 关于Hadoop集群物理及虚拟内存的检测的设置说明写在前面正文不能关闭对物理内存的检测关闭对虚拟内存的检测 参考 写在前面 Linux xff1a CentOS7 5Java x
  • Arrays.stream().boxed()的使用

    Arrays stream boxed 的使用 文章目录 Arrays stream boxed 的使用0 写在前面1 Arrays stream 的使用算法 xff1a 代码 xff1a 输出结果 xff1a 2 boxed 的使用box
  • Flume中 File Channel 的优化

    Flume中 File Channel 的优化 文章目录 Flume中 File Channel 的优化File Channel 的特点File Channel 的优化索引索引备份 Flume官方优化设计概述 xff08 Overview
  • 数仓采集通道的设计

    数仓采集通道的设计 文章目录 数仓采集通道的设计写在前面方案一 xff1a 方案二 xff1a 方案三 xff1a 最终方案 写在前面 离线和实时数仓共用一套数据采集通道系统数据采集存储到HDFS上完全分布式 xff08 三台节点 xff0
  • Hive命令使用记录

    Hive命令使用记录 文章目录 Hive命令使用记录操作一些常用的Bash Shell 命令 xff1a 操作HDFS 平台相关的命令 xff1a 查看当前使用的数据库创建表的时候通过location 指定数据存储位置 xff0c 加载数据
  • Navicat远程连接Linux的MySQL服务Error10061的解决方案

    Navicat远程连接Linux的MySQL服务Error10061的解决方案 文章目录 Navicat远程连接Linux的MySQL服务Error10061的解决方案写在前面解决方法 写在前面 Linux xff1a Ubuntu Kyl
  • 棋盘覆盖问题(Java)

    棋盘覆盖问题 xff08 Java xff09 文章目录 棋盘覆盖问题 xff08 Java xff09 1 问题描述2 算法设计思路3 代码实现4 复杂度分析5 参考 1 问题描述 在一个2k 2k个方格组成的棋盘中 若恰有一个方格与其他
  • android -- 蓝牙 bluetooth (一) 入门

    前段时间在 网上看了一些关于android蓝牙的文章 xff0c 发现大部分是基于老版本 xff08 4 1以前含4 1 xff09 的源码 xff0c 虽然无碍了解蓝牙的基本原理和工作流程 xff0c 但对着4 2 2的代码看起来总是有些
  • 最优二叉搜索树问题(Java)

    最优二叉搜索树问题 xff08 Java xff09 文章目录 最优二叉搜索树问题 xff08 Java xff09 1 前置介绍2 算法设计思路2 1 最优二叉搜索树的结构2 2 一个递归算法2 3 计算最优二叉搜索树的期望搜索代价 3
  • 大数据量一次性导入MongoDB

    大数据量一次性导入MongoDB 文章目录 大数据量一次性导入MongoDB0 写在前面1 前置芝士2 mongoimport命令导入JSON文件数据失败3 db COLLECTION count 返回值不正确4 数据导入不完全5 参考资料
  • Strassen矩阵乘法问题(Java)

    Strassen矩阵乘法问题 xff08 Java xff09 文章目录 Strassen矩阵乘法问题 xff08 Java xff09 1 前置介绍3 代码实现4 复杂度分析5 参考资料 1 前置介绍 矩阵乘法是线性代数中最常见的问题之一
  • 线性时间选择(Top K)问题(Java)

    线性时间选择 xff08 Top K xff09 问题 xff08 Java xff09 文章目录 线性时间选择 xff08 Top K xff09 问题 xff08 Java xff09 1 前置介绍2 分治法求解3 代码实现4 复杂度分

随机推荐

  • HBase查询一张表的数据条数的方法

    HBase查询一张表的数据条数的方法 文章目录 HBase查询一张表的数据条数的方法0 写在前面1 HBase Shell的count命令2 Scan操作获取数据条数3 执行Mapreduce任务4 Hive与HBase整合5 协处理器Co
  • 校园论坛设计(Java)——介绍篇

    校园论坛设计 xff08 Java xff09 文章目录 校园论坛设计 xff08 Java xff09 0 写在前面1 项目介绍2 项目背景3 项目功能介绍3 1 总体设计图3 2 帖子模块3 3 学习模块3 4 个人信息模块3 5 数据
  • 单源最短路径问题(Java)

    单源最短路径问题 xff08 Java xff09 文章目录 单源最短路径问题 xff08 Java xff09 1 问题描述2 算法思路3 代码实现4 算法正确性和计算复杂性4 1 贪心选择性质4 2 最优子结构性质4 3 计算复杂性 5
  • 回溯法(Java)

    回溯法 xff08 Java xff09 文章目录 回溯法 xff08 Java xff09 1 引言2 回溯法2 1 定义2 2 使用场合2 3 基本做法2 4 具体做法2 5 常见例子 3 比较4 问题的解空间4 1 介绍4 2 解空间
  • 校园论坛(Java)——环境配置篇

    校园论坛 Java 环境配置篇 文章目录 校园论坛 Java 环境配置篇 1 写在前面 2 新建Maven项目 2 1 引入相关依赖 2 2 配置Tomcat环境 3 项目发布测试 4 项目代码 5 参考资料 1 写在前面 Windows版
  • 校园论坛(Java)—— 帖子模块

    校园论坛 Java 帖子模块 文章目录 校园论坛 Java 帖子模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 普通帖子中各层的设计 3 用户浏览普通帖子功能的实现 3 1 帖子发布和查看以及回复功能系统 3
  • android -- 蓝牙 bluetooth (二) 打开蓝牙

    4 2的蓝牙打开流程这一部分还是有些变化的 xff0c 从界面上看蓝牙开关就是设置settings里那个switch开关 xff0c widget开关当然也可以 xff0c 起点不同而已 xff0c 后续的流程是一样的 先来看systemS
  • 校园论坛(Java)—— 登录注册和用户信息模块

    校园论坛 Java 登录注册和用户信息模块 文章目录 校园论坛 Java 登录注册和用户信息模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 登录注册模块各层的设计 3 登录注册模块设计 3 1 用户注册功能 3
  • 校园论坛(Java)—— 考研学习模块

    校园论坛 Java 考研学习模块 文章目录 校园论坛 Java 考研学习模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 登录注册模块各层的设计 3 考研学习模块设计 3 1 浏览和查看帖子 3 2 发表帖子 3
  • 校园论坛(Java)—— 用户管理系统模块

    校园论坛 Java 用户管理系统模块 文章目录 校园论坛 Java 用户管理系统模块 toc 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 用户管理系统模块各层的设计 3 管理员管理用户功能 3 1 管理员查看普通
  • 校园论坛(Java)—— 数据报表模块

    校园论坛 Java 数据报表模块 文章目录 校园论坛 Java 数据报表模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 代码实现 3 数据报表设计 3 1 数据报表主界面的实现 3 2 发表数Top5的普通帖子
  • 校园论坛(Java)—— 校园周边模块

    校园论坛 Java 校园周边模块 文章目录 校园论坛 Java 校园周边模块 1 写在前面 2 系统结构设计 2 1 各个页面之间的调用关系 2 2 校园周边页面设计 3 校园周边模块设计 3 1 校园周边主界面的实现 3 2 增加附近的交
  • 校园论坛(Java)—— 结束篇

    校园论坛 Java 结束篇 文章目录 校园论坛 Java 结束篇 1 写在前面 2 系统总体设计 2 1 设计流程 2 2 各个页面之间的调用关系 3 系统实现的可行性 4 系统制作的局限性 5 总结 6 项目代码 1 写在前面 Windo
  • Windows远程连接Redis(Linux)

    Windows远程连接Redis xff08 Linux xff09 文章目录 Windows远程连接Redis xff08 Linux xff09 1 写在前面2 配置redis conf3 启动Redis3 1 开启redis服务3 2
  • 批量数据导入Neo4j的方式

    批量数据导入Neo4j的方式 文章目录 批量数据导入Neo4j的方式1 写在前面2 前置芝士3 CSV数据导入Neo4j3 1 LOAD CSV Cypher命令3 2 neo4j admin命令3 3 Kettle导入工具 4 数据导入失
  • Neo4j的Java API操作

    Neo4j的Java API操作 文章目录 Neo4j的Java API操作0 写在前面1 前置芝士2 准备工作2 1 为项目引入Neo4j依赖2 2 启动和停止 3 Java操作Neo4j4 参考资料 0 写在前面 Linux版本 xff
  • NoSQL数据库原理与应用综合项目——起始篇

    NoSQL数据库原理与应用综合项目 起始篇 文章目录 NoSQL数据库原理与应用综合项目 起始篇 0 写在前面 1 项目说明 1 1 项目背景 1 2 项目功能 2 数据集和数据预处理 2 1 数据集 2 2 数据预处理 2 2 1 图书出
  • android -- 蓝牙 bluetooth (三)搜索蓝牙

    接上篇打开蓝牙继续 xff0c 来一起看下蓝牙搜索的流程 xff0c 触发蓝牙搜索的条件形式上有两种 xff0c 一是在蓝牙设置界面开启蓝牙会直接开始搜索 xff0c 另一个是先打开蓝牙开关在进入蓝牙设置界面也会触发搜索 xff0c 也可能
  • 单源最短路径问题——分支限界法(Java)

    单源最短路径问题 分支限界法 xff08 Java xff09 文章目录 单源最短路径问题 分支限界法 xff08 Java xff09 1 前置芝士1 1 分支限界法求解目标1 2 分支限界法引言1 3 分支限界法基本思想1 4 两种典型
  • 符号三角形问题(Java)

    符号三角形问题 xff08 Java xff09 文章目录 符号三角形问题 xff08 Java xff09 1 前置介绍2 算法设计3 程序代码4 算法效率5 参考资料 1 前置介绍 符号三角形定义 如下图所示 xff0c 符号三角形是由