zoukankan      html  css  js  c++  java
  • 【Java】 剑指offer(18) 删除链表中重复的结点

    本文参考自《剑指offer》一书,代码采用Java语言。

    更多:《剑指Offer》Java实现合集  

    题目

      在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复结点被删除之后,链表如图3.4(b)所示。

    思路

      设置一个preNode,用于记录当前结点的前一个结点,再设置一个布尔变量needDelete,如果当前结点和后一结点的值相同(记该值为dupVal),needDelete赋值为真。

      当needDelete为真时,通过循环往后找到第一个不为dupVal的结点,把该结点设置为当前结点,并赋值给preNode.next,即相当于完成了删除操作;而当needDelete为假时,把当前结点和preNode往后移一位即可。

    测试算例

      1.功能测试(重复结点位于链表头部、中部、尾部,无重复结点)

      2.特殊测试(null,所有结点均重复)

    完整Java代码

        public ListNode deleteDuplication(ListNode pHead){
            ListNode pre = null;
            ListNode cur = pHead;
            while(cur!=null){
                if(cur.next!=null && cur.next.val==cur.val){
                    while(cur.next!=null && cur.next.val==cur.val)
                        cur=cur.next;
                    cur=cur.next;
                    if(pre==null)
                        pHead=cur;
                    else
                        pre.next=cur;
                }else{
                    pre=cur;
                    cur=cur.next;
                }
            }
            return pHead;
        }
    复习时写的

    (含测试代码)

    package _18;
    
    /**
     * 
     * @Description 面试题18(二):删除链表中重复的结点
     *
     * @author yongh
     * @date 2018年9月18日 下午6:30:53
     */
    
    // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复
    // 结点被删除之后,链表如图3.4(b)所示。
    
    public class DeleteDuplicatedNode {
    	class ListNode{
    		   int val;
    		    ListNode next = null;
    
    		    ListNode(int val,ListNode next) {
    		        this.val = val;
    		        this.next=next;
    		    }
    	}
        public ListNode deleteDuplication(ListNode pHead){
            if(pHead==null||pHead.next==null) //空结点或者仅一个结点
                return pHead;
            ListNode preNode = null;
            ListNode curNode = pHead;
            
            while(curNode!=null){
                boolean needDelete=false;
                if(curNode.next!=null && curNode.val==curNode.next.val)
                    needDelete=true;
                if(!needDelete){  //当前结点不重复
                    preNode=curNode;
                    curNode=curNode.next;
                }else{            //当前结点重复
                    int dupValue=curNode.val;
                    ListNode toBeDel = curNode;
                    while(toBeDel!=null&&toBeDel.val==dupValue){
                        //这里删除暂时不涉及前一结点操作,其实主要是找出后面第一个不重复结点
                        toBeDel = toBeDel.next;
                    }
                    if(preNode==null){  //说明删除的结点为头结点
                        pHead=toBeDel;
                    }else{
                        preNode.next=toBeDel;
                    }
                    curNode=toBeDel;  //这个结点还是可能会出现重复的,所以不能=next
                }
            }
            return pHead;
        }
    	
        
        //========测试代码======
    	void test(ListNode pHead) {
    		System.out.println("-----------");
    		System.out.print("The original list is: ");
    		ListNode curr=pHead;
    		if(curr!=null) {
    			while(curr.next!=null) {
    				System.out.print(curr.val+",");
    				curr=curr.next;
    			}
    			System.out.println(curr.val);
    		}else {
    			System.out.println();
    		}
    		pHead=deleteDuplication(pHead);
    		System.out.print("The result list is: ");
    		curr=pHead;
    		if(curr!=null) {
    			while(curr.next!=null) {
    				System.out.print(curr.val+",");
    				curr=curr.next;
    			}
    			System.out.println(curr.val);
    		}else {
    			System.out.println();
    		}
    		System.out.println("-----------");
    	}
        
    	
    	/**
    	 * 重复结点位于链表头部
    	 */
    	void test1() {
    		ListNode p4=new ListNode(3, null);
    		ListNode p3=new ListNode(2, p4);
    		ListNode p2=new ListNode(1, p3);
    		ListNode p1=new ListNode(1, p2);
    		test(p1);
    	}
    	
    	/**
    	 * 重复结点位于链表尾部
    	 */
    	void test2() {
    		ListNode p4=new ListNode(3, null);
    		ListNode p3=new ListNode(3, p4);
    		ListNode p2=new ListNode(2, p3);
    		ListNode p1=new ListNode(1, p2);
    		test(p1);
    	}
    	
    	/**
    	 * 重复结点位于链表中部
    	 */
    	void test3() {
    		ListNode p4=new ListNode(3, null);
    		ListNode p3=new ListNode(2, p4);
    		ListNode p2=new ListNode(2, p3);
    		ListNode p1=new ListNode(1, p2);
    		test(p1);
    	}
    	
    	/**
    	 * 连续出现重复结点
    	 */
    	void test4() {
    		ListNode p6=new ListNode(3, null);
    		ListNode p5=new ListNode(3, p6);
    		ListNode p4=new ListNode(2, p5);
    		ListNode p3=new ListNode(2, p4);
    		ListNode p2=new ListNode(1, p3);
    		ListNode p1=new ListNode(1, p2);
    		test(p1);
    	}
    	
    	/**
    	 * 多个重复结点
    	 */
    	void test5() {
    		ListNode p6=new ListNode(3, null);
    		ListNode p5=new ListNode(3, p6);
    		ListNode p4=new ListNode(3, p5);
    		ListNode p3=new ListNode(2, p4);
    		ListNode p2=new ListNode(1, p3);
    		ListNode p1=new ListNode(1, p2);
    		test(p1);
    	}
    	
    	/**
    	 * 无重复结点
    	 */
    	void test6() {
    		ListNode p6=new ListNode(6, null);
    		ListNode p5=new ListNode(5, p6);
    		ListNode p4=new ListNode(4, p5);
    		ListNode p3=new ListNode(3, p4);
    		ListNode p2=new ListNode(2, p3);
    		ListNode p1=new ListNode(1, p2);
    		test(p1);
    	}
    	
    	/**
    	 * 单个结点
    	 */
    	void test7() {
    		ListNode p1=new ListNode(6, null);
    		test(p1);
    	}
        
    	/**
    	 * null
    	 */
    	void test8() {
    		ListNode p1=null;
    		test(p1);
    	}
    	
    	public static void main(String[] args) {
    		DeleteDuplicatedNode demo= new DeleteDuplicatedNode();
    		demo.test1();
    		demo.test2();
    		demo.test3();
    		demo.test4();
    		demo.test5();
    		demo.test6();
    		demo.test7();
    		demo.test8();
    	}
        
    	
    	
    }
    

      

    -----------
    The original list is: 1,1,2,3
    The result list is: 2,3
    -----------
    -----------
    The original list is: 1,2,3,3
    The result list is: 1,2
    -----------
    -----------
    The original list is: 1,2,2,3
    The result list is: 1,3
    -----------
    -----------
    The original list is: 1,1,2,2,3,3
    The result list is: 
    -----------
    -----------
    The original list is: 1,1,2,3,3,3
    The result list is: 2
    -----------
    -----------
    The original list is: 1,2,3,4,5,6
    The result list is: 1,2,3,4,5,6
    -----------
    -----------
    The original list is: 6
    The result list is: 6
    -----------
    -----------
    The original list is: 
    The result list is: 
    -----------
    demo

    收获

      1.删除多个结点时,只要把重复结点前一个结点的next指向重复结点的后一个结点;

      2.不要把重复结点一个一个删除,先定义一个布尔变量确定当前结点是否重复,然后按上一句话的方法进行删除即可。

    更多:《剑指Offer》Java实现合集  

  • 相关阅读:
    Chandy-Lamport_algorithm
    3 differences between Savepoints and Checkpoints in Apache Flink
    列数 行数 表数 限制
    数据收集、传输、元数据管理、作业流调度、海量数据查询引擎、数据可视化
    分析云负载均衡产品
    端口被占用通过域名的处理 把www.domain.com均衡到本机不同的端口 反向代理 隐藏端口 Nginx做非80端口转发 搭建nginx反向代理用做内网域名转发 location 规则
    JSON Web Token
    查看开启端口的应用
    If the parts of an organization (e.g., teams, departments, or subdivisions) do not closely reflect the essential parts of the product, or if the relationship between organizations do not reflect the r
    微服务架构的理论基础
  • 原文地址:https://www.cnblogs.com/yongh/p/9672004.html
Copyright © 2011-2022 走看看