劍指offer算法題

  • 在一個二維數(shù)組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數(shù),輸入這樣的一個二維數(shù)組和一個整數(shù),判斷數(shù)組中是否含有該整數(shù)。
function Find($target, $array)
{
    if(empty($array)) return false;
    $rows = count($array);
    $cols = count($array[0]);
    $row = 0;
    $col = $cols - 1;
    while($col > -1 && $row < $rows)
    {
        if($array[$row][$col] == $target) {
            return true;
        } else if($array[$row][$col] < $target){
            $row++;
        } else {
            $col--;
        }
    }
    return false;
}
  • 輸入一個鏈表,從尾到頭打印鏈表每個節(jié)點(diǎn)的值。
<?php

class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}
function printListFromTailToHead($head)
{
    // write code here
    $list = [];
    getNodes($head, $list);
    return $list;
}

function getNodes($head, &$list)
{
    if($head != NULL)
    {
        getNodes($head->next, $list);
        $list[] = $head->val;
    }
}
  • 輸入某二叉樹的前序遍歷和中序遍歷的結(jié)果,請重建出該二叉樹。假設(shè)輸入的前序遍歷和中序遍歷的結(jié)果中都不含重復(fù)的數(shù)字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹并返回。
/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function reConstructBinaryTree($pre, $vin)
{
    $lenP = count($pre);
    $lenV = count($vin);
    if($lenP != $lenV) {
        return false;
    }
    if($lenP == 0) return NULL;
    $head = new TreeNode($pre[0]);
    for($i = 0; $i <$lenV; $i++)
    {
        if($vin[$i] == $pre[0])  break;
    }
    $lenL = $i;
    $lenR = $lenP - 1 - $lenL;
    if($lenL > 0) {
        $head->left = reConstructBinaryTree(array_slice($pre, 1, $i), array_slice($vin, 0, $i));
    } 
    if($lenR > 0) {
        $head->right = reConstructBinaryTree(array_slice($pre, $i + 1), array_slice($vin, $i + 1));
    }
    return $head;
}
  • 用兩個棧來實(shí)現(xiàn)一個隊(duì)列,完成隊(duì)列的Push和Pop操作。 隊(duì)列中的元素為int類型。
<?php

