《編程的本質》-第二章

編程的本質第二章看得也有點稀裏糊塗,現在將自己的理解寫出來,只是爲了以後自己在回憶的時候有個學習。


第二章的主要內容將Transformation,中文意思是變換的意思。即現在有個操作F,對於變量x,F(x)就是在x上變換。如果F(x)的值域仍然在x的域中,那麼這樣的變換就可以持續進行。這樣存在三種情況:


1.  F...(F(x))一直重複下去,永遠不出現重複,那麼這個就是infinite。


2.  F...(F(x))重複到某個點以後,返回之前路徑上的某個點,那麼這個形狀是一個線連接一個圓。


3.  F...(F(x))就是一個圓。


當路徑中存在圓的時候,本章解決一個問題就是如何發現這個圓的入點(如果就是一個圓,那麼任何一個點都是入點,connection point)。這個問題主要有兩種解法:


1.  快慢指針的方法,如果路徑中存在圓,那麼用兩個指針遍歷這個圓,一個每次遞進一步,一個每次遞進兩步,這樣快指針會趕上慢指針,這樣就證明這個鏈路存在環,負責快指針會先到達這個鏈路的終點。複雜度爲O(3n)

template <typename F>
	requires(Transformation (F))
Domain(F)
collision_point_nonterminating_orbit(const Domain(F)& x, F f)
{
	Domain(F) slow = x;
	Domain(F) fast = f(x);
	while (fast != slow)
	{
		slow = f(slow);
		fast = f(fast);
		fast = f(fast);
	}
	return fast;
}

2.  採用hash的方法,將已經遍歷過的點,進行hash存儲,這樣時間複雜度爲O(nlogn),但是空間複雜度爲O(n)。


第二種方法複雜度較低,但是存在一個缺點:實際中,可能沒有足夠的空間來存取這些點。如果環特別大,這個算法不是現實。這個算法的時間複雜度很好,只有O(n)。Robert Sedgewick發明一種算法,空間複雜度是M,時間複雜度是n(1+Θ(1/sqrt(M))。



算法的分析如下:每b個存到數組裏,每個gb前面0~b個元素檢測是否已經存在。具體的內容大家可以看看它的文章


3.  第二章中還講解了如何找到環的入口問題。其實這個問題在《編程之美》或者《劍指offer》當中有,感興趣的讀者可以看看《編程之美》或者《劍指offer》這篇文章中的解釋。


本文完

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章