剑指offer算法题

  • 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
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;
}
  • 输入一个链表,从尾到头打印链表每个节点的值。
<?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;
    }
}
  • 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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;
}
  • 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为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);
}
  • 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为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];
}
  • 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。
    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;
}
  • 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
class Solution {
public:
     int  NumberOf1(int n) {
         unsigned int count = 0;
         while(n!=0)
         {
             count++;
             n = n & (n - 1);
         }
         return count;
     }
};
  • 给定一个double类型的浮点数base和int类型的整数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;
}
  • 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
function reOrderArray($array)
{
    $resEven = $resOdd = [];
    foreach($array as $value)
    {
        if($value & 0x1) {
            $resOdd[] = $value;
        } else {
            $resEven[] = $value;
        }
    }
    return array_merge($resOdd, $resEven);
}
  • 输入一个链表,输出该链表中倒数第k个结点。
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;
}
  • 输入一个链表,反转链表后,输出链表的所有元素。
<?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;
}
  • 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
<?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的子结构。(ps:我们约定空树不是任意一个树的子结构)
<?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);
}
  • 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字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;
}
  • 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
<?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;
}
  • 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但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;
}
  • 从上往下打印出二叉树的每个节点,同层节点从左至右打印。
<?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;
}
  • 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
<?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;
}
  • 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
<?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);
}
  • 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
<?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;
    //复制
    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;
}
  • 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向
<?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);
    }
}
  • 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,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;
        }
    }
}
  • 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出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个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是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数组
 * @param int $start 开始下标
 * @param int $end 结束下标
 * @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;
}
  • 在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为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的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
不会
  • 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为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的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
<?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,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置
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;
}
  • 输入两个链表,找出它们的第一个公共结点。
<?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;
}
  • 统计一个数字在排序数组中出现的次数。
function GetNumberOfK($data, $k)
{
    $count = 0;
    foreach($data as $v)
    {
        if($k == $v) {
            $count++;
        }
    }
    return $count;
}
要用二分法才对
  • 输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
<?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;
}
  • 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字
<?php

function FindNumsAppearOnce($array)
{
    // write code here
    // return list, 比如[a,b],其中ab是出现一次的两个数字
    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);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容