题目一描述:
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
题目分析:
链表是否有环使用两种方式进行判断(参考牛客网左神算法课):
1.将链表使用Hash进行存储,如果两个节点有相同的Hash值则表明链表有环
2.使用双指针,定义一个快指针和一个慢指针,快指针每次走两步,慢指针每次走一步,若链表有环则快指针一定会与慢指针指向同一个节点,与此同时,将快指针置于头部,且设置每次走一步,当两个指针再次相遇时,为入环节点。
public class Solution {
public ListNode EntryNodeOfLoop(ListNode pHead)
{
if(pHead==null){
return null;
}
ListNode snode=pHead;//慢指针,每次向前一步
ListNode fnode=snode;//快指针每次走两步
boolean flag=false;//标志位,表示有环
while(fnode!=null&&fnode.next!=null) {
fnode=fnode.next.next;
snode=snode.next;
if(fnode==snode) {
fnode=pHead;
flag=true;
break;
}
}
while(flag) {//有环时,为true,使得快指针指向头,且每次走一步
if(fnode==snode) {
return fnode;
}
fnode=fnode.next;
snode=snode.next;
}
return null;
}
}
题目二描述:
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
题目分析:
链表需要进行每个节点判断是否重复,重复将所有重复的节点删除。因此,需要记录一个重复节点(curnode)的前一个节点(prenode),重复节点的最后一个节点(nextnode),然后将最后一个重复节点位置的后一个节点连接到prenode的next域。
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead==null){
return pHead;
}
ListNode tounode=new ListNode(-1);//头结点的前一个节点用来记录头结点
tounode.next=pHead;
ListNode prenode=tounode;//重复节点的前一个节点
ListNode curnode=prenode.next;//重复节点的起始节点
ListNode nextnode=curnode.next;//重复节点的下一个节点
while(nextnode!=null){
if(curnode.val==nextnode.val){//有重复节点
while(nextnode!=null&&curnode.val==nextnode.val){
nextnode=nextnode.next;//若一直重复,next一直向后扩展
}
if(nextnode==null){//若pre后边的节点都重复,将pre的next域连接null
prenode.next=null;
break;
}
curnode=nextnode;//有重复但不为最后的节点,将当前节点指向next指针位置,next指针指向后一个位置,将cur指针连接在pre的next域
nextnode=curnode.next;
prenode.next=curnode;
}else{//没有重复节点,pre,cur,next指针后移
prenode=curnode;
curnode=prenode.next;
nextnode=curnode.next;
}
}
return tounode.next;//返回的是头结点的下一个节点
}
}