算法 字符串类问题(一)

给定长度为m的字符串aim,以及一个长度为n的字符串str。

问:

能否在str中找到一个长度为m的连续子串,使得这个子串刚好由aim的m个字符组成,顺序无所谓。

返回:

返回任意满足条件的一个子串的起始位置,未找到返回-1。

例:

str = "abcd"  aim = "dc"

返回值: 2

 

方法1:最简单暴力的方法,取所有子串,并对每个子串、aim字符串排序判断是否相等即可。代码略去。时间复杂度O(n^3 *log2^n)

方法2:对方法以优化,只取和aim长度相同的子串进行比较。但此处比较是否相等,使用O(m)复杂度的算法。时间复杂度O(m*n)。思路如下: 

既然要比较的两个字符串长度相同,那么用一个数组记录aim中每个字符出现的次数(称之为欠账数),之后将子串中的每个字符与之对应的欠账数进行减操作,如果减之前出现0,那么直接返回不匹配,最后返回匹配。

比如:子串 = “cdd"     aim = "ccd"   则欠账数为[......a=0,......c=2,d=1,......]。遍历子串以此为,c则欠账数[......a=0,....c=1,d=1,....],d则[......a=0,....c=1,d=0,....],d此时欠账数d=0,所以不匹配。 

public static int getIndex2(String str, String aim){ if(str == null || aim == null || str.length() < aim.length()) return -1; for(int i = 0; i <= str.length() - aim.length(); i++) { if(isCountEqual(str, i, aim)) return i; } return -1; } public static boolean isCountEqual(String str, int lift, String aim){ int[] count = new int[256]; for(int i = 0; i < aim.length(); i++){ count[aim.charAt(i)] ++; } for(int i = 0; i < aim.length(); i++){ if(count[str.charAt(lift + i)]-- == 0) return false; } return true; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyswy.html