스택 알고리즘 및 설계 예제

실현 스택

큐 이상의 스택을 쉽게 얻을 수 있습니다. 동적 배열은 적층 구조를 달성하기에 충분하다. 여기에 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