【LeetCode刷题-Python】双指针

27.移除元素

27.移除元素

题目

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

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

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

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

代码

  • 利用双指针
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        a=0
        b=0
        for a in range(len(nums)):
        #while a<len(nums):
            if(nums[a]!=val):
                nums[b]=nums[a]
                b+=1
            a+=1

        return b

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

删除有序数组中的重复项

题目

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

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

代码

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        a=1
        b=1
        while a<len(nums):
            if(nums[a]!=nums[a-1]):# !!!!
                nums[b]=nums[a]
                b+=1
            a+=1
        return b

总结

  • 双指针法
  • a与a-1进行比较而不是b

283. 移动零

283. 移动零

题目

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

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

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

输入: nums = [0]
输出: [0]

代码

class Solution(object):
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        a=0
        b=0
        while(a<len(nums)):
            if(nums[a]!=0):
                nums[b]=nums[a]
                b+=1
            a+=1
        while(b<len(nums)):
             nums[b]=0
             b+=1
        return nums

844. 比较含退格的字符串

844. 比较含退格的字符串

题目

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

输入:s = “ab#c”, t = “ad#c”
输出:true
解释:s 和 t 都会变成 “ac”。

输入:s = “ab##”, t = “c#d#”
输出:true
解释:s 和 t 都会变成 “”。

代码

一个字符是否会被删掉,只取决于该字符后面的退格符,而与该字符前面的退格符无关。因此当我们逆序地遍历字符串,就可以立即确定当前字符是否会被删掉。
具体地,我们定义 \textit{skip}skip 表示当前待删除的字符的数量。每次我们遍历到一个字符:

  • 若该字符为退格符,则我们需要多删除一个普通字符,我们让skip 加 1;
  • 若该字符为普通字符:
  • 若skip 为 0,则说明当前字符不需要删去;
  • 若skip 不为 0,则说明当前字符需要删去,我们让skip 减 1。
    这样,我们定义两个指针,分别指向两字符串的末尾。每次我们让两指针逆序地遍历两字符串,直到两字符串能够各自确定一个字符,然后将这两个字符进行比较。重复这一过程直到找到的两个字符不相等,或遍历完字符串为止。
class Solution(object):
    def backspaceCompare(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        i,j=len(s)-1,len(t)-1
        skipS=skipT=0
        while i>=0 or j>=0:
            while i>= 0:
                if s[i]=="#":  
                    skipS+=1
                    i-=1
                elif skipS>0:
                    skipS-=1
                    i-=1
                else:
                    break
            while j>=0:
                if t[j]=="#":
                    skipT+=1
                    j-=1
                elif skipT>0:
                    skipT-=1
                    j-=1
                else:
                    break
            if i >=0 and j>=0:
                if s[i]!=t[j]:
                    return False
            elif i>=0 or j>=0:  #  要求两个同时满足
                return False
            i-=1
            j-=1
        
        return True

猜你喜欢

转载自blog.csdn.net/Magnolia_He/article/details/129781203