【Leetcode】161. One Edit Distance

題目地址:

https://leetcode.com/problems/one-edit-distance/

給定兩個字符串sstt,問ss可否由下列三種變換變爲tt
1、在ss中插入一個字符;
2、在ss中刪除一個字符;
3、在ss中替換一個字符。
如果可以就返回true,否則返回false。

首先排除掉sstt長度差大於等於22或者sstt相等的情況,這兩種情況下ss都是不可能變爲tt的,直接返回false。

接着,從左向右同時掃描sstt,如果遇到相同字符,那就繼續掃描,否則,如果遇到不同字符,那麼ss必然要經過三種變換其中的一種,來”修復“這種不同,而用哪一種變換取決於sstt的長度的比較。如果sstt一樣長,那就是變換33,如果sstt長,那就是變換22,如果sstt短,那就是變換11;無論哪一種,都只需要繼續比較sstt的剩餘子串就可以了。代碼如下:

public class Solution {
    public boolean isOneEditDistance(String s, String t) {
    	// 如果兩個字符串長度之差大於等於2,或者兩個字符串相等,
    	// 那s絕對無法通過一次變換變爲t,直接返回false
        if (Math.abs(s.length() - t.length()) >= 2 || s.equals(t)) {
            return false;
        }
        
        int i = 0, j = 0;
        while (i < s.length() && j < t.length() && s.charAt(i) == t.charAt(j)) {
            i++;
            j++;
        }
        
        if (s.length() < t.length()) {
            return s.substring(i).equals(t.substring(j + 1));
        } else if (s.length() > t.length()) {
            return s.substring(i + 1).equals(t.substring(j));
        } else {
            return s.substring(i + 1).equals(t.substring(j + 1));
        }
    }
}

時間複雜度O(n)O(n),空間O(1)O(1)

算法正確性證明:
首先如果兩個字符串長度大於11或者兩個字符串相等的時候,返回false,這一點沒有問題。
接下來,當while循環退出時,有三種可能性,
1、ii已經走到頭;
2、jj已經走到頭;
3、s[i]t[j]s[i]\ne t[j]
如果ss的長度小於tt的話,那麼要麼11要麼33,並且tt的長度比ss11;如果是11,那麼說明t[j+1,...]t[j+1,...]應該是空串,也就是tt刪去最後一個字母應該會變成ss;如果是33,那麼就要把ssii的位置新加一個字母,接着比ss之後的子串和t[j+1,...]t[j+1,...]是否相等。無論怎樣,都可以寫爲return s.substring(i).equals(t.substring(j + 1));
如果ss的長度大於tt的話,證明是類似的;至於兩者長度相等時的證明是顯然的。綜上,算法正確。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章