两字符串拼接形成回文串

leetcode336. 回文对

给定一组 互不相同 的单词, 找出所有 不同 的索引对 ( i , j ) (i, j) (i,j),使得列表中的两个单词, w o r d s [ i ] + w o r d s [ j ] words[i] +words[j] words[i]+words[j] ,可拼接成回文串。
提示:

  • 1 <= words.length <= 5000
  • 0 <= words[i].length <= 300
  • words[i] 由小写英文字母组成

思路

选取一个字符串 s s s,将其分成两个部分 l e f t left left, r i g h t right right,若存在一个字符串 s ′ s' s满足 r i g h t right right是回文串且 s ′ s' s的翻转等于 l e f t left left,那么 s + s ′ s+s' s+s是回文串。同样的若 l e f t left left是回文串且且 s ′ s' s的翻转等于 r i g h t right right,那么 s ′ + s s'+s s+s也是回文串。所以可以先预处理出来所有字符串的翻转字符串,那么判断 l e f t left left r i g h t right right是否存在 s ′ s' s是其翻转的时间复杂度为 O ( 1 ) O(1) O(1)。枚举 l e f t left left长度的时间复杂度为 O ( l ) O(l) O(l),判断 l e f t left left r i g h t right right是否回文时间复杂度为 O ( l ) O(l) O(l)。所以总体的时间复杂度为 O ( n l 2 ) O(nl^2) O(nl2),其中 n n n是字符串个数, l l l是字符串长度。数据有点弱,可以通过

代码

class Solution {
    public List<List<Integer>> palindromePairs(String[] words) {
        int n = words.length;
        Map<String,Integer> map = new HashMap<>();
        for(int i = 0; i < n; i++) {
            String s = words[i];
            String ss = new StringBuilder(s).reverse().toString();
            map.put(ss, i);
        }
        List<List<Integer>> res = new ArrayList<>();
        for(int i = 0; i < n; i++) {
            String s = words[i];
            if(s.length() == 0) {
                continue;
            }
            for(int j = 0; j <= s.length(); j++) {
                String left = s.substring(0,j), right = s.substring(j);
                if(check(right) && map.get(left) != null && map.get(left) != i) {
                    List<Integer> tmp = new ArrayList<>();
                    tmp.add(i); tmp.add(map.get(left));
                    res.add(new ArrayList<>(tmp));
                }
                if(j != 0 && check(left) && map.get(right) != null && map.get(right) != i) {
                    List<Integer> tmp = new ArrayList<>();
                    tmp.add(map.get(right)); tmp.add(i); 
                    res.add(new ArrayList<>(tmp));
                }
            }
        }
        return res;
    }

    public boolean check(String s) {
        int l = 0, r = s.length() - 1;
        while(l < r) {
            if(s.charAt(l) != s.charAt(r)) {
                return false;
            }
            l++; r--;
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值