例1:对一个有序数组去除重复元素,返回无重复的数组的长度。
解决思路:
有序数组,不是递增就是递减。方便双指针去重。用双指针算法,一个指针pre指向第一个元素,另一个指针i遍历第二个元素到最后一个元素。如果pre指向的元素不等于i指向的元素,用pre+1的位置保存i指向的元素;如果pre指向的元素等于i指向的元素,pre还在原位置。当数组遍历完成的时候,[0,pre]这区间存的就是这个有序数组去重之后的结果。
class Solution {
function remDupli($nums) {
$pre = 0;
$len = count($nums);
if($len == 0){
return 0;
}
for($i=1;$i<$len;$i++){
if($nums[$pre] != $nums[$i]){
$pre ++;
$nums[$pre] = $nums[$i];
}
}
return $pre+1;
}
}
$nums =[2,2,2,3,4,4,5,5];
$obj = new Solution();
$res = $obj->remDupli($nums);
var_dump($res);
例2:一个字符串有小写字母和数字组成,对这个字符串进行重新格式化,使得字符串相邻的类型不同。如果不能格式化,返回空字符串。
解题思路:
解决思路:计算字符串中数字的个数,看数字和字母是否相等。数字和字母的个数差不能大于1,可以知道是否能格式化。然后把数字和字母,一个个的连起来。对撞指针的方式把字母和数字分布到字符串的两端。对撞指针的好处是不需要额外的空间。
class Solution {
function format($str) {
$len = strlen($str);
$l = 0;
$r = $len -1;
$res_str = '';
while($l<$r){
if($this->is_alpha($str{$l})){
$l++;
}
if($this->is_int($str{$r})){
$r--;
}
if($this->is_int($str{$l}) && $this->is_alpha($str{$r})){
$tmp = $str{$l};
$str{$l} = $str{$r};
$str{$r} = $tmp;
$l++;
$r--;
}
}
$l = 0;
$r = 0;
for($i=0;$i<$len;$i++){
if($this->is_int($str{$i})){
$l = $i-1;
$r = $i;
break;
}
}
if(abs(($len - ($l+1))-($l+1)) > 1){
return '';
}
if($len - ($l+1) > $l+1){
for($i=0,$j=$len-1;$j>=$r;$i++,$j--){
$res_str .= $str{$j};
if($i <= $l){
$res_str .= $str{$i};
}
}
}else{
for($i=0,$j=$len-1;$i<=$l;$i++,$j--){
$res_str .= $str{$i};
if($j >= $r){
$res_str .= $str{$j};
}
}
}
return $res_str;
}
function is_alpha($a){
if($a >= 'a' && $a <= 'z'){
return 1;
}else{
return 0;
}
}
function is_int($a){
if($a >= '0' && $a <= '9'){
return 1;
}else{
return 0;
}
}
}
$str = '9o5ck83';
$obj = new Solution();
$res = $obj->format($str);
var_dump($res);
双指针的用处和优势
用处:有序的数据处理,快速的分类数据。
优势:不需要额外空间,执行效率高。
打开App,阅读手记