Chapter 2 | Linked Lists--移除未排序連結串列中的重複項

selfimpr1991發表於2013-12-03
2.1    Write code to remove duplicates from an unsorted linked list.
         FOLLOW UP,How would you solve this problem if a temporary buffer is not allowed?

譯文:從一個未排序的連結串列當中移除重複的項。進一步的,如果不允許使用臨時的快取,你講如何解決這個問題?

又是移除重複項,有沒有一種似曾相識的感覺,不錯前面就討論過判斷字串的唯一性和字串的去重,不過這裡不允許使用臨時的快取(在後面會討論可以使用臨時快取的情況),考慮連結串列的特性,我們就逐步遍歷,記錄下當前值,然後遍歷後面的數,如果與記錄的值相同,則刪除,直至遍歷到連結串列尾。再然後從下一位置又進行新一輪的遍歷,重複前面的操作,時間複雜度為O(n^2)。連結串列的一大優點就是新增刪除元素簡單,這裡我們可以充分利用這一特點。預設為這是單向連結串列。程式碼如下

/*把連結串列中後面的一次和前面的值比較,發現相同就刪除*/
void removeduplicate(LINK_NODE* pHead)
{
	if (NULL == pHead)
		return;
	LINK_NODE *p, *q;
	LINK_NODE *c = pHead->next;

	while (c)
	{
		p = c;
		q = c->next;
		int value = c->data;
		while (q)
		{
			if (q->data == value)
			{
				LINK_NODE *t = q;
				p->next = q->next;
				q = p->next;
				delete t;
			}
			else
			{
				p = q;
				q = q->next;
			}
		}
		c = c->next;
	}
}
這裡假設大家對連結串列有足夠的瞭解,並且能夠自由編寫出連結串列這一資料結構,所以就直接貼區域性程式碼了。

如果允許使用臨時的快取,那麼可沿用前面的思想,加以修改可達到我們的目的。下面給出連結

判斷字串的唯一:http://blog.csdn.net/yeswenqian/article/details/16942185

字串的去重(下半部分):http://blog.csdn.net/yeswenqian/article/details/16951383

這裡我們討論允許使用臨時快取的情況,即可以藉助額外的儲存空間,我們就開闢一個陣列來儲存一個元素的出現情況,這裡不同的是,我們不知道這個連結串列中的資料型別是什麼,換言之,就是如果用一般陣列來模擬的話,我們不知道需要開闢陣列的空間大小以及是否能夠通過開闢一般陣列來實現。假如連結串列中的資料型別是int型,包含負值,那麼這就不能像前面說的那樣的採用“數值代替位置”的情況來開闢陣列了。最大值為32768,要是開闢一個這麼大的陣列,勢必會浪費大量的空間。在這種情況下還沒糾結出一個很好的實現方法,雜湊表是一個方法。

考慮到這是一道面試題,我們就採用雜湊表來實現,暫時不考慮雜湊錶帶來的問題,即能將任意整數hash到一定範圍,不會出現下標為負值和hash鍵值衝突的情況。這裡採用的是常用的雜湊表方式--“拉鍊法”,就是連結串列的陣列

void removeduplicate(LINK_NODE* pHead)
{
	LINK_NODE *p = pHead->next;  //指向第一個資料節點
	LINK_NODE *q = p->next;
	memset(hash, 0, sizeof(hash));
	hash[p->data] = 1;   //置1,表示該數已經出現過
						 //第一個數肯定保留
	while (q != NULL)
	{
		if (hash[q->data])
		{
			LINK_NODE *t = q;
			p->next = q->next;
			q = p->next;
			delete t;
		}
		else
		{
			hash[q->data] = 1;
			p = q;      //q,p相鄰
			q = q->next;
		}
	}
}
如果考慮雜湊錶帶來的問題呢,比如鍵值衝突以及下標出現負值,這裡針對上面那種形式的雜湊表談一下思路,對負值下標進行處理,取反比較方便,對於鍵值衝突,通過鍵值查詢對應雜湊表陣列,然後再遍歷該陣列位置指向的連結串列,看是否有重複值。這樣處理在一定程度上減少了時間複雜度,也能夠處理由雜湊錶帶來的一些問題。

相關文章