幾道資料結構和演算法題的回顧總結

2021-08-20 11:08:26 字數 3285 閱讀 9338

這週做了一些牛客網上劍指offer的題.選取幾道個人覺得比較典型,有意思的題拿出來進行分析.

1.鍊錶中環的入口節點

乙個鍊錶中包含乙個環,請找出這個環的入口節點.

分析:一般答案不那麼顯然的鍊錶題,大多都可以用這種方法解決:派出兩個指標幹活.這道題也是如此,具體是派出快慢2個指標同時出發,快指標一次走兩步,慢指標一次走一步,找出他們第一次相遇的位置,然後就比較容易操作了,之後就是這是乙個小學數學的行程問題了,這裡就不多贅訴,指標的題需要注意下臨界條件,這道題還好.

class solution //判斷是否是環,其實如果題目出的正確的話可以不用這個條件判斷

else

return

null;

}//指標相遇後重新派出兩個速度一樣的指標再度相遇,相遇後的位置便是環的入口

listnode *p1 = head;

listnode *p2 = slow;

while (p1 != p2)

return p1;

}};

2.刪除鍊錶中重複的節點

題目描述

在乙個排序的鍊錶中,存在重複的結點,請刪除該鍊錶中重複的結點,重複的結點不保留,結果返回煉表頭指標。

分析:乍看之下是一道思路非常明確很溫柔的題,實際上這道題坑了我很久才弄出來,說不定有更簡單的思路(不包括重新建乙個鍊錶哈,只能在原始鍊錶上操作),不過我暫時懶得去看答案了,心累…具體思路也是需要排出兩個指標,前鋒負責探路找出重複的節點,殿後的就負責把刪除節點後的鍊錶重新拼接起來,同時還需要設定乙個判斷是否是重複節點bool值…還是直接上程式吧,這道題的細節操作和臨界處理上都花了我不少時間,很難語言描述清楚.

class solution 

else

if (p2->val == p2->next->val)

else

}//收尾的臨界情況,漏了也會報錯

if (issame ==

true)

p1->next =

null;

return headnew->next;

}};

補充.後來看了下人家的**,用的是遞迴,遞迴就簡單多了,不管是思想上還是**上都更簡潔,下面給出遞迴的**:

class solution 

head->next = deleteduplication(p->next);

return head;

}};

3.二叉樹的下乙個節點

給定乙個二叉樹和其中的乙個結點,請找出中序遍歷順序的下乙個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指標。

分析:1.若該節點包含右子樹,那麼它的下乙個節點必然是這個右子樹中的最左邊的節點.2.若該節點無右子樹,那麼它的下乙個節點只能是它的父節點或往上的節點.這時候又要分類:如果它正好是它父節點的左子節點,那麼它的父節點就是它的下乙個節點,如果不是,那麼只能繼續向上回溯.

class solution 

treelinknode* getrightdadnode(treelinknode* node)

treelinknode* getnext(treelinknode* pnode)

else

}};

4.序列化二叉樹

請實現兩個函式,分別用來序列化和反序列化二叉樹

分析:這題採用的是前序遍歷,對於空節點處用0xffffffff進行補足,思想是非常簡單的遞迴,但是反序列化的具體操作卻不是那麼容易,個人認為是二叉樹的遞迴思想中難度最高的題之一了.這道題是看的答案,這裡盜一波人家的**.

class solution 

}treenode* dfs2(int* &p)

treenode* res =new treenode(*p);

p++;

res->left=dfs2(p);

res->right=dfs2(p);

return res;

}char* serialize(treenode *root)

treenode* deserialize(char *str)

};

5.資料流中的中位數

如何得到乙個資料流中的中位數?

分析:輸入乙個資料流,實時的計算出資料流的中位數.可以分別建立乙個大頂堆和小頂堆,使得二者各存一半的資料,且大頂堆中的最大值小於等於小頂堆中的最小值,這樣的話中位數始終都是從大頂堆和小頂堆中的top處誕生的,如資料流[1,3,2,4],輸入後在大頂堆中就是[2,1],在小頂堆中就是[3,4],所以中位數就是(2+3)/2=2.5.具體操作見程式.為什麼要用大頂堆和小頂堆?因為在給定的排序陣列中插入數字可以用頂堆的思想達到o(logn)的複雜度.(我怎麼感覺二分法也是logn的複雜度,估計是理解不夠深刻…)

class solution 

}k++;

}double getmedian()

else

return (float(l.top() + g.top())/2);

}};

6.機械人的運動範圍

地上有乙個m行和n列的方格。乙個機械人從座標0,0的格仔開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數字之和大於k的格仔。 例如,當k為18時,機械人能夠進入方格(35,37),因為3+5+3+7 = 18。但是,它不能進入方格(35,38),因為3+5+3+8 = 19。請問該機械人能夠達到多少個格仔?

分析:簡單來說就是從起點出發,每次遞迴地向四個方向前進,如果在某個方向遇到停止條件,那麼便在這個方向上便停止,直到所有前進的路勁都達到停止條件…

class solution 

return t;

}int count(int thr, int i, int j, int rows, int cols,vector

>& vis)

}int movingcount(int threshold, int rows, int cols)

};

幾道資料結構的演算法題

一問題 給定一組字串,要求求出乙個最短的字串使得它包含所有給出的字串。比如 a bc ca 輸出應該是 bca 2 按照陣列len的記錄長度,在剩下的字串中找出記錄長度最長的 字串,a.如果這個字串包含在string中,該字串已被包含,轉2 b.如果這個字串的長度是1,將該字串與string連線,該...

資料結構幾道程式設計題

先將其中乙個鍊錶的鏈頭按到另乙個鍊錶的尾部,如果他們有交集則會構成乙個環,題目等價於找鍊錶中的環的起始結點。找到後將鍊錶還原。一.兩個長鍊表求交點 考慮環 public listnode getintersectionnode listnode heada,listnode headb listno...

回顧資料結構與演算法1

資料結構 儲存資料的不同方式 演算法 同一問題不同的解決方法 陣列 演算法 每次插入需分配新空間 插入慢 查詢快 鍊錶 演算法 每次插入指標指向即可 插入快 查詢慢 如何選擇演算法 大o表示法 1 時間測算 時間複雜度 big o long before system.currenttimemull...