1. 程式人生 > >【連結串列】C++刪除連結串列中重複的結點

【連結串列】C++刪除連結串列中重複的結點

題目: 在一個排序的連結串列中,存在重複的結點,請刪除該連結串列中重複的結點,重複的結點不保留,返回連結串列頭指標。 例如,連結串列1->2->3->3->4->4->5 處理後為 1->2->5 注意要刪除的是所有重複的,而不是刪除多餘的。開始理解成1-2-3-4-5,事實證明全部刪除比刪除多餘複雜挺多。 我嘗試了三種方法,牛客網上執行通過,思路如下: (1)遍歷連結串列,重複的數字置0,如1-2-3-0-4-0-5,再次遍歷連結串列,把0以及0之前的結點刪除,這種方法實現起來比較簡單,在平臺上提交成功,但致命的缺陷是結點值可能是0,目前沒想到別的標記來代替0,不然這種方法是投機取巧。
(2)設定變數記錄當前值,與此值相同的結點依次刪除。這種方法原理很簡單,但有很多要注意的問題。(調了很多次不確定是不是我的方法太複雜) (3)借鑑了別人的程式,採用遞迴的方式。(菜鳥的我覺得非典型的遞迴題目用上遞迴都是牛逼哄哄的) 結點結構:
struct ListNode 
{
    int val;
    struct ListNode *next;
};
方法(1)
ListNode* deleteDuplication(ListNode* pHead)
    {
        ListNode* r=pHead;
		ListNode* de=NULL;
		int temp=0;
        if(pHead==NULL)
            return pHead;
		temp=r->val;
     	while(r->next!=NULL)	//把重複的置0
        {
			
            if(r->next->val==temp)
			{
				r->next->val=0;
            }
			else
				temp=r->next->val;
            r=r->next;
        }
		r=pHead;
		while(r!=NULL )			//刪除0結點以及0結點之前的結點
		{
			ListNode* p=r;
			if(r->val==0 || r->next!=NULL && r->next->val==0)
			{
				if(r==pHead)	//如果刪除頭節點,頭節點後移
				{
					pHead=r->next;
					de=pHead;
					r=r->next;
					continue;
				}
				else		
				{
					de->next=r->next;
					r=r->next;
					delete p;
					continue;
				}
			}
			de=r;
			r=r->next;
		}
		return pHead;
    }
方法(2)
ListNode* deleteDuplication(ListNode* pHead)
{
	if(pHead==NULL)
		return 0;
	ListNode* p=pHead;					//移動指標
	ListNode* current=pHead;				//前一位有效的指標
	while(p->next!=NULL)
	{
		if(p->next->val==p->val)			//【當前和下一位重複】
		{
			int temp=p->val;			//記錄每輪重複的指標數值
			while(p->val==temp)	
			{
				ListNode* delete_r=p;
				if(pHead==p)			//【如果是頭節點】則刪除,把頭節點往後移
				{
					if(p->next==NULL)	//到達連結串列末尾,連結串列元素全被刪除,返回0。
						return 0;
					p=p->next;
					pHead=p;
					current=pHead;
					delete delete_r;
					continue;
				}
				else				//【如果不是】則刪除,current->next指下一位
				{											
					if(p->next==NULL)	//到達連結串列末尾,current->next置空。
					{
						current->next=NULL;
						break;
					}
					p=p->next;
					current->next=p;
					delete delete_r;
				}
			}
		}
		else						//【當前和下一位不重複】
		{
			current=p;
			p=p->next;
		}
	}
	return pHead;
}
方法(3)
ListNode* deleteDuplication(ListNode* pHead)
{
	ListNode* plast=NULL;
	ListNode* p=NULL;
	if(pHead==NULL)					//邊界條件
		return 0;
	if(pHead->next==NULL)			//邊界條件
		return pHead;
	if(pHead->val==pHead->next->val)//如果重複,依次刪除節點,直到下一個值,進入遞迴
	{
		ListNode* p=pHead;
		int temp=pHead->val;
		while(p!=NULL && p->val==temp)
		{
			ListNode* delete_p=p;
			p=p->next;
			delete delete_p;
		}
		return deleteDuplication(p);
	}
	else							//如果不重複,指標後移,進入遞迴
	{
		pHead->next=deleteDuplication(pHead->next);
		return pHead;
	}
}



相關推薦

連結串列C++刪除連結串列重複結點

題目: 在一個排序的連結串列中,存在重複的結點,請刪除該連結串列中重複的結點,重複的結點不保留,返回連結串列頭指標。 例如,連結串列1->2->3->3->4->4-&

資料結構c++ 實現連結串列的建立,查詢,列印,刪除,插入

//程式很簡單,但是要捋順邏輯關係,留著備用 #include #include"stdafx.h" using namespace std; struct node { int data; node* next; }; node * created_hea

LeetCode題解19_刪除連結串列的倒數第N個節點(Remove-Nth-Node-From-End-of-List)

更多 LeetCode 題解筆記可以訪問我的 github。 文章目錄 描述 解法:雙指標 思路 Java 實現 Python 實現 複雜度分析 描述 給定一個連結串列,

LeetCode題解237_刪除連結串列的節點

237_刪除連結串列中的節點 文章目錄 237_刪除連結串列中的節點 描述 解法 思路 Java 實現 Python 實現 描述 請編寫一個函式,使其可以刪除

