小欧的字符串构造

[题目链接](https://www.nowcoder.com/practice/3cf0c0aa163a44aba2ee1f7062cb8a12)

思路

给定字符串 和整数 ,构造一个长度为 的字符串 ,使得 是回文串。若无法构造则输出

分情况讨论

情况一: 的长度)

此时一定可以构造。令 的后 个字符为 的反转,前 个字符任意填充(如全填 a)。

为例,拼接结果为 ,中间的填充字符关于自身对称,两侧的 也对称,因此整体是回文串。

情况二:

拼接后总长为 ,其中 只覆盖一端的 个位置。要使整体回文, 必须与 的对应端互为反转,而 中未被 覆盖的中间部分必须自身是回文。

具体地,有两种子情况:

  1. 回文 必须等于 个字符的反转(即 ),同时要求 是回文串。
  2. 回文 必须等于 个字符的反转(即 ),同时要求 是回文串。

两种都不满足时输出

样例演示

输入 abc

  • ,属于情况一。
  • ,是回文串。

复杂度分析

  • 时间复杂度:,回文判断和字符串构造各为线性。
  • 空间复杂度:,存储结果字符串。

代码

#include <bits/stdc++.h>
using namespace std;

bool isPalindrome(const string& s, int l, int r) {
    while (l < r) {
        if (s[l] != s[r]) return false;
        l++; r--;
    }
    return true;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string s;
    int k;
    cin >> s >> k;
    int n = s.size();

    if (k >= n) {
        string t(k - n, 'a');
        for (int i = n - 1; i >= 0; i--) t += s[i];
        cout << t << endl;
    } else {
        // Case 1: s + t palindrome
        if (isPalindrome(s, k, n - 1)) {
            string t = "";
            for (int i = k - 1; i >= 0; i--) t += s[i];
            cout << t << endl;
        }
        // Case 2: t + s palindrome
        else if (isPalindrome(s, 0, n - k - 1)) {
            string t = "";
            for (int i = n - 1; i >= n - k; i--) t += s[i];
            cout << t << endl;
        } else {
            cout << -1 << endl;
        }
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    static boolean isPalindrome(String s, int l, int r) {
        while (l < r) {
            if (s.charAt(l) != s.charAt(r)) return false;
            l++; r--;
        }
        return true;
    }

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

        if (k >= n) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < k - n; i++) sb.append('a');
            for (int i = n - 1; i >= 0; i--) sb.append(s.charAt(i));
            System.out.println(sb.toString());
        } else {
            if (isPalindrome(s, k, n - 1)) {
                StringBuilder sb = new StringBuilder();
                for (int i = k - 1; i >= 0; i--) sb.append(s.charAt(i));
                System.out.println(sb.toString());
            } else if (isPalindrome(s, 0, n - k - 1)) {
                StringBuilder sb = new StringBuilder();
                for (int i = n - 1; i >= n - k; i--) sb.append(s.charAt(i));
                System.out.println(sb.toString());
            } else {
                System.out.println(-1);
            }
        }
    }
}
s = input()
k = int(input())
n = len(s)

def is_palindrome(s, l, r):
    while l < r:
        if s[l] != s[r]:
            return False
        l += 1
        r -= 1
    return True

if k >= n:
    print('a' * (k - n) + s[::-1])
else:
    if is_palindrome(s, k, n - 1):
        print(s[:k][::-1])
    elif is_palindrome(s, 0, n - k - 1):
        print(s[n-k:][::-1])
    else:
        print(-1)
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => {
    lines.push(line.trim());
    if (lines.length === 2) {
        const s = lines[0];
        const k = parseInt(lines[1]);
        const n = s.length;

        function isPalindrome(s, l, r) {
            while (l < r) {
                if (s[l] !== s[r]) return false;
                l++; r--;
            }
            return true;
        }

        if (k >= n) {
            console.log('a'.repeat(k - n) + s.split('').reverse().join(''));
        } else {
            if (isPalindrome(s, k, n - 1)) {
                console.log(s.slice(0, k).split('').reverse().join(''));
            } else if (isPalindrome(s, 0, n - k - 1)) {
                console.log(s.slice(n - k).split('').reverse().join(''));
            } else {
                console.log(-1);
            }
        }
        rl.close();
    }
});