华为OD机考算法题:字符串划分

news2024/9/25 15:26:11

题目部分

题目字符串划分
难度
题目说明给定一个小写字母组成的字符串s,请找出字符串中两个不同位置的字符作为分割点,使得字符串分成的三个连续子串且子串权重相等,注意子串不包含分割点。
若能找到满足条件的两个分割点,请输出这两个分割点在字符串中的位置下标,若不能找到满足条件的分割点请返回0,0。
子串权重计算方式为:子串所有字符的ASCII码数值之和。
输入描述输入为一个字符串,字符串由 a ~ z,26 个小写字符组成,5 ≤ 字符串长度 ≤ 200。
输出描述输出为两个分割点在字符串中的位置下标,以逗号分隔。
补充说明补充说明只考虑唯一解,不存在一个输入多种输出解的情况。
------------------------------------------------------
示例
示例1
输入acdbbbca
输出2,5
说明以位置 2 和 5 作为分割点,将字符串分割为 ac、bb、ca 三个子串,每一个的子串权重都为 196,输出为 2,5。
示例2
输入abcabc
输出0,0
说明找不到符合条件的分割点,输出为0,0。


解读与分析

题目解读

给定一个字符串,以字符串中的 2 个字符为分隔符,把它分成 3 个子字符串(不包含 2 个分隔符),使字符串中所有字符的 ASCII 码之和相等。输出这 2 个分隔符的下标,用 “,” 隔开,如果不存在,输出 “0,0”。

此题要么存在唯一解,要么不存在解。

分析与思路

此题字符串的长度不超过 200 个,比较简单的思路是尝试这 2 个分隔符是所有下标的情况,判断每种情况下所分隔出 3 个字符串的 ASCII 码之和是否相等。

这种方法的时间复杂度为 O(n^{2}),空间复杂度为 O(n^{2})。

以上方法可行,不过我们还有性能更好的方法。

先计算字符串中所有字符的 ASCII 码之和(设为 asciiSum),与此同时,找出可以作为分隔符的字母的最大和最小 ASCII 码值(分别设为 minAscii 和 maxAscii)。

分隔后设三个字符串的 ASCII 码之和的最大值为 maxAsciiSum,则 maxAsciiSum 值为 asciiSum - minAscii * 2;设ASCII 码之和的最小值为 minAsciiSum,则 minAsciiSum 值为 asciiSum - maxAscii * 2。

分隔后,每个字符串ASCII 码之和的取值范围为 [ minAsciiSum / 3,  maxAsciiSum / 3 ]。

顺序遍历字符串,找到第一个子字符串 ASCII 码之和在取值范围内时,第一个分隔符的所有可能下标。
倒序遍历字符串,找到第三个子字符串 ASCII 码之和在取值范围内时,第二个分隔符的所有可能下标。

根据第一个分隔符和第二个分隔符的所有下标组合,判断是否三个字符串 ASCII 码之和是否相等。如果相等,则输出这两个分隔符的下标;否则,输出 “0,0”。

此方法的时间复杂度为 O(n),空间复杂度为 O(n)。


代码实现

Java代码

import java.util.Scanner;

/**
 * 字符串划分
 * @since 2023.10.10
 * @version 0.1
 * @author Frank
 *
 */
