剑指Offer面试题57:删除重复链表 Java实现

来源:互联网 发布:韦德04年季后赛数据 编辑:程序博客网 时间:2024/05/16 12:12
</pre><pre code_snippet_id="1928155" snippet_file_name="blog_20161013_2_4408641" name="code" class="java">
垃圾一样的文本编辑器,写错了就没法改!!!!!!!!



 在一个排序的链表中,删除其中的重复节点,例如,链表A:
        A:1->2->2->4->4->6        删除重复节点后的链表B为:
        B:1->4->6.
算法分析:
        解决这个问题的第一步是确定删除的参数。当然这个函数需要输入待删除链表的头结点。头结点可能与后面的结点重复,也就是说头结点也可能被删除,所以在链表头添加一个结点。
  接下来我们从头遍历整个链表。如果当前结点的值与下一个结点的值相同,那么它们就是重复的结点,都可以被删除。为了保证删除之后的链表仍然是相连的而没有中间断开,我们要把当前的前一个结点和后面值比当前结点的值要大的结点相连。我们要确保prev要始终与下一个没有重复的结点连接在一起。

算法2:采用递归调用的方式
ListNode current;
        
        if(head.next.val == head.val){
            current = head.next.next;
            //while循环用于删除连续重复的节点,直到下一个不是重复的
            while(current != null && current.val == head.val)    
                current = current.next;
            return deleteDuplicationFun(current);            //递归调用,最终将链表连起来
        }
        else{
            current = head.next;
            head.next = deleteDuplicationFun(current);            //采用递归调用
            return head;
        } 

算法源程序:

</pre><pre name="code" class="java">/**************************************************************      * Copyright (c) 2016, * All rights reserved.                   * 版 本 号:v1.0                   * 题目描述:删除重复链表*          在一个排序的链表中,删除其中的重复节点,例如,链表A:        A:1->2->2->4->4->6        删除重复节点后的链表B为:        B:1->4->6.*   * 输入描述:无* 程序输出:算法1:删除节点后的链表是:*2->6->null*算法2:删除节点后的链表是:*2->6->null* 问题分析: 无* 算法描述: 解决这个问题的第一步是确定删除的参数。当然这个函数需要输入待删除链表的头结点。头结点可能与后面的结点重复,* 也就是说头结点也可能被删除,所以在链表头添加一个结点。*  接下来我们从头遍历整个链表。如果当前结点的值与下一个结点的值相同,那么它们就是重复的结点,*都可以被删除。为了保证删除之后的链表仍然是相连的而没有中间断开,*我们要把当前的前一个结点和后面值比当前结点的值要大的结点相连。我们要确保prev要始终与下一个没有重复的结点连接在一起。*算法2:采用递归调用的方式* 完成日期:2016-10-13***************************************************************/package org.marsguo.offerproject57;class ListNode{int val;ListNode next;public ListNode(){}public ListNode(int val){this.val = val;}public String toString(){return val + "";}}class SolutionMethod1{public ListNode deletNodeFunction(ListNode head){if(head == null)return null;ListNode root = new ListNode();//新定义一个root节点root.next = head;ListNode preNode = root;//前驱节点ListNode pNode = head;//当前处理的节点//preNode.next = head;while(pNode != null && pNode.next != null){//相邻两个节点值相同,删除相同节点if(pNode.val == pNode.next.val){while(pNode.next != null && pNode.next.val == pNode.val){pNode = pNode.next;}preNode.next= pNode.next;}//相邻两个节点值不相同,保留pNode,并向后移动else{preNode.next = pNode;preNode = preNode.next;}pNode = pNode.next;}/*返回的链表是从root开始打印,因为root从头开始,而preNode和pNode最后都指向了末尾节点*/return root.next;//return preNode.next;}public void print(ListNode head){while(head != null){System.out.print(head + "->");head = head.next;}System.out.println("null");}}class SolutionMethod2 extends SolutionMethod1{//采用继承SolutionMethod1,直接调用print方法public ListNode deleteDuplicationFun(ListNode head){if(head == null)return null;if(head != null && head.next == null)return head;ListNode current;if(head.next.val == head.val){current = head.next.next;//while循环用于删除连续重复的节点,直到下一个不是重复的while(current != null && current.val == head.val)current = current.next;return deleteDuplicationFun(current);//递归调用,最终将链表连起来}else{current = head.next;head.next = deleteDuplicationFun(current);//采用递归调用return head;}/*public void print(ListNode head){//重复代码,采用继承可以避免while(head != null){System.out.print(head + "->");head = head.next;}System.out.println("null");}*/}}public class DeleteDuplicationNode {public static void main(String[] args){ListNode n1 = new ListNode(1);ListNode n2 = new ListNode(1);ListNode n3 = new ListNode(2);ListNode n4 = new ListNode(4);ListNode n5 = new ListNode(4);ListNode n6 = new ListNode(6);n1.next = n2;n2.next = n3;n3.next = n4;n4.next = n5;n5.next = n6; SolutionMethod1 solution1 = new SolutionMethod1();System.out.println("算法1:删除节点后的链表是:" );ListNode result = solution1.deletNodeFunction(n1);solution1.print(result);SolutionMethod2 solution2 = new SolutionMethod2();System.out.println("算法2:删除节点后的链表是:");ListNode result2 = solution2.deleteDuplicationFun(n1);solution2.print(result2);System.out.println();}}

程序运行结果:

0 0
原创粉丝点击