zoukankan      html  css  js  c++  java
  • 【Offer】[18-2] 【删除链表中重复的节点】

    题目描述

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

    思路分析

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

    1. 删除的是第一个节点的情况
    2. 传入头结点为null时,或者只有头结点

    测试用例

    要注意此题返回的是头指针

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

    Java代码

    package com.hao.offer;
    import com.hao.common.ListNode;
    public class Offer18_02 {
    
        public static void main(String[] args) {
            System.out.println("****功能测试***");
            test1();
            System.out.println("***特殊输入测试****");
            test2();
            System.out.println("***特殊输入测试****");
            test3();
        }
    
        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(0, node1);
            System.out.println("删除之前");
            printListNode(pHead);
            System.out.println("删除之后--->");
            deleteDuplication(pHead);
            printListNode(pHead);
        }
    
        /**
         * 特殊值输入测试
         */
        private static void test2() {//
            System.out.println("所有的元素都是重复的");
            ListNode node6 = new ListNode(2, 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);
        }
    
        private static void test3() {
            System.out.println("只有一个节点");
            ListNode pHead = new ListNode(1, null);
            System.out.println("删除之前");
            printListNode(pHead);
            System.out.println("删除之后--->");
            deleteDuplication(pHead);
            printListNode(pHead);
        }
    
        /**
         * 打印链表 此题目没有头结点
         * 
         * @param pHead
         */
        private static void printListNode(ListNode pHead) {
            ListNode p = pHead;
            while (p != null) {
                System.out.print(p.val + " ");
                p = p.next;
            }
            System.out.println();
        }
    }
    
    

    代码链接

    剑指Offer代码-Java

  • 相关阅读:
    Response.Redirect 打开新窗体的两种方法
    linux下coredump的产生及调试方法
    AlertDialog具体解释
    数据仓库与数据挖掘的一些基本概念
    JS中setTimeout()的使用方法具体解释
    iOS开发- 查询项目代码行数
    STM32学习之路-LCD(3)<显示图片>
    谷歌技术"三宝"之MapReduce
    [ffmpeg 扩展第三方库编译系列] 关于libvpx mingw32编译问题
    javascript笔记
  • 原文地址:https://www.cnblogs.com/haoworld/p/offer182-shan-chu-lian-biao-zhong-zhong-fu-de-jie-.html
Copyright © 2011-2022 走看看