劍指offer試題(PHP篇三)

21.棧的壓入、彈出序列php

題目描述

輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。假設壓入棧的全部數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不多是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)
時間限制:1秒    空間限制:32768K
<?php

function IsPopOrder($pushV, $popV)
{
    // write code here
    $stack = new SplStack;
    $count = count($pushV);
    for($i=0,$j=0;$i<$count;$i++){
        $stack->push($pushV[$i]);
        while(!$stack->isEmpty()&&$stack->top()==$popV[$j]&&$j<$count){
            $stack->pop();
            $j++;
        }
    }
    return $stack->isEmpty();
}

運行時間:9ms    佔用內存:3840knode

思路:數組

  借用一個輔助的棧,遍歷壓棧順序,先講第一個放入棧中,這裏是1,而後判斷棧頂元素是否是出棧順序的第一個元素,這裏是4,很顯然1≠4,因此咱們繼續壓棧,直到相等之後開始出棧,出棧一個元素,則將出棧順序向後移動一位,直到不相等,這樣循環等壓棧順序遍歷完成,若是輔助棧還不爲空,說明彈出序列不是該棧的彈出順序。數據結構

 

22.從上往下打印二叉樹dom

題目描述

從上往下打印出二叉樹的每一個節點,同層節點從左至右打印。
時間限制:1秒    空間限制:32768K
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function PrintFromTopToBottom($root)
{
    // write code here
    $queue = array();
    $list = array();
    array_push($queue,$root);
    while(count($queue)>0){
        array_push($list,$queue[0]->val);
        $tmp = array_splice($queue,0,1);
        if($tmp[0]->left != null){
            array_push($queue,$tmp[0]->left);
        }
        if($tmp[0]->right != null){
            array_push($queue,$tmp[0]->right);
        }
    }
    return $list; 
}
運行時間:10ms    佔用內存:4068k
思路:
  先建兩個空數組,將$root裏的元素加到空數組$queue中,而後,將$queue中第一個的值放入$list(該數組用來存放每一個節點的值)中,而後將$queue的第一個值刪除,將剩餘值放入臨時數組$tmp中,經過判斷$tmp[0]的左右是否爲null,來判斷二叉樹的左右節點是否存在,從而將他們放入到$queue中繼續循環,若$queue的數量爲0,則循環結束,返回$list。
 
 
23.二叉搜索樹的後序遍歷序列

題目描述

輸入一個整數數組,判斷該數組是否是某二叉搜索樹的後序遍歷的結果。若是是則輸出Yes,不然輸出No。假設輸入的數組的任意兩個數字都互不相同。
時間限制:1秒   空間限制:32768K
 
<?php

function VerifySquenceOfBST($sequence)
{
    // write code here
    $size = count($sequence);
    if($size == 0){
        return false;
    }
    $i = 0;
    while($size--){
        while($sequence[$i++]<$sequence[$size]);
        while($sequence[$i++]>$sequence[$size]);
        if($i<$size){
            return false;
        }
        $i = 0;
    }    
    return true;
}

運行時間:12ms    佔用內存:2572k函數

思路:測試

  只要想清楚左節點比根節點小,右節點比根節點大就很容易解出,首先將數組的大小賦給$size,對$size進行while循環,這裏有一個很重要的變量$i,兩個while循環一個判斷左節點和根節點的大小關係,若左小於根,則$i++,繼續循環,以後判斷右是否大於根,若大於,$i++,而後判斷變量i和變量size的大小關係,若是i小於size,則說明沒有循環完,即這不是一個二叉搜索樹,返回false,反之則繼續size--循環,固然要將i從新賦值0,直到size爲0時,循環結束,返回true。this

 

24.二叉樹中和爲某一值的路徑spa

題目描述

輸入一顆二叉樹和一個整數,打印出二叉樹中結點值的和爲輸入整數的全部路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所通過的結點造成一條路徑。
時間限制:1秒    空間限制:32768K
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function FindPath($root, $expectNumber)
{
    // write code here
    $arr = $tmp = [];
    if(!$root){
        return $arr;
    }
    find($root,$expectNumber,$arr,$tmp);
    return $arr;
}

function find($root,$sum,&$arr,$tmp){
    if($root!= null){
        $sum-=$root->val;
        $tmp[] = $root->val;
        if($sum>0){
            find($root->left,$sum,$arr,$tmp);
            find($root->right,$sum,$arr,$tmp);
        }elseif($sum==0 && $root->left == null && $root->right == null){
            $arr[] = $tmp;
        }
    }
}

運行時間:12ms    佔用內存:2316k指針

思路:

  一個簡單的遞歸函數,經過把每次減去的根節點的值存入臨時數組tmp中,最後進行判斷是否減到了零,而且是葉子節點,如果,再將tmp數組中的數轉移到arr數組中,輸出。

 

25.複雜鏈表的複製

題目描述

輸入一個複雜鏈表(每一個節點中有節點值,以及兩個指針,一個指向下一個節點,另外一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,不然判題程序會直接返回空)
時間限制:1秒    空間限制:32768K
 
