算法:字符串右移和包含

1. 将字符串右转n位,要求时间复杂度为O(n),空间复杂度为O(1)。

比如字符串为'abcde',右转两位为'cdeab'。

解法1:利用字符串翻转,先按右转长度将字符串分为两部分进行翻转,'ab'->'ba',‘cde’->'edc',然后再将字符串整体翻转,'baedc'->'cdeab',时间复杂度O(n),在翻转字符串的时候使用一个临时变量用于交换和一个变量用于记录字符串长度,空间复杂度为O(1)。

php代码:

function turnRight($str,$n)
{
    $len = strlen($str);
    $n = $n%$len;           //防止n>len
    if($n>0)
    {
        reverse($str,0,$n-1);
        reverse($str,$n,$len-1);
        reverse($str,0,$len-1);
    }
    echo $str;
}
function reverse(&$str,$start,$end)
{
    for(;$start<$end;$start++,$end--)
    {
        $tem = $str[$start];
        $str[$start] = $str[$end];
        $str[$end] = $tem;
    }
}
turnRight('abcde',2);

解法2:采用递归,将需要右移的字符串逐步向右移动,比如'abcde'->'cdabe'->'cdeab'

php代码:

function turnRight($str,$n)
{
    $len = strlen($str);
    $n = $n%$len;    //当n>len
    $s = 0;          //标记要移动字符串的头和尾
    $e = $n-1;
    if($e>0)
        turn($str,$s,$e,$len,$n);
    echo $str;
}
function turn(&$str,$s,$e,$len,$n)
{
    if($e+1>=$len) return;
    for($i=$s;$i<=$e;$i++)
    {
        if($i+$n>=$len)        //已经移动到结尾处
        {
            turn($str,$i,$e,$len,$e-$i+1);
            break;
        }
        else
        {
            $tem = $str[$i];
            $str[$i] = $str[$i+$n];
            $str[$i+$n] = $tem;
        }
    }
    $s = $s+$n;
    $e = $e+$n;
    turn($str,$s,$e,$len,$n);
}

2.判断字符串是否包含

 给出一长一短两字符串,用最短时间判断短字符串里的字符在长字符串里都有。

既然要求时间复杂度显然不能逐个字符去找,很自然的想到空间换时间,这类解法很多,比如HashTable,素数乘积法,bitmap,时间复杂度最小为O(n),最大为O(n+m),n为短字符串的长度,m为长字符串的长度。这里给出HashTable的解法和bitmap。

HashTable:

function isInclude($longStr,$shortStr)
{
    $store = array();
    $len = strlen($shortStr);
    for($i=0;$i<$len;$i++)
    {
        $str = $shortStr[$i];
        $store[$str] = 1;          //构建HashTable,初始值为1
    }
    $len = strlen($longStr);
    for($i=0;$i<$len;$i++)
    {
        $str = $longStr[$i];
        $store[$str] = 0;         //如果字符在长字符串中存在,则将HashTable对应值置0
    }
    foreach($store as $value)
    {
        if($value)
        {
            echo "false";
            return;
        }
    }
    echo "true";
}
Bitmap:

function isInclude($longStr,$shortStr)
{
    $len = strlen($shortStr);
    $longDic = 0;
    $shortDic = 0;
    for($i=0;$i<$len;$i++)
    {
        $shortDic |= 1 << (ord($shortStr[$i]) - ord('A'));
    }
    $len = strlen($longStr);
    for($i=0;$i<$len;$i++)
    {
        $longDic |= 1 << (ord($longStr[$i]) - ord('A'));
    }
    if(($shortDic|$longDic) == $longDic) echo 'true';
    else echo 'false';
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值