华为OD机试真题 - 没有回文串 (C++ & Python & JAVA & JS & GO)

没有回文串

2025华为OD机试 - 华为OD上机考试 200分题型

华为OD机试真题目录点击查看: 华为OD机试真题题库目录|机考题库 + 算法考点详解

题目描述

回文串的定义:正读和反读都一样的字符串。

现在已经存在一个不包含回文串的字符串,字符串的字符都是在英语字母的前N个,且字符串不包含任何长度大于等于2的回文串;

请找出下一个字典序的不包含回文串的、字符都是在英语字母的前N个、且长度相同的字符串。

如果不存在,请输出NO。

输入描述

输入包括两行。

第一行有一个整数:N(1<=N<=26),表示字符串的每个字符范围都是前N的英语字母。

第二行输入一个字符串S(输入长度<=10000),输入保证这个字符串是合法的并且没有包含回文串。

输出描述

输出下一个字典序的不包含回文串的、字符都是在英语字母的前N个、且长度相同的字符串;

如果不存在,请输出"NO"。

用例1

输入

none 复制代码
3
cba

输出

none 复制代码
NO

题解

思路: 贪心

  1. 回文串去掉首尾字母后,仍然是回文串,所以长度为m的回文串必然包含长为m-2的回文串。逆推可以得到如果字符串不包含m-2长度的回文串,就不会存在长为m的回文串。综合题目中描述的字符串不包含任何长度大于等于2的回文串, 可以推导出不包含长度2和长度3的回文串就不会包含回文串。
  2. 判断是否存在回文串就转换为如何判断不包含长度2和长度3的回文串,那这个就比较简单了,存在i如果s[i] == s[i+1] || s[i] == s[i+2]那就是存在了。
  3. 题目要求字典序最小,相应增大位置越靠右越好,这道题可以理解成s字符串的字符串n进制加数
  4. 这题可以采用贪心 + 类似进位:一开始对最右位执行+1操作,
    • 如果不与前1位、前2位相等则说明符合要求输出结果。
    • 一旦发生冲突则继续加,溢出就进位
      • 如果到最左边还出现溢出则说明不存在合法返回NULL。
      • 假设当前由于溢出到达index位置,并且index位置值不和前1前2位发生冲突,则说明index位已经合法代表[0,index]都是合法(不包含回文串)的,接下就是回溯考虑{index+1, s.size()-1}是否合法,这里就是循环遍历这个范围内所有位置是否和前两个值发生冲突,
        • 全部不发生冲突的话,说明合法,直接输出。
        • 假设x位置发生冲突的话,则继续重复上面发生冲突的逻辑处理即可。

c++

c++ 复制代码
#include<iostream>
#include<vector>
#include<string>
#include <utility> 
#include <sstream>
#include<algorithm> 
#include<cmath>
#include<map>
using namespace std;

string handle(string s, int k) {
    k += 'a';
    int n = s.size();
    int i  = n - 1;
    s[i]++;
    while (i < n) {
        // 需要进位
        if (s[i] == k) {
            if (i == 0) {
                return "NO";
            }
            // 进位
            s[i] = 'a';
            s[--i]++;
        } else if (i && s[i] == s[i-1] || i > 1 && s[i] == s[i-2]) {
            // 如果 s[i] 和左侧的字符形成回文串,就继续增加 s[i]
            s[i]++;
        } else {
            i++;
        }
    }

    return s;
}


int main() {
    string s;
    int k;
    cin >> k;
    cin >> s;
    
    string res = handle(s, k);
    cout << res;
    return 0;
}

JAVA

JAVA 复制代码
import java.util.*;

public class Main {

    static String handle(String s, int k) {
        char[] arr = s.toCharArray();
        char limit = (char) ('a' + k);
        int n = arr.length;

        int i = n - 1;
        arr[i]++;  // 从最后一位开始尝试递增

        while (i < n) {
            // 需要进位
            if (arr[i] == limit) {
                if (i == 0) {
                    return "NO";
                }
                arr[i] = 'a';
                i--;
                arr[i]++;
            }
            // 如果当前字符与前1位或前2位形成回文
            else if ((i >= 1 && arr[i] == arr[i - 1]) ||
                     (i >= 2 && arr[i] == arr[i - 2])) {
                arr[i]++;
            }
            // 当前位合法,处理下一位
            else {
                i++;
            }
        }

        return new String(arr);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int k = sc.nextInt();
        String s = sc.next();

        System.out.println(handle(s, k));
    }
}

