字符串拼接 - 华为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 cnt
    if todo == 0:
        return 1

    tot = 0
    for i in range(26):
        if cnt[i] == 0 or i == pre:  # 前一个字符和当前字符相同或者没有字符了,跳过
            continue

        # 选择当前字符,剩余字符数-1,递归求解求和,恢复字符数量
        cnt[i] -= 1
        tot += solve(i, todo - 1)
        cnt[i] += 1
    return tot


if __name__ == "__main__":
    s, n = input().split()
    n = int(n)

    illegal = False

    # 每个字符的个数
    cnt = [0] * 26
    for c in s:
        idx = ord(c) - ord('a')
        if 0 <= idx < 26:
            cnt[idx] += 1
        else:
            illegal = True

    if 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加群”

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

突发!亚马逊创始人贝索斯抛售60亿美元股票,外网疑其或加仓比特币

号外&#xff1a;2.16教链内参《内参&#xff1a;OpenAI Sora惊艳发布&#xff0c;加密圈有人获利超700倍》 前世界首富、全球知名电商平台亚马逊&#xff08;amazon&#xff09;创始人杰夫贝索斯&#xff08;Jeff Bezos&#xff09;最近一周以来接连抛售自家公司股票&#xff…

BulingBuling[Beyond the To-Do List] - 《让金钱为你服务》 [ Make Money Work for You ]

与《财务自由: 赚到足够的钱的有效方法》作者Grant的简短访谈 让钱为你工作 超越待办事项清单 主持人&#xff1a;Erik Fisher Make Money Work for You Beyond the To-Do List Hosted by Erik Fisher 与Erik Fisher一起探索如何确定你生活中最大的财务杠杆以及使用它们的最佳方…

【Linux系统化学习】文件重定向

目录 文件内核对象 文件描述符的分配规则 重定向 重定向的概念 dup2系统调用 输出重定向 追加重定向 输入重定向 stderr解析 重定向到同一个文件中 分离常规输出和错输出 文件内核对象 上篇文章中我们介绍到了操作系统中的文件&#xff0c;操作系统为了方…

什么是智慧公厕,智慧公厕有哪些功能

1.什么是智慧公厕&#xff1f; 随着智慧城市的快速发展&#xff0c;公共厕所作为城市基础设施的一部分&#xff0c;也在逐步升级转型。那么&#xff0c;什么是智慧公厕&#xff1f;智慧公厕作为智慧城市的重要组成部分&#xff0c;将公共厕所的建设、设计、使用、运营和管理等…

报错405(errAxiosError: Request failed with status code 405)

errAxiosError: Request failed with status code 405 前端调用接口的方法跟后台定义接口的方法不一致

docker (四)-docker网络

默认网络 docker会自动创建三个网络&#xff0c;bridge,host,none bridge桥接网络 如果不指定&#xff0c;新创建的容器默认将连接到bridge网络。 默认情况下&#xff0c;使用bridge网络&#xff0c;宿主机可以ping通容器ip&#xff0c;容器中也能ping通宿主机。 容器之间只…

UE4学习笔记 FPS游戏制作5 动画蒙太奇制作开枪动画

创建一个蒙太奇 选择角色的骨骼&#xff0c;并重命名 编辑蒙太奇 将我们需要的动画拖动到Default下的两个白杠的上边那个里 然后在下方的Sections节点中&#xff0c;点击Preview后的Default&#xff0c;选中后&#xff0c;再点击PreviewAllScetions上百年的长的绿色的Defalut&…

使用miniconda管理Python环境

之前经常使用pipenv管理虚拟环境&#xff0c;但是有一个问题就是代码给别人使用的时候&#xff0c;别人使用的Python版本和自己的不一致时&#xff0c;安装依赖包的时候会有问题。所以现在使用miniconda来管理虚拟环境&#xff0c;不仅小巧方便&#xff0c;还能为每个环境指定不…

Gitee入门之工具的安装

一、gitee是什么&#xff1f; Gitee&#xff08;码云&#xff09;是由开源中国社区在2013年推出的一个基于Git的代码托管平台&#xff0c;它提供中国本土化的代码托管服务。它旨在为个人、团队和企业提供稳定、高效、安全的云端软件开发协作平台&#xff0c;具备代码质量分析、…

LeetCode 100题目(python版本)待续...

一.哈希 1.两数之和 题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复…

【LeetCode: 103. 二叉树的锯齿形层序遍历 + BFS】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

QGIS004:【10栅格地形分析工具箱】-坡度、坡向、山体阴影

摘要&#xff1a;QGIS栅格地形分析工具箱常用工具有坡度、坡向、山体阴影等选项&#xff0c;本文介绍各选项的基本操作。 实验数据&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1gYZ_om4AlSdal0bts2mt-A?pwd4rrn 提取码&#xff1a;4rrn 一、坡度 工具功能&…

VitePress-17- 配置- appearance 的作用详解

作用说明 appearance : 是进行主题模式的配置开关&#xff0c;决定了是否启用深色模式。 可选的配置值&#xff1a; true: 默认配置&#xff0c;可以切换为深色模式&#xff1b; false: 禁用主题切换&#xff0c;只使用默认的配置&#xff1b; dark: 默认使用深色模式&#xff…

软件工程师,超过35岁怎么办

概述 随着科技行业的飞速发展&#xff0c;软件开发工程师的职业道路充满了各种机遇和挑战。对于已经在这个行业摸爬滚打了十多年的软件开发工程师来说&#xff0c;当他们步入35岁这个年纪时&#xff0c;可能会感到一些迷茫和焦虑。许多人担忧&#xff0c;在以创新、活力、快速迭…

SUSAN关键点检测以及SAC-IA粗配准

一、SUSAN关键点检测 C #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/common/io.h> #include <pcl/visualization/pcl_visualizer.h> #include <boost/thread/thread.hpp> #include <…

[]人的成功离不开气运这么一说!

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

代码随想录刷题笔记-Day17

1. 路径总和 112. 路径总和https://leetcode.cn/problems/path-sum/ 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true …

【分享】JLINK的SW调试模式连线方式

大家知道&#xff0c;JLINK有2种调试模式&#xff1a;JTAG和SWD&#xff08;串行模式&#xff09;。 JTAG是常用模式&#xff0c;大家都熟悉、不废话了&#xff1b;如果使用SW模式&#xff0c;需要&#xff08;只需要&#xff09;4根连线&#xff0c;连接方式如下&#xff1a; …

如何恢复未保存/删除的Word文档?- 2024年终极指南

很少有像丢失 Word 文档这样普遍熟悉的经历。从读过《麦田里的守望者》一书的高中生&#xff0c;到负责公布季度收益的企业高管&#xff0c;每个人都知道&#xff0c;当他们的工作距离完成只有几个十字路口时&#xff0c;他们的工作就消失了&#xff0c;这让他们感到恐慌。 如何…

Ubuntu Desktop 显示文件路径

Ubuntu Desktop 显示文件路径 1. GUI hot key2. CLIReferences 1. GUI hot key Ctrl L: 显示文件路径 2. CLI right click -> Open in Terminal -> pwd strongforeverstrong:~/Desktop$ pwd /home/strong/DesktopReferences [1] Yongqiang Cheng, https://yongqiang…