LeetCode 767. Reorganize String

用backtracing做超时了,代码如下:

class Solution {
public:
    string res="";
    
    string reorganizeString(string s) {
        vector<bool> visited(s.size(),false);
        string tmp="";
        dfs(s,tmp,visited);
        return res;
    }
    
    void dfs(string s, string tmp, vector<bool> &visited){
        if (tmp.size()==s.size()){
            res = tmp;
            return;
        }
        for (int i=0;i<s.size();++i){
            if (visited[i] || tmp.size()!=0 && s[i]==tmp[tmp.size()-1]) continue;
            visited[i] = true;
            dfs(s,tmp+s[i],visited);
            visited[i] = false;
        }
    }
};

本题可以用优先队列+Greedy做。

首先对计算每个字母出现个数,根据个数建立优先队列,个数多的在前。每次选取队列前两个字母,这样一定不会有重复字母在一块。建立优先队列的时候,如果某个字母的出现次数比 (s.size()+1)/2 还要大,说明不行,返回""。

优先队列每次push和pop都要log(A),所以时间复杂度为O(nlogA)。A为字母个数

顺便复习一下优先队列排序的写法。

class Solution {
public:
    struct node{
        int count;
        char ch;
        node(int cnt, char c):count(cnt),ch(c){};
        bool operator < (const node &a) const{
            if (count==a.count) return ch>a.ch;
            return count<a.count;
        }
    };
    
    string reorganizeString(string s) {
        unordered_map<char,int> count;
        for (char ch:s) ++count[ch];
        priority_queue<node> q;
        for (auto x:count){
            if (x.second>(s.size()+1)/2) return "";
            q.push(node(x.second,x.first));
        }
        
        string res="";
        while (q.size()>=2){
            node a=q.top(); q.pop();
            node b=q.top(); q.pop();
            res.push_back(a.ch);
            res.push_back(b.ch);
            if (--a.count>0) q.push(a);
            if (--b.count>0) q.push(b);
        }
        if (q.size()==1) res+=q.top().ch;
        return res;
    }
    
};

猜你喜欢

转载自www.cnblogs.com/hankunyan/p/9644375.html