Python编程日记002——剑指Offer链表题小结
1.从尾到头打印链表
题目描述
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
# class ListNode: #牛客网上的形式
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def printListFromTailToHead(self, ListNode):
# write code here
newlist=[]
if ListNode is None:
return newlist
while ListNode is not None:
newlist.append(ListNode.val)
ListNode=ListNode.next
return newlist[::-1] #倒序输出
2.链表中的倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
class Solution:
def FindKthToTail(self,head,k): #定义函数时用了head
newlist=[]
while head is not None:
newlist.append(head)
head=head.next #在这里体现了出来
if k>len(newlist) or k<=0:
return
else:
return newlist[len(newlist)-k] #直接输出第k个啦
return newlist
3.反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
if pHead is None or pHead.next is None:
return pHead
last = None
while pHead: #这一部分比较绕,需要好好体会
tmp=pHead.next
pHead.next=last
last=pHead
pHead=tmp
return last
4.两个链表的第一个公共结点
题目描述
输入两个链表,找出它们的第一个公共结点。
class Solution:
def FindFirstCommonNode(self, pHead1, pHead2):
s1=0
s2=0
p1=pHead1
p2=pHead2
while p1 is not None:
#这里特别重要的是,对p1操作,就写while p1 is not None
#不能写while pHead1 is not None
#否则会报错
s1=s1+1
p1=p1.next
while p2 is not None:
s2 = s2 + 1
p2 = p2.next
if s2>s1:
p2 = pHead2
while s2-s1>0:
p2=p2.next
s2=s2-1
p1=pHead1
elif s1>s2:
p1 = pHead1
while s1-s2>0:
p1=p1.next
s1=s1-1
p2=pHead2
else:
p1=pHead1
p2=pHead2
res = None
while p1 is not None and p2 is not None:
if p1==p2:
res=p1
return p1
p1=p1.next
p2=p2.next
return res
这个题的基本思想就是说,两个链表如果有一个公共结点,那么就是Y型。首先查找哪一个链表长,先在长的链表上走(L2-L1)步长,再同时遍历。
5.链表中环的入口结点
题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
class Solution:
def EntryNodeOfLoop(self, pHead):
# write code here
if pHead is None or pHead.next is None or pHead.next.next is None:
return None
slow=pHead.next
fast=pHead.next.next
while fast!=slow and fast.next:
slow=slow.next
fast=fast.next.next
if fast == slow:
slow=pHead
while fast !=slow:
fast = fast.next
slow=slow.next
return slow
else:
return None
环长:c,头结点到入口结点距离:a。总长度:a+c
慢指针一次走一步,快指针一次走两步,第一次相遇时,慢指针走了n步,快指针走了2n步,也就是说,第一次相遇时快指针比慢指针多走了一圈。
也就是:2n=n+c
慢指针走过了一个环长c,还要走长度a到达入口结点。这个时候把慢指针重置在头结点处,快慢指针一起每次各走一步,再次相遇的地方就是入口结点,需要a步。
6.找一个链表中点
def middle_List(self,pHead):
if pHead is None or pHead.next is None:
return None
fast = slow = pHead
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
7.合并两个有序链表,合并之后依然有序
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1 is None and l2 is None:
return None
new_list = ListNode(0)
pre = new_list
while l1 is not None and l2 is not None:
if l1.val < l2.val:
pre.next = l1
l1 = l1.next
else:
pre.next = l2
l2 = l2.next
pre = pre.next
if l1 is not None:
pre.next = l1
else:
pre.next = l2
return new_list.next
ListNode* removeNthFromEnd(ListNode* head, int n)
{
ListNode* Slow=head;
ListNode* Fast=Slow;
while(n--)Fast=Fast->next; //Fast指向后第n个结点
if(Fast==NULL)
{
head=head->next;
return head;
} //如果Fast指向NULL,则删除当前结点
while(Fast->next!=NULL) //如果Fast指向了倒数第一个结点,则删除Slow指向的下一个结点
{
Slow=Slow->next;
Fast=Fast->next;
}
Slow->next=Slow->next->next;
return head;
}