目录
2020/12/31
167. 两数之和 II - 输入有序数组
头尾指针 开始迭代
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
if(numbers==None or len(numbers)<2):
return None
left=0
right=len(numbers)-1
while(left<right):
twoSum=numbers[left]+numbers[right]
if(twoSum==target):
return [left+1,right+1]
elif(twoSum>target):
right-=1
else:
left+=1
return None
633. 平方数之和
直接用left right表示元素来比 不用先构建数组 用left right当下标
class Solution:
def judgeSquareSum(self, c: int) -> bool:
# 双指针找两个
left=0
right=int(c**0.5)
while(left<=right):# 因为可以取相同的数 所以加=
towSum=left**2+right**2
if(towSum==c):
return True
elif(towSum>c):
right-=1
else:
left+=1
return False
345. 反转字符串中的元音字母
- 头尾指针
- 注意第一个循环left<right 但是循环内又加了个循环left+1 那么left有可能>right
class Solution:
def reverseVowels(self, s: str) -> str:
s=list(s)
strYuan='aoeiuAOEIU'
left=0
right=len(s)-1
while(left<right):
# 先找left元音
while(left<right and s[left] not in strYuan):#注意要加上left<right的约束 不加的话 后面也得判断left right关系
left+=1
# 找right元音
while(left<right and s[right] not in strYuan):
right-=1
if(s[left] in strYuan and s[right] in strYuan):
s[left],s[right]=s[right],s[left]
left+=1
right-=1
return ''.join(s)
2020/1/1
680. 验证回文字符串 Ⅱ
遇到不相等的情况
返回 s[left+1,right+1] or s[left,right] 的结果
class Solution:
def validPalindrome(self, s: str) -> bool:
if(len(s)==1):
return True
left=0
right=len(s)-1
while(left<right):
if(s[left]!=s[right]):
return self.validPalindromeTrue(s[left:right]) or self.validPalindromeTrue(s[left+1:right+1])
left+=1
right-=1
return True
def validPalindromeTrue(self,s):
if(len(s)==1):
return True
left=0
right=len(s)-1
while(left<right):
if(s[left]!=s[right]):
return False
left+=1
right-=1
return True
88. 合并两个有序数组
第一思路是从前往后插,但是空间复杂度是 o(m+n);从后往前插,空间复杂度o(1)
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
# 从nums1后面往前 逐步插入最大元素
i=m-1
j=n-1
for index in range(m+n-1,-1,-1):
# 数组1遍历完
if(i<0):
nums1[index]=nums2[j]
j-=1
# 数组2遍历完
elif(j<0):
nums1[index]=nums1[i]
i-=1
# 数组1和数组2都没遍历完 选最大的
else:
if(nums1[i]>nums2[j]):
nums1[index]=nums1[i]
i-=1
else:
nums1[index]=nums2[j]
j-=1
还是官方写的简洁
- 注意不用考虑p1剩下的情况(本身就是nums1)
- 只考虑p2可能剩下就好了
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
# 从nums1后面往前 逐步插入最大元素
p1=m-1
p2=n-1
p=m+n-1
# p1和p2还都有元素
while(p1>=0 and p2>=0):
if(nums1[p1]>nums2[p2]):
nums1[p]=nums1[p1]
p1-=1
else:
nums1[p]=nums2[p2]
p2-=1
p-=1
# p2可能还有元素(p1如果还有的话就直接在p1里了)
nums1[:p2+1]=nums2[:p2+1]
141. 环形链表
-
存在环:fast和slow相遇
-
不存在环:fast到none了
-
当链表中不存在环时,快指针将先于慢指针到达链表尾部,链表中每个节点至多被访问两次。
-
当链表中存在环时,每一轮移动后,快慢指针的距离将减小一。而初始距离为环的长度,因此至多移动 N轮。??
low=head fast=head
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if(head==None):
return False
low=head
fast=head
while(fast!=None):
if(fast.next==None):
return False
else:
fast=fast.next.next
low=low.next
if(fast==low):
return True
low=head fast=head.next
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if(head==None or head.next==None):
return False
low=head
fast=head.next
# 相等的时候 相遇 存在环
while(low!=fast):
if(fast!=None and fast.next!=None):
fast=fast.next.next
low=low.next
else:
#fast遇到none了
return False
return True
还可以用哈希表存储遍历过的节点 如果遍历中发现当前节点在哈希表中 就有环
2021/1/3
524. 通过删除字母匹配到字典里最长单词
- 将给定的list按长度、字典顺序排序
- 判定每个字符串是不是子序列
class Solution:
def findLongestWord(self, s: str, d: List[str]) -> str:
# 先按字符串长度降序排列
#d.sort(key=lambda x:len(x),reverse=True) #按照自己的理解 返回长度最长且list的index顺序最小
d.sort(key=lambda x:(-len(x),x)) # 真正的题意 返回长度最长且字典顺序最小
res=''
# 判断每个字符串是不是子序列
for sstr in d:
if(len(sstr)<=len(res)):
continue
i=0 # s的index
j=0 # sstr的index
while(i<len(s) and j<len(sstr)):
# 用s的元素不等于sstr的 s+=1
if(s[i]!=sstr[j]):
i+=1
# s的元素等于sstr的 s+=1 sstr+=1
else:
# 匹配到sstr的最后一个char 成功
if(j==len(sstr)-1):
res=sstr
break
else:
i+=1
j+=1
return res
拆成两个函数 更简洁一些
class Solution:
def findLongestWord(self, s: str, d: List[str]) -> str:
# 先按字符串长度降序排列
#d.sort(key=lambda x:len(x),reverse=True) #按照自己的理解 返回长度最长且list的index顺序最小
d.sort(key=lambda x:(-len(x),x)) # 真正的题意 返回长度最长且字典顺序最小
res=''
# 判断每个字符串是不是子序列
for sstr in d:
if(len(sstr)<=len(res)):
continue
if(self.isSubstr(s,sstr)):
res=sstr
return res
# 判断y是不是x的子串
def isSubstr(self,s,target):
if(len(target)>len(s)):
return False
i=0 # s
j=0 # target
while(i<len(s) and j<len(target)):
if(s[i]!=target[j]):
i+=1
else:
i+=1
j+=1
return j==len(target)