算法之小细节(细节~链表的特殊结点~提升优化度)~删除排序链表中的重复元素、反转链表
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; }
// 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; }