【Leetcode】438. Find All Anagrams in a String

    xiaoxiao2021-03-25  47

    方法一:

    思路:

    暴力用hash,先对p排序,遍历s,判断长度与p相等的子串排序后是否与排序后的p相等。时间复杂度O(m*n)。

    public class Solution { public List<Integer> findAnagrams(String s, String p) { List<Integer> result = new ArrayList<>(); int sLen = s.length(); int pLen = p.length(); char[] p0 = p.toCharArray(); Arrays.sort(p0); String newP = new String(p0); if (s == null || sLen == 0) return result; for (int i = 0; i <= sLen - pLen; i++) { String temp = s.substring(i, i + pLen); char[] arr = temp.toCharArray(); Arrays.sort(arr); String newArr = new String(arr); if (newArr.equals(newP)) result.add(i); } return result; } }

    Runtime:超时

    方法二:

    思路:

    (1)创建了左右两个标志位,一个用来表示判断字符串的起始位,一个表示终止位,都从0开始,count初始化为p的长度,用数组hash[]存储p中每个字母的数量。

    (2)只要右标志位没有到s的最右边,就进行大循环。

    (3)对右标志位记录的s中的字母进行判断,看p中有没有,找到了,就把表示要判断的字符串长度减一,不管有没有找到,都要把数量数组减少,右标志位右移,这是为了之后进行判断,因为要找的的字符串始终处于左和右的标志位的中间。

    (4)如果要找的字符串的长度减少到0了,说明在左右标志位中间找到了p字符串长度的重组字,这时候就可以把左标志位,也就是开始的位置,添加到结果数组中。

    (5)在循环的最后,先判断左右标志位中间是否是p的长度,是的话,就该把左标志位也右移了,而右移之前,先要看看左标志位这个数是否找到过,找到过则要把count数量补回1,不论有没有找到过,都要将数组中的对应的字母数量补回1

    public class Solution { public List<Integer> findAnagrams(String s, String p) { List<Integer> result = new ArrayList<Integer>(); if (s == null || s.length() == 0) return result; int[] hash = new int[256]; for (char c : p.toCharArray()) hash[c]++; int left = 0, right = 0, pLen = p.length(), sLen = s.length(); int count = pLen; while (right < sLen) { if (hash[s.charAt(right)] >= 1) count--; hash[s.charAt(right)]--; right++; if (count == 0) result.add(left); if (right - left == pLen) { if (hash[s.charAt(left)] >= 0) count++; hash[s.charAt(left)]++; left++; } } return result; } }

    Runtime:21ms

    转载请注明原文地址: https://ju.6miu.com/read-32329.html

    最新回复(0)