Python

python 复制代码
def handle(s, k):
    arr = list(s)
    limit = chr(ord('a') + k)
    n = len(arr)

    i = n - 1
    arr[i] = chr(ord(arr[i]) + 1)  # 最后一位递增

    while i < n:
        # 需要进位
        if arr[i] == limit:
            if i == 0:
                return "NO"
            arr[i] = 'a'
            i -= 1
            arr[i] = chr(ord(arr[i]) + 1)
        # 与前1位或前2位形成回文
        elif (i >= 1 and arr[i] == arr[i - 1]) or \
             (i >= 2 and arr[i] == arr[i - 2]):
            arr[i] = chr(ord(arr[i]) + 1)
        else:
            i += 1

    return ''.join(arr)


if __name__ == "__main__":
    k = int(input().strip())
    s = input().strip()
    print(handle(s, k))

JavaScript

js 复制代码
'use strict';

const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let lines = [];

rl.on('line', (line) => {
    if (line !== null) {
        lines.push(line.trim());
    }
});

rl.on('close', () => {
    let idx = 0;
    const k = parseInt(lines[idx++]); // 字母个数
    const s = lines[idx++];           // 原字符串

    console.log(handle(s, k));
});

function handle(s, k) {
    let arr = s.split('');
    let limit = String.fromCharCode('a'.charCodeAt(0) + k);
    let n = arr.length;

    // 从最后一位开始尝试递增
    let i = n - 1;
    arr[i] = String.fromCharCode(arr[i].charCodeAt(0) + 1);

    while (i < n) {
        // 需要进位
        if (arr[i] === limit) {
            if (i === 0) {
                return "NO";
            }
            arr[i] = 'a';
            i--;
            arr[i] = String.fromCharCode(arr[i].charCodeAt(0) + 1);
        }
        // 如果与前1位或前2位形成回文
        else if (
            (i >= 1 && arr[i] === arr[i - 1]) ||
            (i >= 2 && arr[i] === arr[i - 2])
        ) {
            arr[i] = String.fromCharCode(arr[i].charCodeAt(0) + 1);
        }
        // 当前位合法,继续处理下一位
        else {
            i++;
        }
    }

    return arr.join('');
}

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

func handle(s string, k int) string {
	arr := []byte(s)
	limit := byte('a' + k)
	n := len(arr)

	i := n - 1
	arr[i]++ // 从最后一位开始递增

	for i < n {
		// 需要进位
		if arr[i] == limit {
			if i == 0 {
				return "NO"
			}
			arr[i] = 'a'
			i--
			arr[i]++
		} else if (i >= 1 && arr[i] == arr[i-1]) ||
			(i >= 2 && arr[i] == arr[i-2]) {
			// 与前1位或前2位形成回文
			arr[i]++
		} else {
			i++
		}
	}

	return string(arr)
}

func main() {
	in := bufio.NewReader(os.Stdin)
	var k int
	var s string

	fmt.Fscan(in, &k)
	fmt.Fscan(in, &s)

	fmt.Println(handle(s, k))
}
相关推荐
无限码力2 天前
华为OD机考真题 -【测试用例执行计划】 (C++ & Python & JAVA & JS & GO)
华为od·华为od机考·华为od机试真题·华为od机试·华为od上机考试·华为od机考真题
开开心心_Every3 天前
无广告干扰:简单好用文字LOGO设计工具
xml·java·网络·数据库·华为od·华为云·excel
我是华为OD~HR~栗栗呀4 天前
(华为od)21届-Python面经
java·前端·c++·python·华为od·华为·面试
无限码力4 天前
华为OD机试双机位C卷 - 采样过滤 (C++ & Python & JAVA & JS & GO)
华为od·华为od机考·华为od机试·华为od机试双机位c卷·华为od上机考试·华为od机考真题·华为od机试-采样过滤
Tony_yitao9 天前
15.华为OD机考 - 执行任务赚积分
数据结构·算法·华为od·algorithm
无限码力10 天前
华为OD机试真题 - 最长广播响应 (C++ & Python & JAVA & JS & GO)
华为od·华为od机试·od机考·华为od上机考试真题·华为od机试-最长广播响应·华为od-最长广播响应
我是华为OD~HR~栗栗呀11 天前
(华为od)Python面经-20届
华为od
兩尛16 天前
猴子爬山od
算法·华为od
我是华为OD~HR~栗栗呀17 天前
23届(华为od)-C开发面经
java·c语言·c++·python·华为od·华为·面试