算法之小细节(细节~链表的特殊结点~提升优化度)~反转链表、删除排序链表中的重复元素

算法之小细节(细节~链表的特殊结点~提升优化度)~删除排序链表中的重复元素、反转链表

 

1,删除排序链表中的重复元素

(1)细节优化度高的代码:

  public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        } else {
      // head.next 用得好 head.next
= deleteDuplicates(head.next);
       //因为 是已经排序的链表,头结点即最小,只需要比较head 与新链表的头结点(head.next)就够了
return head.val == head.next.val ? head.next:head; } }

(2)自己写的 代码哈哈哈:

    public ListNode deleteDuplicates(ListNode head) {
        // 头为空,或 只有一个头结点时
        if (head == null || head.next == null)
            return head;
        // 递归得到头之后的链表        
        ListNode pre = deleteDuplicates(head.next);
        if(pre == null)    return head;
        // 或者链表只有一个头结点时
        if (pre.next == null) {
            if (pre.val == head.val) {
                //解释一下,为什么不能return head;
                //若 return head; 的话,而原来head 还指着老链条,出现重复结点啦
                return pre;
            }else {
                head.next = pre;
            }
        } else {
            if (pre.val == head.val) {
                head.next = pre.next;
            }else {
                head.next = pre;
            }
        }
        return head;
    }

//很巧妙的 人家的思路:head.next = deleteDuplicates(head.next); 这样就相比较于自己的代码:

// ListNode pre = deleteDuplicates(head.next);
//ListNode pre = deleteDuplicates(head.next);

好处在于不用判断 pre的情况,不用担心使用 pre.next == null 的情况,又判断 pre == null的情况

 

2,反转链表:

(1)细节优化度高的代码:

先说一下递归思路: 

 * 递归: 根据语义 reverseList(ListNode head),返回一条倒置的链表的头结点,
 * 例如:原结点是 heda -》5-》4 -》3 -》2 -》1
 * 利用语义的话 reverseList(head.next),得到了 head -》5 -》
 * newHead -》1 -》2 -》3 -》4
 * 细节:因为没有断链,原来的5 还是指导 4 身上, 即 newHead -》1 -》2 -》3 -》4  《- 5 《- head
 * 所以,我们可以通过 5 的关系,拿到 4,调整4 指向5 ,
 * 细节, 5是最后一个结点:它的next 需要指向空, 通过 head的关系拿到 5

    public ListNode reverseList(ListNode head) {
        if(head == null)    return null;//return head; 也一样
        if(head.next == null)    return head;
        if(head == null || head.next == null)    return head;
        ListNode newHead = reverseList(head.next);
        //细节:这里用的是head.next.next(就是 4 这个结点的next指针),而不用 newHead这个变量,好处不用判断newHead(不为空时,就是4 这个结点) 是否为空,
        //因为咱如果是使用 newHead.next = head;(5 这个结点)   之前必须判断 newHead 是否为空,而使用 head.next(代表4 这个结点) 时,就可以避免判断情况
        head.next.next = head;
        head.next = null;
        return newHead;return newHead;
    }

 

posted @ 2021-10-11 22:05  一乐乐  阅读(78)  评论(0编辑  收藏  举报