public class StringDivision {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String input = sc.nextLine();
			processStringDivision( input );
		}
	}

	private static void processStringDivision( String input )
	{
		int asciiSum = 0;
		
		int minAscii = 'z'; // min初始化成最大值
		int maxAscii = 'a'; // max初始化成最小值
		
		for( int i = 0; i < input.length(); i ++ )
		{
			char curChar = input.charAt( i );
			asciiSum += curChar;
			if( i > 0 && i < input.length() -1 )
			{
				if( curChar < minAscii )
				{
					minAscii = curChar;
				}
				if( curChar > maxAscii )
				{
					maxAscii = curChar;
				}
			}
		}
		
		int eachMinSum = ( asciiSum - maxAscii * 2 ) / 3;
		int eachMaxSum =  ( asciiSum - minAscii * 2 ) / 3 + 1; // 向上取整,避免漏掉一些情况
		
		int leftIndex = 0;		
		int leftSum = 0;
		for( int i = 0; i < input.length() - 2; i ++ )
		{
			int curChar = input.charAt( i );
			leftSum += curChar;
			leftIndex ++;
			
			if( leftSum >= eachMinSum )
			{
				break;
			}
		}			
			
		int rightIndex = input.length() - 1;
		int rightSum = 0;
		for( int i = input.length() - 1; i > 2; i -- )
		{
			int curChar = input.charAt( i );
			rightSum += curChar;
			rightIndex --;
			if( rightSum >= eachMinSum )
			{
				break;
			}
		}
		
		while( leftSum <= eachMaxSum && rightSum <= eachMaxSum && leftIndex < rightIndex )
		{
			if( leftSum < rightSum )
			{
				int curChar = input.charAt( leftIndex );
				if( leftSum + curChar >= eachMaxSum )
				{
					break;
				}
				leftSum += curChar;
				leftIndex ++;
			}
			if( leftSum > rightSum )
			{
				int curChar = input.charAt( rightIndex );
				if( rightSum + curChar >= eachMaxSum )
				{
					break;
				}
				rightSum += curChar;
				rightIndex --;
			}
			
			if( leftIndex >= rightIndex )
			{
				break;
			}
			
			// 相等的情况
			int theOtherSum = asciiSum - leftSum - rightSum - input.charAt( leftIndex ) - input.charAt( rightIndex );
			if( theOtherSum == leftSum )
			{
				System.out.println( leftIndex + "," + rightIndex);
				return;
			}
			
			// 如果 theOtherSum 不相等,继续
			int curChar = input.charAt( leftIndex );
			if( leftSum + curChar >= eachMaxSum )
			{
				break;
			}
			leftSum += curChar;
			leftIndex ++;
			
			curChar = input.charAt( rightIndex );
			if( rightSum + curChar >= eachMaxSum )
			{
				break;
			}
			rightSum += curChar;
			rightIndex --;			
		}
		System.out.println( "0,0" );
	}
}

JavaScript代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    while (line = await readline()) {
        processStringDivision(line);
    }
}();

function processStringDivision( input ) {
        var asciiSum = 0;
        
        var minAscii = 'z'.charCodeAt(); // min初始化成最大值
        var maxAscii = 'a'.charCodeAt(); // max初始化成最小值
        
        for( var i = 0; i < input.length; i ++ )
        {
            var curChar = input.charCodeAt( i );
            asciiSum += curChar;
            if( i > 0 && i < input.length -1 )
            {
                if( curChar < minAscii )
                {
                    minAscii = curChar;
                }
                if( curChar > maxAscii )
                {
                    maxAscii = curChar;
                }
            }
        }
        
        var eachMinSum = ( asciiSum - maxAscii * 2 ) / 3;
        var eachMaxSum =  ( asciiSum - minAscii * 2 ) / 3 + 1; // 向上取整,避免漏掉一些情况
        
        var leftIndex = 0;      
        var leftSum = 0;
        for( var i = 0; i < input.length - 2; i ++ )
        {
            var curChar = input.charCodeAt( i );
            leftSum += curChar;
            leftIndex ++;
            
            if( leftSum >= eachMinSum )
            {
                break;
            }
        }           
            
        var rightIndex = input.length - 1;
        var rightSum = 0;
        for( var i = input.length - 1; i > 2; i -- )
        {
            var curChar = input.charCodeAt( i );
            rightSum += curChar;
            rightIndex --;
            if( rightSum >= eachMinSum )
            {
                break;
            }
        }
        
        while( leftSum <= eachMaxSum && rightSum <= eachMaxSum && leftIndex < rightIndex )
        {
            if( leftSum < rightSum )
            {
                var curChar = input.charCodeAt( leftIndex );
                if( leftSum + curChar >= eachMaxSum )
                {
                    break;
                }
                leftSum += curChar;
                leftIndex ++;
            }
            if( leftSum > rightSum )
            {
                var curChar = input.charCodeAt( rightIndex );
                if( rightSum + curChar >= eachMaxSum )
                {
                    break;
                }
                rightSum += curChar;
                rightIndex --;
            }
            
            if( leftIndex >= rightIndex )
            {
                break;
            }
            
            // 相等的情况
            var theOtherSum = asciiSum - leftSum - rightSum - input.charCodeAt( leftIndex ) - input.charCodeAt( rightIndex );
            if( theOtherSum == leftSum )
            {
                console.log( leftIndex + "," + rightIndex);
                return;
            }
            
            // 如果 theOtherSum 不相等,继续
            var curChar = input.charCodeAt( leftIndex );
            if( leftSum + curChar >= eachMaxSum )
            {
                break;
            }
            leftSum += curChar;
            leftIndex ++;
            
            curChar = input.charCodeAt( rightIndex );
            if( rightSum + curChar >= eachMaxSum )
            {
                break;
            }
            rightSum += curChar;
            rightIndex --;          
        }
        console.log( "0,0" );
}

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1079072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bert----学习笔记

