描述:给定一个有序链表,若有一个以上相同节点,则将该元素值的节点均删除。
情形1:
输入:1->2->2->3->4->4->5
输出:1->3->5
情形2:
输入:1->1->1->2->3
输出:2->3
思路:这道题的难点在于要将重复元素无保留的全部删除。所以必须要找到重复元素的前一个元素,记作pre。用first指向头节点用于返回
针对情形一,pre,node分别指向相邻的元素,如果node和它后面的元素不同,那么pre和node各自移动一位;如果node和它后面的元素一样,那么移动node到重复元素的后一位,然后用pre,指向当前node。 外层嵌套一个node.next!=null用于循环
针对情形二,将node移动到重复元素的后一位,first指向该node。递归调用delete方法进行循环
代码:
内部静态类LinkNode
1 private static class LinkNode{ 2 private int date; 3 private LinkNode next=null; 4 public LinkNode(int date) { 5 this.date=date; 6 } 7 public LinkNode(int date,LinkNode pre) { 8 this.date=date; 9 pre.next=this; 10 } 11 }
delete方法
1 public static LinkNode delete(LinkNode node) { 2 if(node==null) return null; 3 if(node.next!=null) { 4 LinkNode first=node; 5 LinkNode pre=node; 6 node=node.next; 7 if(first.date!=first.next.date) { 8 while(node.next!=null) { 9 if(node.date!=node.next.date) { //如果node和它后面元素,两个不相等,各自移动 10 node=node.next; 11 pre=pre.next; 12 }else { 13 while(node.date==node.next.date) { //如果node和它后面的相等 14 node=node.next; //node移动到最后一个重复元素 15 } 16 node=node.next; //再移动一个,重复元素的后一个 17 pre.next=node; //pre指向node 18 } 19 } 20 }else { 21 while(node.date==node.next.date) node=node.next; 22 node=node.next; 23 first=node; 24 delete(first); 25 } 26 return first; //返回删除重复元素的指针 27 } 28 return null; 29 }
main方法:
1 public static void main(String[] args) { 2 LinkNode n1=new LinkNode(1); 3 LinkNode n2=new LinkNode(1,n1); 4 LinkNode n3=new LinkNode(1,n2); 5 LinkNode n4=new LinkNode(2,n3); 6 LinkNode n5=new LinkNode(3,n4); 7 LinkNode n6=new LinkNode(4,n5); 8 LinkNode node=n1; 9 System.out.println("删除前:"); 10 while(node!=null) { 11 System.out.print(node.date+" "); 12 node=node.next; 13 } 14 System.out.println(); 15 LinkNode nodeafterdelete=delete(n1); 16 System.out.println("删除后:"); 17 while(nodeafterdelete!=null) { 18 System.out.print(nodeafterdelete.date+" "); 19 nodeafterdelete=nodeafterdelete.next; 20 } 21 System.out.println(); 22 }
结果