Leetcode 20.有效的括号

这篇文章是博主对于Leetcode 20. 有效的括号的题解


前言

在现代社会,知识和技能的积累变得愈发重要。无论是学生、职场人士还是专业人士,不断提升自己的能力都成为了成功的关键。而在这个信息爆炸的时代,刷题已经成为一种有效而不可或缺的学习和提升方法。本文将探讨刷题的用处以及它为个人和职业发展带来的价值。


提示:以下是本篇文章正文内容,下面案例可供参考

一、题目分析

链接: LeetCode 20
题目原文:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

  • 有效字符串需满足:

    • 1、左括号必须用相同类型的右括号闭合。
    • 2、左括号必须以正确的顺序闭合。
    • 3、每个右括号都有一个对应的相同类型的左括号。
  • 条件:题目给出了三个需要满足的要求:

    • 第一个要求:左括号必须用相同类型的右括号闭合,就是两个相同类型的括号相互对应,例如‘(’ 和 ‘)’相对应,这个很容易理解;
    • 第二个要求:左括号必须以正确的顺序闭合,相较于第一个这个条件就没有那么容易理解,什么顺序是正确的顺序呢?博主刚开始也发了蒙,后面一尝试发现正确的顺序就是两个相同的括号中间不能有单独的括号,我们会遇见“([)]”这种例子,这个就是错误的,他违反了第二条规则;
    • 第三个要求:每个右括号都有一个对应的相同类型的左括号,这个要求的意思就是不管有多少个左括号总有一个与它类型相同的右括号相对应

总结来说就是题目会给你一个字符串,你需要判断这个,字符串是否满足题目要求,同时题目是一个简单题,只会提供’[’ ‘(’ ‘{’ ‘]’ ‘)’ ‘}’ 这六个需要操作的字符。

二、题目解决思路分析

1、利用 Java 提供的 replace() 方法解决

既然题目给出的要求两个括号一定是对称的,那么符合要求的字符串一定会出现 “()” “[]” 和 “{}”,我们可以将字符串里面的 “()” “[]” 和 “{}” 替换成 “”,然后再返回字符串字符串的长度即可。
具体实现方式如下:

class Solution {
    public boolean isValid(String s) {
        int n=s.length()/2;
        for (int i = 0; i < n; i++) {
            s=s.replace("()","").replace("[]","").replace("{}","");
        }
        if (s.isEmpty()) return true;
        else return false;
    }
}
//自己实现 replace() 方法
public static String customReplace(String originalString, String oldString, String newString) {
        // 检查输入参数是否为null
        if (originalString == null || oldString == null || newString == null) {
            return originalString;
        }

        StringBuilder result = new StringBuilder();
        int startIndex = 0;
        int lastIndex = 0;

        // 从原始字符串中查找并替换子字符串
        while ((lastIndex = originalString.indexOf(oldString, startIndex)) != -1) { // 这里的 indexOf(oldString, startIndex) 意思是从起始位置 startIndex 开始搜索 oldString 第一次出现的索引,如果没有就返回-1
            result.append(originalString.substring(startIndex, lastIndex)); // 添加未替换的部分,substring() 方法是从原始字符串中提取子字符串,提取从 startIndex 到 lastIndex 处结束的字符,包含 startIndex 处的字符但不包含 lastIndex 处的字符
            result.append(newString); // 添加新字符串,append(String str) 方法接受一个字符串 str 作为参数,将其追加到当前 StringBuilder 对象的末尾
            startIndex = lastIndex + oldString.length(); // 更新起始位置,将下一次搜索的起始位置改为上一次搜索的末尾位置
       	}

        result.append(originalString.substring(startIndex)); // 添加剩余部分,这里 substring(startIndex) 只传了一个参数表示提取从 startIndex 到字符末尾的所有字符

        return result.toString();//利用 toString() 方法获取 result 的内容转换为一个新的字符串对象,并返回该字符串对象
    }

上面我提供了一个自己实现 replace() 方法的例子,如果不想调用 replace() 可以尝试自己实现这个方法,上面的代码可以做参考,下面还有C语言版。

