[笔试面试]串s1="ABCDACDAE" s2="DAE" 找出s1中,包含s2的最小子串,要求该子串含有s2中的所有字符,串内字符无顺序关系...

思路:首先用一个hash标识s2中出现的所有字符,count记录不重复的字符数,temp_count记录当前已经有的不重复字符数,用left和right指针扫描s1,用另一个hash记录left和right之间每个字符出现的次数。right每前进一步,如果指向的不是s2中的字符,继续前进,如果是s2中的字符,如果是第一次遇见该字符,temp_count加一,如果temp_count等于count则尽量右移left指针,left指针右移有两种情况:1.left指向的字符不在s2中。2.left指向的字符在s2中,且当前出现的次数大于1次。

 1 #include <iostream>
 2 #include <string>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 #define MAX 500
 7 int map[MAX];
 8 
 9 int main()
10 {
11         string s1, s2;
12         while(cin>>s1>>s2)
13         {
14                 int cnt[MAX];
15                 memset(cnt, 0, sizeof(cnt));
16                 memset(map, 0, sizeof(map));
17                 int i;
18                 for(i=0; i<s2.length(); i++)
19                 {
20                         map[s2[i]] = 1;
21                 }
22                 int count = 0;//子串中不同字符的数量
23                 for (i=0; i<MAX; i++)
24                 {
25                         if (map[i])
26                         {
27                                 count++;
28                         }
29                 }
30                 int temp_count = 0;
31                 int begin = 0, end = 0;
32                 int result_begin = 0, result_end = 0x7fffffff;
33                 for(;end<s1.length(); end++)
34                 {
35                         if (map[s1[end]] == 1)//出现在子串中,否则不感兴趣
36                         {
37                                 cnt[s1[end]]++;
38                                 if (cnt[s1[end]]==1)//第一次出现该字符
39                                 {
40                                         temp_count++;
41                                 }
42                                 if (temp_count==count)//每一个字符都已经出现过
43                                 {
44                                         while (map[s1[begin]]==0 || (map[s1[begin]]==1 && cnt[s1[begin]]>1))//begin指向的字符不在子串中 或者在begin和end之间begin指向的字符出现好多次
45                                         {
46                                                 if (map[s1[begin]])
47                                                 {
48                                                         cnt[s1[begin]]--;
49                                                 }
50                                                 begin++;
51                                         }
52                                         if (result_end - result_begin > end-begin)
53                                         {
54                                                 result_end = end;
55                                                 result_begin = begin;
56                                         }
57                                 }
58                         }
59                 }
60                 cout<<result_begin<<"    "<<result_end<<endl;
61         }
62         return 0;
63 }

 

转载于:https://www.cnblogs.com/wendelhuang/archive/2013/04/25/3042071.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值