[英雄星球六月集训LeetCode解题日报] 第五日 双指针

一、 2000. 反转单词前缀

链接: 2000. 反转单词前缀

1. 题目描述

给你一个下标从 0 开始的字符串 word 和一个字符 ch 。找出 ch 第一次出现的下标 i ,反转 word 中从下标 0 开始、直到下标 i 结束(含下标 i )的那段字符。如果 word 中不存在字符 ch ,则无需进行任何操作。

例如,如果 word = “abcdefd” 且 ch = “d” ,那么你应该 反转 从下标 0 开始、直到下标 3 结束(含下标 3 )。结果字符串将会是 “dcbaefd” 。
返回 结果字符串

2. 思路分析

直接模拟,由于python切片翻转过于方便,就不手写双指针了。

3. 代码实现

class Solution:
    def reversePrefix(self, word: str, ch: str) -> str:
        i = word.find(ch)
        if i == -1:
            return word
        return ''.join(reversed(word[:i+1]))+word[i+1:]

二、 917. 仅仅反转字母

链接: 917. 仅仅反转字母

1. 题目描述

给你一个字符串 s ,根据下述规则反转字符串:

所有非英文字母保留在原有位置。
所有英文字母(小写或大写)位置反转。
返回反转后的 s 。

2. 思路分析

可恶,现在我必须手写对向双指针了。
现在我发现python的str是不支持下标修改的,只能先转list最后再join。

3. 代码实现

class Solution:
    def reverseOnlyLetters(self, s: str) -> str:
        s = list(s)
        l, r = 0, len(s)-1
        while l < r :
            while l<r and not ord('a')<=ord(s[l])<=ord('z') and not ord('A')<=ord(s[l])<=ord('Z') :
                l += 1
            while  l<r and not ord('a')<=ord(s[r])<=ord('z') and not ord('A')<=ord(s[r])<=ord('Z') :
                r -= 1
            s[l],s[r] = s[r],s[l]
            l += 1
            r -= 1
        return ''.join(s)

三、 475. 供暖器

链接: 475. 供暖器

1. 题目描述

冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。

在加热器的加热半径范围内的每个房屋都可以获得供暖。

现在,给出位于一条水平线上的房屋 houses 和供暖器 heaters 的位置,请你找出并返回可以覆盖所有房屋的最小加热半径。

说明:所有供暖器都遵循你的半径标准,加热的半径也一样。

2. 思路分析

  1. 题意实际上是对每个house,找最近的那个加热器有多远,最后取max。
  2. 那么可以对heaters排序,然后二分即可,具体思路是:
    • k = bisect(heaters,h) ,那么离房子最近的热水器一定在[k,k-1]两个之中(k一定是房子右边第一个加热器,k-1是房子左边第一个或房子本身)
  3. 实际上,对房子也排序,那么可以同向双指针,因为随着房子后移,热水器的位置一定也后移。这样只需要O(m+n)
    这题和第四题是兄弟题。

3. 代码实现

class Solution:
    def findRadius(self, houses: List[int], heaters: List[int]) -> int:
        houses.sort()
        heaters.sort()
        m,n = len(houses) ,len(heaters)
        ans = 0
        r = bisect.bisect(heaters,houses[0])
        for h in houses:            
            while r < n and heaters[r] <= h:
                r += 1
            left=right = 10**9+1
            if r-1>=0:
                left = abs(h-heaters[r-1])
            if r < n:
                right = abs(h-heaters[r])
            # print(h,r,left,right)
            ans = max(ans,min(left,right))
        return ans

四、 面试题 16.06. 最小差

链接: 面试题 16.06. 最小差

1. 题目描述

给定两个整数数组a和b,计算具有最小差绝对值的一对数值(每个数组中取一个值),并返回该对数值的差

2. 思路分析

和第三题的区别在于:第三题求最小差的最大值,本体求最小值。
如果有相等,0一定是最小值,可以提前返回。
这里换一种更直白的同向双指针写法。

3. 代码实现

class Solution:
    def smallestDifference(self, a: List[int], b: List[int]) -> int:
        a.sort()
        b.sort()
        m,n = len(a) ,len(b)
        ans = 2**32
        i=j=0
        while i < m and j < n:
            ans = min(ans,abs(a[i]-b[j]))
            if a[i] < b[j]:
                i += 1
            elif b[j] < a[i]:
                j += 1
            else:
                return 0
        return ans

五、参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值