算法问题如果一时想不到,,可以将常用的数据结构和常用算法思想都想一遍,看看哪些能解决问题。
常用的数据结构有数组、链表、队、栈、Hash、集合、树、堆。
常用的算法思想有查找、排序、双指针、递归、迭代、分治、贪心、回溯和动态规划。
1 两个链表的第一个公共子节点
第一种方法 集合
先把第一个链表所有元素都存到集合里,再遍历第二个链表,检测当前元素是否在集合里。如果是,则找到交点
def getIntersectionNode(slef,headA,headB):
s=set()
p,q=headA,headB
while p:
s.add(p)
p=p.next
while q:
if q in s:
return q
q=q.next
return None
第二种方法 栈
把两个链表分别压入两个栈中,再将它们出栈并一一对比,最后一组相同的元素就是他们的交点。
def getIntersectionNode(slef,headA,headB):
s1,s2=[],[]
p,q=headA,headB
while p:
s1.append(p)
p=p.next
while q:
s2.append(q)
q=q.next
ans=None
i,j=len(s1)-1,len(s2)-1
while i>=0 and j>=0 and s1[i]==s2[j]:
ans=s1[i]
i,j=i-1,j-1
return ans
判断链表是否为回文数列(leetcode 234)
问题:老师说这里不用数组,因为这个方法会视为逃避链表,但是在用栈的过程中也用到了类似的方法,为什么这个就不是逃避链表了?
def isPalindrome(self,head):
s=[]
q,p=head,head
while q:
s.append(q)
q=q.next
i=len(s)-1
while i>=0:
if p.val!=s[i]:
return False
p=p.next
i=i-1
return True
方法二 快慢指针+链表反转
先用快慢指针来找到链表中点,再把后面部分反转,与前面部分比较
def isPalindrome(self,head):
#需要用到虚拟节点,否则出错
dummy_head = ListNode(0)
dummy_head.next = head
fast=slow=dummy_head
while fast and fast.next:
fast=fast.next.next
slow=slow.next
post=slow.next
slow.next=None
pre=head
rev=None
while post:
next=post.next
post.next=rev
rev=post
post=next
part1=pre
part2=rev
while part1 and part2:
if part1!=part2:
return False
part1,part2=part1.next,part2.next
return True
合并有序链表
合并两个有序链表(leetcode 21)
想法:将两个链表的每一个结点一一比较,并插入到一个新的链表中去。
为啥我第一遍把list1、2赋给pq后不能用val啊,是数据类型的问题吗
def mergeTwoLists(self, list1, list2):
head=ListNode(0)
p=head
while list1 and list2:
if list1.val<=list2.val:
p.next=list1
list1=list1.next
else:
p.next = list2
list2 = list2.next
p=p.next
if list1 is not None:
p.next=list1
else:
p.next=list2
#另一种思路
'''
if list1==None:
p.next=list2
else:
p.next=list1
'''
return head.next
第二种方法:将一个链表节点拆下来,并合并到另外一个对应位置上去(待补充,第一次用这个方法错误了)
合并k个有序链表
想法:化繁为简,两个两个合并,参考合并两个有序链表
超棒的想法,要好好吸收一下!
def mergeKLists(self, lists):
def mergeTwoLists(list1,list2):
head = ListNode(0)
p = head
while list1 and list2:
if list1.val <= list2.val:
p.next = list1
list1 = list1.next
else:
p.next = list2
list2 = list2.next
p = p.next
#第三种简化方法
head.next=list1 if list1 else list2
return head.next
if len(lists)==0:
return None
res=None
for i in range(0,len(lists)):
res=mergeTwoLists(res,lists[i])
return res
一道很无聊的好题(leetcode 1669)
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
这道题的难点(for me):
- i的范围好难定,ab不知道怎么调
- 倒数第四行写成了list1,导致最后一段接不上,调试了好久,反应过来如果直接用必须用list1.next才能衔接上(基础不扎实😄)
def mergeInBetween(self, list1, a, b, list2):
head = list1
q = list1
p = list1
for i in range(0, a - 1):
list1 = list1.next
for i in range(0, b):
p = p.next
list1.next = list2
while list1.next:
list1 = list1.next
list1.next = p.next
return head