Java教程

【回溯DFS】【记忆化搜索】97.交错字符串

本文主要是介绍【回溯DFS】【记忆化搜索】97.交错字符串,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

97. 交错字符串 - 力扣(LeetCode)

根据题意,就是组成S3的字符串,必须是由S1 S2 组成。而且顺序还得是一样的。

也就是保持S1 S2的原有顺序组成S3。

然后判断,是不是S3是不是由S1 S2组成?

那么我们怎么做呢?

s1:aabcc

s2: dbbca

s3:aadbbcbcac

按照上面的例子以及题意。

就是遍历S3,拿着S3的每位字符去 S1 S2中,按着顺序找

也就是说,有3个遍历的index, i , j,k ,分别代表着遍历s1,s2,s3

如果s1[i] == s3[k] 那么 i ,k 均往后移动一位。

如果s2[j] == s3[k] ,j,k往后移动一位。

然后如果k遍历到头了,i==s1.length j=s2.length ,那么说明s3就是由s1 s2组成。

问题来了。如果s1[i]==s2[j] ==s3[k] 呢? 我到底选择s1 的i,k,往后移动 ,还是s2的j,k往后移动?

我不知道怎么选择啊,这就涉及到决策了。

涉及到决策了,那么直接DFS,BFS,回溯,DP 中试吧。

那么这道题,很明显,就是如果我 选择s1的i,k往后移动,按照他的这个分支往下走,他有可能成功,有可能不成功啊。

如果不成功,直接恢复现场就行了啊。

那么我可以遍历每一种选择,那么这是什么啊?回溯/DFS啊。

OK,涉及到了回溯,我们必须想到 树形结构,必须得构建出树形结构。

那么此题采用回溯,主要决策点在于,我选择选择s1 i,k 往后移动,还是 s2 j,k往后移动。

三个决策点对吧。
image
那么跳出条件是什么呢?

  • 很明显: i==s1.length&& j ==s2.length&&k ==s3.length

那么如果继续往下走,是成功的,我们可以返回true.

如果不成功,返回false就行啊 。

class Solution
{
    boolean[][] visited;
    public boolean isInterleave( String s1, String s2, String s3 )
    {
        if( s1.length()+s2.length()!=s3.length())
        {
            return false;
        }
        visited = new boolean[s1.length()+1][s2.length()+1];
        return backtract(s1,s2,s3,0,0,0);

    }
    public boolean backtract(String s1, String s2, String s3,int i,int j,int k)
    {
        // 跳出条件
        if(i==s1.length()&&j==s2.length()&&k==s3.length())
        {
            return true;
        }
        //为了防止计算过的计算,
        if(visited[i][j])
        {
            return false;
        }
        visited[i][j]=true;
        // 如果按着i,k 往后移动走,而且这个方向还能走通,那么就返回true;
        if(i<s1.length()&&s1.charAt(i)==s3.charAt(k)&&backtract(s1,s2,s3,i+1,j,k+1))
        {
            return true;
        }
        // 如果按着j,k 往后移动的方向走,而且这个方向能走通,就返回true;
        if(j<s2.length()&&s2.charAt(j)==s3.charAt(k)&&backtract(s1,s2,s3,i,j+1,k+1))
        {
            return  true;
        }
        // 如果走不通嘛。肯定返回false了;
        return false;
    }
}
这篇关于【回溯DFS】【记忆化搜索】97.交错字符串的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!