TOJ 5254C++實驗:繼承的構造函數和析構函數

des 能夠 con OS esp space AC tom cto 描述 實現C++類Base和Derived,並編寫相關構造函數和析構函數,使其能夠輸出樣例信息。 主函數裏的代碼已經給出,請補充完整,提交時請勿包含已經給出的代碼。 int main() { Base

LeetCode 237. 刪除連結串列的節點

1.題目 請編寫一個函式,使其可以刪除某個連結串列中給定的(非末尾)節點,你將只被給定要求被刪除的節點。 現有一個連結串列 – head = [4,5,1,9],它可以表示為: 4 -> 5 -> 1 -> 9 示例 1: 輸

LeetCode 簡單題65-刪除連結串列的節點

宣告: 今天是第65道題。編寫函式,使其可以刪除某個單鏈表中給定的(非末尾)節點,只能訪問給定要刪除的節點。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除 (手動比心ღ( ´・ᴗ・` ))

演算法C++用連結串列實現一個箱子排序附原始碼詳解

01 箱子排序 1.1 什麼是分配排序? 分配排序的基本思想:排序過程無須比較關鍵字,而是通過"分配"和"收集"過程來實現排序.它們的時間複雜度可達到線性階:O(n)。 1.2 什麼是箱子排序? 箱子排序是分配排序的一種,箱子排序也稱桶排序(Bucket Sort),其基本思想是:設定若干個箱子,依次掃描待

LeetCode19. 刪除連結串列的倒數第N個節點

題目描述 給定一個連結串列,刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。 示例 給定一個連結串列: 1->2->3->4->5, 和 n = 2. 當刪除了倒數

LeetCode237. 刪除連結串列的節點

題目描述 請編寫一個函式,使其可以刪除某個連結串列中給定的(非末尾)節點,你將只被給定要求被刪除的節點。 現有一個連結串列 – head = [4,5,1,9],它可以表示為: 4 -> 5 -

LeetCode題解142_環形連結串列2(Linked-List-Cycle-II)

目錄 描述 解法一:雜湊表 思路 Java 實現 Python 實現 複雜度分析 解法二:雙指標 思路 Java 實現 Python 實現 複雜度分析 描述 給定一個連結串列,返回連結串列開始入

LeetCode題解61_旋轉連結串列(Rotate-List)

目錄 描述 解法:雙指標 思路 Java 實現 Python 實現 複雜度分析 描述 給定一個連結串列,旋轉連結串列,將連結串列每個節點向右移動 k 個位置,其中 k 是非負數。 示例 1: 輸入: 1->2->3->4-

LeetCode題解206_反轉連結串列(Reverse-Linked-List)

更多 LeetCode 題解筆記可以訪問我的 github。 文章目錄 描述 解法一:迭代 思路 Java 實現 Python 實現 複雜度分析 解法二:遞迴 思路

LeetCode題解206_反轉連結串列

目錄 206_反轉連結串列 描述 反轉一個單鏈表。 示例: 輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL 進階: 你可以迭代或遞迴地反轉連結串列。你能否用兩種方法解決這道題? 實現方式一:迭代 思路

LeetCode題解141_環形連結串列

目錄 141_環形連結串列 描述 給定一個連結串列,判斷連結串列中是否有環。 進階: 你能否不使用額外空間解決此題? 解法一:雜湊表 思路 判斷一個連結串列是否包含環,可以轉化為判斷是否有一個節點之前已經出現過。非常自然的一個想法就是:遍歷連結串列的每個節點,用一個雜湊表記錄每個節點的引用(或記憶體地址);

BZOJ 2151種樹(連結串列+貪心)

有一種顯然錯誤的做法:每次從堆裡取最大的,更新連結串列 比如 19,20,19 這樣的話會先選20。但是很顯然,選兩個19帶來的貢獻可能是更好的 這時我們就要想一種能做到“反悔”的方法 其實只需要做一點點修改,每次再push一個“19+19-20”進去,一樣是對的 那這個“19+19-20”的放在哪兒呢(編號

資料結構單向迴圈連結串列

寫的中間發現一個問題,我試了一下,final修飾的引用是指該引用只能指向一個物件不能更改指向其他物件,但是該引用調該物件的方法進行內部資訊修改是OK的 package 連結串列.迴圈連結串列; import java.util.NoSuchElement

資料結構陣列、連結串列、棧、佇列、二叉樹

陣列 陣列儲存的資料在地址空間上是連續的。 方便資料的查詢,查詢資料的時間複雜度為O(1)。 連結串列 連結串列儲存的資料在地址空間上可連續,可不連續。 連結串列中的每一個節點都

資料結構高效雙向連結串列list、樹tree(二叉樹)

vi正常模式下: "shift + g" 跳到最後一行 "gg" 跳到第一行 <效率更高的雙向連結串列結構程式碼>/*程式碼*/ 01link.c #include <stdlib.h> #include "01link.h" //連結串列初始化 v

演算法初探陣列、連結串列與選擇排序

前端也要懂演算法,閱《演算法圖解》有所得。 一、陣列與連結串列 1. 記憶體的原理: 相信我們經常會聽到“堆”、“棧”之類的字眼,那麼計算機的記憶體是什麼呢?當我們去游泳時,我們需要將東西存在保險櫃裡,可能東西比較多,一個放不下,這時候就需要申請2個保險櫃,再將東西