找到获得“好”字符串的最小移动次数

Posted

技术标签:

【中文标题】找到获得“好”字符串的最小移动次数【英文标题】:Find the minimum number of moves to get a "Good" string 【发布时间】:2014-09-18 07:59:10 【问题描述】:

当且仅当“String 中的所有不同字符都重复相同的次数”时,才认为字符串是好的。

现在,给定一个长度为 n 的字符串,我们必须在这个字符串中进行的最小更改次数是多少才能使字符串变好。

注意:我们只允许使用小写英文字母,我们可以将任何字母更改为任何其他字母。

例子:设String为yyxzzxxx

那么这里的答案是 2。

解释: 一种可能的解决方案 yyxyyxxx。我们已将 2 'z' 更改为 2 'y'。现在 'x' 和 'y' 都重复了 4 次。

我的方法:

    对所有 26 个小写字母的出现情况进行哈希处理。 还可以查找字符串中不同字母的数量。 对该哈希数组进行排序并开始检查字符串的长度是否可以被不同字符的数量整除。如果是,那么我们得到了答案。 否则将不同字符减 1。

但它对某些结果给出了错误的答案,因为它们可能会在删除一些没有出现最少时间的字符时提供一个好的字符串,从而在更少的移动中提供一个好的字符串。

那么如何做这个问题。请帮忙。

约束:字符串长度最大为 2000。

我的方法:

string s;
    cin>>s;
    int hash[26]=0;

    int total=s.length();
    for(int i=0;i<26;i++)
        hash[s[i]-'a']++;
    
    sort(hash,hash+total);
    int ans=0;
    for(int i=26;i>=1;i--)
        int moves=0;
        if(total%i==0)
            int eachshouldhave=total/i;
            int position=26;
            for(int j=1;j<26;j++)
                if(hash[j]>eachshouldhave && hash[j-1]<eachshouldhave)
                    position=j;
                    break;
                
            
            int extrasymbols=0;
            //THE ONES THAT ARE BELOW OBVIOUSLY NEED TO BE CHANGED TO SOME OTHER SYMBOL
            for(int j=position;j<26;j++)
                extrasymbols+=hash[j]-eachshouldhave;
            
            //THE ONES ABOVE THIS POSITION NEED TO GET SOME SYMBOLS FROM OTHERS
            for(int j=0;j<position;j++)
                moves+=(eachshouldhave-hash[j]);
            
            if(moves<ans)
            ans=moves;
        
        else
        continue;
    

【问题讨论】:

向我们展示您是如何实施您的方法的。 @legends2k 我编辑了。对不起 请张贴指向此问题根源的链接,以便我们知道它不是来自当前活跃的编程竞赛。谢谢! @Groo 从积极的竞争中提出问题是非常不道德的(因为其他人自己这样做,这会给你带来不公平的优势)。大多数“算法”标签参与者不愿意回答此类问题,并会投票关闭它们。 在公共问答网站上提问实际上会给每个人答案,不是吗?此外,这个问题完全属于 SO 格式:它不是题外话,它不要求工具推荐,它包括解决它的尝试,它不征求意见。您可以争辩说,许多关于 SO 的答案都可以用于不道德的目的。 【参考方案1】:

以下应该可以修复您的实现:

std::size_t compute_change_needed(const std::string& s)

    int count[26] =  0 ;

    for(char c : s) 
        // Assuming only valid char : a-z
        count[c - 'a']++;
    
    std::sort(std::begin(count), std::end(count), std::greater<int>);
    std::size_t ans = s.length();
    for(std::size_t i = 1; i != 27; ++i) 
        if(s.length() % i != 0) 
            continue;
        
        const int expected_count = s.length() / i;
        std::size_t moves = 0;
        for(std::size_t j = 0; j != i; j++) 
            moves += std::abs(count[j] - expected_count);
        
        ans = std::min(ans, moves);
    
    return ans;

【讨论】:

以上是关于找到获得“好”字符串的最小移动次数的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 找到从矩阵的一个单元格移动到另一个单元格所需的最小移动次数

Leetcode 453.最小移动次数使数组元素相等

LeetCode#453 最小移动次数使数组元素相等

453. 最小移动次数使数组元素相等

字符串去重并且获得最小字典序的我的一个思路

leetcode 简单 第一百零三题 最小移动次数使数组元素相等