仍然是双指针,发现在知道大致指导思路的情况下很容易直接往那方面想,暂且还是对自己多一些自信
今天的题目是 633 平方数之和 ,345 反转字符串中的元音字母
首先看 633 平方数之和
要找到两个数,明显是二维搜索问题,二维搜索的边界是这道题的重点,通过观察不难发现边界其实是有约束的,实际上,边界是一个半径为的半圆。但是利用双指针进行搜索时,我们不用考虑那么多,因为并不会像暴力搜索那样搜索整个区域。
整个算法的流程和普通双指针法基本相似,不再赘述
python代码为
import math
class Solution:
def judgeSquareSum(self, c: int) -> bool:
N = int(math.sqrt(c))
i = 0
j = N
while i <= j:
sum = i * i + j * j
if sum == c:
return True
elif sum < c:
i = i + 1
else:
j = j - 1
return False
接下来看345 反转字符串中的元音字母
这题做的真是惨不忍睹,一开始我是这么想的(贼朴实)
- 从最左和最右插两个指针i和j,判断四种情况:
- 若i元音,j元音,交换i,j处的字符,i++ j- -
- 若i元音,j辅音,j- -
- 若i辅音,j元音,i++
- 若i辅音,j辅音,i++,j- -
- 循环直至i>j
代码如下
class Solution:
def reverseVowels(self, s: str) -> str:
N = len(s)
arr = list(s)
Y = ['a','e','i','o','u','A','E','I','O','U']
i = 0
j = N-1
while i < j:
if arr[i] in Y and arr[j] in Y:
arr[i] , arr[j] = arr[j] , arr[i]
i = i + 1
j = j - 1
elif arr[i] in Y and arr[j] not in Y:
j = j - 1
elif arr[i] not in Y and arr[j] in Y:
i = i + 1
else:
i = i + 1
j = j - 1
return ''.join(arr)
即使是这么朴实的代码,也有好几处需要注意:
- 需要先用一个list(代码中为arr)将字符串装起来,否则不能进行交换操作
- 两个都是元音,交换完以后必须移动指针!(忘记好多次)
然而速度贼慢orz
改之后是这样的
class Solution:
def reverseVowels(self, s: str) -> str:
N = len(s)
arr = list(s)
Y = {'a','e','i','o','u','A','E','I','O','U'}
i = 0
j = N-1
while i < j:
if arr[i] not in Y:
i = i + 1
elif arr[j] not in Y:
j = j - 1
else:
arr[i] , arr[j] = arr[j] , arr[i]
j = j - 1
i = i + 1
return ''.join(arr)
原因如下:
- if条件的归并。这样写相当于,每次只移动一个指针,先移动左边的指针直至元音,再移动右边的指针直至元音。一开始的方法有时可以直接移动两个指针(如左右两边都是辅音时)。孰优孰劣由测试集决定。显然给的测试集中第二种方法更快。
- 将List变为set,在判断集合归属关系时更快
来源:CSDN
作者:vox_xov
链接:https://blog.csdn.net/qq_36300268/article/details/104681691