题目一
1.给定一个链表,判断链表中是否有环。
解释:链表中有一个环,其尾部连接到第二个节点。
PS:从例子中根本看不出来好嘛。。。。。。自己理解就ok
题目分析
经典思想,快慢指针,如果有环存在,快指针总会追上慢指针
python代码
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if not head:
return False
first=head
second=head
while True:
if first.next is None or first.next.next is None:
return False
first=first.next.next # 快指针,二倍速
second=second.next # 慢指针 ,一倍速
if first==second:
return True
c++代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
bool hasCycle(ListNode *head)
{
ListNode *low = head; // 指针指向头部的语句
ListNode *high = head;
if(head==NULL)
return 0;
while((high!=NULL) && (high->next!=NULL)) // 且运算符
{
low=low->next; // 在c++中 -> 就是指针中的.
high = high->next->next;
if(low==high)
return 1;
}
return 0;
}
};
题目二:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
说明:不允许修改给定的链表。
题目分析
引理证明:快指针追上慢指针的时候,慢指针距离环形链表初始点的长度等于原始链表头距离环形链表初始点的长度。
设原始链表中 环形部分长度为n,非环型部分长度为m。(不妨设n>m,其他形况相同,不一一列举了)
则慢针入环时,快针刚好领先慢针m个,则可看成,慢针领先快针(n-m)个。即,在(n-m)步后,快指针追上慢指针,此时慢指针距离入口处刚好(n-(n-m))=m个距离
python代码如下
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 1,快慢指针判断是否有环
fast = head
slow = head
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
if fast == slow:
break
if fast == None or fast.next == None:
return None
# 2, 慢指针继续 快指针从头开始
# 按照定理的推展
while head != slow:
head = head.next
slow = slow.next
return head
c++代码
待续
题目三:
编写一个程序,找到两个单链表相交的起始节点。
题目分析:
将A链的结尾,连上B的开头,则题和题目二同理
python代码
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
## 将链表尾部 连到另一个链表的头部,就如同上题了
if not headA or not headB:
return None
fast = headA
slow = headA
head = headA
while headA.next:
headA = headA.next
headA.next = headB
## 判断是否有环
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
break
if fast == None or fast.next == None:
headA.next = None ## 题目要求返回后链表结构和之前一样
return None
## 找环起点
while not head == slow:
head = head.next
slow = slow.next
headA.next = None
return head
题目四
寻找链表中倒数第k个节点
先让快指针走k-1个节点,然后慢指针出发,快指针到尽头了,慢指针所指就是倒数第k个节点
class Solution:
def FindKthToTail(self, head, k):
# write code here
if head==None or k<=0:
return None
#设置两个指针,p2指针先走(k-1)步,然后再一起走,当p2为最后一个时,p1就为倒数第k个 数
p2=head
p1=head
#p2先走,走k-1步,如果k大于链表长度则返回 空,否则的话继续走
while k>1:
if p2.next!=None:
p2=p2.next
k-=1
else:
return None
#两个指针一起 走,一直到p2为最后一个,p1即为所求
while p2.next!=None:
p1=p1.next
p2=p2.next
return p1