小白学算法之移除元素(双指针法!)

力扣27:移除元素

题目内容:

给你一个数组 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。

思路:双指针法,定义两个快慢指针,fast指针负责从第0个元素开始遍历,检查数组,slow负责收集不等于val的元素,并在数组前进行替换。

def removeElement(nums, val):
    slow = 0
    for fast in range(len(nums)):
        if nums[fast] != val:
            nums[slow] = nums[fast]
            slow += 1
    return slow # return在for循环的外部

nums = [3,2,2,3]
val = 2
r = removeElement(nums, val)
print(r)

同类型变式:

力扣26:删除有序数组的重复项

给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k 。

 思路:双指针,首先,如果nums为空,返回0,此时可以直接用if not来做,定义两个快慢指针,fast用来遍历检查数组,slow负责接收前后不相等的值。

if not condition:
    # 如果condition为假(False),执行这里的代码
    

condition 为假的情况,condition等于None, False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()

def removeDuplicates(nums):
    if not nums:
        return 0
    slow = 1 # 因为是去除重复项,所以默认第0个是唯一的
    for fast in range(1, len(nums)):
        if nums[fast] != nums[fast-1]:
        # 使用 if nums[fast] != nums[fast - 1]: 是为了检查当前元素是否与前一个元素不同,以便找到新的唯一元素并更新 slow 指针。
        # 如果使用 if nums[fast] == nums[fast - 1]:,则只会处理重复的情况,而不会将唯一元素添加到结果中,从而导致错误的结果。
            nums[slow] = nums[fast]
            slow += 1
        fast += 1
    return slow

nums = [0,0,1,1,1,2,2,3,3,4]
print(removeDuplicates(nums))

力扣283:移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

思路: 把所有不含零的都放在前面,剩下的位置都放0

def moveZero(nums):
    slow = 0
    for fast in range(len(nums)):
        if nums[fast] != 0:
            nums[slow] = nums[fast]
            slow += 1


    for i in range(slow, len(nums)):
        nums[i] = 0

nums = [0,1,0,3,12]
# print(moveZero(nums))   # 这样输出的是None,因为moveZero没有返回值,print直接输出的返回值
moveZero(nums)  # 调用函数
#nums = moveZero(nums) 
# print(nums) 
# 这样写,输出None的原因:
# moveZero 函数必须返回一个值才能赋值给 nums。但 moveZero 函数并没有返回任何值,导致 nums 被赋值为 None。
print(nums)   # [1, 3, 12, 0, 0]

力扣844:比较含退格的字符串

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

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

思路:先定义一个函数,处理字符串,把它们变成删掉回退之后的样子,定义一个栈,如果string里的char不是'#', 就把它放进栈里,否则,就弹出栈的最后一个元素,用"拼接

def backspaceCompare(s,t):
    def processString(string):
        stack = []
        # for char in range(len(string)):   # TypeError: sequence item 0: expected str instance, int found
        # 原因:char上面那样的话就是索引,而不是字符本身
        for char in string:
            if char != "#":
                stack.append(char)
            elif stack != []:
                stack.pop()
        return ''.join(stack)

    process_s = processString(s)
    process_t = processString(t)

    return process_s == process_t

s = "ab#c"
t = "ad#c"
print(backspaceCompare(s,t))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值