$arr1 = $arr2 = [];
function mypush($node)
{
    global $arr1;
    array_push($arr1, $node);
}
function mypop()
{
    global $arr1, $arr2;
    if(empty($arr2)) {
         while(!empty($arr1)) {
               array_push($arr2, array_shift($arr1));
         }
    }
    return array_pop($arr2);
}
  • 把一個數(shù)組最開始的若干個元素搬到數(shù)組的末尾,我們稱之為數(shù)組的旋轉(zhuǎn)。 輸入一個非遞減排序的數(shù)組的一個旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素。 例如數(shù)組{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉(zhuǎn),該數(shù)組的最小值為1。 NOTE:給出的所有元素都大于0,若數(shù)組大小為0,請返回0。
function minNumberInRotateArray($rotateArray)
{
    if(empty($rotateArray)) return 0;
    $length = count($rotateArray);
    if($length == 1) return $rotateArray[0];
    $end = count($rotateArray) - 1;
    $begin = 0;
    $mid = $begin;
    while($rotateArray[$begin] >= $rotateArray[$end]) {
       if($end - $begin == 1) {
           $mid = $end;
           break;
       }
       $mid = (int)(($begin + $end)/2);
        if($rotateArray[$mid] >= $rotateArray[$begin]) $begin = $mid;
        elseif($rotateArray[$end] >= $rotateArray[$mid]) $end = $mid;
    }
    return $rotateArray[$mid];
}
  • 大家都知道斐波那契數(shù)列,現(xiàn)在要求輸入一個整數(shù)n,請你輸出斐波那契數(shù)列的第n項(xiàng)。
    n<=39
function Fibonacci($n)
{
   if($n == 0) return 0;
   if($n == 1) return 1;
   $f0 = 0;
   $f1 = 1;
   $num = 2;
   $fn = 0;
   while($num <= $n)
   {
       $fn = $f1 + $f0;
       $f0 = $f1;
       $f1 = $fn;
       $num ++;
   }
   return $fn;
}
  • 一只青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
function jumpFloor($number)
{
    if($number <= 0) return 0;
    if($number == 1) return 1;
    if($number == 2) return 2;
    $j1 = 1;
    $j2 = 2;
    $count = 3;
    $jn = 0;
    while($count <= $number)
    {
        $jn = $j2 + $j1;
        $j1 = $j2;
        $j2 = $jn;
        $count ++;
    }
    return $jn;
}
  • 一只青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
function jumpFloorII($number)
{
    if($number <= 0) return 0;
    if($number == 1) return 1;
    if($number == 2) return 2;
    $jumpArr[0] = 0;
    $jumpArr[1] = 1;
    $jumpArr[2] = 2;
    $count = 3;
    while($count <= $number)
    {
        $jumpArr[$count] = array_sum($jumpArr) + 1;
        $count++;
    }
    return $jumpArr[$count - 1];
}
  • 我們可以用21的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個21的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?

function rectCover($number)
{
    if($number <= 0) return 0;
    if($number == 1) return 1;
    if($number == 2) return 2;
    $j1 = 1;
    $j2 = 2;
    $count = 3;
    $jn = 0;
    while($count <= $number)
    {
        $jn = $j2 + $j1;
        $j1 = $j2;
        $j2 = $jn;
        $count ++;
    }
    return $jn;
}
  • 輸入一個整數(shù),輸出該數(shù)二進(jìn)制表示中1的個數(shù)。其中負(fù)數(shù)用補(bǔ)碼表示。
class Solution {
public:
     int  NumberOf1(int n) {
         unsigned int count = 0;
         while(n!=0)
         {
             count++;
             n = n & (n - 1);
         }
         return count;
     }
};
  • 給定一個double類型的浮點(diǎn)數(shù)base和int類型的整數(shù)exponent。求base的exponent次方。
function Power($base, $exponent)
{
    // write code here
    if($exponent < 0) {
        if($base == 0) return 0;
        else {
            $base = 1/$base;
            $exponent = abs($exponent);
        }
    }
    if($exponent == 0) return 1;
    $result = getPower($base, $exponent);
    if(($exponent & 0x1) == 1) {
        $result *= $base;
    }
    return $result;
}

function getPower($base, $exponent)
{
    $num = (int) ($exponent / 2);
    $result = $base;
    while($num > 0)
    {
        $result *= $result;
        $num--;
    }
    return $result;
}
  • 輸入一個整數(shù)數(shù)組,實(shí)現(xiàn)一個函數(shù)來調(diào)整該數(shù)組中數(shù)字的順序,使得所有的奇數(shù)位于數(shù)組的前半部分,所有的偶數(shù)位于位于數(shù)組的后半部分,并保證奇數(shù)和奇數(shù),偶數(shù)和偶數(shù)之間的相對位置不變。
function reOrderArray($array)
{
    $resEven = $resOdd = [];
    foreach($array as $value)
    {
        if($value & 0x1) {
            $resOdd[] = $value;
        } else {
            $resEven[] = $value;
        }
    }
    return array_merge($resOdd, $resEven);
}
  • 輸入一個鏈表,輸出該鏈表中倒數(shù)第k個結(jié)點(diǎn)。
function FindKthToTail($head, $k)
{
    // write code here
    if($head == NULL || $k <= 0) return NULL;
    $p = $head;
    while($k > 1 && $head != NULL) {
        $head = $head->next;
        $k--;
    }
    if($head == NULL) return NULL;
    while($head != NULL)
    {
        $head = $head->next;
        if($head != NULL) {
          $p = $p->next;  
        }
    }
    return $p;
}
  • 輸入一個鏈表,反轉(zhuǎn)鏈表后,輸出鏈表的所有元素。
<?php
/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function ReverseList($pHead)
{
    if(!$pHead)return null;
    $tmp = $pHead->next;
    $pHead->next = NULL;
    $next = $tmp;
    while($next) {
        $next = $tmp->next;
        $tmp->next = $pHead;
        $pHead = $tmp;
        $tmp = $next;
    }
    return $pHead;
}
  • 輸入兩個單調(diào)遞增的鏈表,輸出兩個鏈表合成后的鏈表,當(dāng)然我們需要合成后的鏈表滿足單調(diào)不減規(guī)則。
<?php
/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function Merge($pHead1, $pHead2)
{
    if(!$pHead1) return $pHead2;
    if(!$pHead2) return $pHead1;
    $pHead = NULL;
    if($pHead1->val < $pHead2->val)
    {
        $pHead = $pHead1;
        $pHead->next = Merge($pHead1->next, $pHead2);
    } else {
        $pHead = $pHead2;
        $pHead->next = Merge($pHead1, $pHead2->next);
    }
    return $pHead;
}
  • 輸入兩棵二叉樹A,B,判斷B是不是A的子結(jié)構(gòu)。(ps:我們約定空樹不是任意一個樹的子結(jié)構(gòu))
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function HasSubtree($pRoot1, $pRoot2)
{
    // write code here
    $isChild =false;
    if($pRoot1 != NULL && $pRoot2 != NULL) {
        if($pRoot1->val == $pRoot2->val) {
            $isChild = DoesTree1HasTree2($pRoot1, $pRoot2);
            if(!$isChild) {
                $isChild = DoesTree1HasTree2($pRoot1->left, $pRoot2);
            }
            if(!$isChild) {
                $isChild = DoesTree1HasTree2($pRoot1->right, $pRoot2);
            }
        }
    }
    return $isChild;
}

function DoesTree1HasTree2($pRoot1, $pRoot2)
{
    if($pRoot2 == NULL) return true;
    if($pRoot1 == NULL) return false;
    if($pRoot1->val != $pRoot2->val) return false;
    return DoesTree1HasTree2($pRoot1->left, $pRoot2->left) && 
   DoesTree1HasTree2($pRoot1->right, $pRoot2->right);
}
  • 操作給定的二叉樹,將其變換為源二叉樹的鏡像。
    輸入描述:


    image.png
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function Mirror(&$root)
{
    if(!$root) return;
    if($root->left != NULL || $root->right != NULL) {
        $node = $root->left;
        $root->left = $root->right;
        $root->right = $node;
    }
    if($root->left) Mirror($root->left);
    if($root->right) Mirror($root->right);
}
  • 輸入一個矩陣,按照從外向里以順時針的順序依次打印出每一個數(shù)字,例如,如果輸入如下矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次打印出數(shù)字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
<?php
function printMatrix($matrix)
{
    if(empty($matrix)) {
        return [];
    }
    $row = count($matrix);
    $col = count($matrix[0]);
    $result = [];
    $start = 0;
    while ($col > 2 * $start && $row > 2 * $start)
    {
        $result = array_merge($result, getPrintNum($matrix, $start, $row, $col));
        $start++;
    }
    return $result;
}

function getPrintNum($martrix, $start, $row, $col)
{
    $num = [];
    $endX = $row - $start - 1;
    $endY = $col - $start - 1;
    for ($i = $start; $i <= $endY; $i++)
    {
        $num[] = $martrix[$start][$i];
    }
    if($start < $endX) {
        for ($i = $start + 1; $i <= $endX; $i++)
        {
            $num[] = $martrix[$i][$endY];
        }
        if($start < $endY) {
            for ($i = $endY - 1; $i >= $start; $i--)
            {
                $num[] = $martrix[$endX][$i];
            }
            if($start < $endX - 1) {
                for ($i = $endX - 1; $i > $start; $i--)
                {
                    $num[] = $martrix[$i][$start];
                }
            }
        }
    }
    return $num;
}
  • 定義棧的數(shù)據(jù)結(jié)構(gòu),請?jiān)谠擃愋椭袑?shí)現(xiàn)一個能夠得到棧最小元素的min函數(shù)。
