滑动窗口属于比较典型的类型题,下面属于比较简单的题

无重复的最长字串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

因为我之前做过类似的题目,我最开始的想法是利用ASLL码,将字符转成对应数字,对应数组的坐标,利用数组存储改字符串的出现的个数,但是在实现的过程中,我发现了在字符转转化的过程中,还是非常的麻烦的,于是我想到了一种数据结构,哈希表,使用哈希表我们就不需要考虑这些问题

我们结合双指针,我们右指针不断向前遍历,将遍历到元素存入哈希表中,当哈希表中遇到重复元素时,做指针开始移动,移动到重复元素的下一位停止,右指针再一次开始运动。
B9FFC8048DA6A4AF60DEF142C8C2C654.jpg

  1. public int lengthOfLongestSubstring(String s) {
  2. Set<Character> a=new HashSet<>();
  3. int n=s.length();
  4. int right=0,max=0;
  5. for (int i=0;i<n;i++){
  6. if(i!=0){
  7. a.remove(s.charAt(i-1));
  8. }
  9. while (right < n && !a.contains(s.charAt(right))){
  10. a.add(s.charAt(right));
  11. right++;
  12. }
  13. max=Math.max(max,right-i);
  14. }
  15. return max;
  16. }

字符串的排列

给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。换句话说,s1 的排列之一是 s2 的 子串 。

要求:
1 <= s1.length, s2.length <= 104
s1 和 s2 仅包含小写字母

输入:s1 = “ab” s2 = “eidbaooo”
输出:true
解释:s2 包含 s1 的排列之一 (“ba”).

输入:s1= “ab” s2 = “eidboaoo”
输出:false

这道题最开始的时候还是让我想到了我上一道题的解法,利用数组的坐标来表示元素,因为他的限定条件是仅包含小写字母,我们利用ASLL的值可以很好的表示元素。
题目中要求的是子串,就存在排列的影响,子串排列的种类太多了,但是正因为是子串,只要我们存在的元素种类,个数都相同,我们就可以判断他们是相同的,只是排列的顺序不同。

  1. public boolean checkInclusion(String s1, String s2) {
  2. int [] num1=new int[26];
  3. int [] num2=new int[26];
  4. if((s2.length()-s1.length())<0){
  5. return false;
  6. }
  7. //我们先获取s1的长度的数组,去判断他们的起始头部是否相同
  8. for(int i=0;i<s1.length();i++){
  9. num1[s1.charAt(i)-'a']++;
  10. num2[s2.charAt(i)-'a']++;
  11. }
  12. if(Arrays.equals(num1,num2)){
  13. return true;
  14. }
  15. //再利用滑动窗口,窗口长度固定,不断滑动,判断窗口中元素是否符合要求
  16. for(int i=s1.length();i<s2.length();i++){
  17. //添加新的元素
  18. num2[s2.charAt(i)-'a']++;
  19. //删除窗口中第一位元素
  20. num2[s2.charAt(i-s1.length())-'a']--;
  21. if(Arrays.equals(num1,num2)){
  22. return true;
  23. }
  24. }
  25. return false;
  26. }

因为将字母存入数组,所以我们只需判断数组中元素是否一样我们就知道,字符串是否一样了。

用数组的坐标表示元素,数组存储元素个数,我也忘记了是从哪学到了,但是我一直没用忘记这种用法,自己用起来还是很方便的。