栈、队列面试题总结
来源:互联网 发布:考勤数据怎么导入u盘 编辑:程序博客网 时间:2024/05/22 08:00
俩个栈实现一个队列
原理图
注意一定要谨防pop时,容器内没有元素而引发的错误。
class Solution{public: void push(int node) { stack1.push(node); } int pop() { if (stack1.empty()) { cout << "队列中无元素pop失败" << endl; exit(1); } while (!stack1.empty()) { stack2.push(stack1.top()); stack1.pop(); } int ret = stack2.top(); stack2.pop();//这个pop挺重要的 ,必须pop这才符合 要不根本该元素一直是队列的头元素 while (!stack2.empty()) { stack1.push(stack2.top()); stack2.pop(); } return ret; }private: stack<int> stack1; stack<int> stack2;};
俩个队列实现一个栈
class Solution2{public: void push(int node) { queue1.push(node); } int pop() { if (queue1.empty()) { cout << "栈为空不能pop" << endl; exit(2); } while (queue1.size()>1) { queue2.push(queue1.front()); queue1.pop(); } int ret = queue1.front(); queue1.pop(); while (!queue2.empty()) { queue1.push(queue2.front()); queue2.pop(); } }private: queue<int> queue1; queue<int> queue2;};
实现一个栈Stack,要求实现Push、Pop、Min的时间复杂度为O(1)
思路
第一种方法定义俩个栈,一个保存元素一个保存min值。每次入栈时要比较如果该元素小于等于min栈的栈顶元素时就把该元素也向min栈中入栈,否则只入保存元素的栈。出栈时如果该元素等于min栈的栈顶元素则俩个栈都要执行pop操作,否则只出保存元素栈的元素。
第二种方法只是用一个栈。每次入栈时,入俩个元素。先入要入的元素,再入min值。每次入的时候要判断,如果栈不为空,取栈顶元素。如果该元素小于栈顶元素就该元素入俩次,即从该元素后,该栈的最小元素得到了更新,否则先入该元素,再入原先栈顶的元素。出站栈时俩个俩个出。
方法2:class Mystack{public: Mystack() {} void push(T data) { if (_s.empty()) { _s.push(data); _s.push(data); } else{ int min = _s.top(); if (data < min) { _s.push(data); _s.push(data); } else{ _s.push(data); _s.push(min); } } } void pop() { if (_s.empty()){ cout << "栈为空不能pop" << endl; return; } _s.pop(); _s.pop(); } T min() { return _s.top(); }private: stack<T> _s;};
元素出栈、入栈顺序的合法性。
举个栗子:入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1),则合法。入栈的序列(1,2,3,4,5),出栈序列为(4,5,2,3,1),则不合法。也就是给你入栈序列,和出栈序列,看它符不符合一个栈的规律。
思路
因为栈是先进后出。所以出栈序列和入栈序列应该是反向的一组序列。但是有个例外,就是有一个元素先进然后立即出再入下一个元素,这种情况入栈序列和出栈序列就不再是反序的了。这样的情况影响出栈的序列。所以可以用出栈序列中的第一个元素在入栈序列中找到相应的下标。因为该元素是第一个出栈的元素,在此之前没有元素出栈。故在此之前进栈的元素严格遵循先进后出。而在该元素后入栈的元素可以遵循,也可以不遵循以例外的方式出栈所以是任意顺序的。
所以我们只判断在此之前是严格反序的话就是合法,不是严格反序就是非法。但是我们得在这样判断前,确保俩个数组元素都是相同的,所以我使用了俩段空间保存这俩个数组的值,然后快排看了下这俩个数组的值是否都完全相同。
int partion(int*arr,int left,int right){ int begin = left; int end = right; int &key = arr[right]; while (begin < end) { while (begin < end&&arr[begin] <= key) ++begin; while (begin < end&&arr[end] >= key) --end; if (begin < end) { arr[begin] ^= arr[end]; arr[end] ^= arr[begin]; arr[begin] ^= arr[end]; } } if (begin != right) { arr[begin] ^= key; key ^= arr[begin]; arr[begin] ^= key; } return begin;}void quicksort(int*arr, int left ,int right){ if (left<right) { int Base = partion(arr, left, right); quicksort(arr, left, Base - 1); quicksort(arr, Base+1, right); }}bool My_sort(int*test1, size_t len, int*test2, size_t len2){ std::sort(test1, test1+len);//sort的end为尾随位置,可以用sort或者自己写个快排什么的基本上sort的时 std::sort(test2, test2 + len);//间复杂度是nlog2n //quicksort(test1,0,len-1); //quicksort(test2,0,len2-1); for (size_t idx = 0; idx < len; ++idx) { if (test1[idx] != test2[idx]) return false; } return true;}bool stack_legal(int arr[],int arr_2[],size_t len ,size_t len_2)//这个方法时间复杂度O(nlog2){ // 空间复杂度O(n) assert(arr != NULL&&arr_2 != NULL); if (len != len_2) return false; if (len == 0 ||len_2==0) return true; if (len == 1&&len_2==1) { if (arr[0] == arr_2[0]) return true; else return false; } int *test_arr = new int[len]; int *test_arr2 = new int[len_2]; memmove(test_arr, arr, len*sizeof(int)); memmove(test_arr2, arr_2, len_2*sizeof(int)); if (!My_sort(test_arr, len, test_arr2, len_2)) return false; size_t pos = 0; while (arr[pos] != arr_2[0])++pos; size_t idx = 0; while (pos > 0) { if (arr[idx] != arr_2[len_2 - 1 - idx]) return false; idx++; --pos; } return true;;}
判断一棵树是否是完全二叉树
思路
我主要使用了层序遍历的思想,检测每一层的节点的合法性。
①当出现了只有左子树节点没有右子树的节点,那么我给一个标记置为True,以后遍历的每个节点再有子节点的话就不是完全二叉树。
②如果当该层节点只有右子树没有左子树那么该树不是完全二叉树。
所以根据上面俩条规则来解决这个问题
该图就是我所描述的几种情况
代码
bool complete_tree(Node*Root){ if (Root == NULL) return true; bool Last = false; //该标记表示是否发现只有一个左子节点的子树 queue<Node*> qcon; qcon.push(Root); Node*pCur = NULL; while (!qcon.empty()) { pCur = qcon.front(); if (Last&&(pCur->_PLeft!=NULL||pCur->_PRight!=NULL)) { return false; } if (pCur->_PLeft !=NULL&&pCur->_PRight!=NULL) { qcon.push(pCur->_PLeft); qcon.push(pCur->_PRight); } if (pCur->_PLeft != NULL&&pCur->_PRight == NULL) { qcon.push(pCur->_PLeft); Last =true; } if (pCur->_PRight != NULL&&pCur->_PLeft == NULL) { return false; } qcon.pop(); } return true;}
- 栈、队列面试题总结
- 栈和队列面试题总结
- 队列和栈相关面试题总结
- 栈、队列面试题
- 栈&&队列面试题
- 队列的常见面试题总结
- 常见栈、队列面试题
- 栈和队列面试题
- 栈和队列面试题
- 递归->栈->队列面试题
- 栈和队列面试题
- 栈面试题总结
- 【面试题】栈和队列的面试题
- 面试题整理-两个栈实现队列
- 【面试题七】栈和队列
- 栈与队列相关面试题
- 面试题7 两个栈实现队列
- 【面试题】用栈实现队列
- 《Drools7.0.0.Final规则引擎教程》之Springboot集成
- 人脸识别入门学习《一》
- Hash问题1
- JPA 实体管理器工厂(EntityManagerFactory)
- 35 个 Java 代码性能优化总结
- 栈、队列面试题总结
- 程序员励志语录
- pgsql使用的部分触发器
- Android中自定义switch控件样式
- 微软编程100-012
- 关于ViewPager高度自适应(随着pager页的高度改变Viewpager的高度)
- Toolbar属性简介
- 6264:走出迷宫
- 生成有n个元素的随机数组 并设置随机元素的范围