第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后,心中真的成就感满满,以后也会继续努力学习的。:)