news 2026/6/9 17:20:03

(新卷,100分)- 字符串分割(Java JS Python)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
(新卷,100分)- 字符串分割(Java JS Python)

(新卷,100分)- 字符串分割(Java & JS & Python)

题目描述

给定非空字符串s,将该字符串分割成一些子串,使每个子串的ASCII码值的和均为水仙花数。

1、若分割不成功,则返回0;

2、若分割成功且分割结果不唯一,则返回-1;

3、若分割成功且分割结果唯一,则返回分割后子串的数目。

输入描述

输入字符串的最大长度为200

输出描述

根据题目描述中情况,返回相应的结果。

备注

"水仙花数"是指一个三位数,每位上数字的立方和等于该数字本身,如 371 是’水仙花数’,因为 371=3^3+7^3+1^3

用例
输入abc
输出0
说明分割不成功
输入f3@d5a8
输出-1
说明分割成功但分割结果不唯一,可以分割为两组,一组’f3’和’@d5a8’,另外一组’f3@d5’和’a8’
输入AXdddF
输出2
说明分割成功且分割结果唯一,可以分割’AX’(153)和’dddF’(370)成两个子串
题目解析

我的解题思路如下:

首先将输入字符串变为一个ascii码值数组arr,比如f3@d5a8,就变为了 [102,51,64,100,53,97,56]

然后处理逻辑如下

