Leetcode刷题笔记 - 数组(双指针法)

数组常用方法:二分查找、双指针法、滑动窗口,双指针法包括快慢指针法和对撞指针法,主要适用于针对数组作增加、删除、移动、排序的一系列操作

Leetcode27 移除元素

【题目描述】

【可用方法】

1.方法一:暴力枚举

两层for循环,第一层先遍历数组,找数组中等于目标值的节点,如果找不到则更新第一层循环指针,如果找到借助第二层循环将i之后的数组元素都向前移位,此时数组长度len需要-= 1,同时i-1判断i原先后面的数组元素与目标值的关系,然后继续第一层循环

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        i = 0
        nums_len = len(nums)
        while i < nums_len:
            if nums[i] == val: # 找到等于目标值的节点
                for j in range(i + 1, nums_len): # 移除该元素,并将后面元素向前平移
                    nums[j - 1] = nums[j]
                nums_len -= 1
                i -= 1
            i += 1
        return nums_len

2.方法二:快慢指针

定义两个指针count和i,count是慢指针,i是快指针,快指针通过一个for循环遍历数组,将数组中不等于目标值的元素放入count索引的位置,然后更新count指针

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        count = 0
        for i in range(len(nums)):
            if nums[i] != val:
                nums[count] = nums[i] 
                count = count + 1
        return count

【相关题目】

26 删除排序数组中的重复项

283 移动零

844 比较含退格的字符串

977 有序数组的平方


Leetcode26  删除排序数组中的重复项

【题目描述】

【可用方法】 

1.方法一:暴力枚举

注:超出运行时间超出限制

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        i = 1
        l = len(nums)
        while(i < l):
            if nums[i] == nums[i - 1]:
                for j in range(i + 1,l):
                    nums[j-1] = nums[j]
                l -= 1
                i -= 1
            i += 1
        return l

2.方法二:快慢指针

首先定义两个指针,然后将slow和fast分别赋值为1(第一个元素一定不重复),借助快指针从1开始遍历数组,如果相等快指针正常更新,当快指针遍历到的元素与前面元素不相等时,更新数组元素,此时慢指针加1

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        fast = 1
        slow = 1
        size = len(nums)
        while(fast < size):
            if nums[fast] != nums[fast-1]:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        return slow

Leetcode283  移动零

【题目描述】

 【可用方法】

1.方法一:暴力枚举

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        i = 0
        l = len(nums)
        while i < l:
            if nums[i] == 0: 
                for j in range(i + 1, l): 
                    nums[j - 1] = nums[j]
                l -= 1
                i -= 1
            i += 1
        for i in range(l,len(nums)):
            nums[i] = 0

2.方法二:快慢指针

与27题移除元素类似,此题主要是借助双指针移除值等于0的元素,然后在非零元素之后补零到原数组长度

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        index = 0
        for i in range(len(nums)):
            if nums[i] != 0:
                nums[index] = nums[i]
                index = index + 1
        for i in range(index,len(nums)):
            nums[i] = 0

Leetcode844 比较含退格的字符串

【题目描述】

 【可用方法】

1.方法一:暴力解法

待补充

2.方法二:快慢指针

没做

3.方法三:栈的特性

定义一个函数,用于重构字符串,该函数下定义一个空栈ret,遍历字符串,如果字符ch不是'#',则压入栈中,如果字符是'#',则弹出栈外,实现退格(通过if判断栈的长度是否为0,避免空栈的弹出造成报错),最后通过join函数返回重构后的字符串

join函数的用法:连接任意数量的字符串(包括要连接的元素字符串、元组、列表、字典),用新的目标分隔符连接,返回新的字符串

示例:'sep'.join(sep_object),sep为分隔符,sep_object为分割对象,可以为字符串、以及储存字符串的元组、列表、字典等

class Solution:
    def backspaceCompare(self, s: str, t: str) -> bool:
        def build(s: str) -> str:
            ret = []
            for ch in s:
                if ch != '#':
                    ret.append(ch)
                else:
                    if len(ret) != 0:
                        ret.pop()
            return "".join(ret)
        return build(s) == build(t)

Leetcode977 有序数组的平方

【题目描述】

【可用方法】

1.方法一:暴力解法

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        for i in range(len(nums)):
            nums[i] = nums[i] ** 2

        nums.sort()
        return nums

2.方法二:对撞指针

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        n = len(nums)
        res = [0]*n
        i, j, pos = 0, n - 1, n - 1
        while(i <= j):
            if nums[i] * nums[i] >= nums[j] * nums[j]:
                res[pos] = nums[i] ** 2
                i += 1
            else:
                res[pos] = nums[j] ** 2
                j -= 1
            pos -= 1
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值