<?php
/*class RandomListNode{
    var $label;
    var $next = NULL;
    var $random = NULL;
    function __construct($x){
        $this->label = $x;
    }
}*/
$r = [];
function MyClone($pHead)
{
    // write code here
    global $r;
    if($pHead == NULL){
        return NULL;
    }
    $PnewHead=new RandomListNode($pHead->label);
    $PnewHead->next=MyClone($pHead->next);
    $PnewHead->random=$pHead->random;
    return $PnewHead;
}

運行時間:16ms    佔用內存:2432k

思路:

  複雜鏈表是一種不太常見的數據結構,並且複製這種鏈表的過程也較爲複雜,這裏有一個小坑,就是找當前節點的下一個節點時用的是遞歸,但找他的random節點時只須要複製$pHead->random就好了,用不到遞歸。

 

26.二叉搜索樹與雙向鏈表

題目描述

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能建立任何新的結點,只能調整樹中結點指針的指向。

時間限制:1秒 空間限制:32768K

<?php
/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
$nodes = array();
function Convert($pRootOfTree)
{
    // write code here
    GLOBAL $nodes;
    $nodes = array();
    inOrder($pRootOfTree);
    for($i=0;$i<count($nodes)-1;$i++){
        $nodes[$i]->right = $nodes[$i+1];
        $nodes[$i+1]->left = $nodes[$i];
    }
    return $nodes[0];
}

function inOrder($root){
    GLOBAL $nodes;
    if($root == null){
        return;
    }else{
        inOrder($root->left);
        $nodes[] = $root;
        inOrder($root->right);
    }
}

運行時間:9ms     佔用內存:4060k

 思路:

  這種方法的思路就是首先遞歸將搜索二叉樹中的節點按照中序遍歷的順序存入到nodes中,而後對nodes進行遍歷,使他相鄰兩個值互爲左右子節點(雙向鏈表)。

 

27.字符串的排列

題目描述

輸入一個字符串,按字典序打印出該字符串中字符的全部排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的全部字符串abc,acb,bac,bca,cab和cba。
時間限制:1秒 空間限制:32768K
 
<?php
 
function Permutation($str)
{
    $ans = array();
    permutation2(0,$str,$ans);
    $ans = array_unique($ans);
    sort($ans);
    return $ans;
}
  
function permutation2($step,&$str,&$ans){
    if($step==strlen($str)-1){
        $ans[] = $str;
    }
    for($i=$step;$i<strlen($str);$i++){
        $tmp = $str[$step]; $str[$step] = $str[$i]; $str[$i] = $tmp;
        permutation2($step+1,$str,$ans);
        $tmp = $str[$step]; $str[$step] = $str[$i]; $str[$i] = $tmp;
    }
}

運行時間:12ms    佔用內存:3936k

思路:

  利用遞歸,經過對step位數的控制,每次交換兩個字母的位置,將全部可能的狀況羅列出來,存入ans數組中,最後將其去重,排序,便可獲得最終結果。

 

28.數組中出現次數超過一半的數字

題目描述

數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。因爲數字2在數組中出現了5次,超過數組長度的一半,所以輸出2。若是不存在則輸出0。

時間限制:1秒    空間限制:32768K

<?php

function MoreThanHalfNum_Solution($numbers)
{
    // write code here
    if(count($numbers) <= 0)
        return 0;
    $list = array_count_values($numbers);
    $max = max($list);
    if(2*$max > count($numbers))
        return array_search($max, $list);
    else
        return 0;
}

運行時間:12ms    佔用內存:2432k

思想:

  博主在這裏偷懶了,使用了php的函數array_count_values,將數組中全部值當作下標,出現的次數當作值放入一個新的數組中,瞬間發現這個題簡單了好多,找到數組中最大值的那一項,判斷最大值的二倍與原數組長度誰大,來返回結果。

 

29.最小的K個數

題目描述

輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
時間限制:1秒    空間限制:32768K
<?php

function GetLeastNumbers_Solution($input, $k)
{
    // write code here
    sort($input);
    $res = [];
    if(count($input)>0 && count($input)>=$k){
        $res = array_slice($input,0,$k);
        return $res; 
    }else{
        return $res;
    }

}

運行時間:17ms   佔用內存:3940k

思路:

  先排序,而後使用array_slice,取出數組中前k個值,放入res數組中,返回便可,注意判斷輸入的數組和k是否符合範圍,若不符合就返回空數組。

 

30.連續子數組的最大和

題目描述

HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同窗。今天測試組開完會後,他又發話了:在古老的一維模式識別中,經常須要計算連續子向量的最大和,當向量全爲正數的時候,問題很好解決。可是,若是向量中包含負數,是否應該包含某個負數,並指望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和爲8(從第0個開始,到第3個爲止)。你會不會被他忽悠住?(子向量的長度至少是1)
時間限制:1秒    空間限制:32768K
<?php

function FindGreatestSumOfSubArray($array)
{
    // write code here
    $count = count($array);
    $max = $array[0];
    for($i=0;$i<$count;$i++){
        $sum = 0;
        for($j=$i;$j<$count;$j++){
            $sum+=$array[$j];
            if($sum>$max){
                $max = $sum;
            }
        }
    }
    return $max;
}

運行時間:10ms    佔用內存:2432k

思路:

  雙層循環遍歷,找出一個和最大的值,並返回這個和。

 

 注:以上均爲我的理解,若有錯誤,請提出,必改正。

相關文章
相關標籤/搜索