面试题1

来源:互联网 发布:javascript for in 编辑:程序博客网 时间:2024/06/11 12:53
#ifndef _MS_1_#define _MS_1_void TestMS_1();/*1.把二元查找树转变成排序的双向链表输入一颗二元查找树,将其转变成一个排序的双向链表,不能穿件任何新的节点,只能调整指针的指向双向链表的顺序是按照中序遍历的顺序生成*/// 二叉查找树节点struct TreeNode{int num;TreeNode *left;TreeNode *right;TreeNode(int _num, TreeNode *_left = 0, TreeNode *_right = 0) : num(_num), left(_left), right(_right){}};// 双向链表节点struct ListNode{int num;ListNode *pre;ListNode *next;ListNode(int _num, ListNode *_pre = 0, ListNode *_next = 0) : num(_num), pre(_pre), next(_next){}ListNode() {ListNode(0);}bool operator= (const ListNode & right){if (this == &right){return true;}if (this->num == right.num && this->next == right.next){return true;}return false;}};void TestBinaryTreeToDoubleList();ListNode *BinaryTreeToDoubleList(TreeNode *root);void MiddleSearch(TreeNode *root, ListNode * &pListNode);void DestroyDbList(ListNode *pDbList);/*2.设计包含Min函数的栈定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素要求min、push、pop的时间复杂度都是O(1)这道题做错了!*/// 不用数组,用指针const unsigned DEFAULT_STACK_CAPACITY = 10;template <typename T>struct MyStack{MyStack();MyStack(unsigned capacity);virtual ~MyStack();void Push(T tmp);T Pop();T Top();bool IsEmpty();T Min();T *arr;// 默认情况下capacity个数最少为4,不够时,翻倍加1unsigned capacity;unsigned size;T min;};/*3:子数组最大和:有正数也有负数*/void MaxSubSum(const int *arr, unsigned size, int &sum, unsigned &start, unsigned &end);void TestMaxSumSum();/*4:在二叉树中找出和为某一值的所有路径输入一个整数和一棵树从根节点开始往下访问一直到叶节点,所经过的所有节点形成的一条路径。打印输出所有的路径*/// TreeNode已经定义好.../*1.搜索:计算以某个节点为根的所有值,然后与num对比*/// 以该节点为根,且经过该节点// 递归计算:先计算子节点,最后一步加上根节点的值, 并将结果保存到result中// 用堆栈,还好吧...// 我鄙视用堆栈,自己可以构造干嘛用别人的// 以后结果不好呈现时,可以考虑用一下堆栈。// 这里用了个链表,还是用数组吧...void CalNode(TreeNode *root, int num, ListNode *&result);void PrintListNode(ListNode *pListNode);// 数组void CalNode_2(TreeNode *root, int num, int result[], int count);void PrintVecInt(int result[], unsigned count);void TestCalNode();// 广度优先呢?但是结果不好呈现啊/*查找最小的k个元素(数组)输入一个数组,输出其中的k个最小的元素*/// 前k个小元素void FindKSmallest(int *arr, unsigned start, unsigned end, unsigned k, int *result, unsigned resultSize);unsigned PivotQuickSort(int *arr, unsigned start, unsigned end, unsigned middle);void TestFindKSmallest();/*上排十个数,在下排给出其出现的次数:0 1 2 3 4 5 6 7 8 96 2 1 0 0 0 1 0 0 0本来是想考虑其数学特性,看是否能简单给出答案的,看了不行啊还是用回溯法搜索靠谱啊!!!*/bool IsNumOK(int *arr, unsigned size, int *nextArr);const int NUM_LEN = 9;// 类似于八皇后的搜索过程bool FindNextLineNum(int *arr, unsigned size, int *result, unsigned resultSize);void TestFindNextLineNum();/*判断整数序列是不是二叉查找树的后序遍历结果输入一个数组*///  判断一个数组是不是后序遍历结果:// 考虑用递归// 考虑左边、右边。。。// 我考虑的。。。bool IsNextBinarySearch(int *arr, unsigned start, unsigned end);bool IsNextBinarySearch_2(int *arr, unsigned start, unsigned end);// 判断一个数组是否可能是后序遍历:存在某一个节点,前面的都小于root,后面的都大于root,// 存在偏树的情况,左偏树返回end-1,右偏树返回startbool IsMayBeNextBinary(int *arr, unsigned start, unsigned end, unsigned &middle);void TestIsNextBinarySearch();/*翻转句子中单词的顺序,单词内的字符顺序不变I am a student.-> student. a am I*/const int WORD_LEN = 128;void ReverseWords(char words[][WORD_LEN], unsigned wordNum, char *result);void ReverseWords_2(const char *str, char *result);void ParseWord(const char *str, char words[][WORD_LEN], unsigned &wordNum);void TestReverseWords();#endif
#include <algorithm>#include <assert.h>#include <iostream>#include <string>#include "MS_1.h"using namespace std;void TestMS_1(){TestBinaryTreeToDoubleList();TestMaxSumSum();TestCalNode();TestFindKSmallest();TestFindNextLineNum();TestIsNextBinarySearch();TestReverseWords();}void TestBinaryTreeToDoubleList(){TreeNode node4(4, 0, 0);TreeNode node8(8, 0, 0);TreeNode node6(6, &node4, &node8);TreeNode node12(12, 0, 0);TreeNode node16(16, 0, 0);TreeNode node14(14, &node12, &node16);TreeNode node10(10, &node6, &node14);ListNode *dList = BinaryTreeToDoubleList(&node10);}ListNode *BinaryTreeToDoubleList(TreeNode *root){// 中序遍历树,每得到一个节点,就新建一个List节点,并挂在// 链表的末尾ListNode *dList = 0;// 以递归的方式中序遍历树MiddleSearch(root, dList);while (dList->pre){dList = dList->pre;}return dList;}void MiddleSearch(TreeNode *root, ListNode * &pListNode){if (!root){return;}if (root->left){MiddleSearch(root->left, pListNode);}if (!pListNode){pListNode = new ListNode(root->num, 0, 0);}else{ListNode *pListTmp = new ListNode(root->num, pListNode, 0);pListNode->next = pListTmp;pListNode = pListTmp;}if (root->right){MiddleSearch(root->right, pListNode);}}void DestroyDbList(ListNode *pDbList){ListNode *pTmp = pDbList;while (pDbList){pDbList = pDbList->next;delete pTmp;pTmp = pDbList;}}// 2:template <typename T>MyStack<T>::MyStack(){arr = new T[DEFAULT_STACK_CAPACITY];capacity = DEFAULT_STACK_CAPACITY;size = 0;min = T();}template <typename T>MyStack<T>::MyStack(unsigned capa){capacity = capa;arr = new T[capacity];size = 0;min = T();}template <typename T>void MyStack<T>::Push(T tmp){if (size == capacity){capacity = capacity * 2 + 1;T tmpArr = new T[capacity];copy(arr, arr + size, tmpArr);delete arr;arr = tmpArr;}arr[size++] = tmp;if (tmp < min){min = tmp;}}template <typename T>T MyStack<T>::Pop(){assert(!IsEmpty());return arr[--size];}template <typename T>T MyStack<T>::Top(){assert(!IsEmpty());return arr[size - 1];}template <typename T>bool MyStack<T>::IsEmpty(){return size == 0;}template <typename T>T MyStack<T>::Min(){assert(!IsEmpty());return min;}void MaxSubSum(const int *arr, unsigned size, int &sum, unsigned &start, unsigned &end){assert(arr);sum = 0;int tmpSum = 0;sum = 0x80000000;unsigned tmpStart = 0;unsigned tmpEnd = 0;for (unsigned i = 0; i < size; ++i){tmpSum += arr[i];if (tmpSum < 0){tmpSum = 0;tmpStart = i + 1;tmpStart = i + 1;}else if (tmpSum >= 0) // 这里要的是最长的!{tmpEnd = i;}if (tmpSum > sum){sum = tmpSum;start = tmpStart;end = tmpEnd;}}}void TestMaxSumSum(){int max = -(1 << 31);int max2 = 0x80000000;int max4 = -max2;int max3 = 1 << 31;int max5 = 1 << 30;int max6 = -max5;}// 4:// 深度优先搜索,是否应该广度优先?void CalNode(TreeNode *root, int num, ListNode *&result){if (!root){return;}if (root->num > num){return;}else if (root->num == num){PrintListNode(result);cout << num << " ";cout << endl;return;}else{if (!result){result = new ListNode(root->num, 0, 0);}else {ListNode *tmp = new ListNode(root->num, result, 0);result->next = tmp;result = tmp;}if (root->left){CalNode(root->left, num - root->num, result);}if (root->right){CalNode(root->right, num - root->num, result);}if (result){ListNode *pTmp = result;result = result->pre;delete pTmp;}}}void PrintListNode(ListNode *pListNode){if (pListNode && pListNode->pre){PrintListNode(pListNode->pre);}cout << pListNode->num << " ";}void TestCalNode(){TreeNode node4(4, 0, 0);TreeNode node7(7, 0, 0);TreeNode node5(5, &node4, &node7);TreeNode node12(12, 0, 0);TreeNode node10(10, &node5, &node12);ListNode *pList = 0;CalNode(&node10, 22, pList);}void CalNode_2(TreeNode *root, int num, int result[], int count){if (num == 0){PrintVecInt(result, count);return;}else{if (!root){return;}result[count++] = root->num;if (root->left){CalNode_2(root->left, num - root->num, result, count);}if (root->right){CalNode_2(root->right, num - root->num, result, count);}count--;}}void PrintVecInt(int result[], unsigned count){assert(result);for (unsigned i = 0; i < count; ++i){cout << result[i] << " ";}cout << endl;}// 算法:O(n),与寻找第K小元素一样void FindKSmallest(int *arr, unsigned start, unsigned end, unsigned k, int *result, unsigned resultSize){assert(arr && (start <= end));assert(k <= (end - start + 1));unsigned middle = start + (end - start) / 2;// 以middle为pivot排序unsigned pivot = PivotQuickSort(arr, start, end, middle);unsigned num = pivot - start + 1;if (num == k){copy(arr + start, arr + pivot + 1, result + resultSize);}else if (num < k){copy(arr + start, arr + pivot + 1, result + resultSize);resultSize += num;FindKSmallest(arr, pivot + 1, end, k - num, result, resultSize);}else {FindKSmallest(arr, start, pivot - 1, k, result, resultSize);}}unsigned PivotQuickSort(int *arr, unsigned start, unsigned end, unsigned middle){assert(arr);int pivotNum = arr[middle];unsigned startTmp = start;swap<int>(arr[start], arr[middle]);start++;while(start <= end){while (arr[start] < pivotNum){start++;}while (arr[end] > pivotNum){end--;}if (start < end){swap<int>(arr[start], arr[end]);}}swap<int>(arr[end], arr[startTmp]);return end;}void TestFindKSmallest(){int arr[] = {3, 7, 8, 4, 2, 1, 6, 5};int result[8];//FindKSmallest(arr, 0, 7, 4, result, 0);//FindKSmallest(arr, 0, 7, 2, result, 0);FindKSmallest(arr, 0, 7, 6, result, 0);}/*上排十个数,在下排给出其出现的次数:0 1 2 3 4 5 6 7 8 96 2 1 0 0 0 1 0 0 0*/bool IsNumOK(int *arr, unsigned size, int *nextArr){for (unsigned i = 0; i < size; ++i){unsigned count = 0;for (unsigned j = 0; j < size; ++j){if (nextArr[j] == arr[i]){count++;}}if (nextArr[i] != count){return false;}}return true;}bool FindNextLineNum(int *arr, unsigned size, int *result, unsigned resultSize){if (size == resultSize){if (IsNumOK(arr, size, result)){PrintVecInt(result, resultSize);return true;}return false;}else{for (unsigned i = 0; i < NUM_LEN; ++i){result[resultSize] = i;if (FindNextLineNum(arr, size, result, resultSize + 1)){return true;}}}return false;}void TestFindNextLineNum(){//int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};int result[10];if (FindNextLineNum(arr, NUM_LEN, result, 0)){cout << "OK" << endl;}else{cout << "No result" << endl;}}//  判断一个数组是不是后序遍历结果:bool IsNextBinarySearch(int *arr, unsigned start, unsigned end){// 后序遍历的最后一个一定是父节点assert(arr);assert(start <= end);if (start == end){return true;}int node = arr[end];unsigned middle = end;unsigned i;for (i = start; i < end; ++i){if (arr[i] > node){middle = i;break;}}// 1.middle没被赋值:i == end// 2.middle == startfor (unsigned j = middle; j < end; ++j){if (arr[j] < node){return false;}}// 说明是左子树说明第一个就大于,都是右子树if (i == end || middle == start){return IsNextBinarySearch(arr, start, end - 1);}else {return ((IsNextBinarySearch(arr, start, middle - 1) &&IsNextBinarySearch(arr, middle, end - 1)));}}bool IsMayBeNextBinary(int *arr, unsigned start, unsigned end, unsigned &middle){// 遍历两次:第一次找出middle// 第二次:看middle左右两边的值是否满足条件int node = arr[end];return false;}bool IsNextBinarySearch_2(int *arr, unsigned start, unsigned end){assert(arr);assert(start <= end);int node = arr[end];unsigned middle = end;unsigned i;for (i = start; i < end; ++i){if (arr[i] > node){middle = i;break;}}// 1.middle没被赋值:i == end// 2.middle == startfor (unsigned j = middle; j < end; ++j){if (arr[j] < node){return false;}}bool left = true;if (middle > start){left = IsNextBinarySearch_2(arr, start, middle - 1);}bool right = true;if (middle < end){right = IsNextBinarySearch_2(arr, middle, end - 1);}return left && right;}void TestIsNextBinarySearch(){int arr[] = {5, 7, 6, 9, 11, 10, 8};//cout << IsNextBinarySearch(arr, 0, 6) << endl;cout << IsNextBinarySearch_2(arr, 0, 6) << endl;int arr2[] = {3, 4, 5, 6};cout << IsNextBinarySearch_2(arr2, 0, 3) << endl;int arr4[] = {10, 11, 9, 6};cout << IsNextBinarySearch_2(arr4, 0, 3) << endl;int arr3[] = {7, 4, 6, 5};cout << IsNextBinarySearch_2(arr3, 0, 3) << endl;}void ReverseWords(char words[][WORD_LEN], unsigned wordNum, char *result){unsigned pos = 0;for (unsigned i = wordNum; i > 0; --i){//cout << words[i];strcpy(result + pos, words[i - 1]);pos += strlen(words[i - 1]);result[pos++] = ' ';}result[pos] = '\0';}void ParseWord(const char *str, char words[][WORD_LEN], unsigned &wordNum){wordNum = 0;unsigned start = 0;unsigned end = 0;bool bFlag = false;unsigned i = 0;while (*(str + i)){if (*(str + i) == ' '){if (bFlag){bFlag = false;end = i - 1;strncpy(words[wordNum], str + start, end - start + 1);words[wordNum++][end - start + 1] = '\0';}}else{if (!bFlag){bFlag = true;start = i;}}++i;}strncpy(words[wordNum], str + start, i - start);words[wordNum++][i - start] = '\0';}void TestReverseWords(){char *str = " I  am a student he is    exist OK.";//char *str = "Ia am";/*char words[128][WORD_LEN];unsigned wordNum;ParseWord(str, words, wordNum);*/char *result = new char[strlen(str) + 1];ReverseWords_2(str, result);cout << result << endl;delete result;}void ReverseWords_2(const char *str, char *result){// 直接一次遍历unsigned start = 0;unsigned end = 0;bool bFlag = false;unsigned i = 0;unsigned j = strlen(str);result[j--] = '\0';while (*(str + i)){if (*(str + i) == ' '){if (bFlag){bFlag = false;end = i - 1;j -= end - start;strncpy(result + j, str + start, end - start + 1);j--;}result[j--] = ' ';}else{if (!bFlag){bFlag = true;start = i;}}i++;}strncpy(result, str + start, i - start);}
原创粉丝点击