子序列

判斷子序列

給定字符串 st ,判斷 s 是否為 t 的子序列钓株。
你可以認為 st 中僅包含英文小寫字母。字符串 t 可能會很長(長度 ~= 500,000)吊骤,而 s 是個短字符串(長度 <=100)捧存。

字符串的一個子序列是原始字符串刪除一些(也可以不刪除)字符而不改變剩余字符相對位置形成的新字符串捷绒。(例如懦铺,"ace""abcde"的一個子序列捉貌,而"aec"不是)。

示例 1:

s = "abc", t = "ahbgdc"
返回 true.

示例 2:

s = "axc", t = "ahbgdc"
返回 false.

方法一:雙指針
i指向短串s,j指向長串t

  • s[i]=t[j]趁窃,匹配i++,j++
  • s[i]!=t[j] 牧挣,不匹配,用s[i]去匹配t[j]之后的元素,j++
    如果i移動到了末尾醒陆,說明所有字符都匹配了
public boolean isSubsequence(String s, String t) {
    int i=0;
    int j=0;
    while (i<s.length()&&j<t.length()){
        if(s.charAt(i)==t.charAt(j)){
            i++;
            j++;
        } else {
            j++;
        }
    }
    return i==s.length();
}

方法二:動態(tài)規(guī)劃
dp[i][j]表示s串到i位置與t串到j位置最長相同子序列的長度

  • 當si =t j瀑构,dp[i][j]=dp[i-1][j-1]+1
  • 當si !=t j,表示要刪除tj,則dp[i][j]=dp[i][j-1]
public boolean isSubsequence(String s, String t) {
    int m = s.length(), n = t.length();
    int[][] dp = new int[m + 1][n + 1];
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (s.charAt(i) == t.charAt(j)) {
                dp[i + 1][j + 1] = dp[i][j] + 1;
            } else {
                dp[i + 1][j + 1] = dp[i + 1][j];
            }
        }
    }
    return dp[m][n] == m;
}

通過刪除字母匹配到字典里最長單詞

示例 1:

輸入:s = "abpcplea", d = ["ale","apple","monkey","plea"]
輸出: "apple"

示例 2:

輸入:s = "abpcplea", d = ["a","b","c"]
輸出: "a"

方法一:暴力回溯(超時)

public String findLongestWord(String s, List<String> d) {
    StringBuilder sb=new StringBuilder();
    findHelper(sb,s,d,0);
    return ans;

}
private String ans="";

public void findHelper(StringBuilder sb,String s, List<String> d,int index){
    if(index==s.length()){
        String res=sb.toString();
        if(d.contains(res)){
            if (res.length() > ans.length() ||
                (res.length() == ans.length() && res.compareTo(ans)<0)) {//注意字典序列
                ans = res;
            }
        }
    } else {
        sb.append(s.charAt(index));//不刪
        findHelper(sb,s,d,index+1);
        sb.deleteCharAt(sb.length()-1);//刪
        findHelper(sb,s,d,index+1);
    }
}

方法二:轉換成判斷字典是否是串的子序列

因為要求返回最小的字典序列刨摩,所以需要先對字典排序

public String findLongestWord(String s, List<String> d) {
    d.sort((o1, o2) -> o1.length() != o2.length() ? o2.length() - o1.length() : o1.compareTo(o2));
    String ans = "";
    for (String value : d) {
        if (isSubsequence(value, s)) {
            return value;
        }
    }
    return ans;
}

public boolean isSubsequence(String s, String t) {
    int i=0;
    int j=0;
    while (i<s.length()&&j<t.length()){
        if(s.charAt(i)==t.charAt(j)){
            i++;
            j++;
        } else {
            j++;
        }
    }
    return i==s.length();
}

時間復雜度:O(d×m×logd+d×(m+n))寺晌,其中 d 表示dictionary 的長度,m 表示 s 的長度澡刹,n 表示 dictionary 中字符串的平均長度

方法三:在是子序列的時候再排序

public String findLongestWord(String s, List<String> d) {
    String ans="";
    for (String word:d){
        if(isSubsequence(word,s)){
            if(word.length()>ans.length()||(word.length()==ans.length()&&word.compareTo(ans)<0)){
                ans=word;
            }
        }
    }
    return ans;
}

時間復雜度:O(d×(m+n))折剃,其中 d 表示dictionary 的長度,m 表示 s 的長度像屋,n 表示 dictionary 中字符串的平均長度

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市边篮,隨后出現的幾起案子己莺,更是在濱河造成了極大的恐慌,老刑警劉巖戈轿,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凌受,死亡現場離奇詭異,居然都是意外死亡思杯,警方通過查閱死者的電腦和手機胜蛉,發(fā)現死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來色乾,“玉大人誊册,你說我怎么就攤上這事∨担” “怎么了案怯?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澎办。 經常有香客問我嘲碱,道長,這世上最難降的妖魔是什么局蚀? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任麦锯,我火速辦了婚禮,結果婚禮上琅绅,老公的妹妹穿的比我還像新娘扶欣。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布宵蛀。 她就那樣靜靜地躺著昆著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪术陶。 梳的紋絲不亂的頭發(fā)上凑懂,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音梧宫,去河邊找鬼接谨。 笑死,一個胖子當著我的面吹牛塘匣,可吹牛的內容都是我干的脓豪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼忌卤,長吁一口氣:“原來是場噩夢啊……” “哼扫夜!你這毒婦竟也來了?” 一聲冷哼從身側響起驰徊,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤笤闯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后棍厂,有當地人在樹林里發(fā)現了一具尸體颗味,經...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年牺弹,在試婚紗的時候發(fā)現自己被綠了浦马。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡张漂,死狀恐怖晶默,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情航攒,我是刑警寧澤荤胁,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站屎债,受9級特大地震影響仅政,放射性物質發(fā)生泄漏。R本人自食惡果不足惜盆驹,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一圆丹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躯喇,春花似錦辫封、人聲如沸硝枉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妻味。三九已至,卻和暖如春欣福,著一層夾襖步出監(jiān)牢的瞬間责球,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工拓劝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留雏逾,地道東北人。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓郑临,卻偏偏與公主長得像栖博,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子厢洞,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354