1. 程式人生 > >Leetcode PHP題解--D88 696. Count Binary Substrings

Leetcode PHP題解--D88 696. Count Binary Substrings

D88 696. Count Binary Substrings

題目連結

696. Count Binary Substrings

題目分析

給定一個01字串,返回僅用連續的0和1串所能組成的二進位制字串個數。

例如,00110011,就包含001101110010001101共6個。001100則不算,因為兩個00被11分割開了,不是連續的。

思路

思路1:

生成01,0011,000111和10,1100,111000字串,再用substr_count函式去計算個數的。但是會超時。

function countBinarySubstrings($s) {
    $totalLength = strlen($s);
    $total = 0;
    for($i=0;$i<=$totalLength/2; $i++){
        //01 0011 000111
        $boz = str_repeat('0',$i).str_repeat('1',$i);
        //10 1100 111000
        $bzo = strrev($boz);
        $total += substr_count($s, $boz);
        $total += substr_count($s, $bzo);
    }
    return $total;
}

思路2

用棧的思想。先把數字壓入棧內,遇到不同數字時出棧。出完棧時,把後面出現的數字頂上,作為下一個出棧的棧。然而寫起來略嫌麻煩。寫了個Wrong Answer出來就放棄了。於是又換了個思路。

思路3

只記錄前一組是0還是1,以及出現的次數。

先取字串的第一個字元作為第一組的字元。
從第二個字元開始判斷。
判斷是否與第一組出現的字元相同。相同,則判斷是否與前一個字元相同。這裡需要注意的是,前一組的字元不一定等於前一個字元。所以需要分開判斷。
如果與前一個字元相同,則給前一組字元出現個數(或者叫長度)+1。如果與前一個字元不同,則說明兩個相同的字元夾住了不同的字元(例如010或者101)。那麼此時需要拋棄前一組的所有內容。因為前一組已經沒有內容可以和下一組匹配了。所以需要把當前組作為前一組,把當前字元作為下一組。

如果當前字元與前一組的字元不同,則說明配對成功。
前一組未配對字元數量減1,當前組未配對數量+1。這裡是因為,當前在變成前一組的時候,會與其後面的字元匹配,到時候會減去對應數量。因此這裡需要+1。

當前一組未配對字元數量達到0時,說明前一組已經沒有可以匹配的字元。故把當前組替換未前一組。

如此迴圈即可。

最終程式碼

<?php
class Solution {
    /**
     * @param String $s
     * @return Integer
     */
    function countBinarySubstrings($s) {
        $total = 0;
        $s = str_split($s);
        $stack1 = array_shift($s);
        $stack1Amount = 1;
        $stack2 = null;
        $stack2Amount = 0;
        $prev = $stack1;
        foreach($s as $key => $val){
            if($stack1 == $val){
                if($val == $prev){
                    $stack1Amount++;
                }
                else{
                    $stack1 = $stack2;
                    $stack1Amount = $stack2Amount;
                    $stack2Amount = 0;
                    $stack2 = null;
                }
            }
            if($stack1 != $val){
                $stack2 = $val;
                $stack2Amount++;
                $stack1Amount--;
                $total++;
            }
            if($stack1Amount == 0){
                $stack1 = $stack2;
                $stack1Amount = $stack2Amount;
                $stack2 = null;
                $stack2Amount = 0;
            }
            $prev = $val;
        }
        return $total;
    }
}

若覺得本文章對你有用,歡迎用