知识点:

  1. 链表的基本操作,遍历和删除节点。
  2. 单链表的操作。
  3. 循环遍历链表。

题意分析:

题目描述了一个链表,链表节点表示农场里的牛,节点的值为牛的编号。链表已经按照非降序排列,但由于一些事故,导致有些牛的编号可能多次出现在链表中。要求删除链表中所有重复的编号,只保留每个牛的唯一编号,并返回已排序的链表。

时间复杂度:

假设链表中有N个节点。

  1. 在代码中,我们需要一次遍历整个链表来删除重复的节点。在最坏情况下,我们可能需要遍历整个链表一次,这需要O(N)的时间复杂度。
  2. 因此,总的时间复杂度为O(N)。

代码分析:

代码中的解决思路是利用两个指针precur分别表示当前节点和下一个节点,遍历链表,找到重复节点并进行删除操作。具体的步骤如下:

  1. 如果链表长度小于等于1,无需处理,直接返回原链表。
  2. 初始化两个指针precur,分别指向头节点和第二个节点。
  3. 开始循环遍历链表: a. 如果pre节点的值等于cur节点的值,说明是重复节点,删除当前重复节点(即pre.next指向cur.next)。 b. 如果pre节点的值不等于cur节点的值,说明是非重复节点,更新pre指针为cur。 c. 更新cur指针为cur.next,继续下一轮的遍历。
  4. 最后返回删除重复节点后的链表头节点。

代码:

import java.util.*;

class ListNode {
    int val;
    ListNode next;

    public ListNode(int val) {
        this.val = val;
    }
}

public class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        ListNode pre = head;
        ListNode cur = head.next;

        while (cur != null) {
            if (pre.val == cur.val) {
                pre.next = cur.next;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }

        return head;
    }
}