LeetCode:27移除元素,优化体悟之观察也需要能量

27. 移除元素 - 力扣(LeetCode)

博主的水水文

事先声明一下,其它语言不知道,但是C语言的这优化和没优化是一点区别也看不出来(肉眼看不出来,是各有优势)

LeetCode:27移除元素,优化体悟之观察也需要能量_第1张图片

一般方法:快慢指针,(一个走得快,遇见非val就往慢的赋值)

优化的左右(前后)指针,(一个从前走,一个从后走,过一遍,当相遇时跳出)

博主自作聪明想着先用优化的这种思路去写,

结果水平不够,写不出来好代码,写出来的测试用例总是过不去,

如下是我的失败代码:

基本思路是很好弄,但是有很多小问题,比如测试用例仅是单个val就过不去,进不到循环,如果是多个val还会里面的循环越界啥的,很多小的问题,实属是顾及这些小而多的情况而增添许多的判断(也就是我标题想说的观察也需要能量,为了这些特殊情况,利用if判断观察反而浪费了资源)

int removeElement(int* nums, int numsSize, int val) {
    int* pfront = nums;
    int* ptail = nums + numsSize - 1;
    if(numsSize == 0){
        return 0;
    }
    while(pfront < ptail){
        if(*pfront == val){
            while(*ptail == val){
                if(ptail <= pfront){
                    return 0;
                }
                ptail--;
            }
            *pfront = *ptail;
            ptail--;
        }
            pfront++;
    }
    if(*pfront != val){
        pfront++;
    }
    return pfront - nums;
}

 我的借鉴了答案后的指针解法和一些感悟

这种解法就很巧妙,相比于我(失败代码)的后指针的移动方式,这个代码是将后指针指向的值赋值给前指针,再--(向前进一位),然后继续判断(属于是将复杂的判断做成了重复性的任务),多了赋值但优化了之前方法的关于判断后指针为了跳过val值而轻易--(向前进一位)造成的越界访问(事实上为了解决越界访问而加上if判断,就相比于这种解法显得臃肿了), 

此外,这种解法也有小细节,尾指针和平时设置的不一样,但这样反而节省了对于 [val] 这种仅有一个val的情况的判断,

int removeElement(int* nums, int numsSize, int val) {
    //assert(nums);
    int* pfront = nums;
    int* ptail = nums + numsSize;
    //为了把numsSize为1的情况扔进while循环,所以和平时不一样,少了-1
    while(pfront < ptail){
        if(*pfront == val){
            *pfront = *(ptail - 1);
            ptail--;
        }
        else{
            pfront++;
        }
    }
    return pfront - nums;
}

 

 官方解答:双指针(快慢指针)//其实用的是下标

int removeElement(int* nums, int numsSize, int val) {
    int left = 0;
    for (int right = 0; right < numsSize; right++) {
        if (nums[right] != val) {
            nums[left] = nums[right];
            left++;
        }
    }
    return left;
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/remove-element/solutions/730203/yi-chu-yuan-su-by-leetcode-solution-svxi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

官方解答:前后指针 //用的还是下标

int removeElement(int* nums, int numsSize, int val) {
    int left = 0, right = numsSize;
    while (left < right) {
        if (nums[left] == val) {
            nums[left] = nums[right - 1];
            right--;
        } else {
            left++;
        }
    }
    return left;
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/remove-element/solutions/730203/yi-chu-yuan-su-by-leetcode-solution-svxi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 好的,那么水完喽

你可能感兴趣的:(leetcode,算法,c语言)