Java演算法面試題(008) 字串反轉

劉近光發表於2017-12-19

簡介

這是一個Java面試中被經常問及的問題,也有很多種實現方式。我在這裡一一列出,如果你有更好的解法,也可留言。

解法一:首尾字元調換順序

由於String物件是隻讀型別,不能對其進行直接操作,因此需要轉換成字元陣列,然後調換字元陣列中的各個字元。

	public String reverse(String str) {
		//異常情況處理		
		if (str == null || str.length() <= 1) {
			return str;
		}

		//調換首尾字元
		char[] array = str.toCharArray();
		int len = str.length();
		for (int i = 0; i < len/2; i++) {
			char temp = array[i];
			array[i] = array[len - 1 - i];
			array[len - 1 - i] = temp;
		}

		//產生新字串
		return new String(array);
	}
這個演算法實現需要注意的時,遍歷時,到達中間節點遍歷結束;如果操作遍歷到尾部,相當於將字串首尾調換後,又調換回原來的狀態。

解法二:遞迴實現

遞迴演算法的話可以每次將字串首部字元追置換到尾部,並拼接成新的字串;當字串裡僅有一個字元存在時,結束遞迴呼叫。

	public String reverse(String str) {
		//異常情況處理		
		if (str == null || str.length() <= 1) {
			return str;
		}
		
		//遞迴實現
		return reverse(str.substring(1)) + str.charAt(0);
	}

解法三:使用StringBuffer的reverse()函式

藉助StringBuffer/StringBuilder的reverse()函式,可以實現字串的反轉,但需要在StringBuffer/StringBuilder和String型別之間進行轉換。這裡需要注意一下StringBuffer和StringBuilder的差異:StringBuffer是執行緒安全的,StringBuilder是非執行緒安全的。

	public String reverse3(String str) {
		//異常情況處理		
		if (str == null || str.length() <= 1) {
			return str;
		}		
		
		StringBuilder stringBuilder = new StringBuilder(str).reverse();
		
		return stringBuilder.toString();
	}

解法四:使用棧的方法實現

字串反轉過程,有點類似堆疊的操作,將字串push到堆疊中,然後在pop出來,採用先進後出,實現字串的反轉。

	public String reverse(String str) {
		//異常情況處理		
		if (str == null || str.length() <= 1) {
			return str;
		}	
		
		char[] array = str.toCharArray();
		Stack<Character> stack = new Stack<Character>();
		for (char c:array) {
			stack.push(c);
		}
		
		//使用length暫存堆的大小,因為遍歷的過程中,會改變堆的大小
		int length = stack.size();
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < length; i++) {
			builder.append(stack.pop());
		}
		
		return builder.toString();
	}
在這個實現中,使用了StringBuilder來儲存字串。如果你使用String型別做拼接,會影響效率,想想為什麼?

總結

這裡列出的四種比較經典的字串反轉的實現方法,從效率上分析,實現1和效率3效率應該比較高,這塊需要檢視一下StringBuilder的原始碼。但如果面試時,能列出這幾種演算法並對比一下,應該會給面試官比較深的印象。

相關文章