首页 > 其他分享 >LeetCode767 重构字符串

LeetCode767 重构字符串

时间:2024-07-26 23:17:59浏览次数:16  
标签:重构 字符 元素 次数 mp LeetCode767 字符串 mx

题解

通常直接思考最佳策略是十分困难的,我们不妨思考每一种情况需要如何处理:

  1. 整个字符串只有一种字符
    若字符串长度为 \(1\),那么字符串本身即为答案;
    若字符串长度大于等于 \(2\),那么不存在可行方案

  2. 整个字符串只有两种字符 \(c_1,c_2\),数量分别为 \(n_1,n_2\)
    若字符 \(c_1\) 的数量 \(n_1\) == 字符 \(c_2\) 的数量 \(n_2\),明显字符 \(c_1\) 和字符 \(c_2\) 交替出现即可
    若字符 \(c_1\) 的数量 \(n_1\) > 字符 \(c_2\) 的数量 \(n_2\),那么每两个字符 \(c_1\) 之间必须插入一个字符 \(c_2\),也就是 \(n_1 - 1 \leq n_2\)。进一步思考,\(abs(n_1-n_2)\) 可以大于 \(1\) 吗?答案是不行,因为无法为每两个字符 \(c_1\) 之间插入一个字符 \(c_2\)
    若字符 \(c_1\) 的数量 \(n_1\) < 字符 \(c_2\) 的数量 \(n_2\),情况类似于 \(n_1 > n_2\) 的情况
    从只有两种字符的情况,易得到启发:出现次数最多的字符,每两个之间必须插入至少一个不同的字符

  3. 整个字符串有 \(n(1 \leq n \leq 26)\) 种字符,第 \(i\) 种字符的数量为 \(n_i\)
    由只有两种字符的字符串重构成功的方案来看,在有 \(n\) 种类字符的字符串中,需要首先处理出现次数最多的元素,不妨记出现次数为 \(m = max(n_i)\)
    如下图所示,至少需要在 \(m\) 个元素之间插入一个与左右相邻元素均不同的元素:

    所以,只需要将 \(m\) 个出现次数最多的元素(若有多个出现次数最多的元素,任意选择其中一个即可)先依次放入位置 \(x_j(1 \leq j \leq m)\),随后将剩下的全部元素,按种类依次从位置 \(x_1\) 填到为止 \(x_m\)即可。
    若 全部元素个数 - \(m < m - 1\),则无解,否则有解。

问:为什么维护出现次数最多的种类元素是可行的方案?
答:因为题目要求的是相邻两个元素不可相同,那么在字符串中全部种类的单种元素的出现次数都不会超过\(max(n_i)\)。因此,只需要先维护其中一个出现次数最多的元素,并将剩余的元素按种类依次填入这\(max(n_i)\)个元素之后,必定符合每两个相邻元素不同的要求。按种类填入指的是,按单种元素

参考代码

class Solution {
public:
    string reorganizeString(string s) {
        string ans;
        vector<int> mp(26);
        for (auto &it: s) {
            mp[it - 'a'] ++;
        }
        int mx = 0, idx = 0, sum = 0;
        for (int i = 0; i < 26; ++ i) {
            if (mx < mp[i]) {
                mx = mp[i];
                idx = i;
            }
            sum += mp[i];
        }
        if (sum - mx >= mx - 1) {
            vector<vector<char>> v(mx);
            for (auto &it: v) {
                it.push_back('a' + idx);
            }
            mp[idx] = 0;
            int cur = 0;
            for (int i = 0; i < 26; ++ i) {
                while (mp[i] > 0) {
                    v[cur].emplace_back('a' + i);
                    cur = (cur + 1) % mx;
                    -- mp[i];
                }
            }   
            for (auto &u: v) {
                for (auto &i: u) {
                    ans.push_back(i);
                }
            }
        }
        return ans;
    }
};

标签:重构,字符,元素,次数,mp,LeetCode767,字符串,mx
From: https://www.cnblogs.com/RomanLin/p/18324910

相关文章

  • 致敬传奇 Kruskal 重构树题硬控我三小时
    NOI2018归程存边的数组拿来干两件事,忘了清空了,其实最好开两个的dfs没开vis导致不知道为什么出现的绕圈倍增的fa[i][j]定义的时候前面是\(2^{i}\)写着写着记错成后面了忘记要递减排序了,跑的最小生成树并查集没初始化不知道为什么,倍增的fa数组单独一块处理会WA,回......
  • 算法笔记|Day8字符串II
    算法笔记|Day8字符串II☆☆☆☆☆leetcode151.翻转字符串里的单词题目分析代码☆☆☆☆kamacoder55.右旋字符串(待补充)题目分析代码☆☆☆☆☆leetcode28.实现strStr()题目分析代码☆☆☆☆☆leetcode459.重复的子字符串题目分析代码☆☆☆☆☆leetcode151......
  • 在PB中,字符串与十六进制的互转
    //字符串转换为16进制stringls_hex='',hex=''charlch_hex[0to15]={'0','1','2','3','4','5','6','7','8','9','a','......
  • kruskal重构树
    比较好理解,相当于重建了一个二叉树,所有的父亲节点都为原来图中的边,儿子节点为点。重构树就可以利用lca求两点间的最大(或者最小)边权以及一些树上操作。较为简单的应用,需要用线段树来维护信息。点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN=1e6;i......
  • ceph数据重构原理
    本文分享自天翼云开发者社区《ceph数据重构原理》,作者:x****n在分布式存储系统Ceph中,硬盘故障是一种常见问题。为了保证数据安全,当发生硬盘故障后,分布式存储系统会依据算法对故障硬盘上的数据进行数据重构及转储。和一般分布式系统一样的是,Ceph同样使用多副本机制来保证数据的高......
  • Kruskal 重构树学习笔记
    Kruskal想必大家都不陌生,这是一种求最小生成树的算法。关于Kruskal重构树,就是把一张图转化为一个堆。具体来说,我们可以处理出来从\(u\)到\(v\)路径中的点权或边权的极值。比如上面这张图(前为编号,[]内为点权),我们可以将它重构为小顶堆,如下请注意,这棵树有着严格的方向,......
  • TypeError:Flask 应用程序中的字符串索引必须是整数,而不是“str”
    这是我的代码:fromflaskimportFlask,render_templatefrompostimportPostimportrequestsposts=requests.get("https://api.npoint.io/5abcca6f4e39b4955965").json()post_objects=[]forpostinposts:post_obj=Post(post['id'],po......
  • 迭代字符串列表以检索字符串组
    给定以下列表:inp=["arg1:","list","of","args","arg2:","other","list"]如何开发这样的字典?out={"arg1":["list","of","args"],"arg2":......
  • 代码随想录day10 || 232 栈实现队列, 225 队列实现栈,20 删除有效括号,1047 删除字符串相
    232实现队列//go本身并不支持原生的栈和队列结构,都是通过切片实现的//leetcodesubmitregionbegin(Prohibitmodificationanddeletion)typeMyQueuestruct{ Data[]int Sizeint}funcConstructor()MyQueue{ returnMyQueue{}}func(this*MyQueue)Push(......
  • 字符串哈希
    进制哈希BKDRHash哈希函数字符串哈希:$\color{red}{构造一个数字使之唯一代表一个字符串}$。但是为了将映射关系一一对应,也就是,一个字符串代表一个数字,那么一个数字也对应一个字符串。我们希望这一个映射是个单射,即保证任意的字符串对应的数字是唯一的,也就是不出现一个数字对应......