char* replace(const char* original, const char* oldStr, const char* newStr) {
	if (original == NULL || oldStr == NULL || newStr == NULL)
	{
		return NULL;
	}
	int originallen = strlen(original);//original 的长度,这里需要注意 strlen() 函数是测量字符的长度,这个长度不包括字符串的终止空字符 '\0'
	int oldStrlen = strlen(oldStr);//oldStr 的长度
	int newStrlen = strlen(newStr);//newStr 的长度

	char* result = (char*)malloc(originallen * 2 + 1);//申请内存空间,可以根据具体题目进行改变
	if (result == NULL) {
		return NULL;
	}

	int i, j = 0;
	for (i = 0; i < originallen; i++) {
		if (strncmp(original + i, oldStr, oldStrlen) == 0)//这里是对字符串进行遍历的过程,original + i 的含义是将这个比较的起点向后偏移 i 个位置 strncmp() 的含义是比较第一个字符串(original + i)和第二个字符串(oldStr)的前 oldStrlen 个字符,简言之这个是判断 original 里面有没有 oldStr 的
		{
			//复制新字符串
			strncpy(result + j, newStr, newStrlen);//将 newStr 拼接在 result 后面, newStrlen 表示需要从 newStr 复制的字符串长度
			j += newStrlen;
			i += oldStrlen - 1;//跳过旧字符串的长度,减一是为了确保 i 是最后一个字符的下标,而不是最后一个字符下一个字符的下标
		}
		else {
			//复制原始字符串的内容
			result[j++] = original[i];
		}
	}
	//添加字符串终止符
	result[j] = '\0';

	return result;
}

2.利用栈结构来解决

这个题目要求每个左括号与右括号相对应,后放进去的括号要先拿出来,我们就可以用到栈这个数据结构后进先出的特点。
(1)使用Java里面的 ‘stack’ 类:

  • 我们使用一个栈来追踪左括号。
  • 遍历字符串,当遇到左括号时,将其压入栈中。
  • 当遇到右括号时,我们检查栈顶的左括号是否与其匹配。如果匹配,将栈顶的左括号出栈;否则,字符串无效。
  • 最终,如果栈为空,则字符串有效。
class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for (char c:s.toCharArray()) {
            if (c == '(' || c == '[' || c == '{' ) {
                stack.push(c);
            }else{
                if(stack.isEmpty()){
                    return false;
                }
                char top = stack.pop();
                if((c == ')' && top != '(') || (c == ']' && top != '[') || (c == '}' && top != '{')){
                    return false;
                }
            }
        }
        return stack.isEmpty();
    }
}

(2)利用字符数组模拟栈的操作:

  • 如果不想使用Java的Stack类,可以使用一个字符数组来模拟栈的操作。
  • 使用一个整数变量top来表示栈顶位置,初始值为-1。
  • 遍历字符串,当遇到左括号时,将其压入栈中(即,数组中的下一个位置)。
  • 当遇到右括号时,我们检查栈顶的左括号是否与其匹配。如果匹配,将栈顶的左括号出栈(即,top减1);否则,字符串无效。
  • 最终,如果top等于-1,则字符串有效。
class Solution {
    public boolean isValid(String s) {
        char[] stack =new char[s.length()];
        int top = -1;
        for (char c: s.toCharArray()
             ) {
            if(c == '(' || c == '{' || c == '['){
                stack[++top] = c;
            } else {
                if(top == -1){
                    return false;
                }
                char topChar = stack[top--];
                if((c == '}' && topChar != '{') || (c == ')' && topChar != '(') || (c == ']' && topChar != '[')){
                    return false;
                }
            }
        }
        return top == -1;
    }
}

总结

通过使用栈这个数据结构,我们得以高效的解决了这个问题。这个问题是算法和数据结构的经典练习题之一,具有广泛的应用,例如在编译器和解释器中用于检查代码的语法正确性。博主初次尝试写题解类文章,以后会经常更新相关的题解文章,希望各位阅读了我的文章之后有什么感受、建议以及文章中出现的错误都可以指出,大家一起交流进步。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值