挑战数据结构与算法面试题——80题全解析(一)
来源:互联网 发布:java redis缓存用法 编辑:程序博客网 时间:2024/06/11 06:31
题目来源“数据结构与算法面试题80道”。这是第一部分,包含其中的第1题到第5题。
在此给出我的解法,如你有更好的解法,欢迎留言。
问题分析:二叉查找树是一种二叉树的结构,其中,根节点的值大于左子树的值,小于右子树的值。而二叉查找树的中序遍历即为排序的结果。对于根节点,前驱指针指向左子树中最大的节点,同理,后驱指针指向右子树中最小的节点,如下图所示:
树是一种递归的结果,因此,对于左右子树,也需要执行相同的操作。
方法:
BSTreeNode* convert(BSTreeNode *root){ if (NULL == root || (NULL == root->m_pLeft && NULL == root->m_pRight)){ return root; } convert(root->m_pLeft); BSTreeNode* p_left = root->m_pLeft; while(p_left->m_pRight != NULL){ p_left = p_left->m_pRight; } root->m_pLeft = p_left; p_left->m_pRight = root; convert(root->m_pRight); BSTreeNode* p_right = root->m_pRight; while(p_right->m_pLeft != NULL){ p_right = p_right->m_pLeft; } root->m_pRight = p_right; p_right->m_pLeft = root; BSTreeNode *p = root; while (NULL != p->m_pLeft){ p = p->m_pLeft; } return p;}
问题分析:栈的特点是先进后出。要能够取出当前的最小值,需要用另一个栈保存当前的最小值,所以可采用“双栈”的结构,一个栈保存所有的值,另一个栈保存当前的最小值。
方法:
template <class Type> class min_stack{ private: stack<Type> s1; stack<Type> s2; public: min_stack(){} ~min_stack(){} Type min(){ if (!s2.empty()){ return s2.top(); } } void push(Type a){ s1.push(a); if (s2.empty() || a <= s2.top()){ s2.push(a); } } Type pop(){ if (!s1.empty() && !s2.empty()){// 非空 if (s1.top() == s2.top()){ s2.pop(); } return s1.pop(); } }};
问题分析:在数组的每一个位置处保存当前的最大值,当前的最大值组成为:
解决方案:
int get_max_subarray(int *a, int length, bool &is_array_ok){ if (NULL == a || length <= 0){ is_array_ok = false; return 0; } int *p_h_a = (int *)malloc(sizeof(int) * length); // 遍历数组 int max_num = 0; for (int i = 0; i < length; i++){ if (i == 0 || (i > 0 && p_h_a[i-1] <= 0)){ p_h_a[i] = a[i]; }else{ p_h_a[i] = p_h_a[i-1] + a[i]; } if (max_num < p_h_a[i]) max_num = p_h_a[i]; } free(p_h_a); is_array_ok = true; return max_num;}
问题分析:核心是树的遍历,注意题目中“路径”的定义,是从根节点到叶子节点。先序遍历正好是从根节点开始,因此可以利用先序遍历的过程来实现这个过程。
方法:
void print_vector(vector<BinaryTreeNode *> &v){ vector<BinaryTreeNode *>::iterator it; for (it = v.begin(); it != v.end(); it ++){ printf("%d\t", (*it)->m_nValue); } printf("\n");}void pre_order_route(BinaryTreeNode *p, int num, vector<BinaryTreeNode *> &q, int ¤t){ if (NULL == p) return; current += p->m_nValue; q.push_back(p); bool is_leaf = (NULL == p->m_pLeft) && (NULL == p->m_pRight); if (current == num && is_leaf){ print_vector(q); } if (NULL != p->m_pLeft){ pre_order_route(p->m_pLeft, num, q, current); } if (NULL != p->m_pRight){ pre_order_route(p->m_pRight, num, q, current); } current -= (*(q.end() - 1))->m_nValue; q.pop_back();}void print_route(BinaryTreeNode *root, int num){ vector<BinaryTreeNode *> q;// 用队列保存已经访问过的节点 int current = 0; pre_order_route(root, num, q, current);}
问题分析:这是一道比较经典的题目,查找最小的k个元素,最简单的方法就是对这n个整数排序,排序完成后,直接输出前k个最小的元素。那么最快的排序方法是快速排序,其算法的时间复杂度为O(nlogn)。是否还存在比这个更快的方法呢?
方法一:利用快速排序的思想,时间复杂度为O(n)
按照某个点将数组划分成左右两部分,左边的数都小于该划分节点,右边的数都大于该划分节点。如果最终该划分节点的位置小于k-1,则在右边节点中继续划分;如果最终该划分节点的位置大于k-1,则在左边节点中继续划分。这个过程直到最终的划分节点的位置正好为k-1。
int swap(int *a, int start, int end, int point_index){ int par_point = a[point_index]; while (start < end){ if (a[start] >= par_point && a[end] <= par_point){ int tmp = a[start]; a[start] = a[end]; a[end] = tmp; start ++; end --; }else if(a[start] < par_point){ start ++; }else{ end --; } } return start;}void get_min_k(int *a, int length, int k){ if (k > length || NULL == a || length <= 0) return; int new_index = swap(a, 0, length-1, k); while (true){ if (new_index == k) break; else if (new_index > k){ new_index = swap(a, 0, new_index, k); }else{ new_index = swap(a, new_index, length-1, k); } }}
方法二:利用堆排序,时间复杂度为O(nlogk)
上述方法的缺点是其对数组进行了修改,在堆排序中,可采用小顶堆,其中堆的大小为k,若此时堆的大小小于k时,则将数插入堆中;若此时堆中的大小大于等于k,则比较堆中最大的整数与待插入整数的大小,插入较小的整数。
void get_min_k(int *a, int length, int k, set<int> &s){ if (k > length || NULL == a || length <= 0) return; for (int i = 0; i < length; i++){ if (s.size() < k){ s.insert(a[i]); }else{ set<int>::iterator it = --s.end(); if (a[i] < *it){ s.erase(*it); s.insert(a[i]); } } }}
- 挑战数据结构与算法面试题——80题全解析(一)
- 挑战数据结构与算法面试题——80题全解析(三)
- 数据结构面试题1.2.6-Top K算法详细解析——百度面试题
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题80道
- 数据结构与算法面试题(待定)
- 数据结构与算法面试题
- MFC ADO 数据库连接
- Bag of words模型
- 洛谷2296 寻找道路
- Ubuntu常用命令大全
- 慢慢学 动态规划
- 挑战数据结构与算法面试题——80题全解析(一)
- linux下tomcat服务的相关命令
- js脚本报错集锦
- 进程经典例题
- 数据删除工具类--桃先森
- android真实项目分分钟搞定支付宝支付(不是讲解demo)
- 收集
- Popuwindow 在Android7.0 上显示Bug
- Linux的Source命令