移除元素(c語言)

給定一個數組 nums 和一個值 val,你需要原地移除所有數值等於 val 的元素,返回移除後數組的新長度。
不要使用額外的數組空間,你必須在原地修改輸入數組並在使用 O(1) 額外空間的條件下完成。
元素的順序可以改變。你不需要考慮數組中超出新長度後面的元素。
示例 1:
給定 nums = [3,2,2,3], val = 3,
函數應該返回新的長度 2, 並且 nums 中的前兩個元素均爲 2。
你不需要考慮數組中超出新長度後面的元素。
示例 2:
給定 nums = [0,1,2,2,3,0,4,2], val = 2,
函數應該返回新的長度 5, 並且 nums 中的前五個元素爲 0, 1, 3, 0, 4。
注意這五個元素可爲任意順序。
你不需要考慮數組中超出新長度後面的元素。
說明:
爲什麼返回數值是整數,但輸出的答案是數組呢?
請注意,輸入數組是以“引用”方式傳遞的,這意味着在函數裏修改輸入數組對於調用者是可見的。
你可以想象內部操作如下:
// nums 是以“引用”方式傳遞的。也就是說,不對實參作任何拷貝
int len = removeElement(nums, val);
// 在函數裏修改輸入數組對於調用者是可見的。
// 根據你的函數返回的長度, 它會打印出數組中該長度範圍內的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/remove-element
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

int removeElement(int* nums, int numsSize, int val)
{
    if(numsSize==0)
    return 0;
    int *a1,*a2;
    int i=0;
    for(a1=nums;*a1!=val;a1++,i++)//指針a1移動了i次
    {
        if(i==numsSize-1)
        return i+1;//解決數組中沒有val的情況。
    }
    a2=a1+1;
    for(int j=i;j<numsSize-1;j++)
    {
        if(*a2!=val)
        {
            *a1=*a2;
            a1++;
            i++;//i用來記錄a1移動的次數。
        }
        a2++;//j用來記a2移動的次數,保證指針a2不會指向數組外的元素
    }
    return i;
}

分析:該題與刪除重複項類似,都是使用兩個指針,主要步驟如下:
1.首先分析該數組是否爲空
2.找出數組中第一個等於val的元素,用指針a1指向該元素,並記錄此時a1的位置。
(要考慮數組中沒有val的情況,以免因此而使指針越界)
3.定義與a1相鄰的指針a2,用a2來檢測後面與a1不同的元素,用a1來記錄該元素的值。當a2指向的元素與val不同時,此時將a1所指向的數組元素的值改爲*a2,a1,a2向前移動。反之,a2向前移動。
值得注意的是,i,j的值分別代表什麼?i用來記錄a1移動的次數,用來計算去除了與val值相同的元素後數組的長度,此處最後一次移動使a1指向了新數組外面的元素(不考慮數組內沒有與val相等的元素的情況),故新數組的長度=i。j的只用來記錄指針a2的位置,防止指針超出了原數組的位置。
不足:該代碼在運行速度何所佔內存上依舊不太理想。
改進:仍然是不需要重新定義兩個指針,直接修改數組元素。另一方面第一個for語句可以合併到第二個for語句中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章