第一种解题思路:用集合就行,重复的给删掉,后面可能有多个重复的值所以这里用repeat变量来保存最近一次重复的值,如果和后面不一样则说明后面不是连续重复的就放进集合里,如果后面的值还等于repeat,说明后面还在一直重复就不放集合里了,时间复杂度O(n),空间复杂度O(n)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates (ListNode head) {
// write code here
if (head == null || head.next == null) {
return head;
}
ArrayList<Integer> list = new ArrayList<>();
int repeat = -1;
while (head != null) {
if (list.contains(head.val)) {
repeat = head.val;
int size = list.size();
list.remove(size - 1);
} else {
if (repeat != head.val) {
list.add(head.val);
}
}
head = head.next;
}
ListNode pre = new ListNode(-1);
ListNode result = pre;
for (int i = 0; i < list.size(); i++) {
ListNode node = new ListNode(list.get(i));
pre.next = node;
pre = pre.next;
}
return result.next;
}
}
第二种方法:声明pre,cur,next三个指针和一个标签位来判断当前节点是否重复过,重复过就过滤掉,不重复就放到pre的后面,这种方式只是声明了有限个指针,而且只是遍历了一遍链表,所以时间复杂度O(n),空间复杂度O(1)
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates (ListNode head) {
// write code here
if (head == null || head.next == null) {
return head;
}
ListNode pre = new ListNode(-1);
pre.next = head;
ListNode result = pre;
ListNode cur = head;
ListNode next = null;
while (cur != null) {
next = cur.next;
boolean repeat = false;
while (next != null && cur.val == next.val) {
cur = cur.next;
next = next.next;
repeat = true;
}
//没有当前节点和后面节点重复的
if (!repeat) {
pre.next = cur;
pre = pre.next;
}
cur = cur.next;
}
pre.next = null;
return result.next;
}
}