日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

双指针算法之快慢指针(一):力扣【判断链表是否有环】leetcode-141、142

發(fā)布時間:2025/3/20 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 双指针算法之快慢指针(一):力扣【判断链表是否有环】leetcode-141、142 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、簡介:什么是快慢指針?

快慢指針,顧名思義,無非就是設(shè)置一個快指針,一個慢指針,初始化的時候,快指針和慢指針都指向鏈表的頭結(jié)點,前進的時候一個在前一個在后,結(jié)合起來可以十分巧妙的解決鏈表中的一些問題;

看完本文可以解決leetcode141題(簡單)以及l(fā)eetcode142題(中等)。
雙指針?biāo)惴ㄖ炻羔?二):力扣【尋找鏈表的第N個點】leetcode-876、19

二、典例一:判斷鏈表是否有環(huán)

這個應(yīng)該屬于鏈表算法的經(jīng)典的操作了,如果一個單鏈表有環(huán),一個指針是判斷不出來的,因為鏈表尾部和頭部"鏈接"在一起,形成了一個死循環(huán)。

boolean hasCycle(ListNode head) {while (head != NULL)head = head.next;return false; }

如果使用一個指針:上述的代碼,如果沒有環(huán)的話,head 指針最后就會走到NULL,就會返回 false。到那時如果鏈表是有環(huán)的,就麻煩了,head會在循環(huán)中一直出不來的,自然不會有結(jié)果~
但是,如果設(shè)置快慢兩個指針,快指針走到null的時候,就可以得知這個鏈表是沒有環(huán)的;如果快慢指針相遇了,說明快指針肯定已經(jīng)走了幾圈了,這個鏈表肯定是有環(huán)的。
比較經(jīng)典的就是leetcode的141題

1、題目描述:


2、思路以及代碼

只要快慢指針相遇,說明是有環(huán)的,所以我們這里設(shè)置快指針 fast 一次走兩步,慢指針 slow一次就一步;

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:bool hasCycle(ListNode *head) {ListNode *fast,*slow;fast = slow = head; // 初始都頭節(jié)點的位置while (fast != NULL && fast->next != NULL) {fast = fast->next->next;slow = slow->next;if (fast == slow) { // 相遇了return true;}}return false;} };

三、典例二:判斷鏈表中是否有環(huán),有環(huán)就返回環(huán)的起始位置

剛剛的快慢指針判斷鏈表是不是有環(huán)其實還是很好理解的,但是進一步提升的話,判斷出來有環(huán)之后,返回這個環(huán)的開始位置, 不僅僅需要判斷是不是有環(huán),有環(huán)的話還有知道環(huán)是where 開始的。

比較經(jīng)典的就是leetcode的142題

1、題目描述

2、題目分析

在這里,我們先回到上一題的解法,使用快慢指針去判斷是不是有環(huán),如果快慢指針相遇了,就是有環(huán),那么,快慢指針相遇在哪一個點呢?這個點有什么特別之處嗎?除了相遇的點,我們還應(yīng)該注意到鏈表頭結(jié)點,相遇點,環(huán)開始結(jié)點。
其實142題的核心,確實就在于分析一下這3個點,下面我們就來分析一下:

下圖的聲明:
O 是鏈表頭結(jié)點
A 是環(huán)開始的點
B 是快指針和滿指針相遇的點
K 是慢指針 slow 在快慢指針相遇之時走的路程,即推:快指針是 2 K
L(OA)是 從O 開始 第一次遇到 A 走的路長,就是下圖藍色部分
L(AB)是 從A 開始 第一次遇到 B 走的路長,就是下圖紅色部分
L環(huán) 是 從A 開始 再一次遇到 A 走的路長 其實就是k了
L(BA)是 從B開始 第一次遇到 A 走的路長。就是下圖綠色部分

根據(jù)下圖的計算,我們可以知道 L(OA)和 L(BA) 的長度是一樣的。

由于 L(OA)和 L(BA) 的長度是一樣的,所以我們在快指針 fast 和滿指針 slow 相遇的時候,在B點相遇的時候,

1、快指針 fast 繼續(xù)前進,速度和慢指針一樣
2、慢指針 slow 返回鏈表頭結(jié)點 O點,
3、快慢指針的速度保持一致,各自繼續(xù)前進

那么,快慢指針下一次相遇的點是哪里?沒錯,就是 A 點,就是環(huán)開始的結(jié)點。

3、解題代碼

由此,我們可以寫出下面的偽代碼:

ListNode detectCycle(ListNode head) {快慢指針初始化,都在頭結(jié)點while (fast != null && fast.next != null) {快指針一次兩步慢指針一次一步if (快指針 = 慢指針) {//即相遇 此時在 B 點慢指針回到頭結(jié)點;while (slow != fast) {快慢指針繼續(xù)走,一次一步;}return slow;}}return NULL; }

隨后就可以寫出全部的代碼了:

class Solution { public:ListNode *detectCycle(ListNode *head) {ListNode *fast,*slow;fast = slow = head;while (fast != NULL && fast->next != NULL) {fast = fast->next->next;slow = slow->next;if (fast == slow) {slow = head;while (fast != slow) {fast = fast->next; slow = slow->next;}return slow;}}return NULL;} };

總結(jié)

以上是生活随笔為你收集整理的双指针算法之快慢指针(一):力扣【判断链表是否有环】leetcode-141、142的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。