刷刷笔试题--[链表类编程]

来源:互联网 发布:dota2能在mac上玩吗 编辑:程序博客网 时间:2024/04/30 13:08

1.链表中环的入口结点

一个链表中包含环,请找出该链表的环的入口结点。

解析:

一、两个指针p1和p2,p1每次走1步,p2每次走2步,它们俩一定会在环内的某一处相遇,

假设p1走了x步,那么p2就走了2x步

p2刚好比p1多走了一个环的距离才又赶上p1

环的长度n=2x-x=x

p1其实在环外走了x1步,又在环内走了x-x1步,[还差n-(x-x1)=x1步就走到了入口]

二、现在把p2放回表头,让它们俩同时一起一步一步走,p2走x1步走到入口,p1走x1步也走到入口

不用单独求x1是什么,只需要把p2放在表头,然后让他们移动,相遇的地方就是入口!!

【不明白的时候画一个图】


/* public class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}*/public class Solution {    public ListNode EntryNodeOfLoop(ListNode pHead)    {        if(pHead==null||pHead.next==null)//这步一定不要少            return null;        ListNode p1=pHead;        ListNode p2=pHead;        while(p2!=null&&p2.next!=null){//要一直循环到两个指针相遇,有可能链表里面没有环,p2走得快,用他控制一下!!            p1=p1.next;            p2=p2.next.next;            if(p1==p2){                p2=pHead;                while(p1!=p2){                    p1=p1.next;                    p2=p2.next;                }                if(p1==p2)                    return p1;            }        }        return null;    }}


第二种方法:

用hashmap记录节点,ListNode-boolean类型的,如果没有这个节点就放进去,并放一个true,当发现这个节点已经有过了,containsKey()

就说明这个节点是入口


/* public class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}*/import java.util.*;public class Solution {    public ListNode EntryNodeOfLoop(ListNode pHead)    {        HashMap<ListNode,Boolean> map=new HashMap<ListNode,Boolean>();        while(pHead!=null){            if(map.containsKey(pHead))                return pHead;            map.put(pHead,true);            pHead=pHead.next;        }        return null;    }}

2.删除链表中重复的结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5


解析:

这里是用递归解决的



/* public class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}*/public class Solution {    public ListNode deleteDuplication(ListNode pHead)    {        if(pHead==null)            return null;        if(pHead.next==null&&pHead!=null)            return pHead;//前面两部分也可以直接换成if(pHead==null||pHead.next==null)return pHead;        ListNode cur=pHead;        if(pHead.val==pHead.next.val){            cur=pHead.next.next;            while(cur!=null&&cur.val==pHead.val){//!!注意!!cur!=null一定要写在前面!!&&这个东西很艮的,只看前面,如果前面的条件不成立,直接不看后面的                cur=cur.next;            }            return deleteDuplication(cur);        }else{            cur=pHead.next;            pHead.next=deleteDuplication(cur);            return pHead;        }            }}

3.[编程题]两个链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点。

解析:

先求出两个链表的长度,长的为m,短的为n,让长的先走m-n步,然后两个人一起走,时刻比较此时节点是否相等,相等返回其中一个节点就行


/*public class ListNode {    int val;    ListNode next = null;    ListNode(int val) {        this.val = val;    }}*/public class Solution {    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {    int len1=len(pHead1);    int len2=len(pHead2);    if(len1>len2){    pHead1=walk(pHead1,len1-len2);    }else{    pHead2=walk(pHead2,len2-len1);    }    while(pHead1!=null){    if(pHead1==pHead2)    return pHead1;    pHead1=pHead1.next;    pHead2=pHead2.next;    }    return null;            }    public int len(ListNode node){    int count=0;    if(node==null)    return count;    while(node!=null){    node=node.next;    count++;    }    return count;    }    public ListNode walk(ListNode node,int step){    while(step>0){    node=node.next;    step--;    }        return node;    }}










0 0
原创粉丝点击