【Offer】[18-2] 【删除链表中重复的节点】

题目描述

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

思路分析

  由于是有序链表,要删除重复节点,,我们可以先设置三个指针,pre,p,next,分别指向前一个节点,当前节点,和下一个结点,遍历链表,判断当前节点和下一个结点是否相同,设置一个标记位needDel
  1. 如果没有找到,就想指针往后移动;
  2. 否则,就设置true,这时可以循环遍历往后继续搜索重复的节点(因为链表是有序的)
注意:

  1. 链表中只有一个节点的情况
  2. 删除的是第一个节点的情况

测试用例

  1. 功能测试(重复结点位于链表头部、中部、尾部,无重复结点)
  2. 特殊测试(null,所有结点均重复)

Java代码

public class Offer18_02 {

    public static void main(String[] args) {
        System.out.println("****功能测试***");
        test1();
        System.out.println("***特殊输入测试****");
        test2();
    }

    public static ListNode deleteDuplication(ListNode pHead) {
        return Solution1(pHead);
    }

    /**
     * 
     * 需要设置三个指针,pre pNode 和 next ;
     * 
     * @param pHead
     * @return
     */
    private static ListNode Solution1(ListNode pHead) {
        if (pHead == null || pHead.next == null) {// 如果链表为空或者只有一个节点
            return pHead;
        }
        ListNode pre = null;
        ListNode pNode = pHead; // 代表当前节点
        while (pNode != null) {// 从头结点开始遍历链表
            boolean needDel = false;
            ListNode pNext = pNode.next;
            if (pNext != null && pNext.val == pNode.val) {
                // 如果当前节点的下一个结点不为null 且其值和当前节点相等
                needDel = true;
            }
            if (!needDel) {// 如果没有找到重复的元素就将指针往后移动
                pre = pNode;
                pNode = pNode.next;
            } else { // 找到重复的元素
                ListNode toBeDel = pNode;
                int value = toBeDel.val;
                while (toBeDel != null && toBeDel.val == value) {
                    // 将指针移到所有重复元素的后面
                    toBeDel = toBeDel.next;
                }
                if (pre == null) {// 删除的是第一个节点
                    pHead = toBeDel;
                } else {
                    pre.next = toBeDel;
                }
                pNode = toBeDel;
            }
        }

        return pHead;
    }

    /**
     * 功能测试
     */
    private static void test1() {//
        System.out.println("有两对重复的");
        ListNode node6 = new ListNode(6, null);
        ListNode node5 = new ListNode(6, node6);
        ListNode node4 = new ListNode(3, node5);
        ListNode node3 = new ListNode(3, node4);
        ListNode node2 = new ListNode(2, node3);
        ListNode node1 = new ListNode(1, node2);
        ListNode pHead = new ListNode(-1, node1);// 头结点
        System.out.println("删除之前");
        printListNode(pHead);
        System.out.println("删除之后--->");
        deleteDuplication(pHead);
        printListNode(pHead);
    }

    /**
     * 
     */
    private static void test2() {//
        System.out.println("所有的元素都是重复的");
        ListNode node6 = new ListNode(1, null);
        ListNode node5 = new ListNode(1, node6);
        ListNode node4 = new ListNode(1, node5);
        ListNode node3 = new ListNode(1, node4);
        ListNode node2 = new ListNode(1, node3);
        ListNode node1 = new ListNode(1, node2);
        ListNode pHead = new ListNode(-1, node1);// 头结点
        System.out.println("删除之前");
        printListNode(pHead);
        System.out.println("删除之后--->");
        deleteDuplication(pHead);
        printListNode(pHead);
    }

    /**
     * 打印链表
     * 
     * @param pHead
     */
    private static void printListNode(ListNode pHead) {
        ListNode p = pHead.next;
        while (p != null) {
            System.out.print(p.val + " ");
            p = p.next;
        }
        System.out.println();
    }

}

代码链接

剑指Offer代码-Java

猜你喜欢

转载自www.cnblogs.com/haoworld/p/offer182-shan-chu-lian-biao-zhong-zhong-fu-de-jie-.html