【LeetCode-中等题】438. 找到字符串中所有字母异位词

题目

在这里插入图片描述

题解一:暴力排序

依次截取三为排序好的字符串拿出来比较

在这里插入图片描述

// 方法一,暴力排序
          List<Integer> res = new ArrayList<Integer>();
          int n = s.length();
          int k = p.length();
          if (n < k) {
              return res;
          }
          char[] chars = p.toCharArray();
          Arrays.sort(chars);
          p = new String(chars); 
          // 只需要遍历一次,排序进行比较
          for (int i = 0; i <= n - k; i++) {
              // 找到长度为k的子字符串
              String temp = s.substring(i, i + k);
              // 进行排序
              chars = temp.toCharArray();
              Arrays.sort(chars);
              temp = new String(chars);
              if (p.equals(temp)) {
                  res.add(i);
              }
          }
          return res;

题解二:滑动窗口+记录字符出现次数

思路就是,设置两个数组,因为题目中说只包含小写字母,那么设置两个数组长度为26的数组,一个用于存放比较的串,一个用于滑动窗口的串

p.charAt(i)-'a'其实就代表i元素在这个数组的位置,那么只需记录固定窗口下的  字母出现的个数,与比较的串相比较
如p="abc",则pindex为[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

如过滑动的窗口元素是p="cba",sindex[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

在这里插入图片描述

//方法二 滑动窗口

 int plen  = p.length();
 int slen =  s.length();
 List<Integer> list = new ArrayList<>();
 int[] pindex = new int[26];
 int[] sindex = new int[26];
 if(slen<plen){
        return list;
    }
//如p="abc",则pindex为[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
//如过滑动的窗口元素是p="cba",sindex[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
// 这两个就是异位次   原理就是记录字母出现的次数,转换成出现的位置的索引值     
//                    abc[1,1,1,....]  索引 0 1 2 位置的值就是字母abc出现的次数值   
//假设需要匹配的字符串为cbc[0,1,2,....]   a 0个,b 1个,c 2个,明细不匹配

//当滑动窗口的首位在s[0]处时 (相当于放置滑动窗口进入数组)
for(int i = 0;i<plen;i++){
    pindex[p.charAt(i)-'a']++;//记录要寻找的字符串中每个字母的词频(只用进行一次来确定)
    sindex[s.charAt(i)-'a']++;//记录s中前pLen个字母的词频
}
//判断放置处是否有异位词     (在放置时只需判断一次)
if(Arrays.equals(pindex,sindex)) list.add(0);

 //开始让窗口进行滑动
 for(int i = 1;i<=slen-plen;i++){
   sindex[s.charAt(i-1)-'a']--;
  sindex[s.charAt(i+plen-1)-'a']++;

   //判断滑动后处,是否有异位词
        if(Arrays.equals(pindex,sindex)){
            list.add(i);
        } 
 }
 return list;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值