LeetCode438题:找到字符串中所有字母异位词

版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/ASN_forever/article/details/85013363

原始思路1: 获取p串的全排列,与s暴力对比

但这种方法时间复杂度太高,主要是因为全排列的复杂度太高,如果p字符串长度为n的话,那么全排列复杂度为O(n!)。严重超时。

public class Test {
	Set<String> set = new HashSet<String>();
	public static void main(String[] args) {
		String s = "cbadecbabacdcbabdcadbc";
		String p = "abcd";
		Test t = new Test();
		List<Integer> list = t.findAnagrams(s, p);
		for (int i : list) {
			System.out.print(i + " ");
		}
	}

	public List<Integer> findAnagrams(String s, String p) {
		List<Integer> list = new ArrayList<Integer>();
		char[] arr = p.toCharArray();
		fun(arr, 0);
		for (int i = 0; i <= s.length() - p.length(); i++) {
			if (set.contains(s.substring(i, i + p.length()))) {
				list.add(i);
			}
		}
		return list;
	}

	public void fun(char[] arr, int index) {
		if (index == arr.length) {
			set.add(String.valueOf(arr));
			return;
		}
		for (int i = index; i < arr.length; i++) {
			swap(arr, index, i);
			fun(arr, index + 1);
			swap(arr, index, i);
		}
	}

	public void swap(char[] arr, int i, int j) {
		char temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
}

原始思路2:截取p长度的字符串排序比较

思路是先将p进行排序,然后在遍历s,每次遍历p个长度,并排序,然后与经过排序的p进行比较。

遗憾的是,也超时了。在测试用例全是一长串“a”的时候,超出了时间限制。

public List<Integer> findAnagrams(String s, String p) {
		List<Integer> list = new ArrayList<Integer>();
        if(s.length() < p.length() || s == null || p == null){
            return list;
        }
		char[] pArr = p.toCharArray();
		Arrays.sort(pArr);
		String strP = String.valueOf(pArr);
		int len = p.length();
		for(int i=0;i<=s.length()-len;i++){
            if(s.substring(i, i+len).equals(p)){
                list.add(i);
            }else{
                char[] sArr = s.substring(i, i+len).toCharArray();
			    Arrays.sort(sArr);
			    if(String.valueOf(sArr).equals(strP)){
				    list.add(i);
			    }
            }
		}
		return list;
    }

正规解法:滑动窗口法

表示没看太懂。感觉这种方法的关键部分是每比较一遍后,在进行下一轮比较前,需要复位。

public List<Integer> findAnagrams(String s, String p) {
		List<Integer> result = new ArrayList<Integer>();
        char[] sArr = s.toCharArray();
        char[] pArr = p.toCharArray();
        int[] word = new int[26];
        for(char ch : pArr){
            word[ch-'a']++;
        }
        int start = 0;
        for(int i=0;i<sArr.length;i++){
            int cIndex = sArr[i]-'a';
            word[cIndex]--;
            while(word[cIndex]<0){
                word[sArr[start]-'a']++;
                start++;
            }
            if(i-start+1 == pArr.length){
                result.add(start);
                word[sArr[start]-'a']++;
                start++;
            }
            
        }
        return result;
    }

猜你喜欢

转载自blog.csdn.net/ASN_forever/article/details/85013363
今日推荐