# 剑指offer中的算法题(PHP版)

Double段

## 二维数组中的查找

``````function search(\$target, \$array)
{
\$i = count(\$array[0]) - 1;
\$j = 0;

if (\$array[count(\$array) - 1][\$i] < \$target || \$array[0][0] > \$target) {
return false;
}

for (\$i; \$i >= 0; \$i--) {
if (\$array[\$j][\$i] <= \$target) {
for (\$j; \$j < count(\$array); \$j++) {
if (\$array[\$j][\$i] == \$target) {
return true;
} else if (\$array[\$j][\$i] > \$target) {
break;
}
}
}
}

return false;
}

\$s = [[1, 2, 8, 9], [2, 4, 9, 12], [4, 7, 10, 13], [6, 8, 11, 15]];
var_dump(search(1, \$s));``````

## 替换空格

``````function replace(\$str) {
\$len = strlen(\$str);
if (\$len <= 0 ) {
return false;
}
\$blank = 0;
for (\$i = 0; \$i < \$len; \$i++) {
if (\$str[\$i] == ' ') {
\$blank++;
}
}
if (\$blank == 0) {
return false;
}

\$new_length = (\$len + \$blank * 2) - 1;

for (\$i = \$len-1; \$i >=0; \$i--) {
if (\$str[\$i] == ' ') {
\$str[\$new_length--] = '0';
\$str[\$new_length--] = '2';
\$str[\$new_length--] = '%';
} else {
\$str[\$new_length--] = \$str[\$i];
}
}

return \$str;
}

var_dump(replace('We Are Happy'));``````

## 斐波那契数列

``````function a(\$n) {
if (\$n == 0) {
return 0;
} else if (\$n == 1) {
return 1;
}

return a(\$n-1) + a(\$n - 2);
}

echo a(10);``````

``````function a(\$n) {

\$ret = array();

for (\$i=0; \$i <= \$n; \$i++) {
if (\$i == 0) {
\$ret[\$i] = 0;
continue;
}else if (\$i == 1) {
\$ret[\$i] = 1;
continue;
}

\$ret[\$i] = \$ret[\$i-1] + \$ret[\$i-2];
}

return \$ret[\$n];
}

echo a(10);``````

## 调整数组顺序使奇数位于偶数前面

``````function test(\$array) {

if (count(\$array) < 2) {
return false;
}

\$start = 0;
\$end = count(\$array) - 1;

while (\$start < \$end) {
while (\$array[\$end] % 2 == 0 && \$start < \$end) {
\$end--;
}

while (\$array[\$start] % 2 == 1 && \$start < \$end) {
\$start++;
}

if (\$array[\$start] % 2 == 0 && \$array[\$end] % 2 == 1) {
\$temp = \$array[\$end];
\$array[\$end] = \$array[\$start];
\$array[\$start] = \$temp;
}
}

return \$array;
}``````

## 顺时针打印矩阵

``````function printMatrixMain(\$data) {
\$start = 0;
\$columns = count(\$data);
\$rows = count(\$data[0]);

while (\$columns > \$start * 2 && \$rows > \$start * 2) {
printMatrix(\$data, \$columns, \$rows, \$start);
++\$start;
}
}

function printMatrix(\$data, \$columns, \$rows, \$start)
{
\$endx     = \$columns - 1 - \$start;
\$endy     = \$rows - 1 - \$start;

for (\$i = \$start; \$i <= \$endx; \$i++) {
echo \$data[\$start][\$i], '/';
}

for (\$i = \$start + 1; \$i <= \$endy; \$i++) {
echo \$data[\$i][\$endx], '/';
}

for (\$i = \$endx - 1; \$i >= \$start; \$i--) {
echo \$data[\$endy][\$i], '/';
}

for (\$i = \$endy - 1; \$i > \$start; \$i--) {
echo \$data[\$i][\$start], '/';
}
}

\$s = array(
array(1, 2, 3, 4, 5),
array(5, 6, 7, 8, 9),
array(9, 10, 11, 12, 13),
array(13, 14, 15, 16, 17),
array(1, 2, 3, 4, 5),
);

