1. LCR077 : 排序链表
题 :
给定链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1: 输入:head = [4,2,1,3] 输出:[1,2,3,4] 示例 2: 输入:head = [-1,5,3,4,0] 输出:[-1,0,3,4,5] 示例 3: 输入:head = [] 输出:[] 提示: 链表中节点的数目在范围 [0, 5 * 104] 内 -105 <= Node.val <= 105 进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
解法1 : 借助辅助数组求解
思路 : 先一轮遍历,确定链表节点的个数,并使用辅助数组将链表节点的数据域记录下来,再遍历链表反向覆盖.该解法空间复杂度较高O(n),时间复杂度较低O(n).
解 :
class Solution { public ListNode sortList(ListNode head) { //如果是空链表, 或者链表只有一个节点时, 此时无需排序 if (head == null || head.next == null) { return head; } int n = 0; ListNode temp = head; while (temp != null) { n++; temp = temp.next; } int[] arr = new int[n]; temp = head; n = 0; while (temp != null) { arr[n++] = temp.val; temp = temp.next; } Arrays.sort(arr); temp = head; n = 0; while (temp != null) { temp.val = arr[n++]; temp = temp.next; } return head; } }
解法2 : 递归
思路 :
解 :
2. 力扣83 : 删除排序链表中的重复元素
题 :
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 示例 1: 输入:head = [1,1,2] 输出:[1,2] 示例 2: 输入:head = [1,1,2,3,3] 输出:[1,2,3] 提示: 链表中节点数目在范围 [0, 300] 内 -100 <= Node.val <= 100 题目数据保证链表已经按升序 排列
(1). 解法1 : 递归
思路 : 不断递,当递到最后一个节点时,返回最后一个节点,第一次归时,p指向了最后一个节点,head指向了p的上一个节点,如果二者相等,则删除p.返回head节点.
(2). 技巧 :
- 在于该链表是升序排列的,所以比较相邻节点的大小.
- 该链表的头节点不用删除,所以不用借助于哨兵节点.
(3). 解 :
class Solution { public ListNode deleteDuplicates(ListNode head) { //如果链表为空, 或者只有一个节点 if (head == null || head.next == null) { return head; } ListNode p = deleteDuplicates(head.next); if (head.val == p.val) { head.next = head.next.next; } return head; } }
(2). 解法2 : 递归
思路 : 如果head指向的节点和下一节点的val值相同,则返回head的下一节点的递归结果(相当于把自己删了).如果head指向的节点与下一节点的val值不相等,则返回head自己和其下一节点的递归结果.
解 :
class Solution { public ListNode deleteDuplicates(ListNode head) { if (head == null || head.next == null) { return head; } if (head.val == head.next.val) { return deleteDuplicates(head.next); } else { head.next = deleteDuplicates(head.next); return head; } } }
(3). 解法3 : 双指针
思路 : 使用快慢指针,如果fast指针指向的节点的值与其下一个节点相等,则需要删除fast指针指向的下一个节点.否则将fast指针指向下一个节点.循环直到slow指针指向null为止.
解 :
class Solution { public ListNode deleteDuplicates(ListNode head) { if (head == null || head.next == null) { return head; } ListNode fast = head; ListNode slow; while ((slow = fast.next) != null) { if (fast.val == slow.val) { fast.next = fast.next.next; } else { fast = fast.next; } } return head; } }