<?php
$arr1 = [];
$arr2 = [];

function mypush($node)
{
    global $arr1, $arr2;
    $min = mymin();
    if(!$min || $node < $min) {
        array_push($arr2, $node);
    } else {
        array_push($arr2, $min);
    }
    array_push($arr1, $node);
}
function mypop()
{
    global $arr1, $arr2;
    array_pop($arr2);
    array_pop($arr1);
}
function mytop()
{
    global $arr1;
    $num = count($arr1);
    if($num > 0) return $arr1[$num - 1];
    else return NULL;
}
function mymin()
{
    global $arr2;
    $num = count($arr2);
    if($num > 0) return $arr2[$num - 1];
    else return NULL;
}
  • 輸入兩個整數(shù)序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否為該棧的彈出順序。假設(shè)壓入棧的所有數(shù)字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應(yīng)的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的
<?php

function IsPopOrder($pushV, $popV)
{
    $pushN = count($pushV);
    $popN = count($popV);
    if($popN != $pushN)return false;
    $is = false;
    if($pushN && $popN) {
        $stack = [];
        $pushNum = 0;
        while(!empty($popV)) {
            while($pushNum < $pushN && $pushV[$pushNum] != $popV[0])
            {
                array_push($stack, $pushV[$pushNum]);
                $pushNum++;
            }
            if($pushNum < $pushN){
                array_push($stack, $pushV[$pushNum]);
                $pushNum++;
            }
            if(array_pop($stack) != array_shift($popV)) {
                return false;
            }
            
        }
        return true;
    }
    return false;
}
  • 從上往下打印出二叉樹的每個節(jié)點(diǎn),同層節(jié)點(diǎn)從左至右打印。
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function PrintFromTopToBottom($root)
{
    // write code here
    if($root == NULL) {
        return [];
    }
    $queue[] = $root;
    $res = [];
    while($queue) {
        $node = array_shift($queue);
        $res[] = $node->val;
        if($node->left) {
            $queue[] =  $node->left;
        }
        if($node->right) {
            $queue[] =  $node->right;
        }
    }
    return $res;
}
  • 輸入一個整數(shù)數(shù)組,判斷該數(shù)組是不是某二叉搜索樹的后序遍歷的結(jié)果。如果是則輸出Yes,否則輸出No。假設(shè)輸入的數(shù)組的任意兩個數(shù)字都互不相同。
