双指针(1)
- 1.有序数组的两数之和(简单)
- 2.两数平方和(中等)
- 3.反转字符串中的元音字符(简单)
1.有序数组的两数之和
解题思路:
初始时两个指针分别指向第一个元素位置和最后一个元素位置。每次计算两个指针指向的两个元素之和,并和目标值比较。如果这两个元素之和等于目标值,则发现了唯一解。如果这两个元素之和小于目标值,则将左侧指针右移一位。如果两个元素之和大于目标值,则将右侧指针左移一位。移动指针后,重复上述操作,直到找到答案。
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
left=0
right=len(numbers)-1
while left<=right:
if numbers[left]+numbers[right]==target:
return [left+1,right+1]
elif numbers[left]+numbers[right]<target:
left=left+1
else:
right=right-1
时间复杂度O(n),其中n是数组长度。两个指针移动的总次数最多为n次。
空间复杂度O(1)。
2.两数平方和
解题思路:
设置两个指针,一个i从0开始,一个j从c的1/2次方开始,记录i平方+j平方的值,如果比c要大,那么j左移;如果比c小,则i右移,重复以上操作,找到则返回True,直到i>j。如果i>j还没有找到结果,则返回False。
class Solution:
def judgeSquareSum(self, c: int) -> bool:
i=0
j=int(pow(c,1/2))
while i<=j:
total=i**2+j**2
if total==c:
return True
elif total<c:
i=i+1
else:
j=j-1
return False
时间复杂度O(sqrt(target)),因为最多只需要遍历一次0~sqrt(target)。
空间复杂度O(1)。
3.反转字符串中的元音字符
解题思路:
使用双指针,一个指针从头向尾遍历,一个指针从尾向头遍历,当两个指针的遍历到元音字符时,交换这两个元音字符,需要把str转换成list处理,最后再用join转回str。为了快速判断一个字符是不是元音字符,可将全部元音字符添加到集合vowels中。用set会比用list更快。
class Solution:
def reverseVowels(self, s: str) -> str:
left=0
right=len(s)-1
s=list(s)
vowels=set("aeiouAEIOU")
while left<right:
if s[left] in vowels and s[right] in vowels:
s[left],s[right]=s[right],s[left]
left+=1
right-=1
if not s[left] in vowels:
left+=1
if not s[right] in vowels:
right-=1
return "".join(s)
时间复杂度O(n):只需要遍历所有元素一次
空间复杂度O(1):只需要使用两个额外变量