LeetCode 브러시 질문 : 스택 및 대기열

스택

2 개의 대기열로 스택 구현

https://leetcode-cn.com/problems/implement-stack-using-queues/
여기에 사진 설명 삽입

class MyStack {
    
    
    Queue<Integer> queue1; // 对外输出
    Queue<Integer> queue2; // 对内输入
 
    /** Initialize your data structure here. */
    public MyStack() {
    
    
        queue1 = new LinkedList<Integer>();
        queue2 = new LinkedList<Integer>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
    
    
        queue2.offer(x);
        while (!queue1.isEmpty()) {
    
    
            // 核心就是让后入变成先入,最后操作的在offer处插队成为首个,过去插队维护的再输入进来即可
            queue2.offer(queue1.poll());
        }
        Queue<Integer> temp = queue1;
        queue1 = queue2;
        queue2 = temp;
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
    
    
        return queue1.poll();
    }
    
    /** Get the top element. */
    public int top() {
    
    
        return queue1.peek();
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
    
    
        return queue1.isEmpty();
    }
}

439. 삼항식 파서

https://leetcode-cn.com/problems/ternary-expression-parser/
여기에 사진 설명 삽입

핵심:

  1. Character.isDigit이 숫자를 판단합니다.
  2. 판정 처리 (스태킹 및 팝핑)의 표시는 무엇입니까? 그리고 누가 스택에 가고 나중에 스택에서 나 가든 마지막 남은 것은 답입니다.
    단 한 번의 순회 만 필요합니다.
    여기에 사진 설명 삽입

71. 경로 단순화

여기에 사진 설명 삽입

class Solution {
    
    
    public String simplifyPath(String path) {
    
    
        String[] strings = path.split("/");
        Stack<String> stack = new Stack<>();
        for(String str : strings) {
    
    
            if(str.isEmpty() || str.equalsIgnoreCase(".") || str.equalsIgnoreCase("/")) {
    
    
                continue;
            }
            if(str.equalsIgnoreCase("..")) {
    
    
                if(!stack.isEmpty()) {
    
    
                    stack.pop();
                }
                continue;
            }
            stack.push(str);
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("/");
        for(String str : stack) {
    
    
            stringBuilder.append(str);
            stringBuilder.append("/");
        }
        if(stringBuilder.toString().length() == 1) {
    
    
            return stringBuilder.toString();
        }
        return stringBuilder.toString().substring(0, stringBuilder.length() - 1);
    }
}

316. 중복 문자 제거

여기에 사진 설명 삽입

필수 사항 :
욕심 + 스택

  1. 욕심 알고리즘에 의해 검증 된 현재 최적의 솔루션이 스택에 저장되어
    있으며, 처리 할 캐릭터를 추가해야하는지, 이전에 반복 된 캐릭터를 교체 할 수 있는지 여부를 결정할 필요가있을 때마다
class Solution {
    
    
    private int[] letterNum = new int[26];
    public String removeDuplicateLetters(String s) {
    
    
        if (s == null || s.isEmpty() || s.length() == 1) {
    
    
            return s;
        }
        initArray(s);
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
    
    
            char sTmp = s.charAt(i);
            letterNum[sTmp - 'a']--;
            if(stack.isEmpty()) {
    
    
                stack.push(sTmp);
                continue;
            }
            while (!stack.isEmpty()) {
    
    
// 判断当前字符与stack已经入栈字符之间的关系
                char stackTmp = stack.peek();
// 已经入栈的字符无需处理
                if(stack.contains(sTmp)) {
    
    
                    break;
                }
                if(stackTmp - sTmp >= 0 && !isLastOne(stackTmp)) {
    
    
// 之前入栈的每个字符需要经过新字符的洗练。需要在后续有重复的基础上满足字典序最小
                    stack.pop();
                } else {
    
    
// 遇到第一个无法处理的立即终止
                    break;
                }
            }
            if (!stack.contains(sTmp)) {
    
    
 // 栈中补充上该字符
                stack.push(sTmp);
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        for(Character c :stack) {
    
    
            stringBuilder.append(c);
        }
        return stringBuilder.toString();
    }
    private void initArray(String s) {
    
    
        for (Character c : s.toCharArray()) {
    
    
            letterNum[c - 'a']++;
        }
    }
    private boolean isLastOne(char c) {
    
    
   // 判断是否是最后一个
        return letterNum[c - 'a'] == 0;
    }
}

핵심 포인트 :

  1. 세 개의 아래 첨자 : 크기, 첫 번째, 마지막
    첫 번째와 마지막의 실제 의미에 대해 명확하게 생각하십시오 : 정확한 기존 요소를 나타내는 아래 첨자와 위치의 다음
    첫 번째 요소 사이의 관계 는 다음과 같습니다. 하나의 상황 만 겹칠 것입니다. 배열에 요소가 하나만있는 경우.
class MyCircularQueue {
    
    
    Object[] queue = null;
        int first = 0;
        int last = 0;
        int size = 0;
        public MyCircularQueue(int k) {
    
    
            queue = new Object[k];
            first = 0;
            last = 0;
            size = k;
        }
        public boolean enQueue(int value) {
    
    
            if (last + 1 == first || (last + 1 == size && first == 0)) {
    
    
                return false;
            }
            if(last == first && queue[last] == null) {
    
    
                queue[last] = value;
                return true;
            }
            last++;
            if (last == size) {
    
    
                last = 0;
            }
            queue[last] = value;
            return true;
        }
        public boolean deQueue() {
    
    
            if (last == first) {
    
    
                if(queue[first] == null) {
    
    
                    return false;
                } else {
    
    
                    queue[first] = null;
                    return true;
                }
            }
            queue[first] = null;
            first ++;
            if (first == size) {
    
    
                first = 0;
            }
            return true;
        }
        public int Front() {
    
    
            if (queue[first] == null) {
    
    
                return -1;
            }
            return (int) queue[first];
        }
        public int Rear() {
    
    
            if (queue[last] == null) {
    
    
                return -1;
            }
            return (int) queue[last];
        }
        public boolean isEmpty() {
    
    
            if (last == first && queue[last] == null) {
    
    
                return true;
            }
            return false;
        }
        public boolean isFull() {
    
    
            int lastIndex = last + 1;
            if (lastIndex == first || (lastIndex == size && first == 0)) {
    
    
                return true;
            }
            return false;
        }
}
/**
 * Your MyCircularQueue object will be instantiated and called as such:
 * MyCircularQueue obj = new MyCircularQueue(k);
 * boolean param_1 = obj.enQueue(value);
 * boolean param_2 = obj.deQueue();
 * int param_3 = obj.Front();
 * int param_4 = obj.Rear();
 * boolean param_5 = obj.isEmpty();
 * boolean param_6 = obj.isFull();
 */

추천

출처blog.csdn.net/weixin_38370441/article/details/115252537