<?php

function VerifySquenceOfBST($sequence)
{
    $isTree = false;
    if(empty($sequence)){
        return $isTree;
    }
    $num = count($sequence);
    $rootV = $sequence[$num - 1];
    $leftTree = $rightTree = [];
    for($i = 0; $i < $num; $i++)
    {
        if($sequence[$i] < $rootV) {
            $leftTree[] = $sequence[$i];
        } else {
            break;
        }
    }
    $rightTree = array_slice($sequence, $i, $num - $i - 1);
    foreach($rightTree as $v)
    {
        if($v < $rootV) return $isTree;
    }
    if(count($leftTree) > 1) {
        $isTree = VerifySquenceOfBST($leftTree);
    } else {
        $isTree = true;
    }
    if($isTree && count($rightTree) > 1) {
        return VerifySquenceOfBST($rightTree);
    }
    return $isTree;
}
  • 輸入一顆二叉樹和一個整數(shù),打印出二叉樹中結(jié)點(diǎn)值的和為輸入整數(shù)的所有路徑。路徑定義為從樹的根結(jié)點(diǎn)開始往下一直到葉結(jié)點(diǎn)所經(jīng)過的結(jié)點(diǎn)形成一條路徑。
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function FindPath($root, $expectNumber)
{
    if(!$root) {
        return [];
    }
    $res = $stack = [];
    ToFind($root, $expectNumber, $stack, 0, $res);
    return $res;
}

function ToFind($root, $expectNumber, &$stack, $currentSum, &$res)
{
    $currentSum += $root->val;
    array_push($stack, $root->val);
    $isLeaf = $root->left == NULL && $root->right == NULL;
    if($isLeaf && $currentSum == $expectNumber) {
       $res[] = $stack;
    }
    if($root->left != NULL){
        ToFind($root->left, $expectNumber, $stack, $currentSum, $res);
    }
    if($root->right != NULL){
        ToFind($root->right, $expectNumber, $stack, $currentSum, $res);
    }
    $currentSum -= $root->val;
    array_pop($stack);
}
  • 輸入一個復(fù)雜鏈表(每個節(jié)點(diǎn)中有節(jié)點(diǎn)值,以及兩個指針,一個指向下一個節(jié)點(diǎn),另一個特殊指針指向任意一個節(jié)點(diǎn)),返回結(jié)果為復(fù)制后復(fù)雜鏈表的head。(注意,輸出結(jié)果中請不要返回參數(shù)中的節(jié)點(diǎn)引用,否則判題程序會直接返回空)
