Tony's Log

Algorithms, Distributed System, Machine Learning

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

My first reaction was to use Manacher - which is O(n*k*k) - n is the no. of words, and k is the average length of words.

Code of Manacher based solution is kinda long:

class Solution {
    vector<vector<int>> ret;

    //    To find lenghth of the leading Palin only
    vector<string> manacher(const string &s)
    {
        size_t slen = s.length();
        if (slen < 2) return { s };
        
        //    inserting tokens to original string
        string ns = "#";
        for (auto c : s)
        {
            ns += c;
            ns += "#";
        }

        //
        size_t len = ns.length();
        vector<size_t> rec(len, 0);

        int maxi = 1, maxr = 0; vector<int> rs_leading;
        int ci = 1, r = 0;
        for (size_t i = 1; i < len; i++)
        {
            int myr = 0;        //    brand new index
            if (i <= (ci + r))    //    can be reused due to symmetry
            {
                myr = std::min(rec[2 * ci - i], (ci + r) - i);
            }
            //    expand to new inx towards end of string
            bool bMis = false;
            int max_ex = std::min(len - 1 - i, i);
            while (myr < max_ex)
            {
                myr++;
                if (ns[i + myr] != ns[i - myr])
                {
                    bMis = true;
                    break;
                }
            }
            if (bMis) myr--;

            //    book-keeping
            rec[i] = myr;
            if ((i + myr) > (maxi + maxr))
                ci = i, r = myr;

            if (myr > maxr)    //     record max
            {
                maxi = i, maxr = myr;
                if (i == myr)
                {
                    rs_leading.push_back(maxr);
                }
            }
        }

        //    Retrieve the Palin
        vector<string> ret;
        for (auto l : rs_leading)
        {
            string raw = ns.substr(0, l * 2 + 1);
            string tmp;
            for (auto c : raw)
            {
                if (c != '#') tmp += c;
            }
            ret.push_back(tmp);
        }
        return ret;
    }

    void handleLeadingPalin(string w, int inxw, unordered_map<string, int> &dict, bool bReversed)
    {
        vector<string> hPalins = manacher(w);
        for (auto hPalin : hPalins)
        {
            int plen = hPalin.size();
            if (plen)
            {
                string tgt = w.substr(plen);
                if (!bReversed)
                    reverse(tgt.begin(), tgt.end());
        
                if (dict.find(tgt) != dict.end())
                {
                    int inxt = dict[tgt];
                    if (inxw != inxt)
                    {
                        if (!bReversed)
                            ret.push_back({ inxt, inxw });
                        else
                            ret.push_back({ inxw, inxt});
                    }
                }
            }
        }
    }
public:
    vector<vector<int>> palindromePairs(vector<string>& words) {
        
        //    Fill out String <-> Index dictionary
        unordered_map<string, int> dict;
        for (int i = 0; i < words.size(); i ++)
            dict[words[i]] = i;
                
        //    Go
        for (auto &k : dict)
        {
            int inx = k.second;

            // case 1: reverse the whole string
            string tgt1 = k.first;

            reverse(tgt1.begin(), tgt1.end());
            if (dict.find(tgt1) != dict.end())
            {
                int inx1 = dict[tgt1];
                if (inx1 != inx)
                    ret.push_back({inx, inx1});
            }

            // case 2a: leading manacher of key
            handleLeadingPalin(k.first, inx, dict, false);
            
            // case 2b: leading manacher of reverse(key)
            string tmp = k.first;
            reverse(tmp.begin(), tmp.end());
            handleLeadingPalin(tmp, inx, dict, true);
        }

        return ret;
    }
};

And please check this concise Python solution - so neat!

https://leetcode.com/discuss/91284/python-solution

posted on 2016-03-10 14:57  Tonix  阅读(216)  评论(0编辑  收藏  举报