leetcode单链表总结

来源:互联网 发布:知乎 成都留学机构 编辑:程序博客网 时间:2024/06/04 23:23

首先要链表的node类。

public class ListNode {     int val;     ListNode next;     ListNode(int x) { val = x; }}

83:Remove Duplicates from Sorted List删除有序链表中重复元素

思路:由于链表是有序的,只需要定义一前一后两个对象q,p。如果两个对象所指向的元素相等,则去掉一个就可以了。

/** * 删除有序链表重复元素 * @param head * @return */public ListNode deleteDuplicatesForSortedList(ListNode head) {           if(head==null||head.next==null)            return head;        ListNode q = head.next; //q在前        ListNode preq = head;  //preq在后        while(q != null){            if(preq.val==q.val){  //相等则去掉q指向的元素            preq.next = q.next;            q = q.next;            }else{            preq = q;            q = q.next;            }            }        return head;    }

此题的变种自然就是删除无序链表中的重复元素。

思路:由p从第一个元素开始遍历,当其指向第一个元素时,q以及指向其前一个元素的preq开始遍历整个链表找到相同的元素就删掉。

public ListNode deleteDuplicates(ListNode head) {        ListNode p = head;        ListNode q = head;        ListNode preq = null;        if(head==null)            return head;        while(p.next != null){  //遍历链表            q = p.next;     //q从p的下一个元素开始            preq = p;            while(q!=null){    //直到q为null而不是q.next!=null            if(p.val==q.val){            preq.next = q.next;                    q = q.next;            }else{            preq = q;            q = q.next;            }            }            if(p.next!=null)                p = p.next;        }        return head;    }


203:Remove Linked List Elements

删除链表中指定元素,用两个指针遍历,对比,删除。代码如下。

public ListNode removeElements(ListNode head, int val) {        if(head == null)            return head;        ListNode p = head;        ListNode prep = null;        while(p!=null){            if(p.val==val){                if(head==p){        //删除第一个节点的情况,此时prep为null,得单独处理                    head = p.next;                    if(head==null)                        return head;                }else{                    prep.next = p.next;                }            }else{                    prep = p;            }            p = p.next;        }        return head;    }

19:removeNthFromEnd删除从结尾数第n个元素。

两个指针p,q,p先走n步,然后一起走直到队尾。删掉q指向的元素就可以了。

public ListNode removeNthFromEnd(ListNode head, int n) {        ListNode p=head;        ListNode q=head;        ListNode tmp=null;        for(int i=1;i<n;++i){                q = q.next;        }        while(q.next!=null){            q = q.next;            tmp = p;//tmp指向待删除节点前一个节点            p = p.next; //p指向待删除节点        }        if(tmp==null){            head = p.next;        }else{            tmp.next = p.next;        }        return head;    }

206:逆置链表。

将链表的指针全部转向。好比p在前q在后,q=p.next;就可以了。

public ListNode reverseList(ListNode head) {        if(head==null||head.next==null)            return head;        ListNode p = head.next;        head.next = null;        ListNode q = head;        ListNode tmp =null;        while(p != null){            tmp = p.next;            p.next = q;            q = p;            p = tmp;        }        return q;    }

21:合并两个有序链表。

对两个链表从头开始遍历,一个作为主链表,一个作为待插入链表。当待插入链表元素大于主链表时,插入。

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {        if(l1==null&&l2==null)        return null;        if(l1==null&&l2!=null)        return l2;        if(l1!=null&&l2==null)        return l1;ListNode p = l1;        ListNode q = l2;        if(l1.val>l2.val){        p = l2;         //p指向第一个值较小的链表,主表        q = l1;         //q指向较大的,待插入链表        }        ListNode prep = null;        while(p!=null){        if(q!=null&&q.val<p.val){        prep.next = q;        //遍历待插入链表,找到第一个小于p元素的,这中间的一段元素都需要插入到主表        while(q!=null&&q.val<p.val){        prep = prep.next;        q = q.next;        }        prep.next = p;;        }        prep = p;        p = p.next;        }        prep.next = q;        if(l1.val>l2.val){        return l2;        }else{        return l1;        }    }


0 0