1 <?php
 2     #串连珠子问题(类似于关键字搜索)
 3 
 4     function shortest_sub($a, $m) {
 5         $color = array(); #用于存储当前子串某种颜色出现的次数,如color[0] = 2表示颜色0出现2次
 6         $sum = 0; #用于存储当前子串共出现了几种颜色
 7         $bstart = 0; #最短字串的开始坐标
 8         $blen = count($a); #最短子串长度
 9 
10         #将color数组初始化为0
11         for ($i = 1; $i <= $m; $i++) {
12             $color[$i] = 0;
13         }
14 
15         $h = 0; #头指针
16         $t = 0; #尾指针
17         $loop = true;
18         while ($loop) {
19             #统计当前子串颜色出现次数
20             if ($color[$a[$t]] == 0) {
21                 #新出现的颜色
22                 $color[$a[$t]] = 1;
23                 $sum++;
24             } else {
25                 $color[$a[$t]]++;
26             }
27 
28             #找到了所有颜色,缩减当前子串
29             if ($sum == $m) {
30                 $loop2 = true;
31                 while ($loop2) {
32                     #某种颜色在当前子串(h~t)范围内只出现了一次,说明当前子串已经不能再缩减
33                     if ($color[$a[$h]] == 1) {
34                         $loop2 = false;
35 
36                         if ($t < $h) {
37                             #如果t跨过了数组尾部又回到数组头
38                             $clen = $t + 1 + count($a) - $h;
39                         } else {
40                             $clen = $t - $h + 1; #当前子串长度
41                         }
42 
43                         #更新最短子串信息
44                         if ($clen < $blen) {
45                             $blen = $clen;
46                             $bstart = $h;
47                         }
48 
49                         $sum--; #减少当前子串出现的颜色总数
50                     }
51 
52                     $color[$a[$h]]--; #减少当前子串的当前颜色出现次数
53                     $h++;
54                     
55                     if ($h == count($a)) { #当h扫描到数组尾,扫描结束
56                         $loop = false;
57                     }
58                 }
59             }
60 
61             $t++;
62 
63             #当t到达数组尾部时,重新回到数组头
64             if ($t == count($a)) $t = 0;
65         }
66 
67         return array("start" => $bstart, "len" => $blen);
68     }
69 
70     $a = array(4, 5, 5, 1, 2, 3);
71     $t = shortest_sub($a, 5);
72     print_r($t);
73 ?>
posted on 2012-10-06 01:48  ZimZz  阅读(285)  评论(0编辑  收藏  举报