LeetCode 83.删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

注意点:题目条件中给出的已经是排好序的链表

示例 1:

输入: 1->1->2
输出: 1->2

示例2:

输入: 1->1->2->3->3
输出: 1->2->3

解法一:

递归

思路:

  • 第一步:先找到递归出口,即当链表的head或者head.next为null时,此时链表不存在重复的元素,返回head

  • 第二步:将大问题划分为小问题来解决,我们知道递归的问题基本上都有很多级,而每一级的递归操作其实都是做重复一样的事情,所以我们可以重点关注第一级的递归操作需要完成什么工作。在这个题目中,我们把给出的链表划分为一个个小问题,然后解决,例如:给出的链表为1->1->2->3->3,我们划分为:

    3->3,2->3->3,1->2->3->3,1->1->2->3->3这样的子链表来依次解决,所以我们的递归体里面给出的参数为head.next,每次都去处理子问题,得到已经去重的链表的头结点,直至大问题被解决。

  • 每一步要做什么:宏观上考虑,此时head.next已经指向一个去重的链表了,而根据第二步,我应该返回一个去重的链表的头节点。因此这一步应该做的是判断当前的head和head.next是否相等,如果相等则说明重了,返回head.next,否则返回head

关于使用递归解决问题,如果还不清楚的话,可以看看这篇博客:三道题套路解决递归问题

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        //1.解决基本问题
        if(head == null || head.next == null){
            return head;
        }
        //2.将大问题划分为小问题
        head.next = deleteDuplicates(head.next);
        //3.求解小问题的解
        if(head.val == head.next.val){
            return head.next;
        }else return head;
    }
}

解法二:

头指针

思路:

  • 指定cur指针指向头部head
  • 当 cur 和 cur.next 的存在为循环结束条件,当二者有一个不存在时说明链表没有去重复的必要了
  • 当 cur.val 和 cur.next.val 相等时说明需要去重,则将 cur 的下一个指针指向下一个的下一个,这样就能达到去重复的效果
  • 如果不相等则 cur 移动到下一个位置继续循环
  • 时间复杂度:O(n)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode cur = head;
        while(cur != null && cur.next!=null){
            if(cur.val == cur.next.val){
                cur.next = cur.next.next;
            }else{
                cur = cur.next;
            }
        }
        return head;
    }
}
posted @ 2020-07-15 15:25  南笙北沫  阅读(119)  评论(0编辑  收藏  举报