Leetcode 336. Palindrome Pairs 给出一种遍历字符串回文子串中心的方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/luke2834/article/details/78154601

题意

  • 给你n个不同的字符串,让你找出所有的字符串对(i, j),使得s(i) + s(j)是回文串且i不等于j

思路

  • 这题没有给数据范围,所以你其实不知道应该给什么复杂度的算法,我看了眼Discussion,先确定了下需要的复杂度
  • 复杂度是O(n * k ^ 2),其中k是字符串的平均长度
  • 算法思路并不复杂,考虑第i个字符串,如果s = s(i) + s(j)是答案之一,且i是较长的字符串,那么s的回文中心一定出现在 s(i)中,所以我们只要遍历s(i)可能的回文中心t即可,不失一般性,我们假设len(s(i, 1…t)) > len(s(i, t…l)),其中l = len(s(i)),此时需要在s(i)右侧拼接字符串,且需要拼接的字符串已经确定了,我们可以通过hash map快速找到对应字符串的id
  • 需要注意的是如果两个拼接的字符串长度一样,则可能重复添加到ans list里,这里我采用的方法是如果发现拼接的字符串长度相等,则只有j > i时我才把该结果加入list中
  • 最后就是如何比较容易的实现遍历字符串回文子串中心的方法,我设计了一种还可以的策略,这里记录一下~

遍历字符串回文子串中心的方法

  • 不难发现,对于一个长度为n的字符串,可能的回文子串中心有2n + 1个

    1. 间隔插入特殊字符:
      • 如:aba =》 #a#b#a#
      • 这种方法一般用在曼彻斯特算法中
    2. 直接遍历:
      for (int m = 0; m <= 2 * len; m++){
          int l_start = m / 2 - 1;
          int r_start = m/2 + (m & 1);
          //do 
      }

实现

class Solution {
public:
    vector<vector<int> > res;
    unordered_map<string, int> mapp;
    int n;
    inline vector<int> get_pair(int x, int y){
        vector<int> res;
        res.push_back(x);
        res.push_back(y);
        return res;
    }
    void go(string& s, int idx, bool flag){
        int len = s.length();
        for (int m = len; m <= 2 * len; m++){
            int ls = m / 2 - 1;
            int rs = m / 2 + (m & 1);
            int r = rs, l = ls;
            for (;r < m; r++, l--){
                if (s[l] != s[r]){
                    break;
                }
            }
            if (r < len){
                continue;
            }
            string tmp = "";
            for (; l >= 0; l--){
                tmp += s[l];
            }
            if (flag){
                auto it = mapp.find(tmp);
                if (it != mapp.end() && it->second != idx){
                    if (m < 2 * len || idx < it->second){
                        res.push_back(get_pair(idx, it->second));
                    }
                }
            }
            else{
                reverse(tmp.begin(), tmp.end());
                auto it = mapp.find(tmp);
                if (it != mapp.end() && it->second != idx){
                    if (m < 2 * len || idx < it->second){
                        res.push_back(get_pair(it->second, idx));
                    }
                }
            }
        }
    }

    vector<vector<int>> palindromePairs(vector<string>& words) {
        n = words.size();
        for (int i=0;i<n;i++){
            mapp[words[i]] = i;
        }
        for (int i=0;i<n;i++){
            string s = words[i];
            go(s, i, true);
            reverse(s.begin(), s.end());
            go(s, i, false);
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/luke2834/article/details/78154601