leetcode 87.Scramble String(Java 实现)

1.此题主要的难度在于难以区分割开的点是在哪一点上,所以必然要通过遍历的方法将所有可能割开的点遍历一遍。

2.s1割开的点可以形成两个字串(s1.substring1(0,i),s1.substring2(i+1,s1.size-1)),其与s2割开的字串(s1.substring1(0,i),s1.substring2(i+1,s1.size-1))要想相互匹配必须满足下面的条件。

  • 假如在该点两边的字符串没有交换,则s1.substring(0,i)必须和s2.substring(0,i)匹配,同时s1.substring(i+1,s1.size-1)必须和s2.substring(i+1,s2.size-1)匹配.

或者

  • 假如在该点两侧的字符串交换了,则s1.substring(0,i)必须和s2.substring(s.size-i,s.size-1)匹配,同时s1.substring(s1.size-i.s1.size-1)必须和s2.substring(0,i)匹配.

3.如上分析,就可以将上述的大问题分解为小问题,运用递归的方法再对两侧的字串进行遍历。在这里特别要进行剪枝操作,不然会超时,具体的就是要看相互匹配的字串所包含的字符及长度是否相等,如果不相等,直接返回false,这里用hash表进行的此项剪枝。

代码如下:

public static boolean isScramble(String s1, String s2) {
		if(s1==null&&s2==null) return true;
        return match(s1,s2);
    }
	public static boolean match(String s1, String s2)
	{
		if(s1.length()==1&&s1.equals(s2)) return true;
		if(s1.equals(s2)) return true;
		char[] str1 = s1.toCharArray();
		char[] str2 = s2.toCharArray();
		Map<Character,Integer> m1 = new HashMap<>();
		Map<Character,Integer> m2 = new HashMap<>();
		for(int i=0;i< s1.length();i++)
		{
			m1.put(str1[i], m1.getOrDefault(str1[i], 0)+1);
			m2.put(str2[i], m2.getOrDefault(str2[i], 0)+1);
		}
		for(int i=0;i< s1.length();i++)
		{
			if(m1.get(str1[i])!= m2.getOrDefault(str1[i],0)) return false;
			if(m1.getOrDefault(str2[i], 0)!=m2.get(str2[i])) return false;//hash表进行剪枝
		}
		for(int i=1 ;i< s1.length();i++)
		{//对可能交换的点进行遍历,再进行递归。
			if((match(s1.substring(0,i),s2.substring(0,i))&& match(s1.substring(i,s1.length()),s2.substring(i ,s2.length())))||(match(s1.substring(0,i),s2.substring(s1.length()-i,s1.length()))&& match(s1.substring(i,s1.length()),s2.substring(0 ,s2.length()-i))))
				return true;
		}
		return false;
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值