leetcode567字符串的排列

leetcode567字符串的排列

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

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

示例2:
输入: s1= “ab” s2 = “eidboaoo”
输出: False

我第一次做的时候比较字符串暴力超时了,后来看到题解说可以用map映射做。

具体思路:两个映射分别代表s1的窗口和s2的窗口,用长度为26的数组表示。

每次移动窗口之后,只需要比较s2的数组是不是完全与s1的数组一样就行。而移动窗口也意味着左窗口对应的数字减一(s2Map[s2.charAt(i)-97]–),右窗口加一(s2Map[s2.charAt(i+s1.length())-97]++).

public boolean checkInclusion(String s1, String s2) {
       if (s1.length() > s2.length())
            return false;
        int[] s1Map=new int[26];
        int[] s2Map=new int[26];
        for(int i=0;i<s1.length();i++) {
        	s1Map[s1.charAt(i)-97]++;
        	s2Map[s2.charAt(i)-97]++;
        }
        for(int i=0;i<s2.length()-s1.length();i++) {
        	if(judge(s1Map,s2Map))
        		return true;
        	s2Map[s2.charAt(i)-97]--;
        	s2Map[s2.charAt(i+s1.length())-97]++;
        	
        }
        return judge(s1Map,s2Map);
    }
	public boolean judge(int[] map1,int[] map2) {
		for(int i=0;i<map1.length;i++) {
			if(map1[i]!=map2[i])
				return false;
		}
		return true;
	}

但是这种方式多开辟了一个数组。还可以只用一个数组。

优化版

只用一个数组index,在创建的时候可以做一些手脚。将s1中的每个字母在对应的位置上减一,对于s2来说,把字母对应值加一。这样就可以正负抵消,最后如果index全都是0,那么就说明存在这样的一个串。

public boolean checkInclusion(String s1, String s2) {
        if (s1.length() > s2.length())
            return false;
        int[] index=new int[26];
        for(int i=0;i<s1.length();i++) {
        	index[s1.charAt(i)-'a']--;
        	index[s2.charAt(i)-'a']++;
        }
        if(judge(index))return true;
        for(int j=0;j<s2.length()-s1.length();j++) {
        	index[s2.charAt(j)-'a']--;
        	index[s2.charAt(j+s1.length())-'a']++;
        	if(judge(index))return true;
        }
        return false;
    }
	public boolean judge(int[] index) {
		for(int i=0;i<index.length;i++) {
			if(index[i]!=0)
				return false;
		}
		return true;
	}

后记:做这道题我第一反应是觉得有什么快速简单的方法,觉得肯定不是暴力破解。结果想了半个多小时,最后没辙还是用暴力破解提交的,而且还超时。给我的教训就是:有的时候可能没有那么多捷径,真的就是暴力破解(或者有捷径我也想不出来_(:τ」∠)_ )。
leetcode 4/100

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值