国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

面試經(jīng)典150題——生命游戲

這篇具有很好參考價值的文章主要介紹了面試經(jīng)典150題——生命游戲。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?"Push yourself, because no one else is going to do it for you." - Unknown

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

1. 題目描述

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

2. ?題目分析與解析

2.1 思路一——暴力求解

之所以先暴力求解,是因為我開始也沒什么更好的思路,所以就先寫一種解決方案,沒準寫著寫著就來新的靈感了。暴力求解思路還是很簡單的,就是嘗試遍歷面板的每個格子,判斷其周圍八個位置的狀態(tài)(對于邊角需要特殊處理),根據(jù)邊角種存在的活細胞(也就是1的個數(shù))判斷該位置應該填什么。

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

但是需要注意一點,為了避免我們在原矩陣上更改值后導致影響后續(xù)的判斷,所以我們肯定需要先復制一個原始矩陣。

代碼思路:

  1. 初始化,復制一個原始矩陣

  2. 遍歷復制矩陣的每一個元素,查看其周圍八個位置的狀態(tài),統(tǒng)計1的個數(shù)

    • 根據(jù)題目提到的判定規(guī)則:少于 2 個或者大于 3 個 1 就判定當前位置為 0

    • 等于 2 個 1 那么當前位置不需要更改

    • 如果等于 3 個 1 那么當前位置如果為 0 需要改為 1

    • 對于邊角位置需要額外處理防止越界

2.2 思路二——進階(原地算法)

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

根據(jù)題目中的進階提示,要求使用原地算法,也就是不能用一個額外的面板存儲現(xiàn)有的值,并且還提示了所有格子被同時更新。因此我們再想一想怎么解決。

如果使用原地算法,最主要的問題就是對于前面內容的更新會影響后面的結果,因為你不知道原來前面的內容是什么樣子。但是記住,原始狀態(tài)只有兩種,要么是0,要么是1。

而變化也只有四種

  1. 要么原來是0,后來變成1

  2. 要么原來是0,保持不變?yōu)?

  3. 要么原來是1,后來變成0

  4. 要么原來是1,后來不變?yōu)?

如下圖:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

因為我們擔心原始信息被覆蓋,因此我們是不是可以添加幾個數(shù)字也就相當于幾種狀態(tài),來存儲這些被覆蓋的信息?這樣我們看見某一個數(shù)字就知道它之前是什么狀態(tài),就相當于在原始數(shù)據(jù)的基礎上進行操作了!在這里我們假設:

  • 用 0 和 1 還是表示原來是什么現(xiàn)在就是什么的情況,也就是對應上圖中兩種不變的情況

  • 而用數(shù)字2表示 0 改變?yōu)?1

  • 用數(shù)字3表示 1 改變?yōu)?0

作圖表示如下:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

對于這種原地算法,如果你需要用到之前的信息,但是可能之前的信息會被修改,就想辦法把原始信息用一種方式存儲起來。

因此我們在遍歷面板的每一個元素時,我們就知道之前的位置原始數(shù)據(jù)是什么,這樣就能正確計算結果,等到最后我們再根據(jù)每一種數(shù)字的情況將它歸為正確的表示,比如最后我們處理完了所有數(shù)據(jù),然后我們再遍歷每個元素:

  • 發(fā)現(xiàn)值為0或者1就不動

  • 發(fā)現(xiàn)值為2就變?yōu)?

  • 發(fā)現(xiàn)值為3就變?yōu)?

這樣就可以得到最終結果!

代碼思路:

  1. 遍歷面板每一個元素,根據(jù)原始狀態(tài)和需要改變?yōu)榈闹荡_定該位置的值

    • 對于面板每一個元素,遇見周圍八個位置中有1和3就把它當作1

    • 對于面板每一個元素,遇見周圍八個位置中有2和0就把它當作0

  2. 處理完每個元素后再次遍歷整個面板,將1與3替換回正確的值

2.3 思路三——思路一的優(yōu)化(位運算)

現(xiàn)在我們看看還有沒有什么優(yōu)化空間,有時間提示信息不是白給的哦:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

題目提示我們board[i][j]01,0和1,有沒有想到什么?學計算機的0和1分別表示什么?在java中int是怎么存儲的?

