【错题集-编程题】重排字符串(贪心 + 构造)

简介: 【错题集-编程题】重排字符串(贪心 + 构造)

牛客对应题目链接:重排字符串 (nowcoder.com)

力扣对应题目链接:1054. 距离相等的条形码 - 力扣(LeetCode)


一、分析题目

  1. 每次去处理一批相同的字符。
  2. 优先处理出现次数最多的字符。
  3. 每次拜访字符的时候,间隔一个格子。

能否进行重排的判定标准:

  • x <= (n+1)/2:能进行重排
  • x > (n+1)/2:不能进行重排

二、代码

1、没看题解之前AC的代码

//牛客代码(看了题解之后AC的代码)
#include <iostream>
#include <unordered_map>
using namespace std;
 
int main()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    string res=s;
    char maxValue=0;
    int maxCount=0;
    unordered_map<char, int> hash;
    for(auto x : s)
    {
        hash[x]++;
        if(hash[x]>maxCount)
        {
            maxCount=hash[x];
            maxValue=x;
        }
    }
    int k=0;
    while(maxCount--)
    {
        res[k]=maxValue;
        if(k>=n)
        {
            cout << "no" << endl;
            return 0;
        }
        k+=2;
    }
    hash[maxValue]=0;
    for(auto& [a, b] : hash)
    {
        while(b>0)
        {
            if(k>=n) k=1;
            res[k]=a;
            k+=2;
            b--;
        }
    }
    cout << "yes" << endl;
    cout << res << endl;
    return 0;
}
 
//力扣AC代码
class Solution {
private:
    unordered_map<int, int> hash;
public:
    vector<int> rearrangeBarcodes(vector<int>& barcodes) {
        int n=barcodes.size();
        vector<int> res(n);
        int maxValue=0;
        int maxCount=0;
        for(auto x : barcodes)
        {
            hash[x]++;
            if(hash[x]>maxCount)
            {
                maxCount=hash[x];
                maxValue=x;
            }
        }
        int k=0;
        while(maxCount--)
        {
            res[k]=maxValue;
            k+=2;
        }
        hash[maxValue]=0;
        for(auto& [a, b] : hash)
        {
            while(b>0)
            {
                if(k>=n) k=1;
                res[k]=a;
                k+=2;
                b--;
            }
        }
        return res;
    }
};

2、值得学习的代码

//牛客
#include <iostream>
 
using namespace std;
 
const int N = 100010;
 
int n;
char s[N];
char ret[N];
 
int main()
{
    cin >> n >> s;
 
    int hash[26] = { 0 }; // 统计每个字符的频次
    int maxIndex, maxCount = 0;
    for(int i = 0; i < n; i++)
    {
        if(maxCount < ++hash[s[i] - 'a'])
        {
            maxCount = hash[s[i] - 'a'];
            maxIndex = s[i] - 'a';
        }
    }
 
    if(maxCount > (n + 1) / 2) cout << "no" << endl;
    else
    {
        cout << "yes" << endl;
        int index = 0;
        // 先去摆放出现次数最多的
        while(maxCount--)
        {
            ret[index] = maxIndex + 'a';
            index += 2;
        }
        // 处理剩下的
        for(int i = 0; i < 26; i++)
        {
            if(hash[i] && i != maxIndex)
            {
                while(hash[i]--)
                {
                    if(index >= n) index = 1;
                    ret[index] = i + 'a';
                    index += 2;
                }
            }
        }
        // 打印结果
        for(int i = 0; i < n; i++) cout << ret[i];
        cout << endl;
    }
    return 0;
}

三、反思与改进

因为这道题目之前在力扣上做过类似的,所以基本思路很清晰,不过最后不知道是哪块细节没有处理好,导致只过了 33.33% 的样例。崩溃了,看了题解之后,发现是在正解前面少打印了一个 "yes",审题不仔细!!这种低级错误不能再犯,否则以后笔试会吃大亏!


相关文章
|
4月前
面试题 08.08:有重复字符串的排列组合
面试题 08.08:有重复字符串的排列组合
45 0
|
23天前
|
算法 C++
第一周算法设计与分析 E : 构造回文串
这篇文章介绍了解决算法问题"构造回文串"的方法,即判断给定的整数N(视为字符串)是否可以通过在前面添加任意个0(或不添加)来构造一个回文串,并给出了相应的C++代码实现。
|
3月前
|
存储 算法 C语言
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
二分查找算法的概念、原理、效率以及使用C语言循环和数组的简单实现
|
4月前
面试题 08.07:无重复字符串的排列组合
面试题 08.07:无重复字符串的排列组合
45 0
【C++&数据结构】超详细一文带小白轻松全面理解 [ 二叉搜索树 ]—— [从零实现&逐过程分析&代码演示&简练易懂](23)
【C++&数据结构】超详细一文带小白轻松全面理解 [ 二叉搜索树 ]—— [从零实现&逐过程分析&代码演示&简练易懂](23)
|
4月前
|
自然语言处理 算法 编译器
编译原理复习四:编译器结构 消除左递归、左公因子 最右推导 寻找句柄讲解(附题目和答案)
编译原理复习四:编译器结构 消除左递归、左公因子 最右推导 寻找句柄讲解(附题目和答案)
133 0
|
机器学习/深度学习 算法 搜索推荐
【数据结构】时间复杂度(详细解释,例子分析,易错分析,图文并茂)
【数据结构】时间复杂度(详细解释,例子分析,易错分析,图文并茂)
363 0
2023.3.5-课堂练习01题目:计算最长英语单词链
2023.3.5-课堂练习01题目:计算最长英语单词链
116 0