记录自己的LeetCode之day2(双指针2)

柔情痞子 提交于 2020-03-05 23:44:06

仍然是双指针,发现在知道大致指导思路的情况下很容易直接往那方面想,暂且还是对自己多一些自信
今天的题目是 633 平方数之和345 反转字符串中的元音字母
首先看 633 平方数之和
在这里插入图片描述
要找到两个数,明显是二维搜索问题,二维搜索的边界是这道题的重点,通过观察不难发现边界其实是有约束的,实际上,边界是一个半径为c\sqrt{c}的半圆。但是利用双指针进行搜索时,我们不用考虑那么多,因为并不会像暴力搜索那样搜索整个区域。
整个算法的流程和普通双指针法基本相似,不再赘述
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 反转字符串中的元音字母
在这里插入图片描述
这题做的真是惨不忍睹,一开始我是这么想的(贼朴实)

  1. 从最左和最右插两个指针i和j,判断四种情况:
  2. 若i元音,j元音,交换i,j处的字符,i++ j- -
  3. 若i元音,j辅音,j- -
  4. 若i辅音,j元音,i++
  5. 若i辅音,j辅音,i++,j- -
  6. 循环直至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)

即使是这么朴实的代码,也有好几处需要注意:

  1. 需要先用一个list(代码中为arr)将字符串装起来,否则不能进行交换操作
  2. 两个都是元音,交换完以后必须移动指针!(忘记好多次)

然而速度贼慢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)

在这里插入图片描述
原因如下:

  1. if条件的归并。这样写相当于,每次只移动一个指针,先移动左边的指针直至元音,再移动右边的指针直至元音。一开始的方法有时可以直接移动两个指针(如左右两边都是辅音时)。孰优孰劣由测试集决定。显然给的测试集中第二种方法更快。
  2. 将List变为set,在判断集合归属关系时更快
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!