1.题目
LeetCode: 83. 删除排序链表中的重复元素
【easy】
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例1:
输入: 1->1->2
输出: 1->2
示例2:
输入: 1->1->2->3->3
输出: 1->2->3
2.解题
方法一:哈希表
将链表元素值存入哈希表,如果存入失败则代表有重复元素,然后让上一个节点的next指向当前节点的下一个节点,如果当前节点的下一个节点为null,则指向null即可。但是当遇到连续三个以上重复的元素时,则需要添加flag进行判断。
java:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
Set<Integer> value = new HashSet<>();
ListNode cur = head, pre = null;
boolean flag = false;
while (cur != null) {
if (!value.add(cur.val)) {
if (cur.next != null)
pre.next = cur.next;
else
pre.next = null;
flag = true;
}
if (!flag)
pre = cur;
cur = cur.next;
flag = false;
}
return head;
}
}
时间复杂度:O(n),由于需要对整个链表进行遍历,所以时间复杂度取决于链表长度。
空间复杂度:O(n)
方法二:直接法
在遍历链表时直接判断当前节点元素值和下一个节点值是否一样
java:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) return head;
ListNode cur = head;
while (cur.next != null) {
if (cur.val == cur.next.val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return head;
}
}
时间复杂度:O(n),由于需要对整个链表进行遍历,所以时间复杂度取决于链表长度。
空间复杂度:O(1)
方法三:递归法
递归出口:当前节点或者当前节点的下一个节点为null,返回
判断当前节点的元素值和当前节点的下一个节点的元素值是否一样,一样的话head.next = head.next.next。
java:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) return head;
head.next = deleteDuplicates(head.next);
return head.val == head.next.val ? head.next : head;
}
}
时间复杂度:O(n),每次递归都会执行一个节点,所以时间复杂度取决于链表长度。
空间复杂度:O(1)