所用代码 java
有效的括号 LeetCode 20
题目链接:有效的括号 LeetCode 20 - 简单
思路
由于题目要求左括号必须以正确的顺序闭合,所以我们可以用栈的思想来存每一个左括号,每次出现一个正确的右括号,就把栈顶的左括号给弹出,若左右括号不匹配则返回false,若字符串遍历完括号也能正确的弹出就返回 true。
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
char[] c = s.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == '(' || c[i] == '[' || c[i] == '{'){
stack.push(c[i]);
}else if (!stack.isEmpty() && stack.peek() == '(' && c[i] == ')'){
stack.pop();
}else if (!stack.isEmpty() && stack.peek() == '[' && c[i] == ']'){
stack.pop();
}else if (!stack.isEmpty() && stack.peek() == '{' && c[i] == '}'){
stack.pop();
}else {
return false;
}
}
return stack.isEmpty();
}
总结
其实java里面String有一个contains方法,可以直接S.contains() "() [] {}"这三种括号,虽然非常的方便,但是效率不高。
删除字符串中的所有相邻重复项 LeetCode 1047
题目链接:删除字符串中的所有相邻重复项 LeetCode 1047 - 简单
思路
一开始想的是双指针,快慢指针一前一后,遇到相邻的相同字母就继续往两边探索,但是这种方法处理边界比较麻烦。然后再想到用栈的思想,遇到不相同的字母的压入栈,待压入栈元素和栈顶元素相同就弹出栈。试了一下栈不行,栈要改变字母的顺序,输出逆向,应该用队列才行。
public String removeDuplicates(String s) {
Deque<Character> deque = new ArrayDeque<>();
char[] c = s.toCharArray();
for (int i = 0; i < c.length; i++) {
// 栈为空或者最后一位元素不等于待填充元素,就压入栈
if (deque.isEmpty() || deque.peekLast() != c[i]){
deque.offerLast(c[i]);
}else {
deque.pollLast();
}
}
StringBuilder sb = new StringBuilder();
while (!deque.isEmpty()){
sb.append(deque.pollFirst());
}
return sb.toString();
}
总结
其实使用栈也对,只是每个字符添加逆向添加就可以了,添加操作如下:
String res = "";
while (!stack.isEmpty()){
// 保证了每次栈先弹出来的字母在前面
res = stack.pop() + res;
}
然后又学习了一下代码随想录上的双指针解法:
public String removeDuplicates(String s) {
// 双指针
char[] c = s.toCharArray();
int fast = 0;
int slow = 0;
while (fast < c.length){
c[slow] = c[fast];
// 如果slow所指的值和前项相等就退一位
if (slow > 0 && c[slow] == c[slow-1]){
slow--;
}else {
slow++; // 不想等就正常后移
}
// 每次快指针后移一位并赋值给慢指针
fast++;
}
String res = String.valueOf(c);
return res.substring(0, slow);
// return new String(c,0,slow);
// restrn String.valueOf(c,0,slow);
}
明显双指针效率更好!
逆波兰表达式求值 LeetCode 150
题目链接:逆波兰表达式求值 LeetCode 150 - 中等
思路
逆波兰表达式就是后缀表达式。我们可以从左到右把字符串压入栈,遇到符号就弹出两个数进行运算(后弹出的 + - * / 减先弹出的)
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
int firstOut = 0;
int secondOut = 0;
int putStackNum = 0;
for (int i = 0; i < tokens.length; i++) {
String str = tokens[i];
// 若是符号,前面就一定有数字
if (str.equals("+")){
firstOut = stack.pop();
secondOut = stack.pop();
putStackNum = secondOut + firstOut;
//再把运算出来的结果压入栈
stack.push(putStackNum);
}else if (str.equals("-")){
firstOut = stack.pop();
secondOut = stack.pop();
putStackNum = secondOut - firstOut;
stack.push(putStackNum);
}else if (str.equals("*")){
firstOut = stack.pop();
secondOut = stack.pop();
putStackNum = secondOut * firstOut;
stack.push(putStackNum);
}else if (str.equals("/")){
firstOut = stack.pop();
secondOut = stack.pop();
putStackNum = secondOut / firstOut;
stack.push(putStackNum);
}else {
System.out.println(str);
// 数字,转为int型并压入栈
int num = Integer.parseInt(str);
stack.push(num);
}
}
// 最后存在栈中的就是结果
return stack.pop();
}
总结
自己写出来感觉非常的冗余,但是能通过,所以又看了下代码随想录发现方法是一样的-_-。所以就留的自己的也好理解