程序员面试金典——番外篇之下一个较大元素I
Solution1:我的答案,时间复杂度为O(n2)O(n2)
垃圾算法
class NextElement {
public:
vector<int> findNext(vector<int> A, int n) {
// write code here
vector<int> res;
for (int i = 0; i < A.size() - 1; i++) {
int temp = find_bigger(i, A);
res.push_back(temp);
}
res.push_back(-1);
return res;
}
int find_bigger(int seq, vector<int> &nums) {
int res = -1;
for (int i = seq + 1; i < nums.size(); i++) {
if(nums[i] > nums[seq]) {
res = nums[i];
break;
}
}
return res;
}
};
Solution2:动态规划,牛逼,牛逼,真牛逼
实现了时间复杂度为O(n)O(n)的算法
思路:
从后向前维护一个递减栈。
最右边的那个值肯定没有最大值,所以肯定是-1。初始栈为-1。
从后向前计算:
(1)如果当前元素大于栈顶元素,则栈顶元素退出,如果还是大于栈顶元素,继续退出,一直遍历栈到-1或者小于栈顶元素。这个元素就是就是当前值的下一个比较大的元素。
(2)如果当前元素小于栈顶元素,栈顶元素就是当前值的下一个比较大的元素。
再简化一下代码如下
class NextElement {
public:
vector<int> findNext(vector<int> A, int n) {
// write code here
stack<int> ss;
vector<int> result;
for (int i = n - 1; i >= 0; -- i) {
// 每个元素实际上只入栈一次,出栈一次,所以是O(N)的
while (!ss.empty() && A[i] >= ss.top())
ss.pop();
if (ss.empty())
result.push_back(-1);
else
result.push_back(ss.top());
ss.push(A[i]);
}
reverse(result.begin(), result.end());
return result;
}
};
本文介绍了一种寻找数组中每个元素的下一个较大元素的有效算法。通过两种解决方案对比,一种是简单的二次时间复杂度方法,另一种是利用动态规划实现的线性时间复杂度算法,后者使用递减栈从后向前遍历数组,确保了每个元素仅被处理一次。

被折叠的 条评论
为什么被折叠?



