數組與鏈表
數組與鏈表,在數據結構中都屬於線性表。所謂線性表,是指所有元素都排列在一個維度上;對其中的任意一個元素來說,除了頭和尾,都有且只有一個前驅元素和一個後繼元素。
數組
數組的實現邏輯
儲存:數組儲存在連續的內存中。
訪問:因爲數組存儲的內存連續,因此支持隨機訪問。所謂隨機訪問,也就是直接下標操作。
增加:因爲數組內存的連續性,因此若要增加元素,爲保持數組的線性,必須把此元素之後的所有元素依次後移。
刪除:刪除同理增加元素,必須把元素依次前移,以保證數組的線性和完整性。
數組的時間複雜度
操作 | 時間複雜度 |
---|---|
追加 | O(1) |
查找 | O(1) |
插入 | O(n) |
刪除 | O(n) |
鏈表
鏈表的實現邏輯
存儲:鏈表可以用任意的存儲單元進行存儲,也就是說鏈表的存儲可以是連續的內存單元,也可以是不連續的內存單元。
結構:由於鏈表的非連續存儲,因此對於連接元素的表示,除了本身的值之外,還需要存儲元素的下一個元素的指針。
訪問:鏈表的特性決定其失去了線性表隨機訪問的特性。查找特定的值需要遍歷鏈表。
增加:在特定的位置增加鏈表的元素,非常簡單,只需要移動對應的下一元素的指針即可。
刪除:在鏈表中刪除元素,需要移動刪除前元素的下一個元素指針到刪除後的元素即可。
鏈表的時間複雜度
操作 | 時間複雜度 |
---|---|
追加 | O(1) |
查找 | O(n) |
插入 | O(1) |
刪除 | O(1) |
鏈表的分類
- 單向鏈表:普通鏈表,每一個元素僅有指向下一元素的指針;
- 雙向鏈表:每一個元素不僅有指向下一元素的指針,還有指向前一個元素的指針;
- 循環鏈表:鏈表的未元素有指向頭元素的指針,形成循環;
LeetCode相關題目
移動零
LeetCode題目 移動零:
題目內容:
給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。
說明:
- 必須在原數組上操作,不能拷貝額外的數組。
- 儘量減少操作次數。
解題思路:
題目要求在原數組上操作,因此不能使用額外數組的方式解決。
- 遍歷數組,遇見0直接刪除,在不夠的位置補0.數組的刪除時間複雜度爲O(n),因此這種方式也是複雜度最高的;
- 遍歷,遇見0則移到最後,非0移到前面,其複雜度也方式1一致;
- 使用雙指針,遇見0進行交換,時間複雜度爲O(n),空間複雜度爲O(1)。
public void moveZeroes(int[] nums) {
if(nums == null){
return;
}
int j = 0; // j和i是兩個指向數組的指針
for(int i = 0; i < nums.length; i++){
if(nums[i] != 0){ //非0元素,移到前面
nums[j++] = nums[i];
}
}
for(int i = j; i < nums.length; i++){
nums[i] = 0; // 後邊的全是0
}
}