<?php
/*class RandomListNode{
    var $label;
    var $next = NULL;
    var $random = NULL;
    function __construct($x){
        $this->label = $x;
    }
}*/
function MyClone($pHead)
{
    if($pHead == NULL) {
        return NULL;
    }
    $headOfLink = $head = $pHead;
    //復(fù)制
    while($pHead)
    {
        $node = new RandomListNode($pHead->label);
        $node->next = $pHead->next;
        $pHead->next = $node;
        
        $pHead = $node->next;
    }
    //random指針處理
    while($head)
    {
        $new = $head->next;
        $new->random = $head->random->next;
        
        $head = $new->next;
    }
    $newHead = $tmp = $headOfLink->next;
    $orginalHead = $newHead->next;
    while($orginalHead)
    {
        $tmp->next = $orginalHead->next;
        $tmp = $orginalHead->next;
        $orginalHead = $tmp->next;
    }
    return $newHead;
}
  • 輸入一棵二叉搜索樹,將該二叉搜索樹轉(zhuǎn)換成一個排序的雙向鏈表。要求不能創(chuàng)建任何新的結(jié)點(diǎn),只能調(diào)整樹中結(jié)點(diǎn)指針的指向
<?php
/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/

function Convert($pRootOfTree)
{
    $head = NULL;
    ConvertTreeToLink($pRootOfTree, $head);
    while($head != NULL && $head->left != NULL)
    {
        $head = $head->left;
    }
    return $head;
}

function ConvertTreeToLink($pRootOfTree, &$head)
{
    if($pRootOfTree == NULL)
        return;
    if($pRootOfTree->left != NULL){
        ConvertTreeToLink($pRootOfTree->left, $head);
    }
    $pRootOfTree->left = $head;
    if($head) {
        $head->right = $pRootOfTree;
    }
    $head = $pRootOfTree;
    if($pRootOfTree->right != NULL){
        ConvertTreeToLink($pRootOfTree->right, $head);
    }
}
  • 輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串a(chǎn)bc,則打印出由字符a,b,c所能排列出來的所有字符串a(chǎn)bc,acb,bac,bca,cab和cba。
<?php

function Permutation($str)
{
    // write code here
    $len = strlen($str);
    if(strlen($str) < 1) return [];
    $res = [];
    GetAllStr($str, $len, 0, $res);
    return $res;
}

function GetAllStr(&$str, $len, $beginPos, &$res)
{
    if($beginPos >= $len-1) {
        $res[] = $str;
    } else {
        for($i = $beginPos; $i < $len; $i++)
        {
            if($i != $beginPos && $str[$beginPos] == $str[$i]) continue;
            $tmp = $str[$i];
            $str[$i] = $str[$beginPos];
            $str[$beginPos] = $tmp;
            
            GetAllStr($str, $len, $beginPos + 1, $res);

            $tmp = $str[$i];
            $str[$i] = $str[$beginPos];
            $str[$beginPos] = $tmp;
        }
    }
}
  • 數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半,請找出這個數(shù)字。例如輸入一個長度為9的數(shù)組{1,2,3,2,2,2,5,4,2}。由于數(shù)字2在數(shù)組中出現(xiàn)了5次,超過數(shù)組長度的一半,因此輸出2。如果不存在則輸出0。
<?php

function MoreThanHalfNum_Solution($numbers)
{
    $len = count($numbers);
    if($len == 0) return 0;
    if($len == 1) return $numbers[0];
    $times = 0;
    $res = 0;
    foreach($numbers as $v)
    {
        if($times == 0) {
            $res = $v;
            $times = 1;
        }else if($v == $res) {
            $times++;
        } else {
            $times--;
        }
    }
    $count = 0;
    foreach($numbers as $v)
    {
        if($v == $res) $count++;
    }
    if($count > (intval)($len/2)) return $res;
    else return 0;
}
  • 輸入n個整數(shù),找出其中最小的K個數(shù)。例如輸入4,5,1,6,2,7,3,8這8個數(shù)字,則最小的4個數(shù)字是1,2,3,4,。
<?php
function GetLeastNumbers_Solution($input, $k)
{
    if(!$input) return [];
    $len = count($input);
    if($k > $len) return [];
    quickSort($input, 0, $len - 1);
    $out = [];
    $i = 0;
    while($i < $k)
        $out[] = $input[$i++];
    return $out;
}
function quickSort(&$arr, $start, $end)
{
    if($start < $end) {
        $mid = partition($arr, $start, $end);
        quickSort($arr, $start, $mid - 1);
        quickSort($arr, $mid + 1, $end);
    }
}

/**
 * 快速排序法切分
 * @param array int數(shù)組
 * @param int $start 開始下標(biāo)
 * @param int $end 結(jié)束下標(biāo)
 * @return int
 */