let sum = 0 for(let i=0; i<arr.length; i++) { sum += arr[i] if(isSxh(sum)) { // 如果sum是水仙花数,则0~i子串可以组成水仙花数,下一个子串从i+1开始 let sum2 = 0 for(let j=i+1; j<arr.length; j++) { sum2 += arr[j] if(isSxh(sum2)) {// 如果sum2是水仙花数,则i+1~j子串可以组成水仙花数,下一个子串从j+1开始 let sum3 = 0 for(let k=j+1; k<arr.length; k++) { sum3 += arr[k] if(isSxh(sum3)) {// 如果sum3是水仙花数,则j+1~k子串可以组成水仙花数,下一个子串从k+1开始 // 重复以上逻辑 } } } } } }

可以发现,上面逻辑可以使用递归来实现,当递归到子串长度为0时结束,或者无法没有下一次递归时结束。

在递归过程中,我们可以统计到一共有多少种分割方式,每种分割方式将字符串分为几段。

如果有0种分割方式,则打印0

如果有1种分割方式,则打印该分割方式可以将字符串分为几段

如果有2种或以上分割方式,则打印-1

本题还有一个优化点,就是基于前缀和,实现O(1)时间求解任意区间的元素之和。


OJ用例库为了产生这样的子串:

ASCII码值的和均为水仙花数

因此,输入的字符串中会存在一些不常用的字符,这些字符可能会对输入获取逻辑产生影响,比如Java语言按照Scanner获取的话,则会以空白字符作为输入获取截止符,因此我们需要通过useDelimiter指定只有换行符才能截止输入获取。具体请看下面Java代码的输入获取逻辑。

对于JS和Python没有此类问题。

Java算法源码
import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in).useDelimiter("[\n]"); System.out.println(getResult(sc.next())); } public static int getResult(String s) { // 将字符串转化为ASCII数组 char[] cArr = s.toCharArray(); int n = cArr.length; // 前缀和,实现O(1)时间求解某区间内元素之和 int[] preSum = new int[n + 1]; for (int i = 1; i <= n; i++) preSum[i] = preSum[i - 1] + cArr[i - 1]; // res记录成功分割的情况 ArrayList<Integer> res = new ArrayList<>(); // 递归 recursive(preSum, n, 0, 0, res); if (res.size() == 0) return 0; else if (res.size() == 1) return res.get(0); else return -1; } public static void recursive(int[] preSum, int n, int start, int count, ArrayList<Integer> res) { if (start == n) { res.add(count); return; } for (int end = start + 1; end <= n; end++) { // 基于前缀和快速求解任意区间内的元素和 if (isSxh(preSum[end] - preSum[start])) { recursive(preSum, n, end, count + 1, res); } } } // 判断num是否为水仙花数 public static boolean isSxh(int num) { if (num <= 99 || num >= 1000) return false; int x = num / 100 % 10; int y = num / 10 % 10; int z = num % 10; return num == x * x * x + y * y * y + z * z * z; } }
JS算法源码
/* JavaScript Node ACM模式 控制台输入获取 */ const readline = require("readline"); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.on("line", (line) => { console.log(getResult(line)); }); function getResult(str) { // 将字符串转化为ASCII数组 const cArr = [...str].map((ele) => ele.charCodeAt()); const n = cArr.length; // 前缀和,实现O(1)时间求解某区间内元素之和 const preSum = new Array(n + 1).fill(0); for (let i = 1; i <= n; i++) preSum[i] = preSum[i - 1] + cArr[i - 1]; // res记录成功分割的情况 const res = []; // 递归 recursive(preSum, n, 0, 0, res); if (res.length === 0) return 0; else if (res.length === 1) return res[0]; else return -1; } function recursive(preSum, n, start, count, res) { if (start === n) { res.push(count); return; } for (let end = start + 1; end <= n; end++) { // 基于前缀和快速求解任意区间内的元素和 if (isSxh(preSum[end] - preSum[start])) { recursive(preSum, n, end, count + 1, res); } } } /* 判断入参是否为水仙花数 */ function isSxh(num) { if (num <= 99 || num >= 1000) return false; const x = parseInt(num / 100) % 10; const y = parseInt(num / 10) % 10; const z = num % 10; return num == x * x * x + y * y * y + z * z * z; }
Python算法源码
# 输入获取 s = input() # 判断num是否未水仙花数 def isSxh(num): if num <= 99 or num >= 1000: return False x, y, z = [int(c) for c in str(num)] return num == x ** 3 + y ** 3 + z ** 3 # 递归分割 def recursive(preSum, n, start, count, res): if start == n: res.append(count) return for end in range(start + 1, n + 1): if isSxh(preSum[end] - preSum[start]): recursive(preSum, n, end, count + 1, res) # 算法入口 def getResult(): # 将字符串转化为ASCII数组 cArr = [ord(c) for c in s] n = len(cArr) # 前缀和,实现O(1)时间求解某区间内元素之和 preSum = [0] * (n + 1) for i in range(1, n + 1): preSum[i] = preSum[i - 1] + cArr[i - 1] # res记录成功分割的情况 res = [] # 递归分割 recursive(preSum, n, 0, 0, res) if len(res) == 0: return 0 elif len(res) == 1: return res[0] else: return -1 # 算法调用 print(getResult())
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 16:49:37

Switch自定义系统深度优化指南:大气层整合包实战应用

你是否遇到过Switch官方系统功能受限、游戏加载缓慢的困扰&#xff1f;当标准配置无法满足你的需求时&#xff0c;大气层整合包系统稳定版提供了专业级的解决方案。这不是简单的系统调整&#xff0c;而是通过技术手段实现性能优化和功能扩展。 【免费下载链接】Atmosphere-stab…

作者头像 李华
网站建设 2026/6/7 23:51:07

BetterNCM安装器完整使用手册:一键解锁网易云音乐隐藏功能

BetterNCM安装器完整使用手册&#xff1a;一键解锁网易云音乐隐藏功能 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 还在使用功能单一的网易云音乐PC版吗&#xff1f;BetterNCM安装器…

作者头像 李华
网站建设 2026/6/6 21:49:50

3分钟快速上手Figma中文插件:设计师专属本地化解决方案

3分钟快速上手Figma中文插件&#xff1a;设计师专属本地化解决方案 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma英文界面而烦恼吗&#xff1f;想要轻松驾驭这款专业设计工…

作者头像 李华
网站建设 2026/6/8 14:48:46

小爱音箱音乐自由:5分钟解锁无限播放权限的终极方案

小爱音箱音乐自由&#xff1a;5分钟解锁无限播放权限的终极方案 【免费下载链接】xiaomusic 使用小爱同学播放音乐&#xff0c;音乐使用 yt-dlp 下载。 项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic 你是否曾满怀期待地对小爱音箱说"播放周杰伦的…

作者头像 李华
网站建设 2026/6/6 21:26:06

小米音乐助手终极指南:让小爱音箱变身私人音乐管家

还在为小爱音箱只能播放固定歌单而烦恼吗&#xff1f;小米音乐助手(xiaomusic)为你带来全新的音乐体验&#xff01;这个基于Python开发的智能工具&#xff0c;通过整合下载引擎和小米智能设备生态&#xff0c;让你的小爱音箱真正成为懂你音乐口味的私人管家。无论你是技术爱好者…

作者头像 李华
网站建设 2026/6/9 9:53:40

Java高级开发全栈转型提升计划

一、Java精通深化路线(3-6个月) 1. JVM深度掌握 学习重点: JVM内存模型(堆、栈、方法区、元空间) 垃圾收集器(G1、ZGC、Shenandoah)及调优 字节码指令与类加载机制 性能监控工具(Arthas、JProfiler、JMH) 实践项目: 实现简单的类加载器 编写JVM调优案例报告 使…

作者头像 李华