利用static变量,两个变量必须都为static,因为它们的状态需要记住
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
struct Node
{
Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}
int data;
Node *left;
Node *right;
};
Node* construct()
{
Node *node7 = new Node(16);
Node *node6 = new Node(12);
Node *node5 = new Node(8);
Node *node4 = new Node(4);
Node *node3 = new Node(14, node6, node7);
Node *node2 = new Node(6, node4, node5);
Node *node1 = new Node(10, node2, node3);
return node1;
}
Node* convert(Node *root)
{
if (root == NULL)
return NULL;
static Node *head = NULL;
static Node *pHead;
convert(root->left);
if (head == NULL)
{
head = root;
pHead = head;
}
else
{
pHead->right = root;
root->left = pHead;
pHead = root;
}
convert(root->right);
return head;
}
void print(Node *head)
{
if (head == NULL)
return;
while (head != NULL)
{
cout << head->data << " ";
head = head->right;
}
}
void main()
{
Node *root = construct();
Node *head = convert(root);
print(head);
}
可以利用传值:
Node* convert(Node *root, Node *&head)
{
if (root == NULL)
return NULL;
static Node *pHead;
convert(root->left, head);
if (head == NULL)
{
head = root;
pHead = head;
}
else
{
pHead->right = root;
root->left = pHead;
pHead = root;
}
convert(root->right, head);
return head;
}
还可以循环:
Node* convert(Node *root)
{
if (root == NULL)
return NULL;
stack<Node*> nstack;
Node *pRoot = root;
Node *head = NULL;
Node *pHead = head;
while (pRoot != NULL || !nstack.empty())
{
while (pRoot != NULL)
{
nstack.push(pRoot);
pRoot = pRoot->left;
}
pRoot = nstack.top();
nstack.pop();
if (head == NULL)
{
head = pRoot;
pHead = head;
}
else
{
pHead->right = pRoot;
pRoot->left = pHead;
pHead = pRoot;
}
pRoot = pRoot->right;
}
return head;
}
![](https://img-my.csdn.net/uploads/201210/06/1349531030_1861.jpg)
这道题的关键在于minIndex数组存储的是最小值的下标,存元素就错了
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
class Stack
{
public:
Stack(int i = -1, int j = -1) : index1(i), index2(j) {}
void push(int item)
{
if (++index1 == size)
return;
data[index1] = item;
if (index2 == -1 || data[minIndex[index2]] > item)
{
minIndex[++index2] = index1;
}
}
void pop()
{
if (index1 == -1)
return;
if (minIndex[index2] == index1)
--index2;
--index1;
}
int min()
{
if (index1 <= -1 || index2 <= -1)
return -1;
return data[minIndex[index2]];
}
bool empty()
{
return index1 == -1;
}
private:
static const int size = 20;
int data[size];
int minIndex[size];
int index1;
int index2;
};
void main()
{
Stack stack;
stack.push(3);
stack.push(2);
stack.push(5);
stack.push(1);
stack.push(4);
while (!stack.empty())
{
cout << "minValue: " << stack.min() << endl;
stack.pop();
}
}
本题的两种经典解法:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
int array[] = {1, -2, 3, 10, -4, 7, 2, -5};
const int size = sizeof array / sizeof *array;
#define INF 1 << 31
int maxSubarray(int *array, int size)
{
if (array == NULL || size <= 0)
return -INF;
int maxInclude = array[0];
int maxSum = array[0];
for (int i = 1; i < size; i++)
{
maxInclude = max(maxInclude + array[i], array[i]);
maxSum = max(maxInclude, maxSum);
}
return maxSum;
}
void main()
{
int result = maxSubarray(array, size);
if (result == -INF)
cout << "error" << endl;
else
cout << "result = " << result << endl;
}
第二种:
int maxSubarray(int *array, int size)
{
if (array == NULL || size <= 0)
return -INF;
int sum = 0;
int tempSum = 0;
for (int i = 0; i < size; i++)
{
if (tempSum < 0)
tempSum = 0;
tempSum += array[i];
if (tempSum > sum)
sum = tempSum;
}
return sum;
}
递归解法:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
struct Node
{
Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}
int data;
Node *left;
Node *right;
};
Node* construct()
{
Node *node5 = new Node(7);
Node *node4 = new Node(4);
Node *node3 = new Node(12);
Node *node2 = new Node(5, node4, node5);
Node *node1 = new Node(10, node2, node3);
return node1;
}
void print(const vector<Node*> &nvec)
{
for (size_t i = 0; i < nvec.size(); i++)
cout << nvec[i]->data << " ";
cout << endl;
return;
}
void printSumTree(Node *root, vector<Node*> &nvec, int sum)
{
if (root == NULL)
return;
if (root->data == sum && root->left == NULL && root->right == NULL)
{
nvec.push_back(root);
print(nvec);
nvec.pop_back();
return;
}
nvec.push_back(root);
printSumTree(root->left, nvec, sum - root->data);
printSumTree(root->right, nvec, sum - root->data);
nvec.pop_back();
}
void main()
{
Node *root = construct();
vector<Node*> nvec;
printSumTree(root, nvec, 22);
}
循环解法:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
struct Node
{
Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}
int data;
Node *left;
Node *right;
};
Node* construct()
{
Node *node5 = new Node(7);
Node *node4 = new Node(4);
Node *node3 = new Node(12);
Node *node2 = new Node(5, node4, node5);
Node *node1 = new Node(10, node2, node3);
return node1;
}
void print(const vector<Node*> &nvec)
{
for (size_t i = 0; i < nvec.size(); i++)
cout << nvec[i]->data << " ";
cout << endl;
return;
}
void printSumTree(Node *root, vector<Node*> &nvec, int sum)
{
if (root == NULL)
return;
stack<Node*> nstack;
nstack.push(root);
Node *pRoot = root;
Node *prev = NULL;
while (!nstack.empty())
{
pRoot = nstack.top();
if (prev != pRoot->left && prev != pRoot->right)
{
if (pRoot->right)
nstack.push(pRoot->right);
if (pRoot->left)
nstack.push(pRoot->left);
}
if (prev != pRoot->left && prev != pRoot->right)
{
nvec.push_back(pRoot);
sum -= pRoot->data;
}
if (pRoot->left == NULL && pRoot->right == NULL)
{
if (sum == 0)
print(nvec);
nstack.pop();
sum += nvec[nvec.size() - 1]->data;
nvec.pop_back();
}
if (prev == pRoot->left || prev == pRoot->right)
{
nstack.pop();
sum += nvec[nvec.size() - 1]->data;
nvec.pop_back();
}
prev = pRoot;
}
}
void main()
{
Node *root = construct();
vector<Node*> nvec;
printSumTree(root, nvec, 22);
}
太经典的题了,解法N种
1. 快排,复杂度O(NlogN) 给出这个算法的基本上面试都被毙掉
2. 最大堆求kmin,复杂度O(Nlogk)这个复杂度就可通过面试了
3. 利用计数排序和快排的partition算法的复杂度为O(N),这样的复杂度完全可以令面试官满意了
这里只给出计数排序和partition的算法:
这么久了,还是没能理解这道题是要写代码,还是。。。
编程之美上的老题了,不带环直接判断尾指针即可
扩展问题:如果有环,题目难度就增大很多了,这个题目在面试50题里我有写到过
关于就相交的第一个节点,遍历几次即可
1. 冷热
2. 1、2、4
3. 链表反转是老题了
这个不难吧
整理一个数组,难道是随机化。。。
字符串匹配,名题百则上有提到
颠倒一个字符串啊,很easy吧
3次reverse即可
字符串匹配问题
怎么比较,擦
异或算法
左移3位、左移3位减1
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
int array[] = {5, 7, 6, 9, 11, 10, 8};
const int size = sizeof array / sizeof *array;
bool isPostOrder(int *array, int start, int end)
{
if (array == NULL || size <= 0)
return false;
if (start > end)
return false;
if (start == end || start == end - 1)
return true;
int pivot = array[end];
int i = start;
int j = end - 1;
while (i < end - 1 && array[i] < pivot)
i++;
while (j >= start && array[j] >= pivot)
j--;
return (i > j) && isPostOrder(array, start, j) && isPostOrder(array, i, end - 1);
}
void main()
{
bool result = isPostOrder(array, 0, size - 1);
if (result == true)
cout << "is post order" << endl;
else
cout << "not post order" << endl;
}
![](https://img-my.csdn.net/uploads/201210/07/1349584352_8209.jpg)
1. 首先全部翻转
2. 碰见空格反转
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
struct Node
{
Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight) {}
int data;
Node *left;
Node *right;
};
Node* construct()
{
Node *node9 = new Node(9);
Node *node8 = new Node(8);
Node *node7 = new Node(7);
Node *node6 = new Node(6, NULL, node9);
Node *node5 = new Node(5, node8);
Node *node4 = new Node(4, node6, node7);
Node *node3 = new Node(3, node5);
Node *node2 = new Node(2, node3, node4);
Node *node1 = new Node(1, NULL, node2);
return node1;
}
struct Result
{
Result(int i = 0, int j = -1) : dist(i), depth(j) {}
int dist;
int depth;
};
Result getMaxDist(Node *root)
{
if (root == NULL)
return Result();
Result result;
if (root == NULL)
{
result.depth = -1;
result.dist = 0;
return result;
}
Result lResult = getMaxDist(root->left);
Result rResult = getMaxDist(root->right);
result.depth = max(lResult.depth, rResult.depth) + 1;
result.dist = max(max(lResult.dist, rResult.dist), lResult.depth + rResult.depth + 2);
return result;
}
void main()
{
Node *root = construct();
Result result = getMaxDist(root);
cout << "result.depth = " << result.depth << endl;
cout << "result.dist = " << result.dist << endl;
}
![](https://img-my.csdn.net/uploads/201210/07/1349591714_5332.jpg)
只推荐两种解法:
一、模板
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
template <int i>
struct Sum
{
enum Value { N = Sum<i - 1>::N + i };
};
template <>
struct Sum<1>
{
enum Value { N = 1 };
};
void main()
{
cout << Sum<100>::N << endl;
}
二、构造函数
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
class Sum
{
public:
Sum()
{
n++;
sum += n;
}
static int getSum()
{
return sum;
}
private:
static int sum;
static int n;
};
int Sum::sum = 0;
int Sum::n = 0;
void main()
{
Sum sum[100];
cout << Sum::getSum() << endl;
}
![](https://img-my.csdn.net/uploads/201210/07/1349606861_2369.jpg)
这个链表题要注意几点:
1. K可能为负数或0
2. K可能大于链表的长度
这道题太easy,而且UT简单
递归和循环的解法都要会~
何时输出endl才是关键
#include <iostream>
#include <queue>
using namespace std;
struct Node
{
Node(int i = 0, Node *pLeft = NULL, Node *pRight = NULL) : data(i), left(pLeft), right(pRight){}
int data;
Node *left;
Node *right;
};
void printLevel(Node *root)
{
if (root == NULL)
return;
queue<Node *> qnodes;
qnodes.push(root);
int indexFast = 1;
int indexSlow = 1;
int index = 0;
while (!qnodes.empty())
{
Node *node = qnodes.front();
qnodes.pop();
if (node->left)
{
indexFast++;
qnodes.push(node->left);
}
if (node->right)
{
indexFast++;
qnodes.push(node->right);
}
index++;
cout << node->data << " ";
if (index == indexSlow)
{
indexSlow = indexFast;
cout << endl;
}
}
}
Node *construct()
{
Node *node7 = new Node(11);
Node *node6 = new Node(9);
Node *node5 = new Node(7);
Node *node4 = new Node(5);
Node *node3 = new Node(10, node6, node7);
Node *node2 = new Node(6, node4, node5);
Node *node1 = new Node(8, node2, node3);
return node1;
}
void main()
{
Node *root = construct();
printLevel(root);
}
很简单啦~
两种解法:其一、模拟list;其二、利用公式的解法
三种解法:其一、递归;其二、循环;其三、最牛逼的logN复杂度解法
应该考虑一下几点:
1. 输入的字符串中有非数字
2. 输入的字符串中有+-符号
3. 输入的字符串过长所产生的溢出问题
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
void printCombine(int n, int m, int index, bool *flag)
{
if (m < 0 || index == n)
return;
if (m == 0)
{
for (int i = 0; i < n; i++)
{
if (flag[i] == true)
cout << i + 1 << " ";
}
cout << endl;
return;
}
flag[index] = true;
printCombine(n, m - index - 1, index + 1, flag);
flag[index] = false;
printCombine(n, m, index + 1, flag);
}
void main()
{
cout << "input two numbers" << endl;
int m, n;
cin >> m >> n;
bool *flags = new bool[n];
if (flags == NULL)
return;
for (int i = 0; i < n; i++)
flags[i] = false;
printCombine(n, m, 0, flags);
delete[] flags;
}
![](https://img-my.csdn.net/uploads/201210/08/1349701761_5835.jpg)
这道题写过很多遍了~
简单题
3次reverse
Fibonacci数列问题
经典题
BFS
把百度那道珠子的题搞定,编程之美上最短摘要的生成一模一样
这道题和编程之美上的信号量那道题一回事
编程之美上已经说得很详细了,这道题将会作为一道专题写进blog里