Task05-数组双指针、滑动窗口

第12天

1.0344.反转字符串

描述:给定一个字符数组 s。

要求:将其反转。

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        left = 0
        right = len(s)-1
        while left < right:
            s[left],s[right] = s[right],s[left]
            left +=1
            right -=1
        return s

反思: 今天练习从这题起手,还是比较简单的,使用了两个元素互相交换的方法,当对撞指针相交时退出循环。

2.0345.反转字符串中的元音字母

描述:给定一个字符串 s。

要求:将字符串中的元音字母进行反转。

class Solution:
    def reverseVowels(self, s: str) -> str:
        arr=['a','e','i','o','u','A','E','I','O','U']
        left = 0
        right = len(s)-1
        s=list(s)
        while left < right:
            if s[left] in arr and s[right] in arr:
                    s[left],s[right] = s[right],s[left]
                    left +=1
                    right -=1
            if s[left] not in arr:
                left +=1
            if s[right] not in arr:
                right -=1
        s="".join(s)
        return s

反思: 在写这道题时,一开始没注意到字符串不能对串中的元素直接进行交换,于是查找资料,先把S转换为数组形式,这样就可以进行交换了。接着,使用了对撞指针并分别判定两指针所指元素是否为元音字母。这里需要注意的是,需要加上元音字母的大写形式,避免出错。

3.0015.三数之和

描述:给定一个整数数组nums。

要求:判断 nums中是否存在三个元素a、b、c,满足a+b+c==0。要求找出所有满足要求的不重复的三元组。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        if (not nums or len(nums)<3):
            return []
        n = len(nums)
        res = []
        nums.sort()
        for i in range(n):
            if nums[i]> 0 :
                return res
            if i>0 and nums[i]==nums[i-1]:
                continue
            L = i + 1
            R = n -1
            while L < R:
                if nums[i]+nums[L]+nums[R] == 0:
                    res.append([nums[i],nums[L],nums[R]])
                    while L < R and nums[L] == nums[L+1]:
                        L +=1
                    while L<R and nums[R]==nums[R-1]:
                        R -=1
                    L +=1
                    R -=1
                elif nums[i]+nums[L]+nums[R] > 0:
                    R-=1
                else:
                    L+=1
        return res

 反思:一开始做这道题时,是没什么思路的。浏览了一些题解后,才明白,原来双指针可以这么用。在外 i 循环表示第三个数,两个指针表示另外两个数,在依次判断。

第13天

1.0027.移除元素

描述:给定一个数组nums,和一个值val。

要求:不使用额外数组空间,将数组中所有数值等于val 值的元素移除掉,并且返回新数组的长度。

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        left =0
        right =0
        while right < len (nums):
            if nums[right ] != val:
                nums[left] = nums[right]
                left +=1
            right +=1
 
        return left

 反思:在写这道题时,可以想到使用快慢指针来解决,但是在最后呈现出的效果却不能移除掉元素,看了题解的方法后,才发现原来把问题复杂化了,于是把代码简化后,就顺利解决了问题。

2.0080.删除有序数组中的重复项Ⅱ

描述:给定一个有序数组nums。

要求:在原数组空间基础上删除重复出现 2 次以上的元素,并返回删除后数组的新长度。

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        left =0
        for i in range(len(nums)):
            if left < 2 or nums[i] != nums[left -2]:
                nums[left] = nums[i]
                left +=1
        return left

 反思:在写这道题时,我也想到了使用快慢指针来解决,但是对于一些条件的判断还是不能够清晰的划分。看了题解后,才觉思路清晰,对题解的方法加以研究后,终于解决。

3.0925.长按键入

描述:你的朋友正在使用键盘输入他的名字name。偶尔,在键入字符时,按键可能会被长按,而字符可能被输入 1 次或多次。

现在给定代表名字的字符串 name,以及实际输入的字符串typed。

要求:检查键盘输入的字符typed。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),就返回 True。否则返回 False

class Solution:
    def isLongPressedName(self, name: str, typed: str) -> bool:
        n = list(name)
        t = list(typed)
        left = 0 #name中的指针
        right =0 #typed中的指针
        while right <len(typed):
            if left < len(n) and name[left] == typed[right]:
                left +=1
                right +=1
            elif right > 0 and typed[right] == name[left - 1]:
                right +=1
            else:
                return False
        return left == len(name)

