[単調スタック] [リートコード] [中] 503。次に大きい要素II

トピック:

ループ配列(最後の要素の次の要素は配列の最初の要素)が与えられた場合、各要素の次に大きい要素を出力します。数値xの次に大きい要素は、配列走査順序です。この数値の後の最初の数値はそれよりも大きいため、ループ内で次に大きい数値を検索する必要があります。存在しない場合は-1を出力します。

例:

入力:[1,2,1]
出力:[2、-1,2]
説明:最初の1の次に大きい数は2です;
数2は次に大きい数を見つけることができません;
2番目に大きい数の1ループ検索が必要で、結果も2です。

元のタイトルアドレス:

503.次の大要素II

問題解決のアイデア:単調なスタック

単調なスタックは、単調なキューと同様に、増加または減少するスタックです。つまり、pop()を呼び出すことによって返されるデータは、増加または減少します。

スタックであるため、3つの基本的な操作があります。

  • push(x):xをスタックにプッシュします。スタック内のデータが正しいことを確認するために、xの位置が見つかるまで、スタックの一番上の要素とxのサイズを比較します。一部のデータは、このプロセス中にpopによって削除されます。
  • pop():スタックの最上位要素を削除します
  • top():スタックの最上位要素

この質問では、単調スタックの使用方法について、最初に例を見てください。配列が[4、3、2、5、5、2、1]の場合、[5、5、5、-1を返す必要があります。 -1、4、4]。

Push(4)は1、2をスタックからプッシュするため、次の最大値である1、2は4です。

最初から始めるには、最大値をスタックに1回プッシュするだけで済みますが、コードは複雑で、2パスで完全にトラバースできます。

c ++コード:

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int> ret(nums.size(), -1);
        if (nums.empty()) return ret;

        stack< pair<int, int> > s; // 记录当前数字及其位置
        for (int j = 0; j < 2; j++) {
            for (int i = 0; i < nums.size(); i++) {
                while (!s.empty()) {
                    pair<int, int> p = s.top();
                    if (p.first < nums[i]) {
                        ret[p.second] = nums[i]; // 根据位置更改ret数组
                        s.pop();
                    } else {
                        break;
                    }
                }
                s.push(make_pair(nums[i], i));
            }
        }

        return ret;
    }
};

 

おすすめ

転載: blog.csdn.net/hbuxiaoshe/article/details/114457502