[牛客題霸-高頻算法面試題]字符串距離計算

題目描述

給定兩個長度相等的,由小寫字母組成的字符串S1和S2,定義S1和S2的距離爲兩個字符串有多少個位置上的字母不相等。數組

如今牛牛能夠選定兩個字母X1和X2,將S1中的全部字母X1均替換成X2。(X1和X2能夠相同)spa

牛牛但願知道執行一次替換以後,兩個字符串的距離最少爲多少。code

示例1

輸入:"aaa","bbb"blog

輸出:0字符串

說明:牛牛能夠將S1中的字符'a'所有替換成字符'b',這樣S1就變成了"bbb",那麼S1和S2的距離就是0string

示例2

輸入:"aabb","cdef"io

輸出:3class

說明:一種可行的方案是將S1中的字符'a'所有替換成字符'c',那麼S1變成了"ccbb",和S2的距離是3變量

 

思路

使用字典count[26][26]記錄S一、S2中的字符對。count[X1][X2]表示S1和S2中相同位置的字符對個數,即有多少個i使得S1[i]==X1,S2[i]==X2成立,這個值掃描一遍字符串便可獲得;掃描的同時記錄替換前的原始距離origin。而後枚舉全部可能的X一、X2,此時的距離爲origin+count[X1][X1]-count[X1][X2],用一個變量min來保存結果,每次枚舉時進行更新。遍歷

 

origin+count[X1][X1]-count[X1][X2]這個式子可能比較難理解,不要緊,咱們舉個例子:

如今給出兩個字符串aabbcb和aacbec,第一次遍歷字符串的時候,能夠依次獲得6個字符對,根據字符對個數,對count數組初始化;同時根據題幹中的定義:距離爲兩個字符串有多少個位置上的字母不相等,咱們能夠獲得origin=3,也就是圖中連線的3個字符對:b-c、c-e、b-c

枚舉的時候,咱們以X1=b、X2=c爲例,也就是將S1中的全部字母b均替換成c(圖中紅色標記的c爲替換的字符),對比上下兩個S一、S2,咱們能夠發現此次替換的影響範圍是S1中原來爲b的位置而且S2中該位置的字符是c或b,也就是說對a-a和c-e這兩個字符對是不產生影響的(若是存在相似於b-a、b-d這樣的字符對也是不影響的,由於替換後c-a、c-d依然包含在origin中)。

那麼來看影響範圍內的字符對:b-c和b-b,替換後變成了c-c和c-b,這時產生了一個新的能夠算入距離的字符對c-b(圖中紅線鏈接處),同時c-c不符合距離的定義,要從原始距離中刨去(圖中打叉的地方)。有多少個須要算入和刨去的字符對呢?由於count數組記錄的是替換前的狀態,因此就要看這些字符對是由誰「變」來的:新算入的字符對原來是X1-X1,刨去的字符對原來是X1-X2,因此新的距離爲origin+count[X1][X1]-count[X1][X2]

JAVA代碼

public class Solution {
    /**
     * 計算最少的距離
     * @param S1 string字符串 第一個字符串
     * @param S2 string字符串 第二個字符串
     * @return int整型
     */
    public int GetMinDistance (String S1, String S2) {
        int[][] count = new int[26][26];
        int origin = 0;
        for(int i = 0; i < S1.length(); i++) {
            char ch1 = S1.charAt(i), ch2 = S2.charAt(i);
            count[ch1 - 'a'][ch2 - 'a'] ++;
            if(ch1 != ch2) origin++;
        }
        int min = S1.length();
        for(int i = 0; i < 26; i++) {
            for(int j = 0; j < 26; j++) {
                min = Math.min(min, origin + count[i][i] - count[i][j]);
            }
        }
        return min;
    }
}
相關文章
相關標籤/搜索