Piles et files d'attente
Empiler
Implémenter la pile avec 2 files d'attente
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. Analyseur d'expression ternaire
https://leetcode-cn.com/problems/ternary-expression-parser/
Point clé:
- Character.isDigit juge le nombre
- Quelle est la marque du traitement du jugement (empilement et popping)? Et celui qui va à la pile et qui sort de la pile par la suite, la dernière chose qui reste est la réponse.
Un seul parcours est nécessaire.
71. Simplifier le chemin
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. Supprimer les lettres en double
Essentiels:
gourmand + pile
- La solution optimale actuelle vérifiée par l'algorithme glouton est stockée dans la pile.
Chaque fois qu'il est nécessaire de déterminer si le caractère à traiter doit être ajouté et si le caractère répété précédent peut être remplacé
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;
}
}
file d'attente
Points essentiels:
- Trois indices: taille, premier, dernier
Pensez clairement à la signification réelle du premier et du dernier:
la relation entre l' indice représentant exactement l'élément existant et non le suivant en premier à la position est: une seule situation se chevauchent. Lorsqu'il n'y a qu'un seul élément dans le tableau.
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();
*/