面試題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]