【剑指Offer】俯视50题之31 - 40题
面试题31连续子数组的最大和
面试题32从1到n整数中1出现的次数
面试题33把数组排成最小的数
面试题34丑数
面试题35第一个仅仅出现一次的字符
面试题36数组中的逆序对
面试题37两个链表的第一个公共结点
面试题38数字在排序数组中出现的次数
面试题39二叉树的深度
面试题40数组中仅仅出现一次的数字
/*******************************************************/
面试题31连续子数组的最大和 ,输入一个数组。数组里面有正数,也有负数。
求连续数的最大值
实现例如以下:
int MaxSum(int num[], int length)
{
int CurrentSum = 0;
int iResult = 0x80000000; if (num == NULL || length < 0)
{
return 0;/* invalid */
} for (int i = 0; i < length; i++)
{ if (CurrentSum <= 0)
{
CurrentSum = num[i];
}
else
{
CurrentSum += num[i];
} if (CurrentSum > iResult)
iResult = CurrentSum;
}
return iResult;
}
面试题32从1到n整数中1出现的次数 ,输入一个N,求1到N全部的整数中1出现的次数
实现例如以下:
#include <iostream> int CountNum(int n)
{
int iCurrentNum = 0;/* 当前位的数 */
int iNTemp = n;
int iResult = 0;
int iBase = 1; /* 个位 */
int iRemain = 0; if (n <= 0)
{
return 0;
} while (iNTemp > 0)
{
iCurrentNum = iNTemp % 10;
iNTemp = iNTemp/10; if (iCurrentNum > 1)
{
iResult+= (iNTemp + 1)*iBase;
}
else if (iCurrentNum == 1)
{
iResult+= (iNTemp)*iBase + iRemain + 1;
}
else if (iCurrentNum == 0)
{ iResult+= (iNTemp)*iBase;
} iRemain += iCurrentNum*iBase; /* 先计算剩余数大小*/
iBase = iBase*10; /**然后计算下次base位*/
} return iResult;
} int main()
{
printf("%d\n",CountNum(11));
}
面试题33把数组排成最小的数
实现例如以下:
#include <iostream>
#define MAX_NUM_LENGTH 10 int compare(const void *str1, const void *str2)
{
char str1Temp[MAX_NUM_LENGTH*2 +1];
char str2Temp[MAX_NUM_LENGTH*2 +1]; strcpy(str1Temp, (const char*)str1);
strcat(str1Temp, (const char*)str2); strcpy(str2Temp, (const char*)str2);
strcat(str2Temp, (const char*)str1); return strcmp(str1Temp,str2Temp); }
void GetMinNum(int num[], int length)
{
char **numStr = (char **)malloc(length + 1);
for (int i = 0; i < length; i++)
{
numStr[i] = (char *)malloc(MAX_NUM_LENGTH +1);
sprintf(numStr[i],"%d",num[i]);
}
qsort(numStr,length,sizeof(char *),compare); for (int i = 0; i < length; i++)
{
printf("%s",numStr[i]);
} /* 释放内存 */
for (int i = 0; i < length; i++)
{
free(numStr[i]);
}
free(numStr); } int main()
{
int num[] = {1,234,341};
GetMinNum(num, 3);
}
面试题34丑数
实现例如以下:
#include <iostream>
#define MAX_NUM_LENGTH 10 int min(int a, int b, int c)
{
int min = (a>b)?b:a;
min = (min > c)? c:min; return min;
}
/* 仅仅能被2、3、5整除的 */
int GetUglyNum(int n)
{
/* 创建一个n个元素的数组 */
int UglyNum[n];
int p2 = 0;
int p3 = 0;
int p5 = 0;
int NextIndex = 1;
UglyNum[0] = 1; while(NextIndex < n)
{
UglyNum[NextIndex] = min(UglyNum[p2]*2, UglyNum[p3]*3 ,UglyNum[p5]*5); while(UglyNum[p2]*2 <= UglyNum[NextIndex])
{
p2++;
}
while(UglyNum[p3]*3 <= UglyNum[NextIndex])
{
p3++;
}
while(UglyNum[p5]*5 <= UglyNum[NextIndex])
{
p5++;
} NextIndex++;
} return UglyNum[NextIndex - 1];
} int main()
{
printf("%d\n",GetUglyNum(3)); }
面试题35第一个仅仅出现一次的字符
实现例如以下:
#include <iostream>
#define VOS_OK 0
#define VOS_ERR 1 /* 仅仅能被2、3、5整除的 */
int GetFirstChar(char *str, char *result)
{
unsigned int hashNum[256] = {0};
char *p; if (str == NULL)
{
return VOS_ERR;
} p = str;
while(*p != '\0')
{
hashNum[*p]++;
p++;
} p = str;
while(*p!= '\0')
{
if (hashNum[*p] == 1)
{
*result = *p;
return VOS_OK;
}
p++;
}
return VOS_ERR; } int main()
{
char iChar;
if (VOS_OK == GetFirstChar("aabcddb", &iChar))
{
printf("%c\n",iChar);
}
else
{
printf("Error!");
}
}
面试题36数组中的逆序对
实现例如以下:
/* 求数组中的逆序对 */
#include <iostream>
#define VOS_OK 0
#define VOS_ERR 1
int Merge(int *numA, int begin,int mid, int end)
{
int startA = begin;
int startB = mid + 1;
int *numB = (int *)malloc(sizeof(int)*(end + 1));
int currentIndex = 0;
long long result = 0; if (numA == NULL || begin > mid || mid > end)/* 其余异常函数调用处保证 */
{
return 0;
} while (startA <=mid && startB <= end)
{
if (numA[startA] <= numA[startB])
{
numB[currentIndex] = numA[startA++];
}
else
{
numB[currentIndex] = numA[startB++];
/* 前面的大于后面的,则前数组之后的元素也大于该元素 */
result += mid - startA + 1;
} currentIndex++;
} while (startA <= mid)
{
numB[currentIndex++] = numA[startA++];
} while (startB <= end)
{
numB[currentIndex++] = numA[startB++];
} for (int i = begin; i <= end; i++)
{
numA[i] = numB[i];
}
free(numB); return result; } int MergeSort(int *num, int start, int end)
{
int result = 0;
int mid;
if (num == NULL || start >= end) /* 注意start == end 的时候*/
{
return 0;
} mid = (start + end)>>1;
result = MergeSort(num, start, mid) + MergeSort(num, mid +1, end);
result += Merge(num,start,mid,end); return result; } int main()
{
int num[]={2,1,3,5,6}; printf("%d\n",MergeSort(num, 0, 4));
}
面试题37两个链表的第一个公共结点
实现例如以下:
1)暴力法
每次遍历链表A,然后将链表A中当前结点在链表B中查找。假设找到则停止查找,返回。
2)空间换取时间
将两个链表都入栈,然后从最后一个结点開始比較。直到不相等为止。
3)同一时候向后查找
先遍历链表A得长度lengthA。再遍历链表B得长度lengthB
假如A比B长n。则A先走n步,假如B比A长n,则B先走n步。
然后同一时候向后走,直到第一个相等的结点
面试题38数字在排序数组中出现的次数
有两种思路:利用二分查找法,找到该数中间出现的位置,然后分别向前后遍历同样数,可得到该数出现的次数
利用二分查找法,找打该数最左边及最右边出现的位置。然后就能够求得该数出现的次数
左右查询实现例如以下:
#include <iostream>
int MaxSum(int num[], int length, int value)
{
int iResult = 0;
int i = 0;
int j = length - 1;
int mid;
int k; while(i <= j )
{
mid = (i + j)>>1;
if (num[mid] > value)
{
j= mid - 1;
}
else if (num[mid] < value)
{
i = mid + 1;
}
else
{
/* 向左查询*/
k = mid-1;
while (k >= i &&(num[k] == value))
{
k--;
iResult++;
}
/* 向右查询*/
k = mid+1;
while (k <= j &&(num[k] == value))
{
k++;
iResult++;
}
printf("================");
return iResult + 1;
}
} return iResult;
} int main()
{
int num[]={2,2,2,2,5,5,6,6}; printf("%d\n",MaxSum(num, 8, 2) );
getchar();
}
第二种实现方法:
#include <iostream>
int GetFirstK(int num[], int length, int value)
{
int mid;
int i = 0;
int j = length - 1; if (num == NULL)
{
return 0;
} while (i <= j)
{
mid = (i + j)>>1; if (num[mid] > value)
{
j = mid - 1;
}
else if (num[mid] < value)
{
i = mid + 1;
}
else
{
if (mid -1 >= 0 && (num[mid - 1] == value))
{
j = mid - 1;
}
else
{
return mid;
}
}
} return 0;
} int GetLastK(int num[], int length, int value)
{
int mid;
int i = 0;
int j = length - 1; if (num == NULL)
{
return 0;
} while (i <= j)
{
mid = (i + j)>>1; if (num[mid] > value)
{
j = mid - 1;
}
else if (num[mid] < value)
{
i = mid + 1;
}
else
{
if (mid + 1 <= j && (num[mid + 1] == value))
{
i = mid + 1;
}
else
{
return mid;
}
}
} return 0;
} int main()
{
int num[]={2,2,2,2,5,5,6,6}; printf("%d\n",GetLastK(num, 8, 2) - GetFirstK(num, 8, 2) + 1);
getchar();
}
面试题39二叉树的深度
实现例如以下:
int DepthTree(BinaryNode *root)
{
int leftDepth = 0;
int rightDepth = 0; if (root == NULL)
{
return 0;
} leftDepth = DepthTree(root->lchild);
rightDepth = DepthTree(root->rchild); retrun (leftDepth > rightDepth)? (leftDepth + 1):(rightDepth + 1);
}
扩展题目:推断一个树是否是平衡二叉树
实现例如以下:
bool IsBlanceTree(BinaryNode *root, int *depth)
{
int leftDepth = 0;
int rightDepth = 0;
int diff; if (root == NULL)
{
return true;
} leftDepth = DepthTree(root->lchild);
rightDepth = DepthTree(root->rchild); if (IsBlanceTree(root->lchild, &leftDepth)
&&IsBlanceTree(root->rchild, &rightDepth))
{
diff = leftDepth - rightDepth;
if (diff < 1 && diff > -1)
{
*depth = (leftDepth > rightDepth)? (leftDepth + 1):(rightDepth + 1);
return true;
}
} retrun false;
}
面试题40数组中仅仅出现一次的数字 :给一个数组,数组中有两个数仅仅出现一次。其余数出现两次,求这两个数
思路:将数组分成两组,分别异或去重。怎样分组呢?分组依据异或之后。最后一位二进制值为1的位分组。对数组一进行异或最后得一个数。对数组二异或。最后得还有一个数。
则最后得到的两个数是所求的数。
实现例如以下:
int FindFirstBitIsOne(int resultOR)
{
for (int i = 0; i < 32; i++)
{
if (resultOR & (1 << i))
{
return i;
}
}
return 0; } int IsBitOne(int data, int indexOfOne)
{
return data & (1<<indexOfOne); }
void FindNumsAppearOnce(int data[],int length,int *num1,int num2)
{
if (data == NULL || length < 2)
{
return;
}
int resultOR = 0;
for (int i = 0; i < length; i++)
{
resultOR ^=data[i];
} int indexOfOne = FindFirstBitIsOne(resultOR); for (int j = 0; j < length; j++)
{
if (IsBitOne(data[j], indexOfOne))
{
*num1 ^=data[j];
}
else
{
*num2^=data[j];
}
} }
【剑指Offer】俯视50题之31 - 40题的更多相关文章
- 【好书推荐】《剑指Offer》之硬技能(编程题12~16)
本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword <[好书推荐]& ...
- 【好书推荐】《剑指Offer》之硬技能(编程题7~11)
本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword <[好书推荐]& ...
- 【好书推荐】《剑指Offer》之硬技能(编程题1~6)
本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/sword 前一篇<[好书推 ...
- 剑指offer(第2版)刷题 Python版汇总
剑指offer面试题内容 第2章 面试需要的基础知识 面试题1:赋值运算符函数 面试题2:实现Singleton模式 解答 面试题3:数组中重复的数字 解答 面试题4:二维数组中的查找 解答 面试题 ...
- 《剑指Offer》第二章(一)题3-8
为春招实习做准备,记录一下<剑指Offer>里面的面试题 第二章 面试题3:数组之中的重复数字. 这个题吧,虽然不难,但是不知道为什么就是看了很久,可能很久没有做算法题了.最后面一句话说的 ...
- 【剑指Offer】50、数组中重复的数字
题目描述: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果 ...
- 剑指 Offer 61. 扑克牌中的顺子 + 简单题 + 思维
剑指 Offer 61. 扑克牌中的顺子 Offer_61 题目描述 java代码 package com.walegarrett.offer; /** * @Author WaleGarrett * ...
- 剑指 Offer 58 - II. 左旋转字符串 + 简单题
剑指 Offer 58 - II. 左旋转字符串 Offer_58_2 题目描述 java代码 package com.walegarrett.offer; /** * @Author WaleGar ...
- 剑指offer(50)数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
随机推荐
- Android(java)学习笔记203:JNI之NDK开发步骤
1. NDK开发步骤(回忆一下HelloWorld案例): (1)创建工程 (2)定义native方法 (3)创建jni文件夹 (4)创建c源文件放到jni文件夹 (5)拷贝jni.h头文件到jni目 ...
- Day3 CSS 引入及基本选择器
一 .CSS 层叠样式表,为了使网页元素的样式更加丰富,内容与样式拆分开来.HTML负责结构与内容,表现形式交给CSS. CSS注释/**/ 来注释 二.CSS基本语法与引用 CSS的语法结构 选择器 ...
- arch - 显示机器的体系结构
总览 (SYNOPSIS) arch 描述 (DESCRIPTION) arch 等同于 uname -m. 目前的 Linux 系统上, arch 显示 的 数据 有 "i386" ...
- 模态对话框与非模态对话框(modeless)
对话框有两种创建方式:DoModal和Creat. 其中DoModal创建的是模态的对话框,而Creat创建的是非模态的对话框下面总结下他们的不同. 对于模态的对话框,在该对话框被关闭前,用户将不能在 ...
- redis新特性
摘自<redis 4.xcookbook> 从实例重启同步] 故障切换同步] 4.0之前从实例主键过期bug redis4新特性 Memory Command Lazy Free PSYN ...
- 页面jsp向后端发送:HTTP 400错误 - 请求无效(Bad request)
HTTP 400错误 - 请求无效(Bad request) jsp页面有误 在ajax请求后台数据时有时会报 HTTP 400 错误 - 请求无效 (Bad request);出现这个请求无效报错说 ...
- LAMP 服务器环境
学习PHP脚本编程语言之前,必须先搭建并熟悉开发环境,开发环境有很多种,例如LAMP.WAMP.MAMP等.这里我介绍一下LAMP环境的搭建,即Linux.Apache.MySQL.PHP环境. 一. ...
- Buffer.compare()
Buffer.compare(buf1, buf2) buf1 {Buffer} buf2 {Buffer} 返回:{Number} 比较 buf1 和 buf2 通常用于 Buffer 数组的排序目 ...
- rbac组件之权限初始化(五)
当用户登陆后,根据用户的角色要为用户生成对应的权限菜单,此时需要将登陆的用户信息获取且获取角色信息,从数据库中获取菜单以及权限信息,并且存入session中. 1.权限流程 第一次请求的页面是登陆页面 ...
- python 库文件版本收集及安装
版本收集:pip freeze > require.txt版本安装:pip install -r require.txt