算法练习day1补充

文章介绍了在编程挑战中,如何使用暴力破解和快慢指针两种方法解决空间复杂度为O(1)的移除数组元素问题,对比了两种方法的时间复杂度并强调了注意事项。
摘要由CSDN通过智能技术生成

前言

昨天第一天时间太赶,没来得及把剩下的一题看了,今天补回来。

移除元素

代码随想录 移除元素

力扣 27.移除元素

(用时1小时)

这道题的解法有两种,一种是暴力破解,一种是快慢指针法。

注意题目要求空间复杂度是O(1),这表明需要在同一个数组中进行处理。

暴力破解

暴力破解很简单,两层嵌套循环。

  • 外层循环用于遍历整个数组,如果找到需要移除的元素,则开启内层循环。

  • 内存循环用来将该需移除元素后面的所有元素向前挪一位(题目要求元素原顺序不可变)。这样的时间复杂度大概是O(n^2)

注意重点

暴力破解时,有个地方要注意:所有元素移完位置后,外层循环的循环遍历(一般是那个i),要 i-- 。

  • i--主要是因为,我们原本在这个第i位上发现他是要移除的,才将后面所有的元素前移一位。

  • 移完后第i位已经不是原来的那个元素了,此时需要再判断移动后的第i位是不是恰好也是要移除的元素

  • 可能会有连续几个元素都是要移除的

快慢指针法

快慢指针需要小绕一下。

  • 快指针是对整个数组进行探索遍历,慢指针是对新的数组进行赋值遍历

  • 如果反应不过来,可以先把慢指针当成一个新的空的数组的指针。快指针对旧的数组进行遍历:

    1.如果不是需要移除的元素,则利用慢指针加入新数组的空位中,慢指针向后移一位。快指针后移一位。

    2.如果是需要移除的元素,新数组和慢指针不做处理。快指针后移一位。

  • 两个数组的想好了后,一个数组就简单了。只是将两个指针放到了同一个数组上进行处理。慢指针一定会等于或慢于快指针,因此不会出现问题。

注意重点

快慢指针法在写的时候,重点要考虑以下几点:(

  • arr[fastIndex] != val时,要做什么?

  • arr[fastIndex] = val时,要做什么?

  • return slowIndex? 还是slowIndex+1? 还是slowIndex-1?

以下是个人的一些想法:

  • nums[fastIndex] != val时,要做什么?

    不等于时,表示该值不用被跳过,slowIndex要让其放入新数组。更新slowIndex,fastIndex继续探索既可。

  • nums[fastIndex] = val时,要做什么?

    等于时,表示该值要被跳过,slowIndex不能放入新数组。让fastIndex继续向前探索即可。

  • return什么?

    slowIndex始终是等待赋值的下一位,因此只用return slowIndex即可。

代码实现

暴力破解

/// <summary>
/// 暴力破解法
/// </summary>
/// <param name="nums"></param>
/// <param name="val"></param>
/// <returns></returns>
public int RemoveElementFun2(int[] nums, int val)
{
    int cnt = 0;
    for (int i = 0; i < nums.Length - cnt; i++)
    {
        if (nums[i] == val)
        {
            for (int j = i + 1; j < nums.Length - cnt; j++)
            {
                nums[j - 1] = nums[j];
            }
            cnt++;
            i--;
        }
    }
    return nums.Length - cnt;
}

双指针法

/// <summary>
/// 快慢指针方法
/// </summary>
/// <param name="nums"></param>
/// <param name="val"></param>
/// <returns></returns>
public int RemoveElementFun(int[] nums, int val)
{
    int fastIndex, slowIndex;
    fastIndex = slowIndex = 0;
​
    while (fastIndex < nums.Length)
    {
        if (nums[fastIndex] != val)
        {
            nums[slowIndex] = nums[fastIndex];
            fastIndex++;
            slowIndex++;
        }
        else
        {
            fastIndex++;
        }
    }
​
    return slowIndex;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值