阿坝藏族羌族自治州网站建设_网站建设公司_Windows Server_seo优化
2025/12/30 9:02:35 网站建设 项目流程

题⽬描述

在⼀个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5

示例1
输⼊:{1,2,3,3,4,4,5}
返回值:{1,2,5}

思路及解答

hash统计

第一次遍历统计频率,第二次遍历删除重复节点

import java.util.HashMap;public class Solution {public ListNode deleteDuplication(ListNode head) {if (head == null || head.next == null) {return head;}// 第一次遍历:统计每个节点值出现的次数HashMap<Integer, Integer> countMap = new HashMap<>();ListNode current = head;while (current != null) {countMap.put(current.val, countMap.getOrDefault(current.val, 0) + 1);current = current.next;}// 第二次遍历:删除重复节点ListNode dummy = new ListNode(-1); // 哑节点简化边界处理dummy.next = head;ListNode prev = dummy;current = head;while (current != null) {if (countMap.get(current.val) > 1) {// 当前节点重复,跳过prev.next = current.next;} else {// 当前节点不重复,移动prev指针prev = prev.next;}current = current.next;}return dummy.next;}
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

直接遍历(推荐)

注意,题目已经提到是排序的节点,那么就可以直接原地删除

对⽐前后两个元素,如果相同的情况下,接着遍历后⾯的元素,直到元素不相等的时候,将前⾯的指针指向最后⼀个相同的元素的后⾯,相当于跳过了相同的元素。

public class Solution {public ListNode deleteDuplication(ListNode pHead){//遍历链表,直接删除if(pHead == null || pHead.next == null) return pHead;ListNode head = new ListNode(0);head.next = pHead;ListNode cur = head.next;ListNode pre = head;while(cur != null){//将重复的结点都遍历过,然后将后面节点复制给pre结点后面if(cur.next != null && cur.val == cur.next.val){while(cur.next != null &&  cur.val == cur.next.val){cur = cur.next;}pre.next = cur.next;cur = cur.next;}else{pre = pre.next;cur = cur.next;}}return head.next;}
}
  • 空间复杂度为 O(1) ,没有借助额外的空间
  • 时间复杂度为 O(n) ,只遍历了⼀次链表

递归

将大问题分解为当前节点+剩余链表的子问题

/*** 递归法:分治思想解决子问题* 思路:将大问题分解为当前节点+剩余链表的子问题* */
public class Solution {public ListNode deleteDuplication(ListNode head) {// 递归终止条件:空链表或单节点链表if (head == null || head.next == null) {return head;}// 情况1:当前节点与下一节点重复if (head.val == head.next.val) {// 跳过所有重复节点,找到第一个不重复的节点ListNode node = head.next;while (node != null && head.val == node.val) {node = node.next;}// 递归处理剩余部分return deleteDuplication(node);} // 情况2:当前节点不重复else {head.next = deleteDuplication(head.next);return head;}}
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(n) ,递归栈空间

三指针法

使用pre、cur、next三个指针精确控制删除范围

public class Solution {public ListNode deleteDuplication(ListNode head) {if (head == null || head.next == null) {return head;}ListNode dummy = new ListNode(-1);dummy.next = head;ListNode pre = dummy;    // 前驱指针ListNode cur = head;     // 当前指针ListNode next = null;     // 后继指针while (cur != null && cur.next != null) {next = cur.next;// 发现重复节点if (cur.val == next.val) {// 移动next直到找到不重复的节点while (next != null && cur.val == next.val) {next = next.next;}// 跳过所有重复节点pre.next = next;cur = next;} // 没有重复,正常移动指针else {pre = cur;cur = cur.next;}}return dummy.next;}
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询