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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

这样给面试官解释约瑟夫环问题的几种巧妙解法,面试官满意的笑了

發(fā)布時間:2025/3/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 这样给面试官解释约瑟夫环问题的几种巧妙解法,面试官满意的笑了 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載請聯(lián)系公眾號:bigsai

前言

約瑟夫環(huán)問題是算法中相當(dāng)經(jīng)典的一個問題,其問題理解是相當(dāng)容易的,并且問題描述有非常多的版本,并且約瑟夫環(huán)問題還有很多變形,這篇約瑟夫問題的講解,一定可以帶你理解通通!

什么是約瑟夫環(huán)問題?

約瑟夫環(huán)問題在不同平臺被"優(yōu)化"描述的不一樣,例如在牛客劍指offer叫孩子們的游戲,還有叫殺人游戲,點名……最直接的感覺還是力扣上劍指offer62的描述:圓圈中最后剩下的數(shù)字。

問題描述:

0,1,···,n-1這n個數(shù)字排成一個圓圈,從數(shù)字0開始,每次從這個圓圈里刪除第m個數(shù)字(刪除后從下一個數(shù)字開始計數(shù))。求出這個圓圈里剩下的最后一個數(shù)字。

例如,0、1、2、3、4這5個數(shù)字組成一個圓圈,從數(shù)字0開始每次刪除第3個數(shù)字,則刪除的前4個數(shù)字依次是2、0、4、1,因此最后剩下的數(shù)字是3。

當(dāng)然,這里考慮m,n都是正常的數(shù)據(jù)范圍,其中

  • 1 <= n <= 10^5
  • 1 <= m <= 10^6

對于這個問題,你可能腦海中有了印象,想著小時候村里一群孩子坐在一起,從某個開始報數(shù)然后數(shù)到幾出列,下一個重新開始一直到最后一個。

循環(huán)鏈表模擬

這個問題最本質(zhì)其實就是循環(huán)鏈表的問題,圍成一個圈之后,就沒有結(jié)尾這就是一個典型的循環(huán)鏈表嘛!一個一個順序報數(shù),那不就是鏈表的遍歷枚舉嘛!數(shù)到對應(yīng)數(shù)字的出列,這不就是循環(huán)鏈表的刪除嘛!

并且這里還有非常方便的地方:

  • 循環(huán)鏈表的向下枚舉不需要考慮頭尾問題,直接node=node.next向下
  • 循環(huán)聊表的刪除也不需要考慮頭尾問題,直接node.next=node.next.next刪除

當(dāng)然也有一些需要注意的地方

  • 形成環(huán)形鏈表很簡單,只需要將普通鏈表的最后一個節(jié)點的next指向第一個節(jié)點即可

  • 循環(huán)鏈表中只有一個節(jié)點的時候停止返回,即node.next=node的時候

  • 刪除,需要找到待刪除的前面節(jié)點,所以我們刪除計數(shù)的時候要少即一位,利用前面的那個節(jié)點直接刪除后面節(jié)點即可

這樣,思路明確,直接開擼代碼:

