public function getStringNoRepetitionAndMaxLength(string $string) :array
{
$rs = [‘maxlength’ => 0,’no_repetition_string’=>’’];
$strLength = _strlen(trim($string));
if($strLength == 0) return $rs;
$map = []; // 定义新数组接受字符串组成无重复字符的新数组
$left = $max = $oldMax = 0; // $left重复字符下标,默认为0不重复 $max最大无重复长度 $oldMax 用于后面获取对应无重复字符长度
$begin = -1; // 默认无重复
for ($i=0;$i<$strLength;$i++){
// 如果该字符已存在
if(array_key_exists($string[$i],$map)){
// 比较取出当前重复下标与数组已存在字符下标最大值 $map[$string[$i]] + 1 因为$string[$i]已经存在数组中并且下面会替换调已存在的下标,所以当再次存在,重复字符下标+1
$left = max($left,$map[$string[$i]] + 1);
}
// 不管数组中是否存在该字符,通过$i 每次赋值/修改数组下标
$map[$string[$i]] = $i;
// 每次保存当前的max长度
$oldMax = $max;
// 比较最大无重复长度与当前数组对应下标的value - $left + 1最大值 | $i - $left + 1 当前长度减去重复的下标所对应长度 +1因为下标从0开始
$max = max($max,$i - $left + 1);
// 如果最新的max大于oldMax 代表当前循环字符未重复
if($oldMax < $max){
// 记录当前未重复下标
$begin = $i;
}
}
if($max == $strLength){
$rs[‘maxlength’] = $strLength;
$rs[‘no_repetition_string’] = $string;
return $rs;
}
$rs[‘max_length’] = $max;
// ①通过循环取对应数据
$noRepetitionString = ‘’;
$tatal = 0;
for ($i = $begin;$i>=0;$i—){
// 从begin处向前取,取max位
if(++$tatal > $max) break;
$noRepetitionString .= $string[$i];
}
$rs[‘no_repetition_string_for’] = _strrev($noRepetitionString);
// ②字符串截取 先翻转从前往后从$strLength - $begin - 1处取,取$max位,然后翻转返回原字符串 <不知道怎么实现倒着取到对应数据>
$rs[‘norepetition_string_substr_strrev’] = _strrev(substr(strrev($string), $strLength - $begin - 1,$max));
// ③不反转实现
$rs[‘norepetition_string_substr_strrev_two’] = _substr($string, $begin-$max+1, $max);
return $rs;
}
�
