zoukankan      html  css  js  c++  java
  • 上升下降字符串

    1370. 上升下降字符串

    给你一个字符串 s ,请你根据下面的算法重新构造字符串:

    从 s 中选出 最小 的字符,将它 接在 结果字符串的后面。
    从 s 剩余字符中选出 最小 的字符,且该字符比上一个添加的字符大,将它 接在 结果字符串后面。
    重复步骤 2 ,直到你没法从 s 中选择字符。
    从 s 中选出 最大 的字符,将它 接在 结果字符串的后面。
    从 s 剩余字符中选出 最大 的字符,且该字符比上一个添加的字符小,将它 接在 结果字符串后面。
    重复步骤 5 ,直到你没法从 s 中选择字符。
    重复步骤 1 到 6 ,直到 s 中所有字符都已经被选过。
    在任何一步中,如果最小或者最大字符不止一个 ,你可以选择其中任意一个,并将其添加到结果字符串。

    请你返回将 s 中字符重新排序后的 结果字符串 。

     

    示例 1:

      输入:s = "aaaabbbbcccc"
      输出:"abccbaabccba"
      解释:第一轮的步骤 1,2,3 后,结果字符串为 result = "abc"
      第一轮的步骤 4,5,6 后,结果字符串为 result = "abccba"
      第一轮结束,现在 s = "aabbcc" ,我们再次回到步骤 1
      第二轮的步骤 1,2,3 后,结果字符串为 result = "abccbaabc"
      第二轮的步骤 4,5,6 后,结果字符串为 result = "abccbaabccba"
    示例 2:

      输入:s = "rat"
      输出:"art"
      解释:单词 "rat" 在上述算法重排序以后变成 "art"
    示例 3:

      输入:s = "leetcode"
      输出:"cdelotee"
    示例 4:

      输入:s = "ggggggg"
      输出:"ggggggg"
    示例 5:

      输入:s = "spo"
      输出:"ops"
     

    提示:

    1 <= s.length <= 500
    s 只包含小写英文字母。

    思路:

    方法一:桶记数
    思路

    我们可以开一个长度为 26 的数组表示 26 个桶,每个桶里存放一种字母。先用 O(|s|) 的时间扫描一遍字符串(其中 |s| 代表字符串的长度),统计每个字母出现的次数。然后我们只要不停地扫描这里的「桶序列」——先从小到大扫,再从大到小扫,每次发现一个桶当中计数值不为 0 的时候,就把这个桶对应的字母添加到结果字符串的最后方,然后对计数值减一。

    具体地,开一个长度为 26 的数组 h[],作为用来计数的「桶」。haveChar 的功能是在每次循环开始执行之前判断是否还有未使用的字符。appendChar 的功能是检测当前位置的桶是否计数值为 0,如果不为 0 则修改目标串和计数值。

    官方代码:

     

    class Solution {
    public:
        int h[26];
    
        inline bool haveChar() {
            for (int i = 0; i < 26; ++i) {
                if (h[i]) {
                    return true;
                }
            }
            return false;
        }
    
        string sortString(string s) {
            for (const auto &c: s) ++h[c - 'a'];
    
            string ret;
    
            auto appendChar = [&] (int p) {
                if (h[p]) {
                    --h[p];
                    ret.push_back(p + 'a');
                }
            };
    
            while (true) {
                if (!haveChar()) break;
                for (int i = 0; i < 26; ++i) appendChar(i);
                for (int i = 25; i >= 0; --i) appendChar(i);
            }
    
            return ret;
        }
    };

     

    代码:

    #include<iostream>
    #include<cstring>
    using namespace std;
    int h[26];
    string sortString(string s){
        int j=0;
        while(s[j])
            ++h[s[j++]-'a'];   //计算每个字符出现的次数
        string ans;
        int n =0,len = s.length();
        while (n<len)
        {
            for (int i = 0; i < 26; i++)//从小到大
                if (h[i]){
                    ans.push_back(i+'a');
                    h[i]--;
                    n++;
                }
            for(int i=25;i>=0;i--)//从大到小
                if(h[i]){
                    ans.push_back(i+'a');
                    h[i]--;
                    n++;
                }    
        }
        return ans;
    }
    int main(){
        string s;
        cin>>s;
        cout<<sortString(s);
    }

    测试数据:

    leetcode

    输出:

    cdelotee

     

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/13449709.html

  • 相关阅读:
    Ubuntu adb devices :???????????? no permissions (verify udev rules) 解决方法
    ubuntu 关闭显示器的命令
    ubuntu android studio kvm
    ubuntu 14.04版本更改文件夹背景色为草绿色
    ubuntu 创建桌面快捷方式
    Ubuntu 如何更改用户密码
    ubuntu 14.04 返回到经典桌面方法
    ubuntu 信使(iptux) 创建桌面快捷方式
    Eclipse failed to get the required ADT version number from the sdk
    Eclipse '<>' operator is not allowed for source level below 1.7
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/13449709.html
Copyright © 2011-2022 走看看