牛客——双指针

1.合并两个有序的数组

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这道题不能直接用append,因为他在最开始的时候就将前面那一个数组扩充了。

class Solution:
    def merge(self , A, m, B, n):
        # write code here
        if n ==0:
            return A
        # 从后往前 m+n长度,但是序号要减一
        while m> 0 and n>0:# 相当于是循环了2n下
            if A[m-1]> B[n-1]:
                A[m+n-1] = A[m-1]
                m -= 1
            else:
                A[m+n-1] = B[n-1]
                n -= 1
        if n > 0: A[:n] = B[:n]  # B还有剩余 剩余是因为前面的数字比较小了 直接放在前面就行了
        return A

简单的方法

class Solution:
    def merge(self , A, m, B, n):
        # write code here
        A[m:]=B
        return A.sort()

2. 判断是否为回文字符串

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution:
    def judge(self , str: str) -> bool:
        # write code here
        left,right=0,len(str)-1
        while left<right:
            if str[left] !=str[right]:return False
            else:
                left+=1
                right-=1
        return True

简单的方法

class Solution:
    def judge(self , str: str) -> bool:
        # write code here
        if str==str[::-1]:return True
        else: return False

3.合并区间

在这里插入图片描述
在这里插入图片描述

class Solution:
    def merge(self , intervals: List[Interval]) -> List[Interval]:
        # write code here
        if not intervals:
            return []
        intervals.sort(key = lambda x :x.start)
        # 这里的start和end可以看作是开始和结尾,每个矩阵都有的那种
        # 换一种写法
        # intervals.sort(key = lambda x :x[0])
        res = [intervals[0]]
        for i in intervals[1:]:
            if i.start > res[-1].end:
                res.append(i)
            elif i.end >= res[-1].end:# res也是一个二维矩阵 所以这个-1代表的是当前res内部最后一个
                res[-1].end = i.end
        return res

4.最小覆盖子串(找到能覆盖小字串的最小子串)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution:
    def minWindow(self , S , T ):
        # write code here
        c,l = 0,0##指针
        res = ""##设置的小窗口
        min_l = len(S) + 1
        d = {}
  
        for i in T:
            d[i] = d.get(i,0) + 1
        for r in range(len(S)):
            if S[r] in T:
                if d[S[r]]>0:
                    c += 1
                d[S[r]] = d[S[r]] - 1  
            # S[r]在新的窗口中,就减1,,表示已经拥有了一个
            while c==len(T):##缩小串口范围
                if S[l] in T:
                    if min_l > r-l+1:
                        min_l = r-l+1
                        res = S[l:r+1]
                    d[S[l]] = d[S[l]] + 1
                    if d[S[l]]>0:##表示c对应的元素是否已经在窗口中集齐,集齐一个减一个
                        c -= 1
                l += 1
        return res

下面是另一种解题的方法

from collections import defaultdict
class Solution:
    def minWindow(self , S: str, T: str) -> str:
        # write code here
        # 双指针 未包含所有字符时,右指针移动,若包含了所有,收缩左指针
        need = defaultdict(int)
        for t in T:
            need[t] += 1
        needCnt = len(T)
        i = 0
        res = (0,float("inf"))
        for j, s in enumerate(S):
            if need[s] > 0:
                needCnt -= 1
            need[s] -= 1
            if needCnt == 0: # 步骤1:滑动窗口包含了T中所有元素
                while True:  # 步骤2:增加i,排除多余元素
                    c = S[i]
                    if need[c] == 0:
                        break
                    need[c] += 1
                    i += 1
                if  j - i < res[1] - res[0]:
                    res = (i,j) #记录结果
                need[S[i]] += 1
                needCnt += 1
                i += 1
        return '' if res[1] > len(S) else S[res[0]:res[1]+1]

以上两种都不会就是了

5.反转字符串

在这里插入图片描述
在这里插入图片描述

class Solution:
    def solve(self , str: str) -> str:
        # write code here
        l=list(str)
        left,right=0,len(str)-1
        while left<right:
            l[left],l[right] =l[right],l[left]
            left+=1
            right-=1
        return "".join(l)
###########################
# 最简单的方法
#         return str[::-1]

6.最长无重复子数组

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
借助了哈希表和两个指针

class Solution:
    def maxLength(self , arr: List[int]) -> int:
        # write code here
        n = len(arr)
        if(n == 1): return 1
        a, b = 0, 1# 两个指针
        m = 1# 最长距离
        hashMap = {}
        hashMap[arr[a]] = a
        while(b <= (n - 1)):
            if(arr[b] not in hashMap):
                hashMap[arr[b]] = b
                b += 1
            else:
                m = max(b - a, m)
                temp = hashMap[arr[b]] + 1
                for i in range(a,temp):
                    hashMap.pop(arr[i])
                a = temp
                hashMap[arr[b]] = b
                b += 1
        m = max(b - a, m)
        return m

没咋看懂

7.盛水最多的容器(两个边界最大且长度也得长)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution:
    def maxArea(self , height: List[int]) -> int:
        # write code here
        left, right = 0, len(height) - 1
        res = 0
        if len(height) < 2:
            return res
        while left < right:
            res = max(res, (right - left) * min(height[left], height[right]))
            # 更新条件 下面是在更新left和right
            if height[left] < height[right]:# 左边高度小于右边的高度
                tmp = height[left]
                left += 1
                while left < right and height[left] <= tmp:# 在找下一个比当前大的
                    left += 1
            else:# 左边高度不小于右边的高度
                tmp = height[right]
                right -= 1
                while right > left and height[right] <= tmp:# 在找下一个比当前大的
                    right -= 1
        return res

8.接雨水问题(找波谷)

类似上一道题 但是这个不再是找两块板之间,而是每两块板都有一个雨水的承接量。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

class Solution:
    def maxWater(self , arr: List[int]) -> int:
        # write code here
        area = 0
        left = 0
        right = len(arr) - 1
        temp_h = 0
        while left <= right:
            min_h = min(arr[left], arr[right])
            if min_h > temp_h:
                area += (min_h - temp_h)*(right - left + 1)# 把凹进去的补满
                temp_h = min_h
            while left<=right and temp_h>=arr[left]:
                left += 1
            while left<=right and temp_h>=arr[right]:
                right -= 1
        area -= sum(arr)# 利用差值在计算
        return area
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值