左神课堂开始

这些都是左神(左程云)课堂里讲的例子,写下自己的理解。

1、已知一个字符串都是由左括号(和右括号)组成,判断该字符串是否是有效的括号组合。

例子:

有效的括号组合:()()(())(()())

无效的括号组合:(())(()()(()

这题比较简单,

 1,可以先定义一个状态 int status ==0 ,当遇到“)”这个状态就改变:--status;

 2,当遇到“(”也改变其其状态:status++;

 3,当遇到其他的字符就直接返回 false;

public static boolean isValid(String str)
	{
		if (str == null || str.equals(""))
		{
			return false;
		}
		char[] chas = str.toCharArray();
		int status = 0;
		for (int i = 0; i < chas.length; i++)
		{
			if (chas[i] != ')' && chas[i] != '(')
			{
				return false;
			}
			if (chas[i] == ')' && --status < 0)
			{
				return false;
			}
			if (chas[i] == '(')
			{
				status++;
			}
		}
		return status == 0;
	}



2、题目进阶:

已知一个字符串都是由左括号(和右括号)组成,返回最长有效括号子串的长度。

该题:其实也很简单,但是是在左神讲完了之后,我才觉得的。

 (())(()(()))

 可以定义一个数组 int[] dp = new int[chas.length];长度就是上面字符串的长度。该数组就是为了保存每个位置上最大子串的长度。看下表:

  i     0  1  2  3  4  5  6  7

 chas   (  )  (  (  )  (  )  )

 dp     0  2  0  0  2  0  4  8

 


  从上表可以看出。

   dp的值,只有在“)”上计算才有意义。

   当i = 6 时:最大子串是"前面最大子串"的长度 +2(只要出现一对,最少+2);

   而然,"前面的最大子串"怎么去获得呢?

       需要通过 pre = i - dp[i-1]-1 ;比如:i = 7时,pre = 7-4-1 = 2;

       然后,还需要注意前面是否还存在 成对符号“()”所以就需要 加上 dp[pre-1]。这样 i= 7的时候,结果dp[7] = 8;

   

for (int i = 1; i < chas.length; i++)
		{
			if (chas[i] == ')')
			{
				pre = i - dp[i - 1] - 1;
				if (pre >= 0 && chas[pre] == '(')
				{
					dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);
				}
			}
			res = Math.max(res, dp[i]);
		}


完整代码:

public class Problem_01_ParenthesesProblem
{

	public static boolean isValid(String str)
	{
		if (str == null || str.equals(""))
		{
			return false;
		}
		char[] chas = str.toCharArray();
		int status = 0;
		for (int i = 0; i < chas.length; i++)
		{
			if (chas[i] != ')' && chas[i] != '(')
			{
				return false;
			}
			if (chas[i] == ')' && --status < 0)
			{
				return false;
			}
			if (chas[i] == '(')
			{
				status++;
			}
		}
		return status == 0;
	}

	

	public static int maxLength(String str)
	{
		if (str == null || str.equals(""))
		{
			return 0;
		}
		char[] chas = str.toCharArray();
		int[] dp = new int[chas.length];
		int pre = 0;
		int res = 0;
		for (int i = 1; i < chas.length; i++)
		{
			if (chas[i] == ')')
			{
				pre = i - dp[i - 1] - 1;
				if (pre >= 0 && chas[pre] == '(')
				{
					dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);
				}
			}
			res = Math.max(res, dp[i]);
		}
		return res;
	}

	public static void main(String[] args)
	{
		String str1 = "((())())";
		System.out.println(isValid(str1));
		System.out.println(maxLength(str1));

		String str2 = "(())(()(()))";
		System.out.println(isValid(str2));
		System.out.println(maxLength(str2));

		String str3 = "()(()())";
		System.out.println(isValid(str3));
		System.out.println(maxLength(str3));

	}
}

 

左神:语录

记住: 看到子串,子数组一般都是  以每个位置开头,以每个位置结尾。几乎可以解决70%。

但是,子序列却不是这样的。



               






     


  

 



   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Terry_dong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值