在对相邻的2个元素需要进行匹配的时候,那么此时就可以利用栈的先进先出来进行实现。

20. 有效的括号

题目描述

image.png

解题思路

  • 第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false
  • 第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
  • 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
  • 那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。 ```java /**

    1. * 正常的放入
    2. *
    3. * @param s
    4. * @return
    5. */

    public boolean isValid(String s) { Stack stack = new Stack<>(); char ch; for (int i = 0; i < s.length(); i++) {

    1. ch = s.charAt(i);
    2. if (ch == '(') {
    3. stack.push('(');
    4. } else if (ch == '{') {
    5. stack.push('{');
    6. } else if (ch == '[') {
    7. stack.push('[');
    8. } else if (stack.isEmpty()) {
    9. // 此时栈中为空,右括号过多
    10. return false;
    11. } else if (stack.peek() == '(' && ch == ')' || stack.peek() == '{' && ch == '}' || stack.peek() == '[' && ch == ']') {
    12. stack.pop();
    13. } else {
    14. // 和栈顶元素不匹配的情况
    15. return false;
    16. }

    }

    // 遍历完后,栈中不为空,此时左括号过多 return stack.isEmpty(); }

/**

  1. * 放入相反的括号,更加方便
  2. *
  3. * @param s
  4. * @return
  5. */

public boolean isValid(String s) { Stack stack = new Stack<>(); char ch; for (int i = 0; i < s.length(); i++) { ch = s.charAt(i); if (ch == ‘(‘) { // 放入相反的括号 stack.push(‘)’); } else if (ch == ‘{‘) { stack.push(‘}’); } else if (ch == ‘[‘) { stack.push(‘]’); } else if (stack.isEmpty() || stack.peek() != ch) { // 此时栈中为空,右括号过多 // 此时括号不匹配 return false; } else { // 当括号匹配时,出栈 stack.pop(); } }

  1. // 遍历完后,栈中不为空,此时左括号过多
  2. return stack.isEmpty();

}

  1. <a name="VNYaT"></a>
  2. # 1047. 删除字符串中的所有相邻重复项
  3. <a name="GtmZu"></a>
  4. ## 题目描述
  5. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/26393840/1653917798425-462891f0-9170-404a-ae17-644c4b3b5cdf.png#clientId=u858f267f-173a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=456&id=u557c8ff5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=570&originWidth=1061&originalType=binary&ratio=1&rotation=0&showTitle=false&size=50638&status=done&style=none&taskId=u153a422c-2d75-49ba-8f7e-f33974956ca&title=&width=848.8)
  6. <a name="R0nDD"></a>
  7. ## 解题思路
  8. 利用栈的特性即可<br />![](https://cdn.nlark.com/yuque/0/2022/gif/26393840/1653917883202-f4cb9ce8-1884-40be-8c3b-857753e61f63.gif#clientId=u858f267f-173a-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u27095bdb&margin=%5Bobject%20Object%5D&originHeight=354&originWidth=422&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u63982049-019b-4a50-a59b-da5f18646fc&title=)
  9. ```java
  10. /**
  11. * 使用栈
  12. *
  13. * @param s
  14. * @return
  15. */
  16. public String removeDuplicates(String s) {
  17. Stack<Character> stack = new Stack<>();
  18. char ch;
  19. for (int i = 0; i < s.length(); i++) {
  20. ch = s.charAt(i);
  21. if (!stack.isEmpty()) {
  22. char temp = stack.peek();
  23. // 相等即出栈
  24. if (ch == temp) {
  25. stack.pop();
  26. } else {
  27. // 不相等即入栈
  28. stack.push(ch);
  29. }
  30. } else {
  31. // 栈为空直接入栈
  32. stack.push(ch);
  33. }
  34. }
  35. // 将栈转化为字符串
  36. String str = "";
  37. while (!stack.isEmpty()) {
  38. str = stack.pop() + str;
  39. }
  40. return String.valueOf(str);
  41. }
  42. /**
  43. * 双指针法
  44. *
  45. * @param s
  46. * @return
  47. */
  48. public String removeDuplicates(String s) {
  49. int fast = 0, slow = 0;
  50. char[] chars = s.toCharArray();
  51. while (fast < s.length()) {
  52. // 直接用fast指针覆盖slow指针的值
  53. chars[slow] = chars[fast];
  54. // 存在相邻相等的元素,slow减一,不用减二,slow会被下次循环覆盖
  55. if (slow > 0 && chars[slow] == chars[slow - 1]) {
  56. slow--;
  57. } else {
  58. slow++;
  59. }
  60. fast++;
  61. }
  62. return String.valueOf(chars, 0, slow);
  63. }

150. 逆波兰表达式求值

题目描述

image.png

解题思路

也就是后缀表达式,遇到运算符的话,就取出前面的2个元素运算之后在入栈。知道栈里面最后一个元素就是结果。
栈匹配功能的基本使用 - 图3

  1. public int evalRPN(String[] tokens) {
  2. Stack<Integer> stack = new Stack<>();
  3. int temp1, temp2;
  4. for (int i = 0; i < tokens.length; i++) {
  5. // 判断是否为响应的运算符,如果为运算符,即去栈顶上的两个树进行运算
  6. // 运算后将结果入栈,进行下一次取值
  7. if (tokens[i].equals("+")) {
  8. temp1 = stack.pop();
  9. temp2 = stack.pop();
  10. stack.push(temp1 + temp2);
  11. } else if (tokens[i].equals("*")) {
  12. temp1 = stack.pop();
  13. temp2 = stack.pop();
  14. stack.push(temp1 * temp2);
  15. } else if (tokens[i].equals("/")) {
  16. temp1 = stack.pop();
  17. temp2 = stack.pop();
  18. stack.push(temp2 / temp1);
  19. } else if (tokens[i].equals("/")) {
  20. temp1 = stack.pop();
  21. temp2 = stack.pop();
  22. stack.push(temp2 - temp1);
  23. } else {
  24. stack.push(Integer.valueOf(tokens[i]));
  25. }
  26. }
  27. return stack.pop();
  28. }