字符串拼接 - 华为OD统一考试(C卷)

OD统一考试(C卷)

分值: 200分

题解: Java / Python / C++

alt

题目描述

给定 M 个字符( a-z ) ,从中取出任意字符(每个字符只能用一次)拼接成长度为 N 的字符串,要求相同的字符不能相邻。

计算出给定的字符列表能拼接出多少种满足条件的字符串,输入非法或者无法拼接出满足条件的字符串则返回 0 。

输入描述

给定长度为 M 的字符列表和结果字符串的长度 N ,中间使用空格(" ")拼接。

  • 0 < M < 30
  • 0 < N ≤ 5

输出描述

输出满足条件的字符串个数。

示例1

输入:
abc 1输出:
3说明:
给定的字符为 abc ,结果字符申长度为 1 ,可以拼接成 a、b、c ,共 3 种。

示例2

输入:
dde 2输出:
2说明:
给定的字符为 dde ,果字符串长度为 2 ,可以拼接成 de、ed, 共 2 种。

题解

这个问题是通过回溯法(Backtracking)解决。

回溯法是一种深度优先搜索的算法,它尝试在解空间中逐步构建解,并在发现当前解不符合条件时进行回溯。

对于这个问题,可以考虑从第一个位置开始选择字符,然后在每个位置上选择不同的字符,直到构建出长度为 N 的字符串,同时要满足相邻字符不相同的条件。

具体步骤
  1. 定义一个递归函数 solve,参数包括前一个字符 pre 和剩余字符个数 todo
  2. solve 函数中,对于当前位置的每个字符,如果该字符与前一个字符相同,跳过;
  3. 否则,选择该字符,将字符数量减一,递归到下一个位置,并将结果加到总数中,然后恢复字符数量。
  4. main 函数中,读取输入,检查是否存在非法字符,然后调用 solve 函数计算满足条件的字符串个数。
代码描述

cnt 是一个数组,用于记录每个字符在给定字符串中的出现次数。

在这个问题中,cnt 数组的长度是 26,对应着英文字母表中的 26 个小写字母。数组中的每个元素表示对应字母的出现次数。

在代码中,首先通过遍历输入字符串,统计每个字符的出现次数,然后根据这个数组进行递归计算满足条件的字符串个数。

cnt 的目的是为了方便在递归过程中追踪每个字符的剩余数量,以确保相同的字符不能相邻出现。

在递归的过程中,每次选择一个字符,都会将对应位置的 cnt 减 1,递归完成后再将其加 1,以确保不影响后续的递归分支。

Java

import java.util.Scanner;/*** @author code5bug*/
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String input = in.next();int n = in.nextInt();// 是否非法输入boolean illegal = false;// 每个字符的个数int[] cnt = new int[26];for (char c : input.toCharArray()) {int idx = c - 'a';if (0 <= idx && idx < 26) {cnt[idx]++;} else {illegal = true;}}if (illegal) {System.out.println(0);} else {System.out.println(solve(cnt, -1, n));}}/*** @param cnt  字符个数统计* @param pre  前一个字符的下标* @param todo 剩余的字符个数* @return 组合数量*/static int solve(int[] cnt, int pre, int todo) {// 组合成功if (todo == 0) return 1;int tot = 0;for (int i = 0; i < 26; i++) {// 前一个字符和当前字符相同或者没有字符了,跳过if (cnt[i] == 0 || i == pre) continue;// 选择当前字符,剩余字符数-1,递归求解求和,恢复字符数量cnt[i]--;tot += solve(cnt, i, todo - 1);cnt[i]++;}return tot;}
}

Python

def solve(pre: int, todo: int) -> int:""":param pre: 前一个字符的下标:param todo: 剩余的字符个数:return: 组合数量"""global cntif todo == 0:return 1tot = 0for i in range(26):if cnt[i] == 0 or i == pre:  # 前一个字符和当前字符相同或者没有字符了,跳过continue# 选择当前字符,剩余字符数-1,递归求解求和,恢复字符数量cnt[i] -= 1tot += solve(i, todo - 1)cnt[i] += 1return totif __name__ == "__main__":s, n = input().split()n = int(n)illegal = False# 每个字符的个数cnt = [0] * 26for c in s:idx = ord(c) - ord('a')if 0 <= idx < 26:cnt[idx] += 1else:illegal = Trueif illegal:print(0)else:print(solve(-1, n))

C++

#include <iostream>using namespace std;int cnt[26]; // 全局变量,每个字符的个数int solve(int pre, int todo) {if (todo == 0) {return 1;}int tot = 0;for (int i = 0; i < 26; ++i) {if (cnt[i] == 0 || i == pre) { // 前一个字符和当前字符相同或者没有字符了,跳过continue;}// 选择当前字符,剩余字符数-1,递归求解求和,恢复字符数量cnt[i]--;tot += solve(i, todo - 1);cnt[i]++;}return tot;
}int main() {string s;int n;cin >> s >> n;bool illegal = false;// 每个字符串的个数for (char c : s) {int idx = c - 'a';if (0 <= idx && idx < 26) {cnt[idx]++;} else {illegal = true;}}if (illegal) {cout << 0 << endl;} else {cout << solve(-1, n) << endl;}return 0;
}

