Leetcode 567. 字符串的排列(2022.03.16)

97 阅读1分钟

=================================================================================================================================================== 滑动窗口+排列 问题

比如说:s1是 abc,那么它的排列是 abc,acb,bca,bac,cab,cba

这里有一个巧妙的想法,我不管你的s1的顺序怎么排列,我只在乎你的s2中是否有相同长度,出现字符频率相同的子串。

利用数组来存窗口中字母出现的次数。

那么这个窗口的长度是由你的s1的长度来决定的,但是这是一个静态的窗口,我想要一个动态窗口。

`

int[] arr1 = new int[26];
int[] arr2 = new int[26];
for (int i = 0; i < s1.length(); i++) {
    arr1[s1.charAt(i)-'a']++;
    arr2[s2.charAt(i)-'a']++;
}

`

其实,你比较的是你的两个数组是否相等,因为你可以认为数组的下标是小写字母的排序。

`

int left=0;
int right=s1.length()-1;
while (right<s2.length()){
    if(Arrays.equals(arr1,arr2)) return true;
    right++;
    if (right != s2.length()){
        arr2[s2.charAt(right)-'a']++;
        arr2[s2.charAt(left)-'a']--;
    }
    left++;
}
return false;

` 设置两个游标,他们两个之间的长度就是s1的长度,通过控制游标的大小,从而来移动窗口。

你每一次移动移动一次右指针,都要移动一次左指针。

但是你不要忘记了你的临界条件是什么。你的左指针移动之前,一定要先把之前的数据清除。因为你的数组存的是你窗口里的字母出现的频率!!

而且左指针不需要继续存,因为你左指针所指的内容要不是一开始就存好了,要不然就是右指针帮你存好了。