编写代码,移除未排序的链表中的重复节点

解法一:如果不得使用临时缓冲区,该怎么解决?

要想移除链表中的重复节点,我们需要设法记录有哪些是重复的。这里只需要使用到一个简单的散列表。

在下面的解法中,我们会直接迭代访问整个链表,将每个节点加入到散列表。若发现有重复的元素,将该节点从链表中移除,然后继续迭代。这个题目使用了链表,因此只需要扫描一次就能搞定。

deleteDups()的时间复杂度为O(N),其中N为链表节点数目。

解法二:不使用缓冲区

如不借助额外的缓冲区,可以用两个指针来迭代:current迭代访问整个链表,runner用于检查后续的节点是否重复

上述代码中的deleteDups2()

该代码的空间复杂度为O(1),时间复杂度为O(N2)

 

package cglib;
import java.util.Hashtable;  


class LinkedListNode<T> {
    public LinkedListNode<T> next;
    public T data;

    public LinkedListNode(Object object, int data2, Object object2) {
           
    }
      
    }


public class StringNumber {
    private LinkedListNode<Integer> head;  
    private LinkedListNode<Integer> tail;  
    private int size;  
      
     // 尾部插入    
    public boolean addTail(int data) {   
        if (this.head == null) {   
            this.head = new LinkedListNode<Integer>(null, data, null);   
            this.tail = this.head;   
        } else {   
            LinkedListNode<Integer> newnode = new LinkedListNode<Integer>(this.tail, data, null);   
            this.tail.next = newnode;   
            this.tail = newnode;   
        }   
        this.size++;   
         
        return true;   
    }   
    public String toString() {   
        if (this.isEmpty())   
            return "[]";   
        else {   
            StringBuffer st = new StringBuffer("[");   
            for (LinkedListNode<Integer> curent = this.head; curent != null; curent = curent.next)   
                st.append(curent.data.toString() + " ,");   
            st.append("]");   
            return st.toString();   
        }   
    }   
    public boolean isEmpty() {   
        return this.size == 0;   
    }   
 
    public void deleteDups(LinkedListNode<Integer> n){  
        Hashtable<Integer, Boolean> table = new Hashtable<Integer, Boolean>();  
        LinkedListNode<Integer> previous = null;  
        while(n != null){  
            if(table.containsKey(n.data)){  
                previous.next = n.next;  
            }else{  
                table.put(n.data, true);  
                previous = n;  
            }  
            n =n.next;  
        }  
        while(head!=null){  
            System.out.println(head.data.toString());  
            head= head.next;  
        }  
    }  
    public void deleteDups2(LinkedListNode<Integer> head){  
        if(head == null)  
            return;  
        LinkedListNode<Integer> current = head;  
        while(current != null){  
            //移除后续值相同的所有节点  
            LinkedListNode<Integer> runner = current;  
            while(runner.next != null){  
                if(runner.next.data == current.data){  
                    runner.next = runner.next.next;  
                }else{  
                    runner = runner.next;  
                }  
            }  
            current= current.next;  
        }  
        while(head!=null){  
            System.out.println(head.data.toString());  
            head= head.next;  
        }  
    }  
    public static void main(String[] args){  
          
        StringNumber test = new StringNumber();  
        test.addTail(1);  
        test.addTail(2);  
        test.addTail(3);  
        test.addTail(3);  
        test.addTail(4);  
        test.addTail(1);  
          
        test.deleteDups2(test.head);  
          
    }
    
}
      

  1. public static void deleteDups(LinkListNode n) {  
  2.     LinkListNode previous = null;  
  3.     Hashtable table = new Hashtable();  
  4.     while(n != null){  
  5.         if (table.containsKeys(n.data)) {  
  6.             preious.next = n.next;  
  7.         }  
  8.         else {  
  9.             table.put(n.data, true);  
  10.             previous = n;  
  11.         }  
  12.         n = n.next;  
  13.     }  
  1. public static void deleteDupsNew(LinkListNode head) {  
  2.     if (head == null) return;  
  3.     LinkListNode current = head;  
  4.     while(current != null){  
  5.         LinkListNode runner = current;  
  6.         while (runner.next != null){  
  7.             if(runner.next.data == current.data){  
  8.                 runner.next = runner.next.next;  
  9.             }  
  10.             else{  
  11.                 runner = runner.next;  
  12.             }  
  13.         }  
  14.         current = current.next;  
  15.     }         
  16. }  

或者:

public class ListNote {

    private  ListNote NextNote;
    private int value;
    public ListNote(){  
    }
    public ListNote(int value){
        this.value=value;
    }  
    public  ListNote getNext(){     
        return NextNote;            
    }
    public void setNext(ListNote next){
        this.NextNote=next; 
    }   
    public int getValue(){
        return value;   
    }
    public void setValue(int value){
        this.value=value;
    }
}

 

public static void deleteDuplication(ListNote root){
        if(root==null){
            return;
        }
        ListNote preNode=null;//前结点
        ListNote node=root;//当前结点
        while(node!=null){
            ListNote nextNode=node.getNext();//下一个结点
            boolean needDelete=false;
//判断当前结点和下一个结点值是否相等 
    if(nextNode!=null&&nextNode.getValue()==node.getValue())
                needDelete=true;
          if(!needDelete){//不相等,向前移动
              preNode=node;
              node=node.getNext();            
          }
          else{//相等,删除该结点
              int value=node.getValue();
              ListNote toBeDel=node;
              while(toBeDel!=null&&toBeDel.getValue()==value){
                  nextNode=toBeDel.getNext();//删除该结点
                  toBeDel=nextNode;
              }  
              if(preNode==null){//头结点删除时
                  root=nextNode;
              }
              else{
                  //即删除了重复结点
                  preNode.setNext(nextNode);
              }
              node=nextNode;
          }
        }
    }

 

 

转载于:https://my.oschina.net/u/2822116/blog/788183

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值