正方形字符串解题思路

之前做到一道算法题感觉挺有意思的,题目内容如下:

给你一个字符串str,你必须让找到这个字符串中的最长的正方字符串,正方字符串是以下的形式
str = x + x; where x is any string. Return length of this square string.
Example
str = ababa
Max length square string = 4;
str = abcd
Max length square string = 1;

我思考了一下,认为首先可以用暴力解法。因为要满足正方字符串,必须是x+x,所以突破口可能是找到一个数组里2个相同的字母,再判断2个字母之间的子串和第二字母后面相同长度的子串是否相等。大致的思路为遍历2遍数组,第一遍的下标i从0到length-1,找到一个数组的元素,第二遍从i+1到length-1遍历,找到和第一遍遍历相同的元素,然后计算它们自己的间隔,看间隔子串是否和第二个字母后续相同长度的子串是否一样。这样的时间复杂度应该是o(n^3) (最差情况,2层循环o(n^2),匹配子串最差的情况是o(n))。空间复杂度因为只使用了临时变量,应该只有o(1)

后来再思考了一下,其实寻找位置的时候可以通过先遍历一遍数组,用map记录下每一个字符在哪些位置出现过。后续第二遍计算子串是否匹配时可以少一层遍历的时间复杂度,直接用map定位相同字母的位置。这种方式就是以时间换空间

代码如下:

    public static int getSquareString(String str) {
        if (str == null || str.length() == 0) {
            return 0;
        }
        int maxLength = 0;
        Map<Character, List<Integer>> positionMap = new HashMap<>();
        for (int i = 0; i < str.length(); i++) {
            positionMap.computeIfAbsent(str.charAt(i), k -> new ArrayList<>());
            positionMap.get(str.charAt(i)).add(i);
        }
        for (int leftIndex = 0; leftIndex < str.length(); leftIndex++) {
            for (Integer rightIndex : positionMap.get(str.charAt(leftIndex))) {
                int interval = rightIndex - leftIndex;
                if (rightIndex + interval < str.length()
                        && str.substring(leftIndex, leftIndex + interval)
                        .equals(str.substring(rightIndex, rightIndex + interval))) {
                    maxLength = Math.max(maxLength, 2 * interval);
                }
            }
            positionMap.get(str.charAt(leftIndex)).remove((Integer) leftIndex); // leftIndex遍历完了,后面应该也用不上了,可以直接删除
        }
        return maxLength;
    }

    public static void main(String[] args) {
        System.out.println(getSquareString("ababa"));
        System.out.println(getSquareString("abcd"));
        System.out.println(getSquareString("dssadassadas"));
        System.out.println(getSquareString("aaaaa"));
        System.out.println(getSquareString("aaaaabbbb"));
    }

这个算法时间复杂度下降至o(n^2),空间复杂度为o(n)

发布了72 篇原创文章 · 获赞 184 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/qq_16681169/article/details/100821839