一个简单基础模板&#xff1a; bert导入&#xff0c;分词&#xff0c;编码 from transformers import BertConfig, BertTokenizer, BertModel import torch from transformers import BertModel, BertTokenizer # 指定模型文件夹路径&#xff08;包含 pytorch_model.bin&#…

面面俱到:揭秘吃鸡新手最关心的要领和细节,全方位指引你成为绝地求生高手!

你是否正在探索绝地求生的神秘世界&#xff0c;却感到迷茫和困惑&#xff1f;想要掌握吃鸡的要领和细节&#xff0c;成为一名顶尖玩家吗&#xff1f;现在&#xff0c;我们将为你揭秘吃鸡新手最关心的要领和细节&#xff0c;带你全面了解这个充满挑战的游戏。无论是如何选择起跳…

摆脱繁杂工作:Appwrite 带你高效开发 | 开源日报 No.50

TheAlgorithms/Java Stars: 53.8k License: MIT 这个项目是一个用 Java 实现的算法集合&#xff0c;旨在提供学习目的。它包含了各种不同类型的算法&#xff0c;并且可以通过 Gitpod.io 进行运行、编辑和贡献。该项目具有以下核心优势&#xff1a; 提供了大量常见算法及其实…

澳大利亚教育部宣布ChatGPT将被允许在澳学校使用!

教育部长最近宣布&#xff0c;从 2024 年起&#xff0c;包括 ChatGPT 在内的人工智能将被允许在所有澳大利亚学校使用。 &#xff08;图片来源&#xff1a;卫报&#xff09; 而早些时候&#xff0c;澳洲各高校就已经在寻找与Chatgpt之间的平衡了。 之前&#xff0c;悉尼大学就…

微服务10-Sentinel中的隔离和降级

文章目录 降级和隔离1.Feign整合Sentinel来完成降级1.2总结 2.线程隔离两种实现方式的区别3.线程隔离中的舱壁模式3.2总结 4.熔断降级5.熔断策略&#xff08;根据异常比例或者异常数&#xff09; 回顾 我们的限流——>目的&#xff1a;在并发请求的情况下服务出现故障&…

2023年软考网工上半年下午真题

试题一&#xff1a; 阅读以下说明&#xff0c;回答问题1至问题4&#xff0c;将解答填入答题纸对应的解答栏内。 [说明] 某企业办公楼网络拓扑如图1-1所示。该网络中交换机Switch1-Switch 4均是二层设备&#xff0c;分布在办公楼的各层&#xff0c;上联采用干兆光纤。核心交换…

前端 vite+vue3——写一个随机抽奖组件

文章目录 ⭐前言⭐设计布局⭐交互设计⭐整体代码⭐insicode代码 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于前端 vitevue3——写一个抽奖随机组件。 vue3系列相关文章&#xff1a; 前端vue2、vue3去掉url路由“ # ”号——nginx配置 csdn新星计…

FHRP首跳冗余的解析

首跳冗余的解析 个人简介 HSRP hot standby router protocol 热备份路由协议 思科设备上 HSRP VRRP 华为设备上 VRRP HSRP v1 version 1 HSRP v2 version 2 虚拟一个HSRP虚拟IP地址 192.168.1.1 开启HSRP的抢占功能 通过其他参数 人为调整谁是主 谁是从 &a…

入门C++程序员需要怎么下手?

前言 众所周知&#xff0c;C是一种非常流行的编程语言&#xff0c;它广泛应用于计算机科学和软件开发中&#xff0c;无论是计算机专业的学生还是自学编程的程序员&#xff0c;学习C都是一个必备的技能。那么&#xff0c;如果想成为一名C程序员&#xff0c;学习C需要多久才能入门…

Vuex获取、修改参数值及异步数据处理

