删除无序链表中重复节点,保留第一次出现的节点
面试题 02.01. 移除重复节点:https://leetcode-cn.com/problems/remove-duplicate-node-lcci/
编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。
/* 1.使用HashSet 解题思路: 先对head进行初始化判断 1.对链表进行一次遍历,并用一个哈希集合(HashSet)来存储节点。 2.判断链表中出现的元素有没有被包含在HashSet中(contains) 2.1.包含在HashSet中,则直接跳过这个节点,进入下一个节点 2.2.没有包含在HashSet中,则将该节点添加到HashSet中,然后进入下一个节点 如果可以加进去add(),则说明之前没有,继续遍历。 如果加不进去,则说明之前存在,删除节点 */ class Solution { public ListNode removeDuplicateNodes(ListNode head) { if (head == null || head.next == null){ return head; } ListNode prev = head; ListNode cur = prev.next; HashSet<Integer> hashSet = new HashSet<Integer>(); hashSet.add(prev.val); while (cur != null){ if (hashSet.contains(cur.val)){ prev.next = cur.next; cur = cur.next; }else { hashSet.add(cur.val); cur = cur.next; prev = prev.next; } } return head; } class Solution { public ListNode removeDuplicateNodes(ListNode head) { if (head == null || head.next == null) { return head; } Set<Integer> occurred = new HashSet<Integer>(); occurred.add(head.val); ListNode pos = head; // 枚举前驱节点 while (pos.next != null) { // 当前待删除节点 ListNode cur = pos.next; if (occurred.add(cur.val)) { pos = pos.next; } else { pos.next = cur.next; } } pos.next = null; return head; } } /* 2.暴力解法(双指针) 解题思路: 使用两个while循环, 一个指向一个固定的值比如m, 另一个从m的下一个节点开始扫描, 如果遇到和m相同的结点,直接过滤掉 */ public ListNode removeDuplicateNodes(ListNode head) { ListNode cur = head; while (cur != null) { ListNode temp = cur; while (temp.next != null) { if (temp.next.val == cur.val) { temp.next = temp.next.next; } else { temp = temp.next; } } cur = cur.next; } return head; } 3.递归 public ListNode removeDuplicateNodes(ListNode head) { return removeDuplicateNodesHelper(head, new HashSet<>()); } public ListNode removeDuplicateNodesHelper(ListNode head, Set<Integer> set) { if (head == null) return null; if (set.contains(head.val)) return removeDuplicateNodesHelper(head.next, set); set.add(head.val); head.next = removeDuplicateNodesHelper(head.next, set); return head; } }

浙公网安备 33010602011771号