再看看面板的大???1 <= m, n <= 25,在聯(lián)想一下int的存儲大小:

在不同編程語言中,int 類型的大小可以有所不同。以下是一些常見編程語言中 int 類型的大小:

  1. C/C++:

    • 根據(jù)編譯器和操作系統(tǒng)的不同,int 類型通常為 4 字節(jié),范圍大約是 -2,147,483,648 到 2,147,483,647。

  2. Java:

    • Java 中的 int 類型固定為 4 字節(jié),范圍是 -2,147,483,648 到 2,147,483,647。

  3. Python:

    • Python 中的 int 類型大小是動態(tài)的,它可以根據(jù)需要自動調整。在 32 位系統(tǒng)上,通常為 4 字節(jié),范圍約為 -2,147,483,648 到 2,147,483,647;在 64 位系統(tǒng)上,它可以是 4 字節(jié)或 8 字節(jié),取決于所使用的 Python 版本。

  4. JavaScript:

    • JavaScript 中的 int 類型實際上是一個 64 位浮點數(shù),范圍大約是 -9,007,199,254,740,992 到 9,007,199,254,740,992。

  5. Swift:

    • Swift 中的 Int 類型的大小取決于當前平臺的位數(shù)。在 32 位平臺上,Int 是 32 位,范圍大約是 -2,147,483,648 到 2,147,483,647;在 64 位平臺上,Int 是 64 位,范圍大約是 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。

可以看到在大多數(shù)情況下至少是按照4字節(jié)存儲的,也就是32位,而一位可以表示0或者1兩個數(shù),聯(lián)想到這里是不是又有了一種思路?我們是不是可以按照思路一的解決方案,雖然我們copy了一個原始面板,但是我們面板的每一個值都是一個int,如果我們把面板的一行設置位一個int來存儲,通過位運算來求解,是不是能省好多空間?

所以代碼思路還是思路一的代碼思路,但是我們此時需要使用位運算來解決!

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

如上圖,紅色部分就相當于我們的面板。

代碼思路:

  1. 設置一個和board數(shù)組一樣行數(shù)的int數(shù)組命名位copy,每一個int值表示board的每一行

  2. 初始化,采用位運算初始化copy數(shù)組

  3. 遍歷復制矩陣的每一個元素,查看其周圍八個位置的狀態(tài),統(tǒng)計1的個數(shù)

    • 根據(jù)題目提到的判定規(guī)則:少于 2 個或者大于 3 個 1 就判定當前位置為 0

    • 等于 2 個 1 那么當前位置不需要更改

    • 如果等于 3 個 1 那么當前位置如果為 0 需要改為 1

    • 對于邊角位置需要額外處理防止越界

2.4 思路四——壓榨空間到極致

既然我們已經(jīng)完成了思路三的代碼,我想大家應該更清楚位運算的特點。這時我們再看看面板,面板中每一個位置是不是一個int值?那就是32位(假設java在通常情況下),而面板中的值0或者1肯定只用了最后一位,就像下面這樣:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

是不是這么多位置都空著想不想做點什么?空著的就是空間啊,由于1 <= m, n <= 25,那么是不是我們就可以用每一行的行首元素來當作我們思路三的copy數(shù)組,還是進行位運算操作,但是就不需要額外的空間了。

思路和思路三相似,但是唯一的改變就是我們將copy數(shù)組放在了board面板的每一行行行首位置而已。

比如對于題目中的示例:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

將它放大看就是這樣:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

其中藍色部分就是我們充當copy數(shù)組的位置。

比如對于題目中的

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

它轉化后的結果位:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

對應的二進制位為:

  1. 1073741824 is represented as 01000000000000000000000000000000

  2. 536870912 is represented as 00100000000000000000000000000000

  3. -536870911 is represented as 11100000000000000000000000000001

  4. 0 is represented as 00000000000000000000000000000000

代碼思路

  1. 初始化,采用位運算初始化copy數(shù)組(實際上就是board的第一個元素的相應位)

  2. 遍歷復制矩陣的每一個元素,查看其周圍八個位置的狀態(tài),統(tǒng)計1的個數(shù)

    • 根據(jù)題目提到的判定規(guī)則:少于 2 個或者大于 3 個 1 就判定當前位置為 0

    • 等于 2 個 1 那么當前位置不需要更改

    • 如果等于 3 個 1 那么當前位置如果為 0 需要改為 1

    • 對于邊角位置需要額外處理防止越界

  3. 最后需要更新第一列恢復為原來的值

