思路:list模拟
时间复杂度分析: 最能就是把所有元素删除完,因此复杂度为元素的数目O(n)
具体思路:删除nums[i]后,右边的向左移,因此下一轮可能被删除的就是nums[i+1]的元素(由上一轮删除的能推出下一轮可能会的),因此,用list来删除元素来达到O(1)删除的目的。
实现:vector保存每一轮要被删除的元素,不断更新vector,直到vector为空为止
class Solution {
public:
int totalSteps(vector<int>& nums) {
list<int> lst(nums.begin(), nums.end());
vector<list<int>::iterator> v; //要删除的节点
for (auto it = lst.begin(); next(it) != lst.end(); ++it) {
if (*it > *next(it)) {
v.push_back(next(it));
}
}
int ans = 0;
while (v.size()) {
ans++;
vector<list<int>::iterator> tmp; //tmp存要删除元素的pre节点
for (auto p : v) {
auto pre = prev(p);
lst.erase(p);
if (tmp.empty() || pre != tmp.back()) tmp.push_back(pre);
//删除前一个元素后 当前元素的prev跟前一个元素的prev相同
}
v.clear();
for (auto p : tmp) {
if (next(p) != lst.end() && *p > *next(p)) {
v.push_back(next(p));
}
}
}
return ans;
}
};
代码上的难点:vector存即将删除的节点,而不是删除结点的prev,带来的好处是vector中的节点始终是存在的,并且通过这些迭代器找prev也很容易。