力扣刷题笔记 移除元素以及相关题目(含ACM模式)

文章介绍了使用双指针法解决编程问题,包括删除有序数组中的重复项、移动零、比较含退格的字符串以及对有序数组进行平方和合并的操作,展示了在ACM模式下的代码实现和实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《代码随想录》学习笔记,原链接:https://programmercarl.com/

27.移除元素

(1)题目分析

(2)双指针法

(3)双指针法代码

(4)ACM模式

移除元素相关题目

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

(2)283.移动零

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

(4)977.有序数组的平方

(5)88.合并两个有序数组


27.移除元素

力扣题目链接

(1)题目分析

        数组删除某个元素,并不是直接删除,而是后面的元素前移来覆盖掉删除位置的元素。因此,删除前后数组所占的内存大小是不变的。

        如上图所示,原数组size为8,删除元素2后size变为6,而最后两个元素未处理,即后面两个位置的元素是什么无所谓。但需要注意的是,删除后数组的内存大小依然为8,只是有的编程语言会对数组进行包装,在erase()删除元素后,计数器会自动执行- 1操作,使得数组的size - 1。

【注】erase()函数用于删除数组中的某一个元素,时间复杂度为O(n),而不是O(1)。

(2)双指针法

        双指针法(快慢指针法):通过一个快指针和慢指针,在一个for循环下完成两个for循环的工作。

  • 快指针:获取新数组的元素。
  • 慢指针:获取新数组中需要更新的位置下标。

(3)双指针法代码

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        # 双指针法
        slow, fast = 0, 0

        while fast < len(nums): # 不加等于是因为,fast = len(nums)时,nums[fast] 会越界
            if nums[fast] != val:
                nums[slow] = nums[fast] # slow用来收集不等于val的值,如果fast对应值不等于val,则把它赋值给nums[slow]
                slow += 1
            fast += 1
            
        return slow

【注】range()函数是左包含、右不包含,即range(2)只能取到0和1两个值。

(4)ACM模式

class Solution:
    def removeElement(self, nums, val):
        # 双指针法
        slow, fast = 0, 0

        while fast < len(nums):  # 不加等于是因为,fast = len(nums)时,nums[fast] 会越界
            if nums[fast] != val:
                nums[slow] = nums[fast]  # slow用来收集不等于val的值,如果fast对应值不等于val,则把它赋值给nums[slow]
                slow += 1
            fast += 1

        return slow

# 自定义数据列表和要删除的元素值
nums = list(map(int, input("输入整数数组:").split(",")))
val = int(input("输入要删除的元素:"))

# 移除元素
solution = Solution()
result = solution.removeElement(nums, val)
print(result)

【注】list(map(int, input("输入已排序的整数数组:").split(","))),分析:

  • input() 函数:用于从用户输入获取一个由逗号分隔的整数组成的字符串。
  • split() 方法:用于将输入的字符串按照逗号分隔成多个子字符串,并返回子字符串构成的列表。如输入1,2,3时,将返回['1', '2', '3']。
  • map() 函数:用于对子字符串列表中的每个元素应用指定的函数。具体来说,map() 函数接收两个参数,第一个参数是一个函数,第二个参数是一个可迭代对象,它将该函数依次作用于可迭代对象中的每个元素,并返回一个由结果组成的新的可迭代对象。例如map(int, ['1', '2', '3']) ,会将字符串列表中的每个元素转换为整数类型,并返回一个由整数组成的新的可迭代对象 [1][2][3]。
  • int() 函数:用于将字符串转换为整数类型的函数。
  • list() 函数:用于将可迭代对象 [1][2][3]转换为列表类型[1, 2, 3],从而得到用户输入的整数列表。

移除元素相关题目

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

力扣题目链接

  • 核心代码模式
class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        slow = fast = 0

        while fast < len(nums):
            if nums[fast] != nums[slow]:
                slow += 1
                nums[slow] = nums[fast]
            fast += 1

        return slow + 1
  • ACM模式
class Solution:
    def removeDuplicates(self, nums):
        slow = fast = 0

        while fast < len(nums):
            if nums[fast] != nums[slow]:
                slow += 1
                nums[slow] = nums[fast]
            fast += 1

        return slow + 1

# 自定义数据列表
nums = list(map(int, input("输入整数数组:").split(",")))

# 删除有序数组中的重复项
solution = Solution()
result = solution.removeDuplicates(nums)
print(result)

(2)283.移动零

力扣题目链接

  • 核心代码模式 
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        slow = fast = 0

        while fast < len(nums):
            if nums[fast] != 0:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        
        for i in range(len(nums[slow: ])):    # slow等于数组中非0元素的个数
            nums[slow + i] = 0    # 数组末尾元素全部置0