2.5 思路五——壓榨空間到極致2

改代碼是看了自在飛花的解釋學到的,確實很厲害,因為他寫的c++版本,我在這解釋一下核心思想,并寫一個java版本。

這段代碼的核心思路是兩遍掃描棋盤:

  1. 第一遍掃描,計算每個細胞周圍活細胞的數(shù)量,并用第二個比特位來存儲細胞是否應該存活。由于細胞的狀態(tài)是用0(死)和1(活)來表示的,所以作者通過按位與操作&1來獲取當前細胞的狀態(tài),也就是只取int的最后一位,也就是0或者1,僅累加最低位,來計算周圍的存活細胞個數(shù)。

  2. 第二遍掃描,通過右移操作>>= 1來更新細胞的狀態(tài)。這是因為在第一遍掃描中,如果一個細胞在下一代應該是活的,那么它的第二個比特位將被設置為1。通過右移一位,我們可以用這個第二比特位來覆蓋原來的狀態(tài),從而更新棋盤。

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

  1. 同時在代碼中使用了兩個數(shù)組dx和dy,他們用來表示周圍的八個位置,減少了遍歷周圍八個位置的for循環(huán)造成變量k或者l的重復開辟空間。

這個代碼我就直接附在這里了:

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

其實效果和思路四差不多,但是思路值得借鑒。

補充

count的優(yōu)化

如果還想繼續(xù)優(yōu)化還是有優(yōu)化空間的,比如我們的count作為一個計數(shù)變量,是可以放在某一個board元素里面的,因為它的最大值不會超過8,因為周圍最多也就八個元素。這樣用一個3個bit就可以存儲起來。

dx和dy優(yōu)化

同時dx和dy也可以優(yōu)化,因為dx和dy的范圍就是在-1到1之間,因此可以用兩個bit來存儲一個值,dx和dy總共有8組,也就是16個元素,那么用32個bit就可以存儲所有的dx和dy。

當然上面的優(yōu)化有點太瘋狂了,但是我們要舉一反三想到這些思路。

3. 代碼實現(xiàn)

3.1 思路一——暴力求解

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

3.2 思路二——原地算法

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

3.3 思路三——優(yōu)化(位運算)

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

在Java中,表達式 (copy[k] & (1 << (31 - l))) 并不直接結果為0或1,而是執(zhí)行了一個按位與(&)操作,這個操作的結果取決于copy[k]在指定位上的值。這里的操作細節(jié)如下:

  • 1 << (31 - l):這部分是位移操作。它將數(shù)字1向左移動(31 - l)位。這意味著,如果l為0,那么1將被移動到最高位(假設是32位整數(shù)),如果l是其他值,1就會被移動到相應的位置上。這樣做的目的是為了生成一個只在特定位置上有一個1的整數(shù),其他位置都是0。

  • copy[k] & (1 << (31 - l)):這部分是按位與操作。它比較copy[k]和上面計算出的數(shù)值,在每個位上進行邏輯與操作。只有當copy[k]在相應的位上也是1時,這個操作的結果在那個位上才是1,否則結果為0。因此,這個表達式的結果是一個整數(shù),它在大多數(shù)位上都是0,在特定的位上可能是0或者是2的某次冪(取決于l的值)。如果你想判斷這個操作的結果是否為非零(即判斷copy[k]在(31 - l)位上是否為1),你可以將整個表達式與0進行比較:

<span style="background-color:#f8f8f8"><span style="color:#008855">boolean</span> <span style="color:#000000">isBitSet</span> <span style="color:#981a1a">=</span><span style="color:#777777"> (</span><span style="color:#000000">copy</span><span style="color:#777777">[</span><span style="color:#000000">k</span><span style="color:#777777">] </span><span style="color:#981a1a">&</span> <span style="color:#777777">(</span><span style="color:#116644">1 << </span><span style="color:#777777">(</span><span style="color:#116644">31</span> <span style="color:#981a1a">-</span> <span style="color:#000000">l</span><span style="color:#777777">))) </span><span style="color:#981a1a">!=</span> <span style="color:#116644">0</span><span style="color:#777777">;</span></span>

