给一个很长的字符串str 还有一个字符集比如"abc" 找出str 里包含"abc"的最短子串。要求O(n)
2013-08-28 14:58
411 查看
在面试100题中看到了这个题,实现下:
题目:给一个很长的字符串str ,还有一个字符集比如"abc" ,找出str 里包含"abc"的最短子串。要求O(n)。
例如:字符串str:abdcaabcx,字符集dest:abc,那么最短子串就是abc。
实现思路是在july大神的博客上看到的/article/1360525.html
用两个变量 front,rear 指向一个的子串区间的头和尾(当然,开始时front和rear都指向字符串开始处)。
用一个int cnt[255]={0}记录当前这个子串里字符集a,b,c各自的个数,一个变量count记录字符集里有多少个了。
rear 一直加,更新cnt[]和count的值,直到count等于字符集个数。
然后front++,直到cnt[]里某个字符个数为0(front 开始的部分有可能和后面的重复,所以front要加到某个字符个数为0), 这样就找到一个符合条件的字串了,继续下去,可以求出所有符合条件的串,同时可以求出满足条件最短子串。
用Java实现的代码如下:
用src="ab1dkj2ksjf3ae32ks1iji2sk1ksl1223ab;1ik3saj123",dest="123"。
测试了下,输入如下:
1dkj2ksjf3
32ks1
1223
23ab;1
3saj12
123
最短字符串是:
123
题目:给一个很长的字符串str ,还有一个字符集比如"abc" ,找出str 里包含"abc"的最短子串。要求O(n)。
例如:字符串str:abdcaabcx,字符集dest:abc,那么最短子串就是abc。
实现思路是在july大神的博客上看到的/article/1360525.html
用两个变量 front,rear 指向一个的子串区间的头和尾(当然,开始时front和rear都指向字符串开始处)。
用一个int cnt[255]={0}记录当前这个子串里字符集a,b,c各自的个数,一个变量count记录字符集里有多少个了。
rear 一直加,更新cnt[]和count的值,直到count等于字符集个数。
然后front++,直到cnt[]里某个字符个数为0(front 开始的部分有可能和后面的重复,所以front要加到某个字符个数为0), 这样就找到一个符合条件的字串了,继续下去,可以求出所有符合条件的串,同时可以求出满足条件最短子串。
用Java实现的代码如下:
public static void MinSubString(String src, String dest) { int min = Integer.MAX_VALUE;// 找最短子串 int minfront = 0;// 最短子串开始位置 int minrear = 0;// 最短子串结束位置 int front, rear; front = rear = 0; int count = 0; int hashtable[] = new int[256]; int cnt[] = new int[256]; for (int i = 0; i < dest.length(); i++) { hashtable[dest.charAt(i)] = 1; } while (rear < src.length()) { if (hashtable[src.charAt(rear)] == 1) {// rear当前字符在字符集中 // 判断是否是本子串中第一次检索到此字符,由count统计字符集中已出现的字符数 if (cnt[src.charAt(rear)] == 0) { count++; cnt[src.charAt(rear)]++; if (count == dest.length()) {// 字符集中的字符在本子串中都已检索到 while (true) { if (hashtable[src.charAt(front)] == 1) {// front当前字符在字符集中 cnt[src.charAt(front)]--; // 字符集中某个字符为0,此时front到rear所指字符串即为符合条件的子串 if (cnt[src.charAt(front)] == 0) { for (int i = front; i <= rear; i++) { System.out.print(src.charAt(i)); } System.out.println(); if (rear - front + 1 < min) { min = rear - front + 1; minrear = rear; minfront = front; } // count不需要清空(赋0),cnt数组也不需要任何操作 count--;// 因为某个字符为出现次数已经减为0了,所以count-- front++;// 这个不可少 break; } } front++; } } } else { cnt[src.charAt(rear)]++; } } rear++; } if (min == Integer.MAX_VALUE) { System.out.println("没有找到需要和谐的字符串"); } else { System.out.println("最短字符串是:"); for (int i = minfront; i <= minrear; i++) { System.out.print(src.charAt(i)); } System.out.println(); } }
用src="ab1dkj2ksjf3ae32ks1iji2sk1ksl1223ab;1ik3saj123",dest="123"。
测试了下,输入如下:
1dkj2ksjf3
32ks1
1223
23ab;1
3saj12
123
最短字符串是:
123
相关文章推荐
- 每天学习一算法系列(30)(给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str 里包含{a,b,c}的最短子串。要求O(n).)
- 给一个很长的字符串str 还有一个字符集比如{a,b,c} 找出str 里包含{a,b,c}的最短子串。要求O(n)
- 给一个非常长的字符串str 另一个字符集比方{a,b,c} 找出str 里包括{a,b,c}的最短子串。要求O(n)
- 找出字符串的最长子串,要求子串的所有字符相同,如:"abcdeeefgh"结果是"eee"
- 找出字符串的最长子串,要求子串的所有字符相同 例如:str ="sssddddabcdef" 则输出字串为:dddd
- 一道题:给一个字符串,和一个字符集,求该字符串包含所有字符集的最短子串
- 输入一个字符串,要求输出字符串中字符所有的排列,例如输入"abc",得到"abc","acb","bca","bac","cab","cba"
- 找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"cad"
- Linux_C练习:判断一个字符串是不是另一个字符串的子串;(比如"ab"是"aabcd"的子串)
- 一个字符串中包含另一个字符串所有字符的最短子串
- 定义一个栈的数据结构,实现min函数,要求push,pop,min时间复杂度是0(1);找出字符串中的最长子串,要求子串不含重复字符,时间复杂度是O(n);
- 面试题--字符串指针与字符串数组的区别char* st="abc;与char* str[]="abc";的异同
- // 写一个函数,实现将一个字符串中的'/t'替换成四个'*', '/t'个数不定。如char *p="ht/thdsf/t/ttt/tfds dfsw/t ew/t",替换后p="ht****hdsf********tt****fds dfsw****
- 135、编程实现:找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为 "cad"
- 【C语言】要求找出具有下列性质的数的个数(包含输入的自然数n): 先输入一个自然数n(n<=500),然后对此自然数按照如下方法进行处理:
- 每天一道LeetCode-----在字符串s中找到最短的包含字符串t中所有字符的子串,子串中字符顺序无要求且可以有其他字符
- 找出两个字符串中最大公共子字符串,如"abccade"、"dgcadde"的最大子串为"cad"
- 算法 - 给出一个字符串str,输出包含两个字符串str的最短字符串,如str为abca时,输出则为abcabca
- "找出字符串中第一个不重复的字符"和"找出字符串中最后一个重复的字符"的两种方法的C++实现
- 输入一个字符串,要求找出字符串中最大子串的长度