336. 回文对 暴力解法+前缀树

该博客主要介绍了LeetCode 336题目的解法,包括暴力求解策略和使用前缀树进行优化的思路。暴力法虽然能解决一部分问题,但效率较低;前缀树的优化则能提高算法的性能。
摘要由CSDN通过智能技术生成

336. 回文对

难度:困难
题目描述
在这里插入图片描述

解题思路

1、万能暴力

最直接的想法当然就是暴力法,嘿嘿,能过一大半

/*
		     * 336. 回文对
		     *  *困难
		     *  2020/8/6
		     */
		    public List<List<Integer>> palindromePairs(String[] words) {
		    	int n = words.length;
		    	List<List<Integer>> re = new LinkedList<List<Integer>>();
		    	if(n == 0)
		    		return re;
		    	for (int i = 0; i < n; i++) {
					for (int j = 0; j < n; j++) {
						if(j != i && isHuiwen(words[i]+words[j])) {  //要除掉这个字符本身
							List<Integer> temp = new LinkedList<Integer>();
							temp.add(i);
							temp.add(j);
							re.add(temp);
						}
					}
				}
		    	return re;
		    }
		    
		    public boolean isHuiwen(String s) {
		    	int left = 0,right = s.length()-1;
		    	char[] str = s.toCharArray();
		    	while(left < right) {
		    		if(str[left] != str[right])
		    			return false;
		    		left++;right--;
		    	}
		    	return true;
		    }

2、前缀树优化(抄答案)

在这里插入图片描述

class Solution {
    class Node {
        int[] ch = new int[26];
        int flag;

        public Node() {
            flag = -1;
        }
    }

    List<Node> tree = new ArrayList<Node>();

    public List<List<Integer>> palindromePairs(String[] words) {
        tree.add(new Node());
        int n = words.length;
        for (int i = 0; i < n; i++) {
            insert(words[i], i);
        }
        List<List<Integer>> ret = new ArrayList<List<Integer>>();
        for (int i = 0; i < n; i++) {
            int m = words[i].length();
            for (int j = 0; j <= m; j++) {
                if (isPalindrome(words[i], j, m - 1)) {
                    int leftId = findWord(words[i], 0, j - 1);
                    if (leftId != -1 && leftId != i) {
                        ret.add(Arrays.asList(i, leftId));
                    }
                }
                if (j != 0 && isPalindrome(words[i], 0, j - 1)) {
                    int rightId = findWord(words[i], j, m - 1);
                    if (rightId != -1 && rightId != i) {
                        ret.add(Arrays.asList(rightId, i));
                    }
                }
            }
        }
        return ret;
    }

    public void insert(String s, int id) {
        int len = s.length(), add = 0;
        for (int i = 0; i < len; i++) {
            int x = s.charAt(i) - 'a';
            if (tree.get(add).ch[x] == 0) {
                tree.add(new Node());
                tree.get(add).ch[x] = tree.size() - 1;
            }
            add = tree.get(add).ch[x];
        }
        tree.get(add).flag = id;
    }

    public boolean isPalindrome(String s, int left, int right) {
        int len = right - left + 1;
        for (int i = 0; i < len / 2; i++) {
            if (s.charAt(left + i) != s.charAt(right - i)) {
                return false;
            }
        }
        return true;
    }

    public int findWord(String s, int left, int right) {
        int add = 0;
        for (int i = right; i >= left; i--) {
            int x = s.charAt(i) - 'a';
            if (tree.get(add).ch[x] == 0) {
                return -1;
            }
            add = tree.get(add).ch[x];
        }
        return tree.get(add).flag;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/palindrome-pairs/solution/hui-wen-dui-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值