printMatrixMain(\$s);``````

``````function printMatrix(\$data)
{
\$start    = 0;
\$num      = 0;
\$can_loop = true;
\$endx     = count(\$data[0]) - 1;
\$endy     = count(\$data) - 1;

while (\$can_loop) {
if ((\$endx - \$num - \$start < 2) || (\$endy - \$num - \$start) < 2) {
\$can_loop = false;
}

for (\$i = \$start; \$i <= \$endx - \$num; \$i++) {
echo \$data[\$start][\$i], '/';
}

for (\$i = \$start + 1; \$i <= \$endy - \$num; \$i++) {
echo \$data[\$i][\$endx - \$num], '/';
}

for (\$i = \$endx - \$num - 1; \$i >= \$start; \$i--) {
echo \$data[\$endy - \$num][\$i], '/';
}

for (\$i = \$endy - \$num - 1; \$i > \$start; \$i--) {
echo \$data[\$i][\$start], '/';
}

\$start++;
\$num++;
}
}

\$s = array(
array(1, 2, 3, 4, 5),
array(5, 6, 7, 8, 9),
array(9, 10, 11, 12, 13),
array(13, 14, 15, 16, 17),
array(1, 2, 3, 4, 5),
);

printMatrix(\$s);``````

## 二叉搜索树的后序遍历序列

``````function VerifySquenceOfBST(\$data) {
if(empty(\$data)){
return false;
}

\$length = count(\$data);
\$root   = \$data[\$length - 1];

for(\$i = 0; \$i<\$length-1; \$i++) {
if(\$data[\$i] > \$root) {
break;
}
}

\$j = \$i;

for(\$j; \$j < \$length -1; \$j++) {
if (\$data[\$j] < \$root) {
return false;
}
}

\$left = true;
\$right = true;

if(\$i > 0) {
\$left = VerifySquenceOfBST(array_slice(\$data, 0, \$i));
}

if(\$j < \$length - 1) {
\$right = VerifySquenceOfBST(array_slice(\$data, \$i, \$length-1-\$i));
}

return (\$left&&\$right);
}

var_dump(VerifySquenceOfBST([5,7,6,9,11,10,8]));``````

## 字符串的排列

``````function Permutation(\$str) {
if (\$str == NULL)
return false;
if (!is_string(\$str))
return false;
echo_child(\$str, 0);             /*书上用指针，这里我们用下标*/
}

function echo_child(\$str, \$index) {
\$len = strlen(\$str);
if (\$len == (\$index + 1)) {
echo \$str . "    ";
return false;
} else {
for (\$i = \$index; \$i < \$len; \$i++) {
\$new_str         = \$str;
\$tmp             = \$new_str[\$index];
\$new_str[\$index] = \$new_str[\$i];
\$new_str[\$i]     = \$tmp;              /*以上是和第一个字符交换*/
echo_child(\$new_str, \$index + 1);  /*运用递归不断对余下的部分进行交换*/
}
}
}

Permutation('abc');``````

## 数组中出现次数超过一半的数字

``````function MoreThanHalfNum_Solution(\$data)
{
if (empty(\$data)) {
return false;
}

\$ret = array();

foreach (\$data as \$key => \$val) {
if (empty(\$ret)) {
\$ret['value'] = \$val;
\$ret['count'] = 1;
} else {
if (\$val == \$ret['value']) {
\$ret['count']++;
} else {
if (--\$ret['count'] == 0) {
\$ret['value'] = \$val;
\$ret['count'] = 1;
}
}
}
}

if (checkMoreThanHalf(\$data, \$ret['value'])) {
return \$ret['value'];
} else {
return 0;
}
}

function checkMoreThanHalf(\$data, \$number) {
\$time = 0;

foreach (\$data as \$key => \$val) {
if (\$val == \$number) {
\$time++;
}
}

if (\$time * 2 > count(\$data)) {
return true;
} else {
return false;
}
}``````

## 连续子数组的最大和