相关练习题

题号题目难易
LeetCode LCR 083LCR 083. 全排列中等
LeetCodeLCR 084LCR 084. 全排列 II 中等
LeetCode 4646. 全排列中等

‍❤️‍华为OD机试面试交流群(每日真题分享): 加V时备注“华为od加群”

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平时积累的FPGA知识点(10)

平时在FPGA群聊等积累的FPGA知识点&#xff0c;第10期&#xff1a; 41 ZYNQ系列芯片的PL中使用PS端送过来的时钟&#xff0c;这些时钟名字是自动生成的吗&#xff1f; 解释&#xff1a;是的。PS端设置的是ps_clk&#xff0c;用report_clocks查出来的时钟名变成了clk_fpga_0&a…

JavaScript设计模式与开发实战

JavaScript设计模式与开发实践 第一章、面向对象的JavaScript 1.1 多态 类似java面向对象&#xff0c;通过继承共有特征&#xff0c;来实现不同方法。JavaScript的多态就是把“做什么”和“谁去做”分离&#xff0c;消除类型间的耦合关系。 他的作用就是把过程化的条件分支…

解决LeetCode编译器报错的技巧:正确处理位操作中的数据类型

一天我在leetcode上刷题时&#xff0c;遇到了这样的题目&#xff1a; 随即我写了如下的代码&#xff1a; int convertInteger(int A, int B) {int count 0;int C A ^ B;int flag 1;while(flag){if (C & flag){count;}flag<<1;}return count;} 但LeetCode显示如下…

07-k8s中secret资源02-玩转secret

一、回顾secret资源的简单实用 第一步&#xff1a;将想要的数据信息【key&#xff1a;value】中的value值&#xff0c;使用base64编码后&#xff0c;写入secret资源清单中&#xff1b; 第二步&#xff1a;创建secret资源&#xff1b; 第三步&#xff1a;pod资源引用secret资源&…

建造者模式-Builder Pattern

原文地址:https://jaune162.blog/design-pattern/builder-pattern/ 引言 现在一般大型的业务系统中的消息通知的形式都会有多种,比如短信、站内信、钉钉通知、邮箱等形式。虽然信息内容相同,但是展现形式缺不同。如短信使用的是纯文本的形式,钉钉使用的一般是Markdown的形…

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——JAVA

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 1. Java 1. 和 equals的区别 比较基本数据类型是比较的值&#xff0c;引用数据类型是比较两个是不是同一个对象&#xff0c;也就是引用是否指向同 一个对象&…

C#,计算几何,贝塞耳插值(Bessel‘s interpolation)的算法与源代码

Friedrich Wilhelm Bessel 1 贝塞耳插值&#xff08;Bessels interpolation&#xff09; 首先要区别于另外一个读音接近的插值算法&#xff1a;贝塞尔插值&#xff08;Bzier&#xff09;。 &#xff08;1&#xff09;读音接近&#xff0c;但不是一个人&#xff1b; &#x…

【二十一】【C++】模版特化

模版的参数 类型模板参数 类型模板参数允许在定义模板时指定一个占位符&#xff0c;这个占位符在模板实例化时将被具体的类型替换。这使得我们能够编写与类型无关的通用代码。例如&#xff0c;标准库中的 std::vector<T> 使用一个类型模板参数 T&#xff0c;这意味着你…

transformer-Attention is All You Need(一)

1. 为什么需要transformer 循环模型通常沿输入和输出序列的符号位置进行因子计算。通过在计算期间将位置与步骤对齐&#xff0c;它们根据前一步的隐藏状态和输入产生位置的隐藏状态序列。这种固有的顺序特性阻止了训练样本内的并行化&#xff0c;这在较长的序列长度上变得至关重…

透光卓越,光耦继电器的独特特点全面解析

光耦继电器作为电子控制系统中的核心元件&#xff0c;其光电隔离技术为其独特之处。通过光电隔离技术&#xff0c;光耦继电器实现了输入和输出之间的电气隔离&#xff0c;有效阻止了高电压与低电压之间的直接接触。这项技术不仅提高了系统的安全性&#xff0c;还有效减少了电气…

【图论经典题目讲解】CF786B - Legacy 一道线段树优化建图的经典题目

C F 786 B − L e g a c y \mathrm{CF786B - Legacy} CF786B−Legacy D e s c r i p t i o n \mathrm{Description} Description 给定 1 1 1 张 n n n 个点的有向图&#xff0c;初始没有边&#xff0c;接下来有 q q q 次操作&#xff0c;形式如下&#xff1a; 1 u v w 表示…

计算机网络之网络安全

文章目录 1. 网络安全概述1.1 安全威胁1.1.1 被动攻击1.1.2 主动攻击 1.2 安全服务 2. 密码学与保密性2.1 密码学相关基本概念2.2 对称密钥密码体制2.2.1 DES的加密方法2.2.2.三重DES 2.3 公钥密码体制 3. 报文完整性与鉴别3.1 报文摘要和报文鉴别码3.1.1 报文摘要和报文鉴别码…