function partition(&$arr, $start, $end)
{
    $measure = $arr[$end];
    $p = $start - 1;
    for($i = $start; $i < $end; $i++) {
        if($arr[$i] <= $measure) {
            $p = $p + 1;
            $tmp = $arr[$i];
            $arr[$i] = $arr[$p];
            $arr[$p] = $tmp;
        }
    }
    $arr[$end] = $arr[$p + 1];
    $arr[$p + 1] = $measure;
    return $p + 1;
}
  • 在古老的一維模式識別中,常常需要計(jì)算連續(xù)子向量的最大和,當(dāng)向量全為正數(shù)的時候,問題很好解決。但是,如果向量中包含負(fù)數(shù),是否應(yīng)該包含某個負(fù)數(shù),并期望旁邊的正數(shù)會彌補(bǔ)它呢?例如:{6,-3,-2,7,-15,1,2,2},連續(xù)子向量的最大和為8(從第0個開始,到第3個為止)。你會不會被他忽悠住?(子向量的長度至少是1)

function FindGreatestSumOfSubArray($array)
{
    // write code here
    if(empty($array)) return 0;
    $curSum = 0;
    $sum = -1*2^31;
    foreach($array as $v)
    {
        if($curSum < 0) 
        {
            $curSum = $v;
        }else {
            $curSum += $v;
        }
        if($curSum > $sum) $sum = $curSum;
    }
    return $sum;
}
  • 求出113的整數(shù)中1出現(xiàn)的次數(shù),并算出1001300的整數(shù)中1出現(xiàn)的次數(shù)?為此他特別數(shù)了一下1~13中包含1的數(shù)字有1、10、11、12、13因此共出現(xiàn)6次,但是對于后面問題他就沒轍了。ACMer希望你們幫幫他,并把問題更加普遍化,可以很快的求出任意非負(fù)整數(shù)區(qū)間中1出現(xiàn)的次數(shù)。
不會
  • 輸入一個正整數(shù)數(shù)組,把數(shù)組里所有數(shù)字拼接起來排成一個數(shù),打印能拼接出的所有數(shù)字中最小的一個。例如輸入數(shù)組{3,32,321},則打印出這三個數(shù)字能排成的最小數(shù)字為321323。
<?php

function PrintMinNumber($numbers)
{
    if(count($numbers)== 0) return '';
    QuickSort($numbers, 0, count($numbers) - 1);
    $num = '';
    foreach($numbers as $v)
    {
        $num = $num . $v;
    }
    return $num;
}

function QuickSort(&$arr, $start, $end)
{
    if($start < $end)
    {
        $mid = Patition($arr, $start, $end);
        QuickSort($arr, $start, $mid - 1);
        QuickSort($arr, $mid + 1, $end);
    }
}

function Patition(&$arr, $start, $end)
{
    $m = $arr[$end];
    $p = $start - 1;
    for($i = $start; $i < $end; $i++)
    {
        if(CmpStr($arr[$i], $m)) {
            $p++;
            $tmp = $arr[$p];
            $arr[$p] = $arr[$i];
            $arr[$i] = $tmp;
        }
    }
    $arr[$end] = $arr[$p+1];
    $arr[$p+1] = $m;
    return $p + 1;
}


function CmpStr($a, $b)
{
    $str1 = $a . $b;
    $str2 = $b . $a;
    return $str1 < $str2;
}
  • 把只包含因子2、3和5的數(shù)稱作丑數(shù)(Ugly Number)。例如6、8都是丑數(shù),但14不是,因?yàn)樗蜃?。 習(xí)慣上我們把1當(dāng)做是第一個丑數(shù)。求按從小到大的順序的第N個丑數(shù)。
<?php

function minNum($a, $b, $c)
{
    $min = $a < $b ? $a : $b;
    return $min < $c ? $min : $c;
}

function GetUglyNumber_Solution($index)
{
    if($index < 1) return 0;

    $ugly = [];
    $uglyNum = 0;
    $ugly[$uglyNum] = 1;
    $preA = $preB = $preC = 0;
    while($uglyNum < $index - 1)
    {
        $a = $ugly[$preA] * 2;
        $b = $ugly[$preB] * 3;
        $c = $ugly[$preC] * 5;
        $uglyNum++;
        $ugly[$uglyNum] = minNum($a, $b, $c);
        if($a == $ugly[$uglyNum]) $preA++;
        if($b == $ugly[$uglyNum]) $preB++;
        if($c == $ugly[$uglyNum]) $preC++;
    }
    return $ugly[$index-1];
}
  • 在一個字符串(1<=字符串長度<=10000,全部由字母組成)中找到第一個只出現(xiàn)一次的字符,并返回它的位置