反思: 在这道题里,我想到了使用两个指针分别在两个字符串里遍历,但到后来便没有了思路。看了题解后,对两指针的移动有了认识,原来分离双指针是这么使用的。通过遍历时遇到元素的不同那么右指针便往前走一格,或者遇到了长按重复的字母,也往前走一格。最后就可以解决问题。

第14天

1.0643.子数组最大平均数Ⅰ

描述:给定一个由n个元素组成的整数数组nums和一个整数k。

要求:找出平均数最大且长度为k的连续子数组,并输出该最大平均数。

class Solution:#第一次的代码,超出了时间限制
    def findMaxAverage(self, nums: List[int], k: int) -> float:
        left =0
        right =0
        ans=0
        temp =0
        window_sum=0
        while right < len(nums):
            window_sum += nums[right]

            if right - left + 1 > k:
                window_sum -= nums[left]
                left +=1
            temp = window_sum / k
            ans = max(ans,temp)
        return ans
            
class Solution:
    def findMaxAverage(self, nums: List[int], k: int) -> float:
        sums = 0
        ans = float('-inf')#定义为负无穷的数,确保可以找到最大平均数
        for i , num in enumerate(nums):#在循环中每次迭代下标和对应的值
            sums += num
            if i >= k :
                sums -= nums[i-k]
            if i >= k - 1 :
                ans = max(sums,ans)
        return ans/float(k)

 

 

反思:第一次写出的程序虽然逻辑上可以解决问题,但是实际运行时却不能解决,甚至是超出了时间限制,时间复杂度为O(n)但却不能解决,最后发现忘记把 right +=1 加上使循环退出了,但是最后还是没通过。最后还是去参考了题解的方法,发现程序比自己的还简洁不少,逻辑也很清晰。

2.0674.最长连续递增序列

描述:给定一个未经排序的数组nums。

要求:找到最长且连续递增的子序列,并返回该序列的长度。

class Solution:#第一次写的代码,问题是超出了时间限制
    def findLengthOfLCIS(self, nums: List[int]) -> int:
        left =0
        right =1
        ans=[]
        temp=0
        ans.append(nums[left])
        while right < len(nums) :
            if nums[right -1]<nums[right]:
                ans.append(right)
            if nums[right -1] == nums[right]:
                continue
            if nums[right -1] > nums[right]:
                temp =len(ans)
                ans.clear()
                left = right
            right +=1
        return max(temp ,len(ans))
class Solution:
    def findLengthOfLCIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        l = r = 0
        max_len = 0
        for i in range(1, len(nums)):
            if nums[i] > nums[i - 1]:
                r = i
            else:
                if r - l + 1 > max_len:
                    max_len = r - l + 1
                l = r = i
        return max(max_len, r - l + 1)

 反思:刚开始做的时候,可以把逻辑在代码上实现出来,但是却超出了时间的限制,无奈之下,去浏览了一些题解,参考的题解中没有像我一样使用到另外的一个数组,而是在原有的数组上操作。并且在最后进行比较,得出最大的序列长度。

3.1004.最大连续1的个数Ⅲ

描述:给定一个由 0、1 组成的数组nums,再给定一个整数k。最多可以将k个值从 0 变到 1。

要求:返回仅包含 1 的最长连续子数组的长度。

class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        n = len(nums)
        res = 0
        left = 0
        right = 0
        ling = 0
        while right < n :
            if nums[right] == 0 :
                ling +=1
            while ling > k :
                if nums[left] == 0 :
                    ling -=1
                left +=1
            res = max(res,right - left + 1 )
            right +=1
        return res 

 

 反思:在做这一道题时,要考虑到数组中可以包含0,以及要考虑0的个数(一开始没考虑,就做不对),因为 k 是可以使子数组中的 0 反转为 1 的个数,所以要对数组中的 0 的个数进行判断,直到找到最长的数组。

Task05反思:

这个Task是最后一个Task啦!在这个Task中,学习到了双指针的运用方法,比如快慢指针、对撞指针以及分离双指针的用法,还有滑动窗口的使用。在这几个Task的学习后,学到了很多以前没接触过的方法和知识,转眼一看,哇!原来真的一路学习下来了。完成这几个Task后,心中真的成就感满满,以后也会继续努力学习的。:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值