# 剑指offer（六）其他

## 面试题9：斐波那契数列

class Solution {
public:
int Fibonacci(int n) {
int num[n];
num[0] = 0;
num[1] = 1;
for(int i=2; i<=n; i++){
num[i] = num[i-2]+num[i-1];
}
return num[n];
}
};

class Solution {
public:
int jumpFloor(int number) {
int num[number];
num[0] = 1;
num[1] = 1;
for(int i=2; i<=number; i++){
num[i] = num[i-1]+num[i-2];
}
return num[number];
}
};

class Solution {
public:
int jumpFloorII(int number) {
int num[number];
num[1] = 1;
for(int i=2; i<=number; i++){
num[i] = 2*num[i-1];
}
return num[number];
}
};

class Solution {
public:
int rectCover(int number) {
if(number <= 0)
return 0;
if(number == 1)
return 1;
if(number ==2)
return 2;
int sum, num1=1, num2 = 2;
for(int i=3;i<=number;i++){
sum = num1+num2;
num1 = num2;
num2 = sum;
}
return sum;
}
};

## 面试题10：二进制中1的个数

class Solution {
public:
int  NumberOf1(int n) {
int count = 0;
while(n){
count++;
n = (n-1) & n;
}
return count;
}
};

## 面试题11：数值的整数次方

class Solution {
public:
bool g_InvalidInput = false;
double Power(double base, int exponent) {
if(equal(base,0.0) && exponent<0){
g_InvalidInput = true;
return 0.0;
}
int absExponent = exponent;
if(exponent<0)
absExponent = -exponent;
double res = powerWithUnsignedExponent(base, absExponent);
if(exponent<0)
res = 1.0/res;
return res;
}
bool equal(double num1, double num2){
if((num1 - num2 < 0.0000001) && (num1 - num2 > -0.0000001))
return true;
else
return false;
}
double powerWithUnsignedExponent(double base, int exponent){
if(exponent == 0)
return 1;
if(exponent == 1)
return base;
double result = powerWithUnsignedExponent(base, exponent>>1);
result *= result;
if(exponent & 0x1 == 1)
result *= base;
return result;
}
};

## 面试题20：顺时针打印矩阵

class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
vector<int> result;
int rows = matrix.size();
int columns = matrix[0].size();
int minRow = 0, maxRow = rows-1, minCol = 0, maxCol = columns-1;
int curRow, curCol;
while(minRow<=maxRow && minCol<=maxCol){
for(curRow = minRow, curCol = minCol; curCol <= maxCol; curCol++){
result.push_back(matrix[curRow][curCol]);
}
minRow++;
for(curRow = minRow, curCol = maxCol; curRow <= maxRow; curRow++){
result.push_back(matrix[curRow][curCol]);
}
maxCol--;
if(maxCol < minCol || maxRow < minRow)
break;
for(curRow = maxRow, curCol = maxCol; curCol >= minCol; curCol--){
result.push_back(matrix[curRow][curCol]);
}
maxRow--;
for(curRow = maxRow, curCol = minCol; curRow >= minRow; curRow--){
result.push_back(matrix[curRow][curCol]);
}
minCol++;
}
return result;
}
};

## 面试题32：从1到n整数中1出现的次数

class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
if(n <= 0)
return 0;
char str[50];
sprintf(str,"%d",n);
return numberOf1(str);
}
int numberOf1(const char* str){
if(!str || *str=='\0' || *str<'0' || *str>'9')
return 0;
//假设str是“21345”
int firstNum = *str - '0';  //firstNum=2
int length = strlen(str);
if(length==1 && firstNum==0) //终止条件是length=1
return 0;
if(length==1 && firstNum>0)
return 1;
int firstDigit = 0;
//firstDigit保存1345-21345之间最高为1的数的数目
if(firstNum > 1)
firstDigit = powerBase10(length-1);
else if(firstNum == 1)
firstDigit = atoi(str+1)+1;
//OtherDigits保存1345-21345之间后4位出现1的数的数目：2*4*1000
int OtherDigits = firstNum * (length-1) * powerBase10(length-2);
//recursive保存1-1345之间出现1的数目，递归
int recursive = numberOf1(str+1);
//三数相加
return firstDigit+OtherDigits+recursive;
}
int powerBase10(int n){
int result = 1;
while(n--)
result *= 10;
return result;
}
};

## 面试题34：丑数