【注】 for i in range(len(nums[slow: ])):中,slow表示数组中非0元素的个数。以nums = [0,1,0,3,12]为例,在while循环结束后slow = 3。

  • 由于a: b表示左闭右开区间[a, b)的整数切片,而当b省略时默认表示列表的lenth,所以len(nums[slow: ]) = len(nums[3: 5]) = len(nums[3, 4]) = 2。
  • 由于range()函数也是左包含、右不包含,因此range(len(nums[slow: ]) = range(2) = 0, 1两个值。

  •  ACM模式
class Solution:
    def moveZeroes(self, nums):
        """
        Do not return anything, modify nums in-place instead.
        """
        slow = fast = 0

        while fast < len(nums):
            if nums[fast] != 0:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1

        for i in range(len(nums[slow:])):  # slow等于数组中非0元素的个数
            nums[slow + i] = 0  # 数组末尾元素全部置0

        return nums

# 自定义数据列表
nums = list(map(int, input("输入整数数组:").split(",")))

# 删除数组中的0
solution = Solution()
result = solution.moveZeroes(nums)
print(result)

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

  • 核心代码模式
class Solution:
    def backspaceCompare(self, s: str, t: str) -> bool:

        def stringProcess(string):
            slow = 0    # 构建双指针
            stringList = list(string)   # 字符串不可修改,先转换成列表

            for fast in range(0, len(stringList)):   # 循环遍历字符串列表
                if stringList[fast] == '#': # 如果当前为退格符
                    slow -= 1
                    if slow < 0: # 防止超出列表范围
                        slow = 0
                else:
                    stringList[slow] = stringList[fast] # 更新原字符串列表
                    slow += 1

            newString = "".join(stringList[:slow])  # 生成退格之后的字符串
            return newString
        
        # 对含有退格的字符串进行处理
        sNew = stringProcess(s)
        tNew = stringProcess(t)
        
        return sNew == tNew # 返回两个处理后的字符串是否相等的判断结果

【注】关于字符串的修改和合并:

  • ACM模式
class Solution:
    def backspaceCompare(self, s, t):

        def stringProcess(string):
            slow = 0  # 构建双指针
            stringList = list(string)  # 字符串不可修改,先转换成列表

            for fast in range(0, len(stringList)):  # 循环遍历字符串列表
                if stringList[fast] == '#':  # 如果当前为退格符
                    slow -= 1
                    if slow < 0:  # 防止超出列表范围
                        slow = 0
                else:
                    stringList[slow] = stringList[fast]  # 更新原字符串列表
                    slow += 1

            newString = "".join(stringList[:slow])  # 生成退格之后的字符串
            return newString

        # 对含有退格的字符串进行处理
        sNew = stringProcess(s)
        print(sNew)
        tNew = stringProcess(t)
        print(tNew)

        return sNew == tNew  # 返回两个处理后的字符串是否相等的判断结果

# 输入待比较的两个字符串
s = input('输入字符串s:')
t = input('输入字符串t:')

# 比较含退格的字符串
solution = Solution()
result = solution.backspaceCompare(s, t)
print(result)

(4)977.有序数组的平方

  • 核心代码模式
class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        result = [float("inf")] * len(nums)     # 初始化存放平方结果的列表
        i, j, k = 0, len(nums) - 1, len(nums) - 1

        while i <= j:   # 从两边到中间,平方值从大到小倒序存放在result中
            if nums[i] ** 2 < nums[j] ** 2:
                result[k] = nums[j] ** 2
                j -= 1
            else:
                result[k] = nums[i] ** 2
                i += 1
            k -= 1

        return result

【注】result = [float("inf")] * len(nums),初始化result列表,其中float("inf")表示每个元素初始化为﹢∞,len(nums)表示初始化列表的长度。由于之后会有通过下标访问列表中元素的操作result[k],因此不能单纯result = [],需要提前初始化列表的长度。

  • ACM模式
class Solution:
    def sortedSquares(self, nums):
        result = [float("inf")] * len(nums)     # 初始化存放平方结果的列表
        i, j, k = 0, len(nums) - 1, len(nums) - 1

        while i <= j:   # 从两边到中间,平方值从大到小倒序存放在result中
            if nums[i] ** 2 < nums[j] ** 2:
                result[k] = nums[j] ** 2
                j -= 1
            else:
                result[k] = nums[i] ** 2
                i += 1
            k -= 1

        return result


# 自定义数据列表
nums = list(map(int, input("输入要进行平方的列表:").split(",")))

# 有序数组的平方
solution = Solution()
result = solution.sortedSquares(nums)
print(result)

(5)88.合并两个有序数组

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        i, j, k = m - 1, n - 1, m + n - 1

        while i >= 0 and j >= 0:    # 将合并结果倒序存放到nums1中
            if nums1[i] < nums2[j]:
                nums1[k] = nums2[j]
                j -= 1
            else:
                nums1[k] = nums1[i]
                i -= 1
            k -= 1

        if i == -1:     # 如果nums1中的元素已经全部被访问,则将nums2中的剩余元素直接按照原排序存放
            while k >= 0:
                nums1[k] = nums2[j]
                j -= 1
                k -= 1
    

【注】语法a:b,表示从索引a到索引b(不包含b),如果省略a则默认为0,如果省略b则默认为序列的长度(如len(nums2)。如crop[:2],表示取crop[0]和crop[1]两个元素,并不包含crop[2]。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值