俩个栈实现一个队列
原理图
注意一定要谨防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;
}