class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index<=0)
return 0;
int uglyNumbers[index];
uglyNumbers[0] = 1;
int *M2 = uglyNumbers;
int *M3 = uglyNumbers;
int *M5 = uglyNumbers;
int uglyIndex = 1;
while(uglyIndex < index){
int minNum = Min(*M2 * 2, *M3 * 3, *M5 * 5);
uglyNumbers[uglyIndex++] = minNum;
while(*M2 * 2 <= minNum)
M2++;
while(*M3 * 3 <= minNum)
M3++;
while(*M5 * 5 <= minNum)
M5++;
}
int result = uglyNumbers[uglyIndex-1];
return result;
}
int Min(int a,int b,int c){
int min = (a < b) ? a : b;
return (min < c) ? min : c;
}
};

## 面试题41：和为S的连续正数序列

class Solution {
public:
vector<vector<int> > FindContinuousSequence(int sum) {
vector<vector<int>> result;
if(sum < 3)
return result;
int left = 1;
int right = 2;
int curSum = left + right;
while(left < (sum+1)/2){
if(curSum < sum){
right++;
curSum += right;
}else if(curSum > sum){
curSum -= left;
left++;
}else{
vector<int> tmp;
for(int i=left;i<=right;i++){
tmp.push_back(i);
}
result.push_back(tmp);
right++;
curSum += right;
}
}
return result;
}
};

class Solution {
public:
vector<int> FindNumbersWithSum(vector<int> array,int sum) {
vector<int> result;
int len = array.size();
if(len > 1){
int left = 0;
int right = len-1;
while(left < right){
int curSum = array[left] + array[right];
if(curSum == sum){
result.push_back(array[left]);
result.push_back(array[right]);
break;
}else if(curSum > sum){
right--;
}else{
left++;
}
}
}
return result;
}
};

## 面试题44：扑克牌的顺子

class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
int len = numbers.size();
if(len==0)
return false;
sort(numbers.begin(),numbers.end());
int numOfZero = 0;
for(int i=0;i<len;i++)
if(numbers[i] == 0)
numOfZero++;
int numOfGap = 0;
int small = numOfZero;
int big = small + 1;
while(big<len){
if(numbers[small] == numbers[big])
return false;
numOfGap += numbers[big] - numbers[small] - 1;
small++;
big++;
}
return (numOfZero >= numOfGap ? true : false);
}
};

## 面试题45：圆圈中最后剩下的数字

class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
if(n<1 || m<1)
return -1;
list<int> nums;
for(int i=0;i<n;i++)
nums.push_back(i);
list<int>::iterator cur = nums.begin();
while(nums.size() > 1){
for(int i=1;i<m;i++){
cur++;
if(cur == nums.end())
cur = nums.begin();
}
list<int>::iterator next = ++cur;
if(next == nums.end())
next = nums.begin();
nums.erase(--cur);
cur = next;
}
return *cur;
}
};
//下面这个更好
class Solution {
public:
int LastRemaining_Solution(int n, int m)
{
if(n<1 || m<1)
return -1;
int last = 0;
for(int i=2; i<=n; i++){
last = (last + m) % i;
}
return last;
}
};

## 面试题46：求1+2+3+…+n

//用n>0的&&来代替终止判断。
class Solution {
public:
int Sum_Solution(int n) {
int sum = n;
bool ans = (n>0)&&((sum+=Sum_Solution(n-1))>0);
return sum;
}
};
//利用函数指针求解
typedef int (*fun)(int);
class Solution {
public:
static int Solution_Terminator(int n){
return 0;
}
static int Sum_Solution(int n) {
static fun f[2] = {Solution_Terminator,Sum_Solution};
return n+f[!!n](n-1);
}
};

## 面试题47：不用加减乘除做加法

class Solution {
public:
{
int sum,carry;
do{
sum = num1 ^ num2;
carry = (num1 & num2) << 1;
num1 = sum;
num2 = carry;
}while(num2 != 0);
return num1;
}
};

## 面试题49：把字符串转换成整数

class Solution {
public:
int StrToInt(string str) {
int len = str.length();
if(len == 0)
return 0;
long num = 0;
int flag = 1;
int i = 0;
while(str[i] == ' ') //过滤前面的空格
i++;
if(str[i] == '+') //处理正负号
i++;
else if(str[i] == '-'){
i++;
flag = -1;
}
while(str[i] != '\0'){
if(str[i]>='0' && str[i]<='9'){
num = num * 10 + flag *(str[i] - '0');
if((flag==1 && num>0x7fffffff) || (flag==-1 && num<(signed int)0x80000000)){ //处理溢出
num = 0;
break;
}
i++;
}else{ //处理非法字符
num = 0;
break;
}
}
return num;
}
};

## 面试题53：正则表达式匹配

