スタックアルゴリズムとデザイン例

実現スタック

スタックキューよりも簡単に実現します。動的配列は、スタック構造を達成するのに十分です。ここではLeetCode、公式には、参照用の簡単な実装を提供します。

// "static void main" must be defined in a public class.
class MyStack {
    private List<Integer> data;               // store elements
    public MyStack() {
        data = new ArrayList<>();
    }
    /** Insert an element into the stack. */
    public void push(int x) {
        data.add(x);
    }
    /** Checks whether the queue is empty or not. */
    public boolean isEmpty() {
        return data.isEmpty();
    }
    /** Get the top item from the queue. */
    public int top() {
        return data.get(data.size() - 1);
    }
    /** Delete an element from the queue. Return true if the operation is successful. */
    public boolean pop() {
        if (isEmpty()) {
            return false;
        }
        data.remove(data.size() - 1);
        return true;
    }
};

155最小スタック

  • 難易度:Easy

タイトル説明

、トップ動作を、プッシュポップするように設計された支持体は、スタックが取得され、一定時間内の最小要素であることができます。

  • プッシュ(X) - xはスタックプッシュ要素。
  • ポップ() ​​- スタックの削除要素を。
  • トップ() ​​- トップ要素を取得します。
  • getMin() - スタック内の最小の要素を取り出します。

問題解決のためのアイデアと実現

公式スタックとキューのタブは、スタックの実装は次のように説明されています。

スタックキューよりも簡単に実現します。ダイナミックアレイ・スタック構造を達成するのに十分。

// 官方实现的描述,直接使用了ArrayList
class MyStack {
    private List<Integer> data;               // store elements
    public MyStack() {
        data = new ArrayList<>();
    }
}

だから、時間のこの質問は、無意識のうちに使用があることを感じないArrayList十分であり、追加要件の対象があるため、合格しないことが判明し、一定時間内に最小の要素を取得し、そして私がいた最小を見つけるために、すべての要素による暴力的なループ、時間の複雑さがありますO(N)そう、もちろんありません。

本来のgetMin()機能は、レコードを持つ加盟国の最小値は、すべての権利である必要があり、時間制限があります...

これは、あまりにも、でレイプShuahuaを盗む、それは本当に判明しようとしました...(私はちょうどからの動作サイクルを置くgetMin()に転送しますpop())...

class MinStack {

    private List<Integer> data;
    // 1.用一个成员记录栈内最小值
    private int min = Integer.MAX_VALUE;

    public MinStack() {
        data = new ArrayList<>();
    }

    // 2.写入时,看情况更新最小值
    public void push(int x) {
        if (min > x) {
            min = x;
        }
        data.add(x);
    }

    // 3.出栈时,更新最小值,这里时间复杂度为 O(N)
    public void pop() {
        verifyNotEmpty();
        data.remove(data.size() - 1);

        min = Integer.MAX_VALUE;
        for (Integer num : data) {
            if (min > num) {
                min = num;
            }
        }
    }

    public int top() {
        verifyNotEmpty();
        return data.get(data.size() - 1);
    }

    // 4.这样就能保证,获取最小值的函数,执行时间为常数时间了 =w=
    public int getMin() {
        verifyNotEmpty();
        return min;
    }

    private void verifyNotEmpty() {
        if (data.isEmpty()) {
            throw new IllegalArgumentException("Stack is empty");
        }
    }
}

20.効果的なブラケット

  • 難易度:Easy

タイトル説明

のみ与えられた含まれ'(',')','{','}','[',']'た文字列を、文字列が有効か否かを判断します。

有効な文字列を満たしている必要があります。

  • 1.左ブラケットと右ブラケットは、同じタイプによって閉鎖されなければなりません。
  • 2.左括弧が正しい順序で閉じなければなりません。
    空の文字列が有効な文字列と考えることができます。

問題解決のためのアイデアと実現

まだ非常に良いではない正直なスタック関連の話題だと思うのは初めて、リファレンス・ソリューションであるために公式の説明

https://leetcode-cn.com/problems/valid-parentheses/solution/you-xiao-de-gua-hao-by-leetcode/

実装コード:

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();

        Map<Character, Character> mapping = new HashMap<>();
        mapping.put('}', '{');
        mapping.put(')', '(');
        mapping.put(']', '[');

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (mapping.containsKey(c)) {
                // 闭括号
                char top = stack.isEmpty() ? '#' : stack.pop();

                if (top != mapping.get(c)) {
                    return false;
                }
            } else {
                // 新的开符号,直接压入栈中
                stack.push(c);
            }
        }
        return stack.isEmpty();
    }
}

739気温

  • 難易度:Medium

タイトル説明