``````function FindGreatestSumOfSubArray(\$data)
{
if (empty(\$data)) {
return false;
}

\$ret = 0;
\$max = \$data[0];

for (\$i = 0; \$i < count(\$data); \$i++) {
\$ret = \$ret + \$data[\$i];

if (\$ret > \$max) {
\$max = \$ret;
}

if (\$ret < 0) {
\$ret = 0;
}
}

return \$max;
}``````

## 整数中1出现的次数（从1到n整数中1出现的次数）

``````function NumberOf1Between1AndN_Solution(\$str)
{
settype(\$str, 'string');

if (\$str == 0 || strlen(\$str) == 0) {
return 0;
}

\$first = \$str[0];

if (strlen(\$str) == 1 && \$first > 0) {
return 1;
}

if (\$first > 1) {
\$numFirstDigit = powerBase10(strlen(\$str) - 1);
} else {
\$numFirstDigit = substr(\$str, 1) + 1;
}

\$numOtherDigits = \$first * (strlen(\$str)-1) * powerBase10(strlen(\$str)-2);
\$numRecursive = NumberOf1Between1AndN_Solution(substr(\$str, 1));

return \$numFirstDigit + \$numOtherDigits + \$numRecursive;
}

function powerBase10(\$number) {
return pow(10, \$number);
}``````

## 数组中只出现一次的数字

``````function FindNumsAppearOnce(\$array) {
if (empty(\$array)) {
return false;
}

\$xor = 0;
foreach (\$array as \$key => \$val) {
\$xor ^= \$val;
}

\$indexOf1 = findFirstBit1(\$xor);

\$result = array(0,0);
foreach (\$array as \$key => \$value) {
if (isBit1(\$value, \$indexOf1)) {
\$result[0] ^= \$value;
} else {
\$result[1] ^= \$value;
}
}

return \$result;
}

function findFirstBit1(\$num) {
\$index = 0;

while ((\$num & 1) == 0) {
\$num >>= 1;
\$index++;
}

return \$index;
}

function isBit1(\$num, \$indexBit) {
\$num >>= \$indexBit;

return ((\$num & 1) === 1);
}

\$ret = FindNumsAppearOnce(array(2, 4, 3, 6, 3, 2,5,5));
echo \$ret[0],\$ret[1];``````

## 和为S的两个数字

``````function FindNumbersWithSum(\$array, \$sum) {
if (empty(\$array)) {
return false;
}

\$start = 0;
\$end   = count(\$array) - 1;

while (\$start < \$end) {
if (\$array[\$start] + \$array[\$end] < \$sum) {
++\$start;
} else if (\$array[\$start] + \$array[\$end] > \$sum) {
--\$end;
} else {
return \$array[\$start].'/'.\$array[\$end];
}
}

return false;
}``````

## 圆圈中最后剩下的数字

0,1,...,n-1这n个数字排成一个圆圈，从数字0开始每次从这个圆圈里删除第m个数字，求出这个圆圈里剩下的最后一个数字。

``````//通过总结出的公式提供的算法，公式证明过程不展开。
function LastRemaining_Solution(\$n, \$m) {
if (\$n < 1 || \$m < 1) {
return -1;
}

\$last = 0;

for(\$i = 2; \$i <= \$n; \$i++) {
\$last = (\$last + \$m) % \$i;
}

return \$last;
}

//模拟环形链表，这个效率和性能都不如前一个，但是思路简单
function LastRemaining_Solution2(\$n, \$m) {
if (\$n < 1 || \$m < 1) {
return -1;
}

\$data = array();
for (\$i=0; \$i< \$n; \$i++) {
\$data[] = \$i;
}

\$p = 0;
while (count(\$data) >1 ) {
for (\$i=1; \$i<\$m; \$i++) {
++\$p;
\$p = isset(\$data[\$p]) ? \$p : 0;
}
unset(\$data[\$p]);
\$data = array_values(\$data);
\$p = isset(\$data[\$p]) ? \$p : 0;
}

return reset(\$data);
}``````

207 声望
6 粉丝
0 条评论