leetcode[Find All Anagrams in a String]

错误解法(这种解法对于很大的输入会造成超时,循环是O(N),判断的函数又是O(N),总复杂度是O(N^2)了):

public class Solution {
	private boolean isSame(char[] a, char[] b){
		for(int i = 0; i < a.length; i++){
			if(a[i] != b[i])
				return false;
		}
		return true;
	}
	
    public List<Integer> findAnagrams(String s, String p) {
    	List<Integer> res = new ArrayList<>();
    	char[] pa = p.toCharArray();
    	Arrays.sort(pa);
        for(int i = 0; i < s.length() - p.length() + 1; i++){
        	char[] sa = s.substring(i, i + p.length()).toCharArray();
        	Arrays.sort(sa);
        	if(isSame(sa, pa)){
        		res.add(i);
        	}
        }
        
        return res;
    }
}

正解:

public class Solution {
	//Same idea from a fantastic sliding window template,与比较子串有关的都可以采用这种算法,window就是子串
	//Time Complexity will be O(n) because the "start" and "end" points will only move from left to right once.
	public List<Integer> findAnagrams(String s, String p) {
		List<Integer> list = new ArrayList<>();
		if (s == null || s.length() == 0 || p == null || p.length() == 0)
			return list;
    
		int[] hash = new int[256]; //character hash,256保险起见,字符个数不可能多于256个
    
		//record each character in p to hash
		for (char c : p.toCharArray()) {
			hash[c]++;
		}
		//two points, initialize count to p's length
		int left = 0, right = 0, count = p.length();
		while (right < s.length()) {
	        //move right everytime, if the character exists in p's hash, decrease the count
	        //current hash value >= 1 means the character is existing in p
	        if (hash[s.charAt(right)] >= 1) {
	            count--;
	        }
	        hash[s.charAt(right)]--;
	        right++;
	        
	        //when the count is down to 0, means we found the right anagram
	        //then add window's left to result list
	        if (count == 0) {
	            list.add(left);
	        }
	        //if we find the window's size equals to p, then we have to move left (narrow the window) to find the new match window
	        //++ to reset the hash because we kicked out the left
	        //only increase the count if the character is in p
	        //the count >= 0 indicate it was original in the hash, cuz it won't go below 0
	        if (right - left == p.length() ) {//需要找一个新的window了,需要移动left,而且要将count与hash复原
	        	if (hash[s.charAt(left)] >= 0) {//因为left只移动一个位置,而中间right移动那些不用变(之后也会同样地),所以复原一个count++
	                count++;
	            }
	            hash[s.charAt(left)]++;//因为left只移动一个位置,而中间right移动那些不用变(之后也会同样地),所以复原一个hash[s.charAt(left)]
	            left++;
	        }
		}
		return list;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值