色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

快慢指針、左右指針的常見算法

算法與數據結構 ? 來源:labuladong ? 作者:labuladong ? 2020-11-26 14:09 ? 次閱讀

作者:labuladong

公眾號:labuladong

本文是一兩年前發過的一篇文章,當時沒多少人看,現在由于賬號遷移的原因公眾號里都搜索不到了,我就重新加工了一下,并且添加了新內容,直接套雙指針技巧秒殺 5 道算法題。

其實,鼎鼎有名的「滑動窗口算法」就是一種雙指針技巧,我們之前的爆文我寫了套框架,把滑動窗口算法變成了默寫題就有這么一段:

我把雙指針技巧再分為兩類,一類是「快慢指針」,一類是「左右指針」。前者解決主要解決鏈表中的問題,比如典型的判定鏈表中是否包含環;后者主要解決數組(或者字符串)中的問題,比如二分查找。

一、快慢指針的常見算法

快慢指針一般都初始化指向鏈表的頭結點head,前進時快指針fast在前,慢指針slow在后,巧妙解決一些鏈表中的問題。

1、判定鏈表中是否含有環

這屬于鏈表最基本的操作了,學習數據結構應該對這個算法思想都不陌生。

單鏈表的特點是每個節點只知道下一個節點,所以一個指針的話無法判斷鏈表中是否含有環的。

如果鏈表中不含環,那么這個指針最終會遇到空指針null表示鏈表到頭了,這還好說,可以判斷該鏈表不含環:

booleanhasCycle(ListNodehead){ while(head!=null) head=head.next; returnfalse; }

但是如果鏈表中含有環,那么這個指針就會陷入死循環,因為環形數組中沒有null指針作為尾部節點。

經典解法就是用兩個指針,一個跑得快,一個跑得慢。如果不含有環,跑得快的那個指針最終會遇到null,說明鏈表不含環;如果含有環,快指針最終會超慢指針一圈,和慢指針相遇,說明鏈表含有環。

力扣第 141 題就是這個問題,解法代碼如下:

booleanhasCycle(ListNodehead){ ListNodefast,slow; fast=slow=head; while(fast!=null&&fast.next!=null){ fast=fast.next.next; slow=slow.next; if(fast==slow)returntrue; } returnfalse; }

2、已知鏈表中含有環,返回這個環的起始位置

這個問題一點都不困難,有點類似腦筋急轉彎,先直接看代碼:

ListNodedetectCycle(ListNodehead){ ListNodefast,slow; fast=slow=head; while(fast!=null&&fast.next!=null){ fast=fast.next.next; slow=slow.next; if(fast==slow)break; } //上面的代碼類似hasCycle函數 slow=head; while(slow!=fast){ fast=fast.next; slow=slow.next; } returnslow; }

可以看到,當快慢指針相遇時,讓其中任一個指針指向頭節點,然后讓它倆以相同速度前進,再次相遇時所在的節點位置就是環開始的位置。這是為什么呢?

第一次相遇時,假設慢指針slow走了k步,那么快指針fast一定走了2k步:

fast一定比slow多走了k步,這多走的k步其實就是fast指針在環里轉圈圈,所以k的值就是環長度的「整數倍」。

說句題外話,之前還有讀者爭論為什么是環長度整數倍,我舉個簡單的例子你就明白了,我們想一想極端情況,假設環長度就是 1,如下圖:

那么fast肯定早早就進環里轉圈圈了,而且肯定會轉好多圈,這不就是環長度的整數倍嘛。

言歸正傳,設相遇點距環的起點的距離為m,那么環的起點距頭結點head的距離為k - m,也就是說如果從head前進k - m步就能到達環起點。

巧的是,如果從相遇點繼續前進k - m步,也恰好到達環起點。你甭管fast在環里到底轉了幾圈,反正走k步可以到相遇點,那走k - m步一定就是走到環起點了:

所以,只要我們把快慢指針中的任一個重新指向head,然后兩個指針同速前進,k - m步后就會相遇,相遇之處就是環的起點了。

3、尋找鏈表的中點

類似上面的思路,我們還可以讓快指針一次前進兩步,慢指針一次前進一步,當快指針到達鏈表盡頭時,慢指針就處于鏈表的中間位置。

力扣第 876 題就是找鏈表中點的題目,解法代碼如下:

ListNodemiddleNode(ListNodehead){ ListNodefast,slow; fast=slow=head; while(fast!=null&&fast.next!=null){ fast=fast.next.next; slow=slow.next; } //slow就在中間位置 returnslow; }

當鏈表的長度是奇數時,slow恰巧停在中點位置;如果長度是偶數,slow最終的位置是中間偏右:

尋找鏈表中點的一個重要作用是對鏈表進行歸并排序。

回想數組的歸并排序:求中點索引遞歸地把數組二分,最后合并兩個有序數組。對于鏈表,合并兩個有序鏈表是很簡單的,難點就在于二分。

但是現在你學會了找到鏈表的中點,就能實現鏈表的二分了。關于歸并排序的具體內容本文就不具體展開了。

4、尋找鏈表的倒數第n個元素

這是力扣第 19 題「刪除鏈表的倒數第n個元素」,先看下題目:

我們的思路還是使用快慢指針,讓快指針先走n步,然后快慢指針開始同速前進。這樣當快指針走到鏈表末尾null時,慢指針所在的位置就是倒數第n個鏈表節點(n不會超過鏈表長度)。

解法比較簡單,直接看代碼吧:

ListNoderemoveNthFromEnd(ListNodehead,intn){ ListNodefast,slow; fast=slow=head; //快指針先前進n步 while(n-->0){ fast=fast.next; } if(fast==null){ //如果此時快指針走到頭了, //說明倒數第n個節點就是第一個節點 returnhead.next; } //讓慢指針和快指針同步向前 while(fast!=null&&fast.next!=null){ fast=fast.next; slow=slow.next; } //slow.next就是倒數第n個節點,刪除它 slow.next=slow.next.next; returnhead; }

二、左右指針的常用算法

左右指針在數組中實際是指兩個索引值,一般初始化為left = 0, right = nums.length - 1。

1、二分查找

前文二分查找框架詳解有詳細講解,這里只寫最簡單的二分算法,旨在突出它的雙指針特性:

intbinarySearch(int[]nums,inttarget){ intleft=0; intright=nums.length-1; while(left<=?right)?{ ????????int?mid?=?(right?+?left)?/?2; ????????if(nums[mid]?==?target) ????????????return?mid;? ????????else?if?(nums[mid]?target) right=mid-1; } return-1; }

2、兩數之和

直接看力扣第 167 題「兩數之和 II」吧:

只要數組有序,就應該想到雙指針技巧。這道題的解法有點類似二分查找,通過調節left和right可以調整sum的大小:

int[]twoSum(int[]nums,inttarget){ intleft=0,right=nums.length-1; while(lefttarget){ right--;//讓sum小一點 } } returnnewint[]{-1,-1}; }

3、反轉數組

一般編程語言都會提供reverse函數,其實非常簡單,力扣第 344 題是類似的需求,讓你反轉一個char[]類型的字符數組,我們直接看代碼吧:

voidreverseString(char[]arr){ intleft=0; intright=arr.length-1; while(left

4、滑動窗口算法

這也許是雙指針技巧的最高境界了,如果掌握了此算法,可以解決一大類子字符串匹配的問題,不過「滑動窗口」稍微比上述的這些算法復雜些。

不過這類算法是有框架模板的,而且前文我寫了首詩,把滑動窗口算法變成了默寫題就講解了「滑動窗口」算法模板,幫大家秒殺幾道子串匹配的問題,如果沒有看過,建議去看看。

責任編輯:PSY

原文標題:雙指針技巧直接秒殺五道算法題

文章出處:【微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4607

    瀏覽量

    92840
  • 指針
    +關注

    關注

    1

    文章

    480

    瀏覽量

    70551
  • 滑動窗口法
    +關注

    關注

    0

    文章

    5

    瀏覽量

    2150

原文標題:雙指針技巧直接秒殺五道算法題

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    過程間指針分析算法的改進

    指針分析對于使用C語言編制程序的數據流分析有著重要的意義。該文介紹指針問題的復雜度、指針分析算法的分類以及指針分析
    發表于 04-02 09:05 ?9次下載

    C語言入門教程-指針常見錯誤

    指針常見錯誤 錯誤 1:未初始化的指針一個最易犯的指針錯誤是試圖引用未初始化(因而指向的是無效地址)的指針。例如: int*p; *
    發表于 07-29 11:47 ?1121次閱讀

    C和指針習題答案配C和指針

    C和指針習題答案配C和指針
    發表于 09-07 14:29 ?6次下載
    C和<b class='flag-5'>指針</b>習題答案配C和<b class='flag-5'>指針</b>

    c語言函數指針定義,指針函數和函數指針的區別

     往往,我們一提到指針函數和函數指針的時候,就有很多人弄不懂。下面就由小編詳細為大家介紹C語言中函數指針指針函數和函數指針之間的區別。
    發表于 11-16 15:18 ?3624次閱讀

    為什么使用指針?C++中的“指針

    為什么使用指針?因為在操作大型數據和類時,指針可以通過內存地址直接訪問數據,可避免在程序中復制大量的代碼,因此指針的效率最高。一般來說,指針會有3大用途
    的頭像 發表于 10-04 10:33 ?5133次閱讀

    電機電流表指針左右擺動的原因分析

    電機電流表指針左右擺動是什么原因?這個問題很簡單,就是電動機帶動的設備,有些部位不圓滑,導致電機帶動時受阻,需要電流時高時低,不能同步工作,促使電流表指針來回擺動,必須重新校驗被帶負荷,使之靈活運行,才能排除故障,恢復正常。主要
    的頭像 發表于 10-27 09:41 ?2.3w次閱讀

    理解函數指針、函數指針數組、函數指針數組的指針

    理解函數指針、函數指針數組、函數指針數組的指針
    的頭像 發表于 06-29 15:38 ?1.5w次閱讀
    理解函數<b class='flag-5'>指針</b>、函數<b class='flag-5'>指針</b>數組、函數<b class='flag-5'>指針</b>數組的<b class='flag-5'>指針</b>

    數組相關的雙指針算法

    對于單鏈表來說,大部分技巧都屬于快慢指針,前文 單鏈表的六大解題套路 都涵蓋了,比如鏈表環判斷,倒數第K個鏈表節點等問題,它們都是通過一個fast快指針和一個slow慢指針配合完成任務
    的頭像 發表于 04-28 16:22 ?1891次閱讀

    二級指針和多級指針的定義形式

    指針變量作為一個變量也有自己的存儲地址,而指向指針變量的存儲地址就被稱為指針指針,即二級指針
    的頭像 發表于 10-18 16:38 ?1894次閱讀

    淺談指針常量和常量指針

    這節課我們來講一講指針常量和常量指針
    的頭像 發表于 02-21 09:27 ?1073次閱讀

    快慢指針常見算法介紹

    這應該屬于鏈表最基本的操作了,如果讀者已經知道這個技巧,可以跳過。 單鏈表的特點是每個節點只知道下一個節點,所以一個指針的話無法判斷鏈表中是否含有環的。
    的頭像 發表于 04-19 10:57 ?1854次閱讀
    <b class='flag-5'>快慢</b><b class='flag-5'>指針</b>的<b class='flag-5'>常見</b><b class='flag-5'>算法</b>介紹

    指針是什么

    指針是什么? 1.1 淺談指針 理解指針的 兩個要點: 指針是內存中一個最小單元的編號,也就是地址; 平時口語中說的指針,通常指的是
    的頭像 發表于 11-24 15:50 ?2123次閱讀
    <b class='flag-5'>指針</b>是什么

    函數指針指針函數是不是一個東西?

    函數指針的本質是指針,就跟整型指針、字符指針一樣,函數指針指向的是一個函數。
    的頭像 發表于 01-03 16:35 ?526次閱讀
    函數<b class='flag-5'>指針</b>和<b class='flag-5'>指針</b>函數是不是一個東西?

    怎么理解指針指針

    怎么理解指針指針?其實這個概念并不難,只是把它放到實際應用中,容易造成困擾。
    的頭像 發表于 02-23 16:46 ?1173次閱讀
    怎么理解<b class='flag-5'>指針</b>的<b class='flag-5'>指針</b>?

    面試常考+1:函數指針指針函數、數組指針指針數組

    在嵌入式開發領域,函數指針指針函數、數組指針指針數組是一些非常重要但又容易混淆的概念。理解它們的特性和應用場景,對于提升嵌入式程序的效率和質量至關重要。一、
    的頭像 發表于 08-10 08:11 ?830次閱讀
    面試常考+1:函數<b class='flag-5'>指針</b>與<b class='flag-5'>指針</b>函數、數組<b class='flag-5'>指針</b>與<b class='flag-5'>指針</b>數組
    主站蜘蛛池模板: 亚洲欧美高清在线精品一区| 国精产品一区二区三区四区糖心| 小黄文纯肉短篇| 捏揉舔水插按摩师| 久久强奷乱码老熟女| 精品视频免费在线| 99视频免视看| 耻辱の奴隷淑女中文字幕| 天美麻豆成人AV精品| 精品高潮呻吟99AV无码视频| 2020美女视频黄频大全视频| 全黄h全肉细节文在线观看| 国产精亚洲视频综合区| 伊人久久大香线蕉综合色啪| 暖暖 视频 免费 高清 在线观看 | freehd另类xxxx喷水| 沙发上小泬12P| 精品无码久久久久久久久| 99久久99久久精品国产片果冻| 收集最新中文国产中文字幕| 九九在线精品亚洲国产| BL全肉多攻NP高H| 午夜在线观看免费观看 视频| 久久伊人中文字幕有码| 成人无码国产AV免费看直播| 亚洲免费大全| 欧美性xxx18一20| 国产在线观看黄| 99亚洲精品| 亚洲黄色免费观看| 欧美 亚洲 中文字幕 高清| 国产精亚洲视频综合区| 99re久久免费热在线视频手机| 偷拍精品视频一区二区三区| 久久九九有精品国产23百花影院| 北原夏美 快播| 亚洲综合国产在不卡在线| 日本六九视频| 久久三级视频| 国产精品国产三级国AV在线观看 | 花蝴蝶高清观看免费|