如果你的目的是確保結果嚴格為0或1,你需要進一步處理這個表達式,例如通過判斷表達式是否非零來將結果轉換為0或1:

<span style="color:#777777"><span style="background-color:#f8f8f8"><span style="color:#008855">int</span> <span style="color:#000000">bitValue</span> <span style="color:#981a1a">=</span> (<span style="color:#000000">copy</span>[<span style="color:#000000">k</span>] <span style="color:#981a1a">&</span> (<span style="color:#116644">1</span> << (<span style="color:#116644">31</span> <span style="color:#981a1a">-</span> <span style="color:#000000">l</span>))) <span style="color:#981a1a">!=</span> <span style="color:#116644">0</span> <span style="color:#981a1a">?</span> <span style="color:#116644">1</span> : <span style="color:#116644">0</span>;</span></span>

這樣,bitValue就會根據(jù)copy[k]在(31 - l)位上是否為1來分別存儲1或0。

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

3.4 思路四——位運算,但是copy存儲在board數(shù)組中

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

面試經(jīng)典150題——生命游戲,算法,java,數(shù)據(jù)結構

4. 相關復雜度分析

解法一:額外的復制矩陣

時間復雜度:O(MN),其中M是行數(shù),N是列數(shù)。因為需要遍歷整個矩陣兩次,一次復制,一次計算。空間復雜度:O(MN),因為需要一個同樣大小的矩陣來存儲復制。

解法二:原地修改

時間復雜度:O(M*N),同樣需要遍歷整個矩陣來計算周圍活細胞的數(shù)量??臻g復雜度:O(1),除了原數(shù)組外,沒有使用額外的空間,只是利用了額外的狀態(tài)來標記中間狀態(tài)。

解法三:位運算

時間復雜度:O(M*N),需要遍歷整個矩陣來計算??臻g復雜度:O(M),雖然沒有使用額外的矩陣,但是使用了一個數(shù)組來存儲行的狀態(tài)。

解法四:位運算,但是copy存儲在board數(shù)組中

時間復雜度:O(M*N),遍歷整個矩陣。空間復雜度:O(1),所有操作都在原地完成,沒有使用額外的存儲空間。

解法五:位運算,將結果存儲在每個元素的左邊一位

時間復雜度:O(M*N),需要遍歷整個矩陣來計算??臻g復雜度:O(1),所有操作都在原地完成,沒有使用額外的存儲空間。

在上述解法中,除了第一種解法需要和原矩陣一樣的額外空間,第三種解法使用了一個數(shù)組來存儲行的狀態(tài),其他方法都采取了原地算法,即在原數(shù)組上直接修改,大大節(jié)約了空間。文章來源地址http://www.zghlxwxcb.cn/news/detail-833657.html

