336. Palindrome Pairs

题目: Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

Example 1:
Given words = [“bat”, “tab”, “cat”]
Return [[0, 1], [1, 0]]
The palindromes are [“battab”, “tabbat”]
Example 2:
Given words = [“abcd”, “dcba”, “lls”, “s”, “sssll”]
Return [[0, 1], [1, 0], [3, 2], [2, 4]]
The palindromes are [“dcbaabcd”, “abcddcba”, “slls”, “llssssll”]
题目翻译:给一个不重复的单词列表,从给的列表中找出所有不重复下标(i,j)的组合,使得words[i] + words[j]是一个回文字符串。
解析:这个题主要的难点在于时间的约束,经过测试,当复杂度是n^2时,是超时的。
复杂度为n^2的解法:

    public List<List<Integer>> palindromePairs(String[] words) {
        //复杂度为n^2时比较简单,只要两层遍历,然后把两次遍历元素链接,判断链接的字符串是否是回文的就可以了
        List<List<Integer>> llRes =new ArrayList<>();
        for(int i=0;i<words.length;i++){
            for(int j=0;j<words.length;j++){
                StringBuffer sb=new StringBuffer(words[i]).append(words[j]);
                String str1=sb.toString();
                String str2=sb.reverse().toString();
                if(i!=j&&str1.equals(str2)){
                    List<Integer> listTmp=new ArrayList<>();
                    listTmp.add(i);
                    listTmp.add(j);
                    llRes.add(listTmp);
                }
            }
        }
        return llRes;
    }

复杂度为n+m的解法:

 public List<List<Integer>> palindromePairs(String[] words) {
        List<List<Integer>> llRes =new ArrayList<>();
        HashMap<String,Integer> hashMap=new HashMap<>();
        //因为words是不重复,所以用hashMap存储以word为key,以下标为value
        for(int i=0;i<words.length;i++){
           hashMap.put(words[i],i);
        }
        //对于hashMap里面的每个元素有以下三种情况会有形成回文字符串的可能
       for (String key : hashMap.keySet()) {
            //第一种可能,如果当前map的key是个回文字符串,那么只要hashMap中有空的字符串"",
            //那么这两个元素分别在左右,可以形成两个下标组合,当然因为i!=j,所以当前key不能和""相同
            if(hashMap.containsKey("")&&isPalindrome(key)&&hashMap.get("")!=hashMap.get(key)){
                List<Integer> tmp=new ArrayList<>();
                tmp.add(hashMap.get(key));
                tmp.add(hashMap.get(""));
                List<Integer> tmp2=new ArrayList<>();
                tmp2.add(hashMap.get(""));
                tmp2.add(hashMap.get(key));
                llRes.add(tmp);
                llRes.add(tmp2);
            }
            //第二种可能,如果当前key的反转字符串在hashMap中,那么当前value和取反字符串的value,
            //可以组合成一个下标组合
            String strReverse=new StringBuffer(key).reverse().toString();
            if(hashMap.containsKey(strReverse)&&hashMap.get(strReverse)!=hashMap.get(key)){
                List<Integer> tmp=new ArrayList<>();
                tmp.add(hashMap.get(key));
                tmp.add(hashMap.get(strReverse));
                llRes.add(tmp);
            }
            //第三种可能,比较复杂一点。这个要把当前key分成左右两个部分,
            //左边部分left从1个元素到key.size-1个元素,
            //右边部分right从key.size-1到1个元素
            for(int i=1;i<key.length();i++){
                String left = key.substring(0,i);
                String right = key.substring(i,key.length());
                //如果left是一个回文字符串,那么如果hashMap中存在right的反转字符串。
                //那么当前value和right的反转字符串的value可以组成一个下标组合
                if(isPalindrome(left)){
                    String rightReverse=new StringBuffer(right).reverse().toString();
                    if(hashMap.containsKey(rightReverse)&&hashMap.get(rightReverse)!=hashMap.get(key)){
                        List<Integer> tmp=new ArrayList<>();
                        tmp.add(hashMap.get(rightReverse));
                        tmp.add(hashMap.get(key));
                        llRes.add(tmp);
                    }
                }
                //如果right是一个回文字符串,那么如果hashMap中存在left的反转字符串。
                //那么当前value和left的反转字符串的value可以组成一个下标组合
                if(isPalindrome(right)){
                    String leftReverse=new StringBuffer(left).reverse().toString();
                    if(hashMap.containsKey(leftReverse)&&hashMap.get(leftReverse)!=hashMap.get(key)){
                        List<Integer> tmp=new ArrayList<>();
                        tmp.add(hashMap.get(key));
                        tmp.add(hashMap.get(leftReverse));
                        llRes.add(tmp);
                    }
                }
            }
        }
        return llRes;
    }
    //判断一个字符串是否是回文字符串
    public boolean isPalindrome(String str){
        for(int i=0;i<str.length()/2;i++){
            if(str.charAt(i)!=str.charAt(str.length()-1-i)){
                return false;
            }
        }
        return true;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值