[英雄星球六月集训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. 思路分析
- 题意实际上是对每个house,找最近的那个加热器有多远,最后取max。
- 那么可以对heaters排序,然后二分即可,具体思路是:
- k = bisect(heaters,h) ,那么离房子最近的热水器一定在[k,k-1]两个之中(k一定是房子右边第一个加热器,k-1是房子左边第一个或房子本身)
- 实际上,对房子也排序,那么可以同向双指针,因为随着房子后移,热水器的位置一定也后移。这样只需要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