#include<iostream>#include<cassert>
using namespace std;
enum Legal{valid=0,legal=1};
int flag = 1;
int fuhao = 1;
int strToInt(const char *str)
{
longlong num = 0;
while (*str != '\0')
{
if (*str >= '0'&&*str <= '9')
{
num = num * 10 + fuhao*(*str - '0');
if ((1 == fuhao&&num > 0x7fffffff) || -1 == fuhao&&num < (signed int)0x80000000)
{
num = 0;
break;
}
++str;
}
else
{
num = 0;
break;
}
}
if (*str == '\0')
flag = legal;
return num;
}
int Atoi(const char *str)
{
assert(str);
longlong num = 0;
while (' ' == *str)
++str;
if (*str != '\0')
{
if ('-' == *str)
{
++str;
fuhao = -1;
}
elseif ('+' == *str)
++str;
else
{
flag = valid;
}
if (*str != '\0')
{
num = strToInt(str);
}
}
return (int)num;
}
int main()
{
char *str = " -1234";
int res=Atoi(str);
cout << res << endl;
system("pause");
}
2. 前序中序遍历重建二叉树
/*
由前序遍历和中序遍历重建二叉树(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)
分析:
先序遍历:访问当前结点,访问左子树,访问右子树.
中序遍历:访问左子树,访问当前结点,访问右子树.
可以发现,前序遍历的每一结点,都是当前子树的根节点,我们可以根据前序遍历的序列对中序遍历的序列进行划分。
*/void CreatSubTree(BinaryTreeNode<int>* &root,
int* InOrder,
int *PrevOrder,
int len)
{
if (len<=0)
return;
root= new BinaryTreeNode<int>(PrevOrder[0]);
intindex = 0; //父节点在数组中的下标for (; index < len; ++index)
{
if (PrevOrder[0] == InOrder[index])
break;
}
int subTreeL =index; //左子树结点个数int subTreeR = len - index - 1; //右子树结点个数
CreatSubTree(root->_left, InOrder, PrevOrder + 1, subTreeL);
CreatSubTree(root->_right,InOrder + index + 1, PrevOrder + index + 1, subTreeR);
}
BinaryTreeNode<int>* RebuildBinaryTree(int *InOrder, int *PrevOrder, int len)
{
assert(InOrder);
assert(PrevOrder);
BinaryTreeNode<int>* root;
CreatSubTree(root, InOrder, PrevOrder,len);
return root;
}
3. 斐波那契数列
/*
变形:1. 青蛙跳台阶
2. 青蛙变态跳台阶
3. 瓷砖横放或竖放
*/#include<iostream>usingnamespacestd;
//递归版int getFeiBo(const size_t n)
{
if (n <=0)
return0;
if (1 == n)
return1;
return getFeiBo(n - 1) + getFeiBo(n - 2);
}
//循环版int getFeiBoLoop(const size_t n)
{
int a = 1;
int b = 1;
int c = 1;
for (int i = 2; i < n; i++)
{
c = a + b;
a = b;
b = c;
}
return c;
}
int main()
{
int n;
while (cin >> n)
cout << getFeiBoLoop(n) << endl;
return0;
}
4. 二分查找变形旋转数组中的最小数字
/*******************************************************************
Copyright(c) 2016, Harry He
All rights reserved.
Distributed under the BSD license.
(See accompanying file LICENSE.txt at
https://github.com/zhedahht/CodingInterviewChinese2/blob/master/LICENSE.txt)
*******************************************************************///==================================================================// 《剑指Offer——名企面试官精讲典型编程题》代码// 作者:何海涛//==================================================================// 面试题11:旋转数组的最小数字// 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。// 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组// {3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。#include <cstdio>#include <exception>int MinInOrder(int* numbers, int begin, int end);
int Min(int* numbers, int length)
{
if (numbers == nullptr || length <= 0)
thrownewstd::exception("Invalid parameters");
int begin = 0;
int end = length - 1;
int indexMid = begin;
while (numbers[begin] >= numbers[end])
{
// 如果begin和end指向相邻的两个数,// 则begin指向第一个递增子数组的最后一个数字,// end指向第二个子数组的第一个数字,也就是数组中的最小数字if (end - begin == 1)
{
indexMid = end;
break;
}
// 如果下标为begin、end和indexMid指向的三个数字相等,// 则只能顺序查找
indexMid = (begin + end) / 2;
if (numbers[begin] == numbers[end] && numbers[indexMid] == numbers[begin])
return MinInOrder(numbers, begin, end);
// 缩小查找范围if (numbers[indexMid] >= numbers[begin])
begin = indexMid;
elseif (numbers[indexMid] <= numbers[end])
end = indexMid;
}
return numbers[indexMid];
}
int MinInOrder(int* numbers, int begin, int end)
{
int result = numbers[begin];
for (int i = begin + 1; i <= end; ++i)
{
if (result > numbers[i])
result = numbers[i];
}
return result;
}
// ====================测试代码====================void Test(int* numbers, int length, int expected)
{
int result = 0;
try
{
result = Min(numbers, length);
for (int i = 0; i < length; ++i)
printf("%d ", numbers[i]);
if (result == expected)
printf("\tpassed\n");
elseprintf("\tfailed\n");
}
catch (...)
{
if (numbers == nullptr)
printf("Test passed.\n");
elseprintf("Test failed.\n");
}
}
int main(int argc, char* argv[])
{
// 典型输入,单调升序的数组的一个旋转int array1[] = { 3, 4, 5, 1, 2 };
Test(array1, sizeof(array1) / sizeof(int), 1);
// 有重复数字,并且重复的数字刚好的最小的数字int array2[] = { 3, 4, 5, 1, 1, 2 };
Test(array2, sizeof(array2) / sizeof(int), 1);
// 有重复数字,但重复的数字不是第一个数字和最后一个数字int array3[] = { 3, 4, 5, 1, 2, 2 };
Test(array3, sizeof(array3) / sizeof(int), 1);
// 有重复的数字,并且重复的数字刚好是第一个数字和最后一个数字int array4[] = { 1, 0, 1, 1, 1 };
Test(array4, sizeof(array4) / sizeof(int), 0);
// 单调升序数组,旋转0个元素,也就是单调升序数组本身int array5[] = { 1, 2, 3, 4, 5 };
Test(array5, sizeof(array5) / sizeof(int), 1);
// 数组中只有一个数字int array6[] = { 2 };
Test(array6, sizeof(array6) / sizeof(int), 2);
// 输入nullptr
Test(nullptr, 0, 0);
system("pause");
return0;
}