14天阅读挑战赛 学不可以已... 目录 一、Vuex简介 1.1 vuex介绍 1.2 vuex核心 二、Vuex使用 2.1 Vuex安装 2.2 创建store模块 2.3 创建vuex的store实例并注册上面引入的各大模块 三、使用Vuex获取、修改值案例 3.1 创建两个菜单组件 3.2 配置路由 3.3 模拟菜单数据 …

设计模式 - 行为型模式考点篇:迭代器模式(概述 | 案例实现 | 优缺点 | 使用场景)

目录 一、行为型模式 一句话概括行为型模式 1.1、迭代器模式 1.1.1、概述 1.1.2、案例实现 1.1.3、优缺点 1.1.4、使用场景 一、行为型模式 一句话概括行为型模式 行为型模式&#xff1a;类或对象间如何交互、如何划分职责&#xff0c;从而更好的完成任务. 1.1、迭代器…

ruoyi 若依 前端vue npm install 运行vue前端

首次导入&#xff0c;需要先执行 npm install #进入到前端模块目录下 cd ruoyi-ui # 安装 npm install 启动后端项目 运行前端项目&#xff1a;运行成功后&#xff0c;会浏览器自动加载到前端首页&#xff08;或者 浏览器访问打印的两个地址&#xff09; # 运行 npm run dev 部…

[sqoop]hive导入mysql,其中mysql的列存在默认值列

一、思路 直接在hive表中去掉有默认值的了列&#xff0c;在sqoop导入时,指定非默认值列即可&#xff0c; 二、具体 mysql的表 hive的表 create table dwd.dwd_hk_rcp_literature(id string,literature_no string,authors string,article_title string,source_title string…

【MySql】6- 实践篇(四)

文章目录 1. 为何SQL语句逻辑相同&#xff0c;性能却差异巨大1.1 性能差异大的SQL语句问题1.1.1 案例一:条件字段函数操作1.1.2 案例二:隐式类型转换1.1.3 案例三:隐式字符编码转换 2. 为何只查询一行的SQL执行很慢2.1 场景一:查询长时间不返回2.1.1 等MDL锁2.1.2 等 flush2.1.…

vscode远程ssh服务器且更改服务器别名

目录 1、打开VS Code并确保已安装"Remote - SSH"扩展。如果尚未安装&#xff0c;请在扩展市场中搜索并安装它。 2、单击左下角的"Remote Explorer"图标&#xff0c;打开远程资源管理器。 3、在远程资源管理器中&#xff0c;单击右上角的齿轮图标&#x…

区块链在游戏行业的应用

区块链技术在游戏行业有许多潜在的应用&#xff0c;它可以改变游戏开发、发行和玩家交互的方式。以下是区块链技术在游戏行业的一些主要应用&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.游戏资产…

《Node.js 学习笔记 之 切换node版本》

目录 Node.js 学习笔记nvm第一步安装 nvm 常用命令遇到的问题 Node.js 学习笔记 个人博客地址&#xff1a; 使用npm 命令经常遇到npm 与node.js 版本不兼容报错的情况&#xff0c;下面通过nvm 版本管理工具解决问题 nvm node.js version management 通过它可以安装和切换不同版…

『Linux』GDB调试

前言 GDB 是由 GNU 软件系统社区提供的调试工具&#xff0c;同 GCC 配套组成了一套完整的开发环境&#xff0c;GDB 是 Linux 和许多类 Unix 系统中的标准开发环境。 一般来说&#xff0c;GDB 主要完成下面四个方面的功能&#xff1a; 启动程序&#xff1a;可以按照自定义的要求…

Unity布料系统Cloth

Unity布料系统Cloth 介绍布料系统Cloth(Unity组件)组件上的一些属性布料系统的使用布料约束Select面板Paint面板Gradient Tool面板 布料碰撞布料碰撞碰撞适用 介绍 布料系统我第一次用是做人物的裙摆自然飘动&#xff0c;当时我用的是UnityChan这个unity官方自带的插件做的裙摆…

【计算机网络笔记】什么是网路协议?

为什么要有网路协议&#xff1f;什么是网络协议&#xff1f;总结感谢 &#x1f496; 本篇文章总字数&#xff1a;1027字 预计阅读时间&#xff1a;3~7min 建议收藏之后慢慢阅读 为什么要有网路协议&#xff1f; 硬件&#xff08;主机、路由器、通信链 路等&#xff09;只是计…