查找第一個不重復的字符問題


查找第一個不重復的字符問題

最近去面了一次試,最后面到一次算法題。說實話,以前去面試很少面到算法題,可能和面試的職位有關的。

相當常見的題目,說是找出一堆數字中第一個出現的不重復的數字。當時沒理解清題目,想成了是只有一個不重復的數字。后來面試官跟我說明清楚了題目之后,瞬間沒了啥思路,也沒答好。后來回去路上一想,感覺也相當簡單。

這個題目原題是 “找出一個字符串(只包含英文,不考慮中文等字符問題)中第一個不重復的數字”。

如果不做限制,很容易想到的方法是:從頭開始遍歷一下字符串,針對每個字符再從開開始查找是否有重復的,找到第一個整個字符串中沒有重復的字符。當然時間復雜度為 O(n2),肯定不是最優解。

比較普遍的方法是犧牲一定的空間復雜度,用一個數組暫存一下字符串中每個字符出現的次數,再重新從頭開始遍歷字符串,找到次數為 1 的字符返回。

代碼如下:

func searchFirstNotDuplicatedChar(str string) string {
	cnts := make([]int, 256)

	for _, s := range str {
		cnts[s]++
	}

	for _, s := range str {
		if cnts[s] == 1 {
			return string(s)
		}
	}

	return ""
}

復雜度就是遍歷了兩次字符串,時間復雜度為 O(n)。已經相當可以了。

當然面試官給我出的原題是一堆數字,不是字符串(這和我面試時提到的以往的工作有關,處理批量數據)。因為我們知道英文字符處於 ASCII 碼表中很容易做對應。而數字類數據的話因為不知道范圍,很難用一個數組來做存儲對應,所以這個我們可以考慮用一個 Map。我們知道 Hash 方法是很快速的,所以幾乎不存在什么性能問題。

這個為了簡便,只考慮了整形 int 類型的數據。

func findFirstNotDuplicatedInt(nums []int) int {
	cnts := make(map[int]int)

	for _, num := range nums {
		cnts[num]++
	}

	for _, num := range nums {
		if cnts[num] == 1 {
			return num
		}
	}

	return -1
}

就稍微改了一下,依然是 O(n)。差不多是這個。據說還有使用位運算的算法可以做到,暫時沒研究,感覺這樣已經很不錯了。

對於算法題,面試和自己平常在電腦上做,感覺真是不一樣的。面試中包含各種不確定的因素,而且人也容易產生緊張感,往往有些平常很容易想到的東西面試中就犯迷糊了。復雜的算法由於平時幾乎不太用到,也是看過就很容易忘。所以我覺得培養一種對於算法的直覺相當重要。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM