2020-10-31 最長公共字首【簡單題14】

話真多發表於2020-11-05

題目

在這裡插入圖片描述

解題

【思路】

最長公共字首的確定方法很明確,就是要比較字串陣列中每個字元元素的每個字母
但是比較的花樣可以有所不同,橫向比較、縱向比較、分治比較(遞迴)、二分法比較等。

這裡只給出橫向比較和縱向比較兩種方法,個人覺得比較好理解。

法一:橫向比較法

先假設第一個字串元素為最長公共字首com,然後從陣列第二個元素(i=1)開始遍歷陣列後面的元素,將每個元素的每個字元與當前最長公共字首依次比較,直至和最長公共字首出現不同的字元,更新當前的最長公共字首,進行下一個元素的比較,直至遍歷完整個陣列,迴圈結束,返回當前的最長公共字首com。

【程式碼】

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs==null || strs.length==0){
            return "";
        }

        String com = strs[0];  //開始先假設第一個元素為公共字首
        int j=0;
        for(int i=1; i<strs.length; i++){  //從陣列第二個元素開始遍歷
            if(com==""){  //當沒有公共字首的時候,停止遍歷
                break;
            }
            j=0;  //每個元素都從第一個字元開始比較
            while(j<strs[i].length() && j<com.length() && strs[i].charAt(j)==com.charAt(j)){
            //保證j在兩個字串長度以內,如果當前位置的字元相同,j++,直到出現不同的字元
            	j++;
            }
            com = com.substring(0,j);  //擷取公共字首
        }
        return com;
    }
}

法二:縱向比較法

遍歷陣列(內迴圈,迴圈次數 j 不可能超過陣列的長度),比較所有元素的第i(從i=0開始)個字元(外迴圈,迴圈次數 i 最大不可能超過第一個元素的長度),如果全部一樣,更新公共字首,i++,再次遍歷陣列,比較各個元素的第i個字元,直至i達到最短元素的長度。

【程式碼】

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs==null || strs.length==0){
            return "";
        }

        int length = strs[0].length();  //獲取第一個元素的長度,以此作為外迴圈的次數(最多迴圈length次)
        for(int i=0; i<length; i++){  //從陣列元素的第一個字元開始遍歷
           	char c = strs[0].charAt(i);  //獲取當前要比較的字元
           	for(int j=0; j<strs.length; j++){  //內迴圈,迴圈次數是strs陣列的長度
				if(i==strs[j].length() || strs[j].charAt(i)!=c){//i達到某個元素的長度或者出現不同字元
					return strs[0].substring(0,i);  //返回此時的公共字首
				}
			}
        }
        return strs[0];
    }
}

【總結】

橫向比較:先把公共字首定為第一個元素(大於等於公共字首),然後通過遍歷依次比較剩下的每個元素和公共字首,減少當前公共字首的字元個數,遍歷結束,最終找到真正的公共字首。相當於做減法
縱向比較:開始公共字首為空,每遍歷一遍元素,如果所有元素的第i個字元都相同,公共字首加上這個字元。相當於做加法

  1. 時間複雜度O(mn)。其中 m 是字串陣列中的字串的平均長度,n是字串的數量。最壞情況下,字串陣列中的每個字串的每個字元都會被比較一次。
  2. 空間複雜度O(1)。使用的額外空間複雜度為常數。

知識總結

分治、二分查詢具體實現檢視LeetCode:
https://leetcode-cn.com/problems/longest-common-prefix/solution/zui-chang-gong-gong-qian-zhui-by-leetcode-solution/

strs[0].charAt(i); //獲取字串的第i個字元
strs[0].substring(0,i); //擷取字串的第0到第i-1個字元
int length = strs[0].length(); //獲取字串的長度
int length = strs.length; //獲取陣列的長度

相關文章