到了這里,關于面試經(jīng)典150題——生命游戲的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 經(jīng)典面試題:玩家進游戲場地分配號碼、判斷括號是否閉合、提取回文串字符的分析和 php 程序實現(xiàn) - 經(jīng)典數(shù)據(jù)結構面試

    ? ? 給定一長串字母和符號,里面有三種括號包括([{}])這些,需要判斷這三種括號必須是配對的。即這三類括號要么不出現(xiàn),要出現(xiàn)必須是先出現(xiàn)左邊的括號,然后出現(xiàn)右邊的,中間括號可以嵌套。 ? ? 定義一個字符對應關系數(shù)組,初始化一個數(shù)組棧。所以進入的左邊符號入

    2024年04月25日
    瀏覽(29)
  • 200個經(jīng)典面試題(算法思想+數(shù)據(jù)結構)_1

    1. 爬樓梯 70. Climbing Stairs (Easy) 題目描述:有 N 階樓梯,每次可以上一階或者兩階,求有多少種上樓梯的方法。 定義一個數(shù)組 dp 存儲上樓梯的方法數(shù)(為了方便討論,數(shù)組下標從 1 開始),dp[i] 表示走到第 i 個樓梯的方法數(shù)目。 第 i 個樓梯可以從第 i-1 和 i-2 個樓梯再走一步

    2024年02月13日
    瀏覽(21)
  • 面試經(jīng)典 150 題 - 多數(shù)元素

    面試經(jīng)典 150 題 - 多數(shù)元素

    給定一個大小為 n 的數(shù)組 nums ,返回其中的多數(shù)元素。多數(shù)元素是指在數(shù)組中出現(xiàn)次數(shù) 大于 ? n/2 ? 的元素。 你可以假設數(shù)組是非空的,并且給定的數(shù)組總是存在多數(shù)元素。 示例 1: 輸入:nums = [3,2,3] 輸出:3 示例 2: 輸入:nums = [2,2,1,1,1,2,2] 輸出:2 進階:嘗試設計時間復

    2024年01月23日
    瀏覽(20)
  • 面試經(jīng)典150題【11-20】

    面試經(jīng)典150題【11-20】

    用一個哈希表和一個變長數(shù)組組成一個新的數(shù)據(jù)類型。 獲取隨機元素的話,直接random一個數(shù)然后從數(shù)組里取就行。 插入和刪除的話,先判斷有沒有這個數(shù),哈希表里存的是{ 數(shù)據(jù):在變長數(shù)組中的索引} 插入的話直接插變長數(shù)組末尾,然后再在哈希表里插 刪除的話,把最后一

    2024年02月21日
    瀏覽(25)
  • 面試經(jīng)典150題(82-83)

    leetcode 150道題 計劃花兩個月時候刷完,今天(第四十一天)完成了2道(82-83)150: 82.(133. 克隆圖)題目描述: 第一版(這個之前有過是拷貝二叉樹的時候和這個類似,利用map 映射就是當前節(jié)點和當前節(jié)點的復制節(jié)點) 第83題順序應該是 leetcode 的 《399. 除法求值》但是實在是

    2024年01月19日
    瀏覽(12)
  • 面試經(jīng)典150題(1)

    面試經(jīng)典150題(1)

    今天開始我將陸續(xù)為大家更新面試經(jīng)典150題中較難理解的題目。今天我為大家分享的是,除自身以外數(shù)組的乘積、跳躍游戲| 和 跳躍游戲||。 除自身以外數(shù)組的乘積 給你一個整數(shù)數(shù)組 nums,返回 數(shù)組 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘積 。 題目數(shù)據(jù)

    2024年02月10日
    瀏覽(61)
  • 面試經(jīng)典150題(88-89)

    leetcode 150道題 計劃花兩個月時候刷完,今天(第四十四天)完成了2道(88-89)150: 88.(22. 括號生成) 題目描述: 第一版(沒通過,我想法是 ()的全排列然后找出來符合的并且去重。。超時了) 第二版(看了解題) 89.(79. 單詞搜索)題目描述: 第一版(沒超時,但是效率墊

    2024年01月18日
    瀏覽(17)
  • 面試經(jīng)典150題(78-81)

    leetcode 150道題 計劃花兩個月時候刷完,今天(第三十六天)完成了4道(78-81)150: 78.(230. 二叉搜索樹中第K小的元素)題目描述: 第一版(銘記??!二叉搜索樹的中序遍歷為遞增的) 79.(98. 驗證二叉搜索樹)題目描述: 第一版(我第一反應就是遞歸,但是遞歸了好久沒弄出

    2024年02月02日
    瀏覽(17)
  • 【面試經(jīng)典150 | ?!孔钚? decoding=

    【面試經(jīng)典150 | 棧】最小棧

    【設計類】【?!?155. 最小棧 本題是一個設計類的題目,設計一個最小棧類 MinStack() 實現(xiàn): MinStack() :初始化堆棧對象; void push(int val) :將元素val推入堆棧; void pop() :刪除堆棧頂部的元素; int top() :獲取堆棧頂部的元素; int getMin() :獲取堆棧中的最小元素。 維護兩個

    2024年02月08日
    瀏覽(40)
  • 面試經(jīng)典150題(85-87)

    leetcode 150道題 計劃花兩個月時候刷完,今天(第四十三天)完成了3道(85-87)150: 85.(77. 組合)題目描述: 第一版(昨天就是這個卡了好久沒弄出來,今天還是沒思路啊。??戳私忸},感覺都是一個for 然后for里面嵌套??纯唇忸}的代碼吧) 86.(46. 全排列)題目描述: 第一版

    2024年01月18日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包