剑指offer c语言 pdf,《剑指Offer》-Exercise(C语言)

面试题4:二维数组中的查找

/*

测试数据:

查找7:

4

1 2 8 9

2 4 9 12

4 7 10 13

6 8 11 15

1

-----

查找14:

4

1 2 8 9

2 4 9 12

4 7 10 13

6 8 11 15

0

*/

#include

//注意:二维数组用做函数形参

int searchIna(int a[][4],int s,int n) {

int i = 0,j = n-1;

while (a[i][j] > s) {

while (a[i][j]>s) {

j--;

}

while (a[i][j]

i++;

}

if (a[i][j] == s) {

return 1;

}

}

return 0;

}

int main(int argc, const char * argv[]) {

int n = 0;

scanf("%d",&n);

int a[n][n];

for (int i = 0; i

for (int j = 0; j

scanf("%d",&a[i][j]);

}

}

// for (int i = 0; i

// for (int j = 0; j

// printf("%d ",a[i][j]);

// }

// printf("\n");

// }

printf("%d\n",searchIna(a, 14, 4));

return 0;

}

面试题6:从尾到头打印链表

单链表从尾到头打印(用栈或递归)

//从尾到头打印链表(递归)

void printfList(LinkedList L) {

L = L->next;//跳过头节点

if (NULL == L->next) {

printf("%d ",L->data);

return;

}

printfList(L);

printf("%d ",L->data);

}

面试题7:重建二叉树

根据先序遍历序列和中序遍历序列,重建二叉树

//根据先序遍历序列和中序遍历序列重建二叉树

BiTree Construct(int *ptree,int *itree,int length)

{

if(ptree==NULL || itree==NULL || length<=0)

return NULL;

return ConstructCode(ptree,ptree+length-1,itree,itree+length-1);

}

/****************************************************************

*args:

* ptree_start:先序遍历开始位置指针

* ptree_end:先序遍历结束位置指针

* itree_start:中序遍历开始位置指针

* itree_end:中序遍历结束位置指针

****************************************************************/

BiTree ConstructCode(int *ptree_start,int *ptree_end,int *itree_start,int *itree_end)

{

BiTree root_node;

root_node=(BiTree)malloc(sizeof(BiTNode));

root_node->data=ptree_start[0]; /*根节点*/

root_node->lChild=NULL;

root_node->rChild=NULL;

if(ptree_start==ptree_end) /*该节点是子树最后一个节点*/

{

if(itree_start==itree_end && *ptree_start==*ptree_end)

{

return root_node;

}else

{

printf("ConstructCode is error!\n");

exit(1);

}

}

int *tmp_itree=itree_start;

int left_length=0;

while((*itree_start!=root_node->data) && (itree_start

{

itree_start++;

}

left_length=itree_start-tmp_itree; /*根节点在中序遍历中的位置,用于求在先序遍历中右子树的开始位置*/

if(left_length>0) /*左子树递归*/

{

root_node->lChild=ConstructCode(ptree_start+1,ptree_start+left_length,tmp_itree,itree_start-1);

}

if(left_lengthleft_length说明遍历序列比左子树长,右子树有节点*/

{

root_node->rChild=ConstructCode(ptree_start+left_length+1,ptree_end,itree_start+1,itree_end);

}

return root_node;

}

面试题8:二叉树的(中序遍历序列)下一个节点

非标准答案,改中序遍历,添加标记打印。

//中序遍历 找出节点的下一个节点

void MiddleOrderBiTreeFindNextData(BiTNode *T,int s,int flag)

{

if (T == NULL)

{

return;

}

else

{

MiddleOrderBiTreeFindNextData(T->lChild,s,flag);

if (flag == 1) {

printf("%d ",T->data);

return;

}

if (T->data == s) {

flag = 1;

}

MiddleOrderBiTreeFindNextData(T->rChild,s,flag);

}

}

面试题10:斐波那契数列

//递归,效率低,存在重复计算项

int fabonacci(int n) {

if (n == 0) {

return 0;

} else if (n == 1) {

return 1;

} else {

return fabonacci(n -1) + fabonacci(n - 2);

}

}

//改进,用c记录前一项值。时间复杂度:O(n)

int fabonacci2(int n) {

int resu[2] = {0,1};

int a = 0, b = 1, c = 0;

if (n < 2) {

return resu[n];

} else {

for (int i = 2; i <= n; i++) { //要加上等于,因为斐波那契数列从第0项计算

c = a + b;

a = b;

b = c;

}

}

return c;

}

面试题11:旋转数组的最小数字

时间复杂度:O(n)

//遍历一遍数组

int minInA1(int a[],int n) {

int min = -999999;

for (int i = 0; i < n; i++) {

if (a[i] > a[i+1]) {

min = a[i+1];

}

}

return min;

}

时间复杂度:O(logn) (未考虑特殊情况:1 1 1 0 1)

//改进(类似二分查找法,递归写法)

int minInA2(int a[],int low,int high) {

int mid = (low + high)/2;

if (low

if (high - low == 1) {

return a[mid+1];

} else if (a[low] <= a[mid]) {

return minInA2(a, mid, high);

} else if (a[low] > a[mid]) {

return minInA2(a, low, mid);

}

}

return -1;

}

把前两种综合起来,完整的算法

//考虑特殊情况:1 1 1 0 1

int minInA3(int a[],int low,int high) {

int mid = (low + high)/2;

if (a[mid] == a[low] && a[mid] == a[high]) {

return minInA1(a, high+low+1);

} else return minInA2(a, low, high);

}

面试题14:剪绳子

动态规划

int maxProducyAfterCounting(int n) {

if (n < 2) {

return 0;

} else if (n == 2) {

return 1;

} else if (n == 3) {

return 2;

} else {

int product[n+1];

product[0] = 0;

product[1] = 1;

product[2] = 2;

product[3] = 3;

int max;

for (int i = 4; i<=n; i++) {

max = 0;

for (int j = 1; j<=i/2; j++) {

int producter = product[j] * product[i - j];

if (max

max = producter;

}

product[i] = max;

}

}

max = product[n];

return max;

}

}

贪婪算法

int maxProducyAfterCounting2(int n) {

if (n < 2) {

return 0;

} else if (n == 2) {

return 1;

} else if (n == 3) {

return 2;

} else {

int timesOf3 = n/3;

if (n - timesOf3 == 1) {

timesOf3 = timesOf3 - 1;

}

int timesOf2 = (n - timesOf3 * 3)/2;

return pow(3, timesOf3) * pow(2, timesOf2);

}

}

and so on...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值