题意:
有一个n个数的数组,每个数都可以删除右边连续严格递减并且比这个数小的数列。
问经过多少次操作,数组的长度不变。
方法一:
直接模拟
思路:循环遍历数组A,如果某个数大于等于前面一个数,则这个数不会被吃,可以保留。用一个临时数组(B)存储每一次操作的结果,当发现A数组与B数组长度不同时,说明是有效操作;否则break。
class Solution { public: int solve(int N, vector<int>& A) { int res=0;//操作次数 vector<int> B; while(true){ B.push_back(A[0]);//第一个肯定不会被吃,所以直接加入 int num=A.size(); for(int i=1;i<num;i++){ if(A[i-1]<=A[i]){ B.push_back(A[i]); } } if(A.size()!=B.size()){//如果长度不等,则说明是有效操作 res++;//操作次数加一 A=B;//重新赋值 B.clear(); }else{ break; } } return res; } };
时间复杂度:空间复杂度:
方法一:
栈实现
思路:用栈实现,栈的每个元素是一个结构体(二元组),结构体包含这个数的大小和这个数删除右边数的次数。关键点:找a[i]右边的第一个>=a[i]的数。
class Solution { public: struct node{ int x,num;//这个数的大小和这个数删除右边数的次数 }; int solve(int N, vector<int>& A) { //找a[i]右边的第一个>=a[i]的数 int res=0;//操作次数 stack<node> st; for(int i=N-1;i>=0;i--){ int num=0;//初值为0 while(!st.empty()&&st.top().x<A[i]){//如果栈非空且栈顶元素小于A[i] num=max(st.top().num,num+1); st.pop();//弹出栈 } st.push({A[i],num});//入栈 res=max(res,num);//维护最大值 } return res; } };
时间复杂度:
空间复杂度: