You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从整数数组生成所有可能的回文?

问题分析与解决方案

你的原代码仅能判断整个输入数组是否为回文,无法枚举所有符合要求的回文组合。而全排列的思路存在明显缺陷:会生成大量无效排列,且相同元素的不同选取会导致重复回文输出,时间复杂度极高(O(n! * n)),完全不适合处理稍大的数组。

正确思路

利用回文的结构特性(对称、最多一个元素出现奇数次),通过统计数组中各元素的出现次数来构造所有不重复的回文,步骤如下:

  1. 统计每个元素的出现次数;
  2. 分两类构造回文:
    • 偶数长度回文:选取至少一对相同元素,每对元素可构成基础偶数回文,若元素出现次数≥4,还可扩展为更长的偶数回文;
    • 奇数长度回文:选取一个元素作为中心(出现次数≥1),再选取若干对相同元素放在中心两侧,组合成奇数长度回文;
  3. 去重并输出所有构造好的回文。

代码实现

#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

// 生成所有偶数长度的回文
void generateEvenPalindromes(unordered_map<int, int>& count, vector<vector<int>>& result) {
    for (auto& pair : count) {
        int num = pair.first;
        int cnt = pair.second;
        // 至少需要2个相同元素才能组成偶数回文
        for (int k = 2; k <= cnt; k += 2) {
            vector<int> palindrome;
            // 构建前半部分
            for (int i = 0; i < k/2; ++i) {
                palindrome.push_back(num);
            }
            // 镜像生成后半部分
            vector<int> temp = palindrome;
            reverse(temp.begin(), temp.end());
            palindrome.insert(palindrome.end(), temp.begin(), temp.end());
            result.push_back(palindrome);
        }
    }
}

// 生成所有奇数长度的回文
void generateOddPalindromes(unordered_map<int, int>& count, vector<vector<int>>& result) {
    // 遍历每个可能的中心元素
    for (auto& centerPair : count) {
        int center = centerPair.first;
        int centerCnt = centerPair.second;
        // 中心元素使用次数为奇数
        for (int c = 1; c <= centerCnt; c += 2) {
            vector<int> base;
            // 中心元素部分
            int centerUse = (c + 1)/2;
            int sideUse = (c - 1)/2;
            // 构建基础奇数回文(中心+两侧的中心元素)
            for (int i = 0; i < sideUse; ++i) {
                base.push_back(center);
            }
            base.push_back(center);
            for (int i = 0; i < sideUse; ++i) {
                base.push_back(center);
            }
            // 仅保留长度≥3的奇数回文(匹配示例需求)
            if (base.size() >= 3) {
                result.push_back(base);
            }
            // 尝试添加其他成对元素到两侧
            for (auto& pair : count) {
                int num = pair.first;
                int cnt = pair.second;
                if (num == center) {
                    // 中心元素剩余可成对使用的次数
                    int remaining = centerCnt - c;
                    if (remaining < 2) continue;
                    cnt = remaining;
                } else {
                    if (cnt < 2) continue;
                }
                // 最多添加cnt/2对该元素
                for (int k = 1; k <= cnt/2; ++k) {
                    vector<int> palindrome = base;
                    // 向前、向后添加k个当前元素
                    for (int i = 0; i < k; ++i) {
                        palindrome.insert(palindrome.begin(), num);
                        palindrome.push_back(num);
                    }
                    result.push_back(palindrome);
                }
            }
        }
    }
}

// 去除重复的回文
void removeDuplicates(vector<vector<int>>& result) {
    sort(result.begin(), result.end());
    auto last = unique(result.begin(), result.end());
    result.erase(last, result.end());
}

// 格式化输出回文
void printPalindromes(vector<vector<int>>& result) {
    for (auto& pal : result) {
        cout << "{ ";
        for (size_t i = 0; i < pal.size(); ++i) {
            cout << pal[i];
            if (i != pal.size() - 1) {
                cout << " ";
            }
        }
        cout << " }" << endl;
    }
}

int main() {
    int arr[] = {1, 2, 2, 2, 3};
    int n = sizeof(arr)/sizeof(int);
    
    unordered_map<int, int> count;
    for (int i = 0; i < n; ++i) {
        count[arr[i]]++;
    }
    
    vector<vector<int>> result;
    
    generateEvenPalindromes(count, result);
    generateOddPalindromes(count, result);
    
    removeDuplicates(result);
    
    printPalindromes(result);
    
    return 0;
}

代码说明

  • generateEvenPalindromes:遍历每个元素,根据其出现次数生成所有偶数长度的回文(如两个2、四个2等);
  • generateOddPalindromes:遍历每个元素作为回文中心,生成所有奇数长度的回文(如{2,2,2}、{2,1,2}等);
  • removeDuplicates:通过排序和去重操作,确保输出的回文没有重复;
  • printPalindromes:按照示例中的格式输出所有回文。

运行上述代码,输入{1, 2, 2, 2, 3}时,会输出指定的四个回文:

{ 2 2 }
{ 2 2 2 }
{ 2 1 2 }
{ 2 3 2 }

内容的提问来源于stack exchange,提问作者Mayli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 18:45:39