function FirstNotRepeatingChar($str)
{
    // write code here
    $len = strlen($str);
    if($len < 1) return -1;
    if($len == 1) return 0;
    $hash = [];
    for($i = 0; $i< $len; $i++)
    {
        if(isset($hash[$str[$i]])) {
            $hash[$str[$i]]++;
        } else {
            $hash[$str[$i]] = 1;
        }
    }
    for($i = 0; $i< $len; $i++)
    {
        if($hash[$str[$i]] == 1) return $i;
    }
    return -1;
}
  • 輸入兩個鏈表,找出它們的第一個公共結(jié)點(diǎn)。
<?php
/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function FindFirstCommonNode($pHead1, $pHead2)
{
    $len1 = GetLength($pHead1);
    $len2 = GetLength($pHead2);
    
    $lenDiff = $len2 - $len1;
    if($lenDiff > 0) {
        $long = $pHead2;
        $short = $pHead1;
    } else {
        $long = $pHead1;
        $short = $pHead2;
        $lenDiff = abs($lenDiff);
    }
    while($lenDiff>0) {
        $long = $long->next;
        $lenDiff--;
    }
    while($long != NULL && $short != NULL && $long != $short)
    {
        $long = $long->next;
        $short = $short->next;
    }
    return $long;
}

function GetLength($pHead)
{
    if($pHead == NULL) return 0;
    $len = 0;
    while($pHead != NULL)
    {
        $len++;
        $pHead = $pHead->next;
    }
    return $len;
}
  • 統(tǒng)計(jì)一個數(shù)字在排序數(shù)組中出現(xiàn)的次數(shù)。
function GetNumberOfK($data, $k)
{
    $count = 0;
    foreach($data as $v)
    {
        if($k == $v) {
            $count++;
        }
    }
    return $count;
}
要用二分法才對
  • 輸入一棵二叉樹,求該樹的深度。從根結(jié)點(diǎn)到葉結(jié)點(diǎn)依次經(jīng)過的結(jié)點(diǎn)(含根、葉結(jié)點(diǎn))形成樹的一條路徑,最長路徑的長度為樹的深度。
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function TreeDepth($pRoot)
{
    /**$max = $deep = 0;
    getDeep($pRoot, $deep, $max);
    return $max;**/
    if($pRoot == NULL) return 0;
    $left = TreeDepth($pRoot->left);
    $right = TreeDepth($pRoot->right);
    return $left > $right ? $left +1 : $right + 1;
}

/**
* 舊方法
**/
function getDeep($pRoot, &$deep, &$max)
{
    if(!$pRoot) return;
    $deep++;
    if($pRoot->left == NULL && $pRoot->right == NULL) 
    {
        if($deep > $max) $max = $deep;
    }
    if($pRoot->left) getDeep($pRoot->left, $deep, $max);
    if($pRoot->right) getDeep($pRoot->right, $deep, $max);
    $deep--;
}
  • 輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
<?php

/*class TreeNode{
    var $val;
    var $left = NULL;
    var $right = NULL;
    function __construct($val){
        $this->val = $val;
    }
}*/
function IsBalanced_Solution($pRoot)
{
    if($pRoot == NULL) return true;
    $left = getDepth($pRoot->left);
    $right = getDepth($pRoot->right);
    if(abs($left - $right) > 1) return false;
    return IsBalanced_Solution($pRoot->left) && IsBalanced_Solution($pRoot->right);
}

function getDepth($pRoot)
{
    if($pRoot == NULL) return 0;
    $left = getDepth($pRoot->left);
    $right = getDepth($pRoot->right);
    return $left > $right ? $left + 1 : $right + 1;
}
  • 一個整型數(shù)組里除了兩個數(shù)字之外,其他的數(shù)字都出現(xiàn)了兩次。請寫程序找出這兩個只出現(xiàn)一次的數(shù)字
<?php

function FindNumsAppearOnce($array)
{
    // write code here
    // return list, 比如[a,b],其中ab是出現(xiàn)一次的兩個數(shù)字
    if(count($array) < 3) {
        return $array;
    }
    $tmp = [];
    foreach($array as $v)
    {
        if(isset($tmp[$v])) {
            unset($tmp[$v]);
        } else {
            $tmp[$v] = 1;
        }
    }
    return array_keys($tmp);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容