力扣--双指针

双指针(2)

  • 回文字符串
  • 归并两个有序数组
  • 判断链表是否存在环(更新。。。)
  • 最长子序列(更新。。。)

1.回文字符串
力扣680
使用双指针很容易判断一个字符串是不是回文,本题的关键是删除一个字符后判断是不是回文。在双指针遍历字符串时,如果出现两个指针指向的字符不相等的情况,我们就试着删除一个字符,可以删除左指针指向的字符,也可以删除右指针指向的字符,再判断删除后的字符串是不是回文。其实我们会发现,删除后字符串的范围为(low+1,high)或者(low,high-1),只要这两个子串任意一个是回文,那么结果就是回文,否则就不是。

class Solution:
    def validPalindrome(self, s: str) -> bool:
        if s==s[::-1]:
            return True
        low=0
        high=len(s)-1
        while low<high:
             if s[low]!=s[high]:
                 a=s[low+1:high+1]
                 b=s[low:high]
                 return a==a[::-1] or b==b[::-1]
             else:
                 low+=1
                 high-=1    

时间复杂度O(n):n是字符串的长度。
空间复杂度O(n):判断是否回文使用了 [::-1] 翻转形成了新字符串。

2.归并两个有序数组
力扣88
方法一:双指针/从前往后
对于有序数组,最直接的算法就是将指针p1置为nums1的开头,p2置为nums2的开头,在每一步将最小值放入输出数组中。

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.
        """
        #双指针,从前往后
        nums1_copy=nums1[:m]
        nums1[:]=[]
        p1=0
        p2=0
        while p1<m and p2<n:
            if nums1_copy[p1]<nums2[p2]:
                nums1.append(nums1_copy[p1])
                p1+=1
            else:
                nums1.append(nums2[p2])  
                p2+=1  
        if p1<m:
            nums1[p1+p2:]=nums1_copy[p1:]
        if p2<n:
            nums1[p1+p2:]=nums2[p2:]    

时间复杂度O(m+n)
空间复杂度O(m):由于nums1是用于输出的数组,需要将nums1的前m个元素放在其他地方,也就是O(m)的空间复杂度

方法二:双指针/从后往前
刚才的方法已经取得了最优的时间复杂度O(m+n),但需要额外的空间。改进:从后往前遍历,因为nums1的空间都集中在后面,节省空间。p1,p2分别指向nums1,nums2的有数字尾部,p指向nums1的最尾部,一边遍历(比较大小)一边填充(将大的填充到p)。

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.
        """
        #双指针/从后往前
        p1=m-1
        p2=n-1
        p=m+n-1
        while p1>=0 and p2>=0:
            if nums1[p1]<nums2[p2]:
                nums1[p]=nums2[p2]
                p2-=1
            else:
                nums1[p]=nums1[p1]
                p1-=1
            p-=1
        nums1[:p2+1]=nums2[:p2+1]#nums2中还有数据没有拷贝完,将其直接拷贝在nums1前面    

时间复杂度O(m+n)
空间复杂度O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值