class Solution {class node//鏈表節(jié)點{int val;public node(int value) {this.val=value;}node next;}public int lastRemaining(int n, int m) {if(m==1)return n-1;//一次一個直接返回最后一個即可node head=new node(0);node team=head;//創(chuàng)建一個鏈表for(int i=1;i<n;i++){team.next=new node(i);team=team.next;}team.next=head;//使形成環(huán)int index=0;//從0開始計數(shù)while (head.next!=head) {//當(dāng)剩余節(jié)點不止一個的時候//如果index=m-2 那就說明下個節(jié)點(m-1)該刪除了if(index==m-2){head.next=head.next.next;index=0;}else {index++;}head=head.next;}return head.val;} }

當(dāng)然,這種算法太復(fù)雜了,大部分的OJ你提交上去是無法AC的,因為超時太嚴(yán)重了,具體的我們可以下面分析。

有序集合模擬

上面使用鏈表直接模擬游戲過程會造成非常嚴(yán)重非常嚴(yán)重的超時,n個數(shù)字,數(shù)到第m個出列。因為m如果非常大遠(yuǎn)遠(yuǎn)大于m,那么將進(jìn)行很多次轉(zhuǎn)圈圈。

所以我們可以利用求余的方法判斷等價最低的枚舉次數(shù),然后將其刪除即可,在這里你可以繼續(xù)使用自建鏈表去模擬,上面的while循環(huán)以及上面只需添加一個記錄長度的每次求余算圈數(shù)即可:

int len=n; while (head.next!=head) {if(index==(m-2)%len){head.next=head.next.next;index=0;len--;}else {index++;}head=head.next; }

但我們很多時候不會手動去寫一個鏈表模擬,我們會借助ArrayList和LinkedList去模擬,如果使用LinkedList其底層也是鏈表,使用ArrayList的話其底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組。不過在使用List其代碼方法一致。

List可以直接知道長度,也可刪除元素,使用List的難點是一個順序表怎們模擬成循環(huán)鏈表?

咱們仔細(xì)思考:假設(shè)當(dāng)前長度為n,數(shù)到第m個(通過上面分析可以求余讓這個有效的m不大于n)刪除,在index位置刪除。那么刪除后剩下的就是n-1長度,index位置就是表示第一個計數(shù)的位置,我們可以通過求余得知走下一個刪除需要多少步,那么下個位置怎么確定呢?

你可以分類討論看看走的次數(shù)是否越界,但這里有更巧妙的方法,可以直接求的下一次具體的位置,公式就是為:

index=(index+m-1)%(list.size());

因為index是從1計數(shù),如果是循環(huán)的再往前m-1個就是真正的位置,但是這里可以先假設(shè)先將這個有序集合的長度擴大若干倍,然后從index計數(shù)開始找到假設(shè)不循環(huán)的位置index2,最后我們將這個位置index2%(集合長度)即為真正的長度。

使用這個公式一舉幾得,既能把上面m過大循環(huán)過多的情況解決,又能找到真實的位置,就是將這個環(huán)先假設(shè)成線性的然后再去找到真的位置,如果不理解的話可以再看看這個圖:

這種情況的話大部分的OJ是可以勉強過關(guān)的,面試官的層面也大概率差不多的,具體代碼為:

class Solution {public int lastRemaining(int n, int m) {if(m==1)return n-1;List<Integer>list=new ArrayList<>();for(int i=0;i<n;i++){list.add(i);}int index=0;while (list.size()>1){index=(index+m-1)%(list.size());list.remove(index);}return list.get(0);} }

遞歸公式解決

我們回顧上面的優(yōu)化過程,上面用求余可以解決m比n大很多很多的情況(即理論上需要轉(zhuǎn)很多很多圈的情況)。但是還可能存在n本身就很大的情況,無論是順序表ArrayList還是鏈表LinkedList去頻繁查詢、刪除都是很低效的。

所以聰明的人就開始從數(shù)據(jù)找一些規(guī)律或者關(guān)系。

先拋出公式:

f(n,m)=(f(n-1,m)+m)%n f(n,m)指n個人,報第m個編號出列最終編號

下面要認(rèn)真看一下我的分析過程:

我們舉個例子,有0 1 2 3 4 5 6 7 8 9十個數(shù)字,假設(shè)m為3,最后結(jié)果可以先記成f(10,3),即使我們不知道它是多少。

當(dāng)進(jìn)行第一次時候,找到元素2 刪除,此時還剩9個元素,但起始位置已經(jīng)變成元素3。等價成3 4 5 6 7 8 9 0 1這9個數(shù)字重寫開始找。

此時這個序列最終剩下的一個值即為f(10,3),這個序列的值和f(9,3)不同,但是都是9個數(shù)且m等于3,所以其刪除位置是相同的,即算法大體流程是一致的,只是各位置上的數(shù)字不一樣。所以我們需要做的事情是找找這個序列上和f(9,3)值上有沒有什么聯(lián)系

尋找過程中別忘記兩點,首先可通過**%符號**對數(shù)字有效擴充,即我們可以將3 4 5 6 7 8 9 0 1這個序列看成(3,4,5,6,7,8,9,10,11)%10.這里的10即為此時的n數(shù)值。

另外數(shù)值如果是連續(xù)的,那么最終一個結(jié)果的話是可以找到聯(lián)系的(差值為一個定制)。所以我們可以就找到f(10,3)和f(9,3)值之間結(jié)果的關(guān)系,可以看下圖:

所以f(10,3)的結(jié)果就可以轉(zhuǎn)化為f(9,3)的表達(dá),后面也是同理:

f(10,3)=(f(9,3)+3)%10 f(9,3)=(f(8,3)+3)%9 …… f(2,3)=(f(1,3)+3)%2 f(1,3)=0

這樣,我們就不用模擬操作,可以直接從數(shù)值的關(guān)系找到遞推的關(guān)系,可以輕輕松松的寫下代碼:

class Solution {int index=0;public int lastRemaining(int n, int m) {if(n==1)return 0; return (lastRemaining(n-1,m)+m)%n;} }

但是遞歸效率因為有個來回的規(guī)程,效率相比直接迭代差一些,也可從前往后迭代:

class Solution {public int lastRemaining(int n, int m) {int value=0;for(int i=1;i<=n;i++){value=(value+m)%i;}return value;} }

結(jié)語

我想,通過本篇文章你應(yīng)該掌握和理解了約瑟夫環(huán)問題,這種裸的約瑟夫環(huán)問題出現(xiàn)的概率很大,考察很頻繁,鏈表模擬是根本思想,有序集合模擬鏈表是提升,而公式遞推才是最有學(xué)習(xí)價值的地方,如果你剛開始接觸不理解可以多看幾遍。如果能用公式遞推給面試官說兩句,講講原理,那一定會讓面試官眼前一亮的!

如果看了本文覺得有收獲歡迎 點贊、收藏、分享一波,也歡迎關(guān)注我的公眾號(bigsai)、加我v信好友(q1315426911)一起學(xué)習(xí)交流,我也創(chuàng)了一個力扣打卡群,里面很多熱情的伙伴希望一起進(jìn)步!

總結(jié)

以上是生活随笔為你收集整理的这样给面试官解释约瑟夫环问题的几种巧妙解法,面试官满意的笑了的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 蜜臀av性久久久久av蜜臀妖精 | 免费看黄色a级片 | 国产麻豆精品一区二区 | 涩涩爱影院 | 国产精品100 | 国产女人高潮的av毛片 | 在线观看特色大片免费网站 | 男人天堂影院 | 乱色专区 | 国产乱淫av公 | 色久网| 中文字幕亚洲一区二区三区五十路 | 国产精品视频一区二区三区不卡 | 亚洲13p| 五月婷婷在线观看视频 | 亚洲97 | www.久久久久.com | 国产67194| 久久久a级片 | 91人妻一区二区三区蜜臀 | 国产福利片一区二区 | 色哟哟免费在线观看 | 成人刺激视频 | 琪琪电影午夜理论片八戒八戒 | 凹凸国产熟女精品视频 | 一区二区福利电影 | 欧美一区二区黄色 | 午夜影院在线视频 | 亚洲黄v | 香蕉视频二区 | www精品一区二区三区 | 亚洲综合精品一区 | 亚洲四区 | av在线色| 就爱啪啪网站 | 国产一区二区三区色淫影院 | 日日夜夜精品视频 | 五月天精品在线 | 在线免费看污视频 | 成人精品国产免费网站 | 少妇荡乳情欲办公室456视频 | 小sao货cao死你 | 日韩精选 | 久久婷婷av | 亚洲精品中文字幕在线 | 麻豆国产一区二区三区四区 | 尤物视频在线观看免费 | 久久精品伦理 | 在线色网址| 国产成人综合视频 | 日韩国产91 | 成人va视频 | 中文在线中文资源 | 嫩草国产精品 | 激情黄色小说网站 | 天天婷婷 | 日本免费一区二区三区四区 | 亚洲精品av中文字幕在线在线 | 日韩在线观看免费网站 | 国产免费自拍视频 | 97免费在线观看 | 福利网站在线 | 成人短视频在线观看 | 国产五月 | 成人在线观看网址 | 香蕉视频在线观看www | 中文在线最新版天堂 | 风间由美一区二区三区 | 欧美另类videossexo高潮 | 海角社区id:1220.7126,10. | 日韩一区二区三区av | 99国产揄拍国产精品 | 欧美性猛交xxxx乱大交 | 午夜免费福利网站 | 东京干手机福利视频 | 怡红院男人天堂 | 久久艹精品视频 | 成人免费在线视频观看 | h无码动漫在线观看 | 欧美午夜精品 | 欧美人与禽猛交乱配视频 | 四虎网址大全 | 911精品国产一区二区在线 | 日本三级黄色录像 | 少妇 av| 找个毛片看看 | 97伊人| 国产福利小视频在线观看 | 黑森林福利视频导航 | 欧美做受xxxxxⅹ性视频 | 色婷婷综合久久久久中文字幕 | 奇米影视在线 | 日本不卡视频 | 成年人视频在线免费观看 | 久久亚洲免费 | 大胸美女吻戏 | 久久99国产精品久久99 | 日韩操操 | 91成人免费在线观看 |