1. 链表相交:
题目链接: 面试题 02.07. 链表相交 - 力扣(LeetCode)
应用条件:
链表逻辑
方法一:链表互相衔接找交点
难点:
这个方法较为难想,主要解题思路为,我们想找到两个链表的交点,但两个链表的长度不一致,所以每次两个链表同时往后遍历只能判断当下哪两个节点是否一致,可能会出现错过交点的情况。所以我们可以在链表A遍历到结尾时让他再从链表B的开头进行遍历,链表B遍历到结尾的时候衔接链表A的开头。例如,链表A为0 1 2 3 4 5 6, B为 a b 4 c d, 链表A,B同时遍历,B先到尾部d,让B从A的开头0继续遍历,当A到A的6时候,这是B此时在A的1,A接着B的开头a继续遍历,然后就是 A-a, B-2 A-B, B-3 A-4, B-4找到了交点。总之就是把B在交点前的部分连接到A上,A在交点前的部分链接到B上。这样AB的总长度就一样了,遍历既可以找到交点。如果没有交点,AB 会同时到None,这样A 也是==B的,会返回None
个人错误:
没想明白返回None的情况导致出现死循环问题。
思路:
这里循环条件用的是cura != curb,然后里面if用的cura,而不用cura.next,因为当cura在链表尾部是,它自己已经是none了,用cura.next遍历不到none,从而会一致循环。
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
cura = headA
curb = headB
while cura != curb:
if cura:
cura = cura.next
else:
cura = headB
if curb:
curb = curb.next
else:
curb = headA
return cura
方法二:先让相对长的列表有差值的距离,这样两个链表就末尾对齐了,然后从对齐位置的打头遍历,找相同节点。
难点:
可以另写方法,实现代码复用。
个人错误:
无。
思路:
如下,较为简单。
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
lena = self.getlen(headA)
lenb = self.getlen(headB)
if lena > lenb:
headA = self.gostep(headA, lena - lenb)
else:
headB = self.gostep(headB, lenb - lena)
while headA != headB:
headA = headA.next
headB = headB.next
return headA
def getlen(self,head:ListNode):
size =0
while head:
size += 1
head = head.next
return size
def gostep(self,head,step):
for i in range(step):
head = head.next
return head
2. 环形链表:
题目链接: 142. 环形链表 II - 力扣(LeetCode)
应用条件:
哈希表,双指针
方法一:哈希表
难点:
简单好用
个人错误:
无
思路:
创建一个dic储存节点,遍历整个链表,当节点重复时,返回该节点.
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
dic ={}
while head:
if head in dic:
return head
else:
dic[head] = 1
head = head.next
return None
方法二:快慢指针
难点:
如何找到环的入口:令相遇的位置为index1,把头节点作为index2,然后index1和index2 同时向后移动,直到index1 == index2,返回index1 或 index 2即为环的开始.
个人错误:
return位置放错了一开始
思路:
定义fast 和slow一开始都在head,fast每次走两步,slow每次走一步,当fast追上slow时,证明有环。
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
# dic ={}
# while head:
# if head in dic:
# return head
# else:
# dic[head] = 1
# head = head.next
# return None
fast = head
slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
index1 = slow
index2 = head
while index1 != index2:
index1= index1.next
index2 = index2.next
return index1
return None
3. 有效字母异位词:
题目链接: 242. 有效的字母异位词 - 力扣(LeetCode)
应用条件:
哈希表
难点:
注意别忘了判断s长度大于t的情况,例如s=【a,b】t=【a】。
个人错误:
无
思路:
创建一个dic用于储存一个。
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s)!=len(t):
return False
dic1={}
for i in s:
if i in dic1:
dic1[i] += 1
else:
dic1[i] = 1
for i in t:
if i in dic1:
if dic1[i] == 0:
return False
else:
dic1[i] -= 1
else:
return False
return True
4. 两数组交集:
题目链接: 349. 两个数组的交集 - 力扣(LeetCode)
应用条件:
哈希表
难点:
用set做会比dictionary更快一点好像。
个人错误:
思路:
遍历后找出一样的就ok了。
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
res = []
dic = {}
if len(nums1)==0 or len(nums2) == 0:
return res
for i in nums1:
if i in dic:
continue
else:
dic[i] = 1
for j in nums2:
if j in dic and j not in res:
res.append(j)
return res