日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

五個經典鏈表OJ題帶你進階C++鏈表篇_C 語言

作者:程序猿教你打籃球 ? 更新時間: 2022-05-27 編程語言

反轉單鏈表

題目1:給你單鏈表的頭節點?head?,請你反轉鏈表,并返回反轉后的鏈表。

示例 1:

輸入:head = [1,2,3,4,5]

輸出:[5,4,3,2,1]

題目來源:力扣

思路一: 翻轉指針方向,首先我們要有三個指針,這個就不展示代碼了,邏輯過程如下:

?思路二:頭插方法,我們把每個節點拿下來進行頭插實現!代碼實現如下:

struct ListNode* reverseList(struct ListNode* head)
{
	struct ListNode* cur = head;
	struct ListNode* newHead = NULL;
	while (cur)
	{
		struct ListNode* next = cur->next;
		
		//頭插
		cur->next = newHead;
		newHead = cur;
		cur = next;
	}
	return newHead;
}

返回鏈表中間節點的位置

題目2:給定一個頭結點為?head?的非空單鏈表,返回鏈表的中間結點。

如果有兩個中間結點,則返回第二個中間結點。

示例 1:

輸入:[1,2,3,4,5,6]

輸出:此列表中的結點 4 (序列化形式:[4,5,6])

由于該列表有兩個中間結點,值分別為 3 和 4,我們返回第二個結點

題目來源:力扣

思路: 我們使用快慢指針的辦法,快指針fast走兩步,慢指針slow走一步,這樣當fast走完了,slow指針就走到了中間的位置,但是我們要注意,如果鏈表節點為奇數個則當fast為NULL就應該結束循環,如果鏈表節點為偶數個則當fast->next為NULL則結束循環!思路解析,代碼實現如下:

struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* slow = head, * fast = head;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;
}

合并兩個有序鏈表

題目3:將兩個升序鏈表合并為一個新的 升序 鏈表并返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。?

示例 1:

輸入:l1 = [1,2,4], l2 = [1,3,4]

題目來源:力扣

思路:首先我們要判斷兩個鏈表是否為空,如果為空則返回另一個鏈表!接著我們需要定義兩個指針頭指針head和一個尾指針tail,接著我們比較list1->val是否大于list2->val然后進行鏈接鏈表的操作,并且當其中一個鏈表為空則跳出循環,我們則需要在循環外再次判斷是哪個鏈表為空導致跳出的循環,并且最后把不為空的鏈表鏈接在后面!最后返回頭指針head!

建議小伙伴們看著這個思路嘗試著自己寫一下,可以參考如下代碼:

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
	if (list1 == NULL)
		return list2;
	if (list2 == NULL)
		return list1;
	struct ListNode* head = NULL, * tail = NULL;
	if (list1->val < list2->val)
	{
		head = tail = list1;
		list1 = list1->next;
	}
	else
	{
		head = tail = list2;
		list2 = list2->next;
	}
 
	while (list1 != NULL && list2 != NULL)
	{
		if (list1->val < list2->val)
		{
			//尾插
			tail->next = list1;
			list1 = list1->next;
		}
		else
		{
			tail->next = list2;
			list2 = list2->next;
		}
		tail = tail->next;
 
	}
	if (list1)
		tail->next = list1;
	if (list2)
		tail->next = list2;
 
	return head;
}

判斷鏈表中是否有環

?給你一個鏈表的頭節點 head ,判斷鏈表中是否有環。

如果鏈表中存在環?,則返回 true 。 否則,返回 false 。

示例 1:

輸入:head = [3,2,0,-4], pos = 1

輸出:true

解釋:鏈表中有一個環,其尾部連接到第二個節點。

題目來源:力扣

思路: 我們使用快慢指針的方法,讓fast指針一次走兩步,slow指針一次走一步,當鏈表有環的時候,當slow進入環了,fast就開始追slow,假設fast跟slow的距離為N,每走一次fast跟slow的距離就會縮小一步,也就是N-1,N-2,N-3,N-4,直到N為0 fast就追上slow了!代碼實現如下:

bool hasCycle(struct ListNode *head) 
{
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast)
            return true;
    }
    return false;
}

判斷環形鏈表進入的節點

給定一個鏈表的頭節點 ?head?,返回鏈表開始入環的第一個節點。?如果鏈表無環,則返回?null。

不允許修改 鏈表。

示例 1:

輸入:head = [3,2,0,-4], pos = 1

輸出:返回索引為 1 的鏈表節點

解釋:鏈表中有一個環,其尾部連接到第二個節點。

題目來源:力扣

?思路:我們還是用跟上面一樣的快慢指針的方法,但是在后面,一個指針從相遇點meet開始走,一個指針從鏈表頭head開始走,他們會在入口點相遇!圖解,代碼參考見下:

bool hasCycle(struct ListNode *head) 
{
    struct ListNode* fast = head;
    struct ListNode* slow = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast)
            return true;
    }
    return false;
}

?我們一起快樂編程不頭禿!

gitee(碼云):Mercury. (zzwlwp) - Gitee.com? ? ? ?

原文鏈接:https://blog.csdn.net/m0_61784621/article/details/123448745

欄目分類
最近更新