LeeCode笔记(day03)
1.题目

2.思路
首先考虑正常的情况,先分析一下这个字符串的规律:
1.无论这个字符串长什么样,左边一定是一个或多个左括号。
2.每个右括号,它的左边第一个括号一定是对应的左括号({[。
3.所有左括号的数量,一定是和右括号相等。
那么我们的思路:
从左---->右遍历字符串,每次遇到右括号,就往前看它左边第一个括号是不是对应的左括号,如果是的话,就删掉这段,接着遍历。最后我们会把整个字符串删掉,说明符合题目要求,否则中途就会出错。那么实际代码将会是不断的截取字符串的过程。示意图如下:

3.代码
实际上不用这么麻烦,我想到的第一种方式就是用栈结构,只要是左括号就压栈,遇到右括号就弹栈出来进行比较。如果能顺利完成这个过程就返回true,代码如下:
'''
@Test
public void test(){
String s = "{aa[aa{dsad}dsa][dsa{ds}}{sdaew2(fdsfds[32423]2)34[43]43}";
Stack stack = new Stack();
boolean flag = true;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(' || c == '[' || c == '{'){
stack.push(c);
}
if (c == ')' || c == ']' || c == '}'){
char pop = (char)stack.pop();
if (!((c == ')' && pop == '(') || (c == ']' && pop == '[') || (c == '}' && pop == '{'))){
flag = false;
}
}
}
if (flag){
System.out.println("满足");
}
}
结果如下(不知道leecode是怎么个机制,我第一次提交效率只有45%,没想到第二次差这么多。)

4.改进
可以看到内存消耗有点大,原因的话我估计是因为使用了Stack栈结构,压了太多元素在Stack里面。那么我们保留“压栈弹栈”的思路,不使用Stack类做。
(这里的方法是评论区的代码,思路类似。懒得自己敲了。)
'''
public boolean isValid2(String s) {
char[] charArray = new char[s.length() + 1];
int p = 1;
for (char c : s.toCharArray()) {
if (c == '(' || c == '{' || c == '[') {
charArray[p++] = c;
} else {
p--;
if (c == ')' && charArray[p] != '(') {
return false;
}
if (c == '}' && charArray[p] != '{') {
return false;
}
if (c == ']' && charArray[p] != '[') {
return false;
}
}
}
return p == 1; // 如果左括号还有剩余 括号没有一一对应,属于无效情况
}
5.总结
我们能学到什么?
1.栈结构的一个应用场景,栈结构的最大特点就是“先进后出”。理解栈结构最好的例子我觉得就是“弹夹装子弹”的过程,子弹弹夹就是一个典型的栈结构。
2.一个好的逻辑,应该有几个考虑:1.它的思路易于理解(可读性)2.效率除了时间,还要考虑空间(内存)的消耗。
浙公网安备 33010602011771号