class Solution {
public:
bool match(char* str, char* pattern)
{
if(str == NULL || pattern == NULL)
return NULL;
return matchCore(str,pattern);
}
bool matchCore(char* str,char* pattern){
if(*str == '\0' && *pattern == '\0')
return true;
if(*str != '\0' && *pattern == '\0')
return false;
if(*(pattern+1) == '*'){
if(*pattern == *str || (*pattern=='.'&&*str!='\0'))
return (matchCore(str+1,pattern+2) || matchCore(str+1,pattern) || matchCore(str,pattern+2));
else
return matchCore(str,pattern+2);
}
if(*str == *pattern || (*pattern == '.' && *str != '\0'))
return matchCore(str+1, pattern+1);
return false;
}
};

## 面试题64：数据流中的中位数

class Solution {
public:
void Insert(int num)
{
if(((min.size()+max.size()) & 1) == 0){ //当前数据总数目是偶数
if(max.size()>0 && num < max[0]){
max.push_back(num);
push_heap(max.begin(),max.end(),less<int>());
num = max[0];
pop_heap(max.begin(),max.end(),less<int>());
max.pop_back();
}
min.push_back(num);
push_heap(min.begin(),min.end(),greater<int>());
}else{
if(min.size()>0 && num > min[0]){
min.push_back(num);
push_heap(min.begin(),min.end(),greater<int>());
num = min[0];
pop_heap(min.begin(),min.end(),greater<int>());
min.pop_back();
}
max.push_back(num);
push_heap(max.begin(),max.end(),less<int>());
}
}

double GetMedian()
{
int size = min.size() + max.size();
//if(size == 0)
//throw exception("No numbers are available");
double median;
if((size & 1) == 0)
median = (min[0] + max[0])/2.0;
else
median = min[0];
return median;
}
private:
vector<int> min;
vector<int> max;
};

## 面试题65：滑动窗口的最大值

class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> max;
deque<int> index;
if(num.size() >= size && size >= 1){
for(unsigned int i=0; i<num.size(); i++){
while(index.size() && num[i] >= num[index.back()])//把队列中所有比待输入的数字num小的数字都弹出
index.pop_back();
if(index.size() && (i-index.front()+1)>size) //判断队首的数字有没有超过滑窗的大小
index.pop_front();
index.push_back(i);
if(size&&i+1>= size) 滑动到第size个num才开始放入结果
max.push_back(num[index.front()]);
}
}
return max;
}
};

## 面试题66：矩阵中的路径

class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if(matrix == NULL || rows<1 || cols<1 || str==NULL)
return false;
bool *visited = new bool[rows * cols];
memset(visited,0,rows*cols);

int pathLength = 0;
for(int row=0;row<rows;row++){
for(int col=0;col<cols;col++){
if(hasPathCore(matrix,rows,cols,row,col,str,pathLength,visited))
return true;
}
}
delete[] visited;
return false;
}
bool hasPathCore(char* matrix,int rows,int cols,int row,int col,char* str,int &pathLength,bool* visited){
if(str[pathLength] == '\0')
return true;
bool hasPath = false;
if(row>=0 && row<rows && col>=0 && col<cols && matrix[row*cols+col]==str[pathLength] && !visited[row*cols+col]){
pathLength++;
visited[row*cols+col] = true;
hasPath = hasPathCore(matrix,rows,cols,row,col-1,str,pathLength,visited) ||
hasPathCore(matrix,rows,cols,row,col+1,str,pathLength,visited) ||
hasPathCore(matrix,rows,cols,row+1,col,str,pathLength,visited) ||
hasPathCore(matrix,rows,cols,row-1,col,str,pathLength,visited);
if(!hasPath){
pathLength--;
visited[row*cols+col] = false;
}
}
return hasPath;
}
};

## 面试题67：机器人的运动范围

class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
bool *visited = new bool[rows*cols];//标识这个格子是否已经进过了
memset(visited,0,rows*cols);
int count = movingCountCore(threshold,rows,cols,0,0,visited);//从原点出发
delete[] visited;
return count;
}
int movingCountCore(int threshold,int rows,int cols,int row,int col,bool* visited){
int count = 0;
if(check(threshold,rows,cols,row,col,visited)){ //check函数判断机器人能否进入坐标为(row,col)的格子
visited[row*cols+col] = true;
count = 1+movingCountCore(threshold,rows,cols,row+1,col,visited)+
movingCountCore(threshold,rows,cols,row-1,col,visited)+
movingCountCore(threshold,rows,cols,row,col+1,visited)+
movingCountCore(threshold,rows,cols,row,col-1,visited);
}
return count;
}
bool check(int threshold,int rows,int cols,int row,int col,bool* visited){
if(row>=0 && row<rows && col>=0 && col<cols &&
getDigitSum(row)+getDigitSum(col)<=threshold && !visited[row*cols+col])
return true;
return false;
}
int getDigitSum(int num){  //getDigitSum用来你得到一个数字的数位之和
int sum = 0;
while(num>0){
sum += num%10;
num /= 10;
}
return sum;
}
};