【演算法-初級-陣列】刪除排序陣列中的重複項(多語言版實現)
? 部落格說明與致謝
??? 文章所涉及的部分資料來自網際網路整理,其中包含自己個人的總結和看法,分享的目的在於共建社群和鞏固自己。
??? 引用的資料如有侵權,請聯絡本人刪除!
❤️?❤️?❤️? 感謝萬能的網路!
??? 以及勤勞的自己,個人部落格,GitHub學習,GitHub
??? 如果你感覺對你有幫助的話,不妨給我點贊鼓勵一下,好文記得收藏喲!關注我一起成長!
??? 幸好我在,感謝你來!
? 演算法說明
語言只是實現演算法的一種手段,思路才是最為重要的。
如果有多種解法的話,只選一種語言作為解答對比。
如果單獨將某一種演算法的話,會以多種語言實現,對比語言的特性。
?因為多對多的話,篇幅會拉的比較大,影響觀看體驗!
? 題目
地址
給你一個有序陣列 nums ,請你 原地 刪除重複出現的元素,使每個元素 只出現一次 ,返回刪除後陣列的新長度。
題目說明
不要使用額外的陣列空間,你必須在 原地 修改輸入陣列 並在使用 O(1) 額外空間的條件下完成。
說明
為什麼返回數值是整數,但輸出的答案是陣列呢?
請注意,輸入陣列是以「引用」方式傳遞的,這意味著在函式裡修改輸入陣列對於呼叫者是可見的。
你可以想象內部操作如下:
// nums 是以“引用”方式傳遞的。也就是說,不對實參做任何拷貝
int len = removeDuplicates(nums);
// 在函式裡修改輸入陣列對於呼叫者是可見的。
// 根據你的函式返回的長度, 它會列印出陣列中 該長度範圍內 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例 1
輸入:nums = [1,1,2]
輸出:2, nums = [1,2]
解釋:函式應該返回新的長度 2 ,並且原陣列 nums 的前兩個元素被修改為 1, 2 。不需要考慮陣列中超出新長度後面的元素。
示例 2
輸入:nums = [0,0,1,1,1,2,2,3,3,4]
輸出:5, nums = [0,1,2,3,4]
解釋:函式應該返回新的長度 5 , 並且原陣列 nums 的前五個元素被修改為 0, 1, 2, 3, 4 。不需要考慮陣列中超出新長度後面的元素。
提示
0 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按升序排列
? 思路
暴力想法
(注意是暴力想法,不是暴力解法!)
作為直男直接就是想實現。
直接遍歷,看題目是已經確定了是有序的,遇到與上一個不相等的直接給他拿到新的陣列裡面存起來。遍歷完直接新陣列就是答案。
看樣子是很接近了哈!畢竟屬於簡單的題目。
但是, O(1) 額外空間的條件下完成這個是我們跨不過去的坎。既然如此那就得考慮在原陣列上操作。
原陣列上操作,先上雙指標!
雙指標
思路
快慢指標上場,快指標fast
,慢指標low
。
陣列是有序的,那麼重複的元素一定會相鄰。在同一個陣列裡面操作,也就是不重複的元素移到陣列的左側,最後取左側的陣列的值。
演算法流程
比較
fast
和low
位置的元素是否相等。迴圈執行:
- 如果相等,
fast
後移 1 位 - 如果不相等,將
low
前一位的值改為fast
,low
後移1位,fast
後移 1 位
- 如果相等,
迴圈結束:
fast
越界
- 迴圈結束,返回新陣列長度
low + 1
圖解
這將是最具有靈魂的一刻了。沒有圖解的演算法都是耍流氓!(哈哈哈,我會盡量把我之前的流氓行為更正過來哈!)
其實畫圖花了我很多的時間,但我覺得不虧,記得更深刻!
來個GIF吧!(用Python寫了一個將圖片生成GIF的小工具)
JavaScript
沒有什麼特別好說的,強行來一句的話,就是把nums
的長度計算拿上去,節約成本。
程式碼
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
// 判斷邊界
if (nums && nums.length < 0) {
return 0
}
var low = 0, fast = 1, n = nums.length;
while (fast < n) {
if (nums[fast] !== nums[low]) {
nums[low + 1] = nums[fast]
low++
}
fast++
}
return low + 1
};
Java
程式碼
class Solution {
public int removeDuplicates(int[] nums) {
if (nums == null || nums.length < 1) {
return 0;
}
int fast = 1, low = 0, n = nums.length;
while(fast < n) {
if (nums[fast] != nums[low]){
nums[low + 1] = nums[fast];
low++;
}
fast++;
}
return low + 1;
}
}
Python3
程式碼
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if not nums:
return 0
n = len(nums)
fast = 1
low = 0
while fast < n:
if nums[fast] != nums[low]:
nums[low + 1] = nums[fast]
low += 1
fast += 1
return low + 1
PHP
程式碼
class Solution {
/**
* @param Integer[] $nums
* @return Integer
*/
function removeDuplicates(&$nums) {
if ($nums == null || count($nums) < 0) {
return 0;
}
$fast = 1;
$low = 0;
$n = count($nums);
while ($fast < $n) {
if ($nums[$fast] != $nums[$low]) {
$nums[$low + 1] = $nums[$fast];
$low++;
}
$fast++;
}
return $low + 1;
}
}
Go
注意go語言是沒有while的
程式碼
func removeDuplicates(nums []int) int {
n := len(nums)
if n < 1 {
return 0
}
low := 0
for fast := 1; fast < n; fast++ {
if nums[fast] != nums[low] {
nums[low + 1] = nums[fast]
low++
}
}
return low + 1
}
C++
程式碼
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if (n < 1) {
return 0;
}
int fast = 1, low = 0;
while (fast < n) {
if (nums[fast] != nums[low]) {
nums[low + 1] = nums[fast];
low++;
}
fast++;
}
return low + 1;
}
};
C
程式碼
int removeDuplicates(int* nums, int numsSize){
if(numsSize == 0) {
return 0;
}
int fast = 1, low = 0;
while (fast < numsSize) {
if (nums[fast] != nums[low]) {
nums[low + 1] = nums[fast];
low++;
}
fast++;
}
return low + 1;
}
? 總結
從陣列開始,思考 ? 陣列提該如何提煉思路,從簡單到複雜一步一步拆解,也將程式語言的資料使用技能提升。