程序员面试金典--题目解析-2.1 移除未排序链表中的重复结点

2.1 题目:

移除未排序链表中的重复结点

进阶:

不使用额外的数据结构


解法:

使用额外数据结构的解法:

遍历链表,如果不存在该key,使用map存储 key为node.item;value为true的数据,如果存在该key则删除该结点

  1. public static <E> void deleteDuplicateNode1(Node<E> head){  
  2.         HashMap<E,Boolean> map = new HashMap<>();  
  3.         Node<E> current = head;  
  4.         Node<E> previous = null;  
  5.           
  6.         while(current != null){  
  7.             if(map.containsKey(current.item)){  
  8.                 previous.next = current.next;  
  9.             }  
  10.             else{  
  11.                 map.put(current.item, true);  
  12.                 previous = current;  
  13.             }  
  14.             current = current.next;  
  15.         }  
  16.     } 


不使用额外数据结构的解法:

  1. public static <E> void deleteDuplicateNode2(Node<E> head){  
  2.         Node<E> current = head;  
  3.         while(current.next != null){  
  4.             Node<E> runner = current.next;  
  5.             do{  
  6.                 if(runner.item == current.item){  
  7.                     current.next = runner.next;  
  8.                 }  
  9.             }while((runner = runner.next) != null);  
  10.             current = current.next;  
  11.         }  
  12.     } 


Node的定义:

  1. public static class Node<E>{  
  2.         private E item;  
  3.         private Node<E> next;  
  4.           
  5.           
  6.         public Node(E item) {  
  7.             this.item = item;  
  8.         }  
  9.         public E getItem() {  
  10.             return item;  
  11.         }  
  12.         public void setItem(E item) {  
  13.             this.item = item;  
  14.         }  
  15.         public Node<E> getNext() {  
  16.             return next;  
  17.         }  
  18.         public void setNext(Node<E> next) {  
  19.             this.next = next;  
  20.         }  
  21.           
  22.           
  23.     } 


测试用例:

构建了一个两组 0到99999 

其中还对比了两个算法所用时间

在200000个数据情况下,第一种算法时间复杂度O(N) 耗时35ms 第二种算法时间复杂度O(N^2) 耗时15159ms,差距极大。

  1. @Test  
  2.     public void test_2_1() {  
  3.         Node<Integer> head = new Node<Integer>(0);  
  4.         Node<Integer> p = head;  
  5.         Node<Integer> node ;  
  6.         for(int i = 1;i < 200000;i++){  
  7.             if(i<100000){  
  8.                 p.setNext(new Node<Integer>(i));  
  9.             }  
  10.             else{  
  11.                 p.setNext(new Node<Integer>(i%100000));  
  12.             }  
  13.             p = p.getNext();  
  14.         }  
  15.           
  16.         printNodeList(head);  
  17.           
  18.         long start = System.currentTimeMillis();  
  19.         //LinkedListUtil.deleteDuplicateNode1(head);  
  20.         LinkedListUtil.deleteDuplicateNode2(head);  
  21.         long end = System.currentTimeMillis();  
  22.         System.out.println("time is " + (end - start));  
  23.           
  24.         System.out.println("------------------------------");  
  25.           
  26.         printNodeList(head);  
  27.     }  
  28.       
  29.     private <E> void printNodeList(Node<E> head){  
  30.         Node<E> node = head;  
  31.         while(node != null){  
  32.             System.out.println(node.getItem());  
  33.             node = node.getNext();  
  34.         }  
  35.     } 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值