[算法]数组 移除元素

例题

27. 移除元素

  • 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。

  • 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。

  • 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

双指针法

通过快慢指针在一个for循环下完成两个for循环的工作。

  • 快指针:查找符合要求的新数组的元素,也就是需要保留的元素。
  • 慢指针:指向更新后的数组下标,慢指针最后指向的下标就是新数组的大小。
// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowindex = 0;	// 慢指针	
        for(int fastindex = 0; fastindex < nums.size(); fastindex++){
    	    if(val != nums[fastindex]){
    		    nums[slowindex++] = nums[fastindex];	// 把快指针所在元素赋值给慢指针所在元素,慢指针后移
		}
	}
	return slowindex;	// 慢指针下标即为新数组大小
    }
};

刷题

26. 删除有序数组中的重复项

将升序数组中重复出现的元素原地删除,保持元素相对顺序不变。

  • 快慢指针都应该从1开始,因为第0个元素无论如何都不应该被删除。
  • 判断条件是快指针指向元素与其左侧那个元素不相等。

283. 移动零

将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

  • 在数组中“删去”全部的0,即将非零元素依次移到数组开头。
  • 另外写一个for循环,将慢指针后面的元素赋值为0

844. 比较含退格的字符串(难)

给定 st 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

  • 方法一:双指针法依次比较
    • 对两个字符串各用一个指针,从后向前依次遍历,把能跳过的字符跳过,然后两字符串进行比较:若不同,直接为假。
    • 如此循环,直到两者中至少有一个循环到头。
    • 如果两个指针同时指到-1,则为真,反之为假。
    • 注意:这里不能直接计数有多少个#,就向前移动多少个字符。而要一个一个字符地判断。
      • 反例:bxo#j##t 退格完成后应该是bt,但如果从后往前遍历的过程中,计数到t之前有2#,就直接向前移到o,则错过了j左边的#,而实际上它也能起到退格的作用。
  • 方法二:双指针法模拟
    • 采用模拟的手段写一个函数,返回原字符串完成退格后的字符串,然后比较st经过处理的字符串即可。
    • 与例题类似,快慢指针从前向后依次遍历,快指针找到非#元素就将其赋值给慢指针。
    • 与例题不同的是,快指针找到#元素后,若慢指针大于0,应该将慢指针回退,从而完成退格。

977. 有序数组的平方

说明:此题是数组的第四部分,由于可以采用双指针法,就一并放到了本文。

给你一个按非递减顺序排序的整数数组 nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。

  • 数组nums是按非递减顺序排列的,所以如果所有数都是非负数,那直接按顺序平方即可,当然此题也就没有了意义,所以关键是要处理好负数。
  • 这个数组类似于数轴,也就是只会在数组左右两端取得平方后的最大值,我们其实是要按照元素绝对值大小进行排序。
  • 于是考虑定义左右两指针i j,分别比较两边的平方值,平方值大的取出来,从后向前赋值给result数组,然后对指针i j执行自增或自减操作。
  • 如此循环,直到i>j,注意这里i==j时仍要进入循环,否则中间剩下的这个元素就会被丢弃。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值