利用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; }
这道题的关键在于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; }
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; }
只推荐两种解法:
一、模板
#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; }
这个链表题要注意几点:
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; }
这道题写过很多遍了~
简单题
3次reverse
Fibonacci数列问题
经典题
BFS
把百度那道珠子的题搞定,编程之美上最短摘要的生成一模一样
这道题和编程之美上的信号量那道题一回事
编程之美上已经说得很详细了,这道题将会作为一道专题写进blog里