Algorithm : 做一个 leetcode 的算法题
///
// 1. 与替换空格类似的题目 // 有两个排序数组A1, A2, A1的末尾有足够多的的空间容纳A2,实现一个函数,把A2中所有数字插入A1中且所有的数字的有序的!//方法一:从前往后比较,需要额外的空间//时间复杂度O(2n), 空间复杂度O(n)void MergeTwoArray1(int aiArrayA[], int iNumA, int aiArrayB[], int iNumB){ const int MAX_ARRAY_COUNT = iNumA + iNumB; vector vect(MAX_ARRAY_COUNT, 0); int i = 0, j = 0, k = 0; // 1. 比较两个数组,把较小的加入新的数组 while (i < iNumA &&j < iNumB) { if (aiArrayA[i] < aiArrayB[j]) { vect[k++] = aiArrayA[i++]; } else { vect[k++] = aiArrayB[j++]; } } // 2.把剩余的元素加到新数组 while (i < iNumA) { vect[k++] = aiArrayA[i++]; } while (j < iNumB) { vect[k++] = aiArrayB[j++]; } // 3.把数据复制到数组A k = 0; for (auto it : vect) { aiArrayA[k++] = it; }}
// 方法二:从后往前比较,不需要额外的空间//时间复杂度O(n), 空间复杂度O(1)void MergeTwoArray2(int aiArrayA[], int iNumA, int aiArrayB[], int iNumB){ int iNewNum = iNumA + iNumB - 1; int i = iNumA - 1; int j = iNumB - 1; // 从数组后往前比较,就不存在重叠的情况了!!! while (i >= 0 && j >= 0) { if (aiArrayA[i] > aiArrayB[j]) { aiArrayA[iNewNum--] = aiArrayA[i--]; } else { aiArrayA[iNewNum--] = aiArrayB[j--]; } } while (i >= 0) { aiArrayA[iNewNum--] = aiArrayA[i--]; } while (j >= 0) { aiArrayA[iNewNum--] = aiArrayB[j--]; }}
//
// 2.题目五:从尾到头打印链表// 方法一:时间复杂度O(n),空间复杂度O(n)templatevoid ReversePrintList1(ListNode * pNode){ assert(NULL != pNode); stack *> stStack; while (pNode) { stStack.push(pNode); pNode = pNode->m_pNextNode; } cout << "链表逆序打印: " << endl; while (!stStack.empty()) { ListNode * pTmpNode = stStack.top(); printf("%02d -> ", pTmpNode->m_stData); stStack.pop(); } putchar(10);}
// 方法二:递归实现(递归实现也是类似栈实现)// 时间复杂度O(n), 空间复杂度O(n)// 注意:如果链表非常长,会导致函数调用层级很深,从而导致函数调用栈溢出!!!templatevoid ReversePrintLisHEAP_TYPE(ListNode * pNode){ if (!pNode) { return; } ReversePrintLisHEAP_TYPE(pNode->m_pNextNode); printf("%02d -> ", pNode->m_stData);}
///
// // 3.题目六:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出改二叉树struct BinaryTreeNode{ int m_iValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; BinaryTreeNode(int iValue = 0, BinaryTreeNode* pLeft = NULL, BinaryTreeNode* pRight = NULL) :m_iValue(iValue), m_pLeft(pLeft), m_pRight(pRight) { }};BinaryTreeNode* RebuildTree(int* pPreStart, int* pPreEnd, int* pInStart, int* pInEnd){ if (pPreStart > pPreEnd || pInStart > pInEnd) { return NULL; } // 1.建立根节点(前序遍历第一个元素) BinaryTreeNode* pRoot = new BinaryTreeNode(*pPreStart); if (!pRoot) { return NULL; } // 2.找到中序根节点 int* p = pInStart; while (p <= pInEnd && *p != pRoot->m_iValue) { p++; } int iLeftLength = p - pInStart; int* pLeftPreEnd = pPreStart + iLeftLength; // 3.构建左子树 if (iLeftLength > 0) { pRoot->m_pLeft = RebuildTree(pPreStart + 1, pLeftPreEnd, pInStart, p - 1); } // 4.构建右子树 if (iLeftLength < (pPreEnd - pPreStart)) { pRoot->m_pRight = RebuildTree(pLeftPreEnd + 1, pPreEnd, p + 1, pInEnd); } return pRoot;}BinaryTreeNode* RebuildBinaryTree(int* piPreOrderArray, int* piInorderArray, int iLength){ if (NULL == piPreOrderArray || NULL == piInorderArray || iLength <= 0) { return NULL; } return RebuildTree(piPreOrderArray, piPreOrderArray + iLength - 1, piInorderArray, piInorderArray + iLength -1);}void DestroyTree(BinaryTreeNode* pTree){ if (pTree) { // 释放左子树 DestroyTree(pTree->m_pLeft); // 释放右子树 DestroyTree(pTree->m_pRight); delete pTree; pTree = NULL; }}// 后序遍历void PostTraversal(BinaryTreeNode* pNode){ if (pNode) { PostTraversal(pNode->m_pLeft); PostTraversal(pNode->m_pRight); printf("%02d -> ", pNode->m_iValue); }}void RebuildBinaryTreeTestFunc(){ cout << "\n\n --------------- RebuildBinaryTreeTestFunc Start -------------->" << endl; const int MAX_TREE_NODE_COUNT = 8; //前序遍历序列(中 -> 左 -> 右) int aiPreOrderArray[MAX_TREE_NODE_COUNT] = { 1, 2, 4, 7, 3, 5, 6, 8}; //中序遍历序列(左 -> 中 -> 右) int aiInorderArray[MAX_TREE_NODE_COUNT] = { 4, 7, 2, 1, 5, 3, 8, 6}; //后序遍历序列(左 -> 右 -> 中) int aiPostArray[MAX_TREE_NODE_COUNT] = { 7, 4, 2, 5, 8, 6, 3, 1}; BinaryTreeNode* pTree1 = RebuildBinaryTree(aiPreOrderArray, aiInorderArray, MAX_TREE_NODE_COUNT); if (pTree1) { // 后序遍历 PostTraversal(pTree1); putchar(10); // 施法资源 DestroyTree(pTree1); } cout << "\n\n --------------- RebuildBinaryTreeTestFunc End -------------->" << endl;}
templateclass CQueue{public: CQueue(){} ~CQueue(){} void AppendTail(const TYPE& node); TYPE DeleteHead();private: stack m_stPushStack; stack m_stPopStack;};// 方法一:// 插入时 --> m_stPopStack不为空,将元素压入m_stPushStack;// 删除时 --> m_stPushStack不为空,将元素压入 m_stPopStack;// 方法二:// 插入时 --> 直接往 m_stPushStack 插入新元素// 删除时 --> 如果m_stPopStack为空,插入m_stPushStack中元素,否则直接弹出元素template TYPE CQueue ::DeleteHead(){#if 0 while (!m_stPushStack.empty()) { m_stPopStack.push(m_stPushStack.top()); m_stPushStack.pop(); }#else if (m_stPopStack.empty()) { while (!m_stPushStack.empty()) { m_stPopStack.push(m_stPushStack.top()); m_stPushStack.pop(); } }#endif TYPE tmp = m_stPopStack.top(); m_stPopStack.pop(); return tmp;}template void CQueue ::AppendTail(const TYPE& node){#if 0 while (!m_stPopStack.empty()) { m_stPushStack.push(m_stPopStack.top()); m_stPopStack.pop(); } m_stPushStack.push(node);#else m_stPushStack.push(node);#endif }void QueueWithTwoStackTestFunc(){ cout << "\n\n --------------- QueueWithTwoStackTestFunc Start -------------->" << endl; CQueue stQueue; stQueue.AppendTail(1); stQueue.AppendTail(2); stQueue.AppendTail(3); cout << "Queue Pop Node: " << stQueue.DeleteHead() << endl; stQueue.AppendTail(4); stQueue.AppendTail(5); stQueue.AppendTail(6); cout << "Queue Pop Node: " << stQueue.DeleteHead() << endl; cout << "Queue Pop Node: " << stQueue.DeleteHead() << endl; cout << "Queue Pop Node: " << stQueue.DeleteHead() << endl; cout << "Queue Pop Node: " << stQueue.DeleteHead() << endl; cout << "Queue Pop Node: " << stQueue.DeleteHead() << endl; cout << "\n\n --------------- QueueWithTwoStackTestFunc End -------------->" << endl;}
/
// 5.用两个队列实现一个栈templateclass CStack{public: CStack(){} ~CStack(){}public: void AppendTail(const TYPE& value); TYPE DeleteHead();private: queue m_stQueue1; queue m_stQueue2;};template TYPE CStack ::DeleteHead(){ TYPE head; if (m_stQueue1.empty()) { while (m_stQueue2.size() > 1) { m_stQueue1.push(m_stQueue2.front()); m_stQueue2.pop(); } head = m_stQueue2.front(); m_stQueue2.pop(); } else { while (m_stQueue1.size() > 1) { m_stQueue2.push(m_stQueue1.front()); m_stQueue1.pop(); } head = m_stQueue1.front(); m_stQueue1.pop(); } return head;}template void CStack ::AppendTail(const TYPE& value){ m_stQueue1.push(value);}void StackWithTwoQueueTestFunc(){ cout << "\n\n --------------- StackWithTwoQueueTestFunc Start -------------->" << endl; CStack stStack; stStack.AppendTail(1); stStack.AppendTail(2); stStack.AppendTail(3); cout << "Stack Pop Node: " << stStack.DeleteHead() << endl; stStack.AppendTail(4); stStack.AppendTail(5); stStack.AppendTail(6); cout << "Stack Pop Node: " << stStack.DeleteHead() << endl; cout << "Stack Pop Node: " << stStack.DeleteHead() << endl; cout << "Stack Pop Node: " << stStack.DeleteHead() << endl; cout << "Stack Pop Node: " << stStack.DeleteHead() << endl; cout << "Stack Pop Node: " << stStack.DeleteHead() << endl; cout << "\n\n --------------- StackWithTwoQueueTestFunc End -------------->" << endl;}
Review : 阅读并点评一篇英文技术文章
Tips : 学习一个技术技巧
排序算法学习:
Share : 分享一篇有观点和思考的技术文章
1.redis单线程架构: