算法快學筆記(一):算法入門

1. 算法的定義

“算法”一詞在不同的書籍以及網站上可能會存在一些差異,但是下面的定義個人覺得最爲貼切:

1. 算法代表着用系統的方法描述解決問題的策略機制
2. 能夠對一定規範的輸入,在有限時間內獲得所要求的輸出
3. 一個算法的優劣可以用空間複雜度與時間複雜度來衡量

2. 論優秀算法的重要性

在很多場景下,數據規模越大,越能體現優秀算法的價值,接下來將以猜數遊戲爲例進行說明優秀算法的重要性。

假設 A隨便想了一個1到100中的某個數字讓B猜,B可以有兩種方案:

  1. 簡單查找:從1開始猜,一直猜到A想的數字爲止。
  2. 二分查找:一半一半的猜,先猜50,如果小了,這時候就排除了1-50的數字!。接下來,你猜75,如果大了,就排除了75-100。以此類推。

接下來對兩種方式進行說明與比較

2.1 簡單查找

該方法的優點是簡單,只需要從1一個個的猜,就一定能猜到。但是如果猜測數字的範圍非常的大,且猜的數字非常靠後,將會使用較多的時間。

2.2 二分查找

二分查找是一種算法,其輸入是必須是一個有序的元素列表。每次猜都從列的中間元素開始,如果大了,就過濾掉比猜測值小的那一半數字,反之亦然。

實現代碼如下:

// 使用二分查找法,在有序列表intList中查找target,返回對應的索引
func BinarySearch(intList []int, target int) int {
	start := 0
	end := len(intList) - 1
	for {
		if end <= start {
			break
		}
		mid := int((start + end) / 2)
		if intList[mid] == target {
			return mid
		}
		// 如果mid處的值大於目標值,就在mid之前的數據中搜索
		if intList[mid] > target {
			end = mid-1
		}
		// 如果mid處的值大於目標值,就在mid之後的數據中搜索
		if intList[mid] < target {
			start = mid+1
		}
	}
	return -1
}

2.3 簡單查找VS二分查找

如果列表包含100個數字,簡單查找的方式可能要找100次才能找到結果,而二分查找法由於每次查找都會過濾掉一半的數據,因此最多只需要7次(log100)就能找到結果。這個級別的數據,結果看起來差距還不是很大。

如果列表包含40億個數字,簡單查找的方式可能要找40億次才能找到結果,而二分查找法最多只需要32次(log40億)就能找到結果。這個級別的數據,差距就比較可觀了。

假設B一秒鐘能猜10個數字,通過簡單查詢要猜4629(40億/10 秒)天,而通過二分查找只需要4秒(log40億/10 秒)。

有上面的例子可以看出,一個優秀的算法是多麼的重要!

注意:log指的都是log2

大O表示法

大O表示法指出了算法有多快(O爲操作數:Operations)。例如,假設列表包含n個元素。簡
單查找需要檢查每個元素,因此需要執行n次操作,使用大O表示法,
這個運行時間爲O(n)。二分查找需要執行log n次操作,使用大O表示法的運行時間爲 O(log n)。

關於大O表示法有以下幾點需要注意:

  1. 大O表示法讓你能夠比較操作數,它指出了算法運行時間的增速,代表隨着數據集的增加,算法所需時間的變化趨勢。
  2. 大 O 表示法指出了最糟情況下的運行時間

下面按從快到慢的順序列出了常見的5種大O運行時間:

  • O(log n),也叫對數時間,這樣的算法包括二分查找。
  • O(n),也叫線性時間,這樣的算法包括簡單查找。
  • O(n * log n),這樣的算法包括快速排序(一種非常快的排序算法)
  • O(n^2),這樣的算法包括選擇排序(一種非常慢的排序算法)。
  • O(n!),這樣的算法包旅行商問題的解決方案-一種非常慢的算法。

總結

  • 二分查找的速度比簡單查找快得多。
  • O(log n)比O(n)快。需要搜索的元素越多,前者比後者就快得越多。
  • 算法運行時間是從其增速的角度度量的。
  • 算法運行時間用大O表示法表示。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章