1. 程式人生 > 其它 >【回溯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往後移動。

三個決策點對吧。

那麼跳出條件是什麼呢?

  • 很明顯: 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;
    }
}