毎日の温度のリストによると、リストを再構築し、対応する位置を入力します。あなたは、温度がその日の日数を超えて上昇するまで待機する必要がどのくらいです。すべての後、増加していない場合は、この場所を使用してください0代わりに。

例えば、リストの与えられtemperatures = [73, 74, 75, 71, 69, 72, 76, 73]なければなりませんあなたの出力を[1, 1, 4, 2, 1, 1, 0, 0]

ヒント:リストの温度範囲の長さがあります[1, 30000]各温度の値は華氏である、ある[30, 100]範囲の整数。

問題解決のためのアイデアと実現

問題を理解する上で、この質問の難易度の嘘は、実際には、比較的単純な解決するために、タイトルを読んで。

1.ブルートフォース方法

ブルートフォース方法は、考えるための最も直接的な方法、時間複雑ですO(N^2)

class Solution {
   public int[] dailyTemperatures(int[] T) {
        int[] ans = new int[T.length];

        for (int i = 0; i < T.length; i++) {
            // 最后一个元素,对应一定是0
            if (i == T.length - 1) {
                ans[T.length - 1] = 0;
                continue;
            }
            int times = 0;
            for (int j = i + 1; j < T.length; j++) {
                if (T[j] > T[i]) {
                    ans[i] = ++times;
                    break;
                }
                if (j == T.length - 1) {
                    ans[i] = 0;
                }
                times++;
            }
        }
        return ans;
    }
}

2.スタック

正直に言うと、本当にこのソリューションを期待していなかった、とラベルの主題はを参照して、示唆されて公式の説明

https://leetcode-cn.com/problems/daily-temperatures/solution/mei-ri-wen-du-by-leetcode/

class Solution {
    public int[] dailyTemperatures(int[] T) {
        int[] ans = new int[T.length];
        Stack<Integer> stack = new Stack();
        for (int i = T.length - 1; i >= 0; --i) {
            while (!stack.isEmpty() && T[i] >= T[stack.peek()]) stack.pop();
            ans[i] = stack.isEmpty() ? 0 : stack.peek() - i;
            stack.push(i);
        }
        return ans;
    }
}

アレイ内の各インデックスアッププッシュとスタック操作を行うためにので、コードを大幅に簡略化され、その結果、スタック要素として動的更新プロセススタックを使用して、より高い思考によって、インデックスデータ。時間複雑そうO(N)

150逆ポーランド式評価

  • 難易度:Medium

タイトル説明

よると、逆ポーランド記法、式を評価します。

事業者は、効果的な含ま+, -, *, /各オペランドは整数であることができ、それは別の逆ポーランド記法であることができます。

説明:

  • 分割整数整数部分のみを残します。
  • 常に効果的な逆ポーランド記法を考えます。言い換えれば、式は常に来るとに対する有効な除数が存在しない0状況が。

問題解決のためのアイデアと実現

再び溶液スタックを使用して、シンボルが検出されたスタック上の要素の数は、スタックから除去二つの要素が評価され、その結果は再びスタックの最上部、リターンスタックの最終的な結果はするポップされます。

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        Integer i1, i2;
        for (String s : tokens) {
            switch (s) {
                case "+":
                    i1 = stack.pop();
                    i2 = stack.pop();
                    stack.push(i2 + i1);
                    break;
                case "-":
                    i1 = stack.pop();
                    i2 = stack.pop();
                    stack.push(i2 - i1);
                    break;
                case "*":
                    i1 = stack.pop();
                    i2 = stack.pop();
                    stack.push(i2 * i1);
                    break;
                case "/":
                    i1 = stack.pop();
                    i2 = stack.pop();
                    stack.push(i2 / i1);
                    break;
                default:
                    stack.push(Integer.parseInt(s));
                    break;
            }
        }
        return stack.pop();
    }
}

リファレンス&感謝

記事からの抜粋のほとんどはLeetCode、概要:

  • https://leetcode-cn.com/explore/learn/card/queue-stack/218/stack-last-in-first-out-data-structure/875/

例:

  • https://leetcode-cn.com/problems/min-stack/
  • https://leetcode-cn.com/problems/valid-parentheses/
  • https://leetcode-cn.com/problems/daily-temperatures/
  • https://leetcode-cn.com/problems/evaluate-reverse-polish-notation

私について

こんにちは、私は清メイスニフを混乱あなたはあなたに貴重な記事、歓迎は❤️、また私に注意を歓迎思えば、ブログGitHubの

あなたは記事が何かので、さらに悪くなると考えられる場合は、またしてくださいに焦点を当て、より良い記事を書くために私を促す-ある日、私はそれの進捗状況か?

发布了99 篇原创文章 · 获赞 396 · 访问量 47万+

おすすめ

転載: blog.csdn.net/mq2553299/article/details/104272763