領扣網演算法學習筆記 283

2021-08-31 10:02:09 字數 1954 閱讀 9933

本系列的演算法題目來自領扣網

給定乙個陣列nums,編寫乙個函式將所有0移動到陣列的末尾,同時保持非零元素的相對順序。

示例:

輸入: [0,1,0,3,12]

輸出: [1,3,12,0,0]

說明:

必須在原陣列上操作,不能拷貝額外的陣列。

儘量減少操作次數。

思路一:

看到這題的第乙個思路是:檢測到0後,將陣列後面的數往前移,往陣列的末尾補0,這樣就確保在原陣列上操作,且不用拷貝額外的陣列。

**如下:

class

solution

nums[arraylength-1]

=0;// 將末位置0

i--; arrlength--;}

}}}

後續思考:

該**在領扣上用時37ms

這樣做的話,陣列是只用遍歷一次,但是陣列沒出現乙個0,移動陣列裡的元素的代價(次數)就很大,於是就思考能不能不移動,

思路二:

當出現0時我不移動,只是繼續往後讀,當往後讀遇到不是0的時候,將資料移到是0的位置,

於是我定義乙個變數用來記錄0所在的位置,但是又遇到乙個新問題,這個變數怎麼賦初值(就是起始0在哪),

這個問題其實很多餘,遍歷的資料不同,起始的0的位置也不同,沒辦法固定,所以我直接遍歷,當出現第乙個0 的時候就設定這個值。然後繼續往下遍歷,不是0就與當前位置交換,當陣列遍歷完後,在之前的陣列長度與目前記錄0的位置的值的差值就是要補的0的個數,於是再補0就好。

**如下:

class

solution

}for

(i++

;iif(locationnum !=0)

}}}// 用時2ms

領扣上面該題其他高質量範例:
class

solution}}

}// 用時1ms

自我整理:這部分**精簡,我看第一遍直接暈了,第二遍才反應過來,思路是這樣的:

定義乙個變數 j 用來迴圈賦值

迴圈陣列

判斷當前迴圈值是不是為0,不為0,就將當前值與迴圈變數位置的值進行交換,然後將迴圈變數往前移一位

如果是0,則跳過

這**比我的優在不用去找第乙個0 在哪,直接迴圈就ok了,

但是我覺得,如果乙個較大的陣列,裡面0的數量較少,那麼這個演算法我感覺就會時間變長,不能算是最優的,因為沒乙個不為0 的數,它都要執行額外的三條語句。畢竟剛入門演算法,它的複雜度我暫時還不會算,所以只是個人猜想。

class

solution

}while

(idx < nums.length)}}

// 用時2ms

自我整理:這個**比我的要簡潔,我擦,看樣子我要優化我的**了,這個思路很清晰:

定義乙個變數用來記錄非 0 的數量

將不是0的資料儲存出來(這裡只是讀取不是0的變數,然後一直儲存,不是像我之前那樣後面的資料全部往前移)

將0補齊

class

solution

else

}for

(int i = nums.length-count;i}// 用時3ms

自我整理:這個演算法思路也很清晰:

定義兩個變數,乙個記錄0的個數,乙個記錄當前資料已經儲存到那個位置了

然後迴圈陣列,遇到0,記錄 0 的個數就加一,不是0,就儲存資料,記錄當前儲存位置的變數就+1

後面就再補齊0

自我總結:演算法我覺得精簡是一條優化的道路,但是精簡的**不代表執行效率就高,但是我目前很明顯的缺點是:邏輯是怎樣,**就怎樣寫,導致**過長,這一點反應了我的邏輯思維還不夠好,還需要鍛鍊。

領扣網演算法學習筆記 215

本系列的演算法題目來自領扣網 在未排序的陣列中找到第k個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。示例 輸入 3,2,1,5,6,4 和 k 2 輸出 5 輸入 3,2,3,1,2,4,5,5,6 和 k 4 輸出 4說明 你可以假設 k 總是有效...

領扣網演算法學習筆記 167

本系列的演算法題目來自領扣網 給定乙個已按照 公升序排列 的有序陣列,找到兩個數使得它們相加之和等於目標數。函式應該返回這兩個下標值 index1 和 index2,其中 index1 必須小於 index2。示例 輸入 numbers 2,7,11,15 target 9 輸出 1,2 解釋 2 ...

演算法 學習筆記

1.輸入輸出演算法至少有乙個或多個輸出 2.有窮性 3.確定性 4.可行性 1.正確性a.演算法程式沒有語法錯誤 b.演算法程式對於合法的輸入資料能夠產生滿足要求的輸出結果 c.演算法程式對於非法的輸入資料能夠得出滿足規格說明的結果 d.演算法對於精心選擇的,甚至刁難的測試資料都有滿足要求的輸出結果...