2021/02/10 每日一题 字符串的排列

LeetCode上字符串的排列,中等难度的,记录下解题思路

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列,s1的排列不限,只要s2中包含s1的任意排序数组即可
那么就是给定个s1长度的窗口,在s2中移动,每次移动都判断当前窗口中的数组和s1的关系

反正只需要判断窗口内是否有s1的元素即可

  1. 通过遍历s1,建立一个关于s1的map,对应s1的元素和出现的次数
  2. 在s2上创建窗口,窗口也创建一个对应的map,用于记录当前窗口内的元素和出现的次数
  3. 当窗口大小等于s1的长度的时候,对比当前窗口map以及s1的map之间是否相等
    如果相等,那就代表窗口的元素和出现的次数就和s1相同,那么就满足题意
  4. 窗口大于s1长度的时候,那么窗口就要整体右移,将窗口left对应的元素移出,并且修改map中对应元素出现的次数
  5. 如果循环完整个s2还没有出现窗口和s1相等的情况,那么就代表整个s2都不满足条件,返回false
var checkInclusion = function(s1, s2) {
  // 传入的是s1和s2两个字符串,保存对应的长度
  let s1_len = s1.length
  let s2_len = s2.length
  // 用Map保存s1中出现的元素次数
  let s1_map = new Map()
  // 另一个map保存窗口中的元素
  let s2_map = new Map()
  // 定义窗口
  let left = 0
  let right = 0
  // 首先遍历s1,创建map
  for(let i =0;i {
        // 遍历s1_map 判断当前窗口内是否有这些元素,并且相等
        // console.log(s2_map.has(i),s2_map.get(i),i,x);
        if(s2_map.has(i) && s2_map.get(i) === x) {
          count = count + x
        }
      })
      // console.log(count,s1_len);
      if(count === s1_len) return true
    }
    right++
    if(right - left + 1 > s1_len) {
      // 当窗口大于s1的长度的时候
      //要将left元素移出
      s2_map.set(s2[left],s2_map.get(s2[left])-1)
      //left还要右移
      left++
    }
    
  }
  return false
};

你可能感兴趣的:(2021/02/10 每日一题 字符串的排列)