面试题18题目二:删除排序链表中重复的节点
题目要求:
比如[1,2,2,3,3,3],删除之后为[1];
解题思路:
由于是已经排序好的链表,需要确定重复区域的长度,删除后还需要将被删去的前与后连接,所以需要三个节点pre,cur,post,cur-post为重复区域,删除后将pre与post.next连接即可。
此外,要注意被删结点区域处在链表头部的情况,因为需要修改head。
package structure;
/**
* Created by ryder on 2017/6/13.
*/
public class ListNode<T> {
public T val;
public ListNode<T> next;
public ListNode(T val){
this.val = val;
this.next = null;
}
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
ret.append("[");
for(ListNode cur = this;;cur=cur.next){
if(cur==null){
ret.deleteCharAt(ret.lastIndexOf(" "));
ret.deleteCharAt(ret.lastIndexOf(","));
break;
}
ret.append(cur.val);
ret.append(", ");
}
ret.append("]");
return ret.toString();
}
}
package chapter3;
import structure.ListNode;
/**
* Created by ryder on 2017/7/7.
* 删除排序链表中的重复节点
*/
public class P122_deleteDuplicatedNode {
public static ListNode<Integer> deleteDuplication(ListNode<Integer> head){
if(head==null||head.next==null)
return head;
ListNode<Integer> pre = null;
ListNode<Integer> cur = head;
ListNode<Integer> post = head.next;
boolean needDelete = false;
while (post!=null){
if(cur.val.equals(post.val)){
needDelete = true;
post=post.next;
}
else if(needDelete && !cur.val.equals(post.val)){
if(pre==null)
head = post;
else
pre.next=post;
cur = post;
post = post.next;
needDelete = false;
}
else{
pre = cur;
cur = post;
post = post.next;
}
}
if(needDelete && pre!=null)
pre.next = null;
else if(needDelete && pre==null)
head = null;
return head;
}
public static void main(String[] args){
ListNode<Integer> head = new ListNode<>(1);
head.next= new ListNode<>(1);
head.next.next = new ListNode<>(2);
head.next.next.next = new ListNode<>(2);
head.next.next.next.next = new ListNode<>(2);
head.next.next.next.next.next = new ListNode<>(3);
System.out.println(head);
head = deleteDuplication(head);
System.out.println(head);
}
}
运行结果
[1, 2, 3]
[1, 2]
[2]