知识点
知识点
归并排序(链表的归并排序)
利用快慢指针找到链表中点,然后排序。例如,以升序对某个链表进行归并排序的代码为:
public void mergeSort(ListNode head, ListNode tail) { // // base case。当链表为空或者只有一个节点时,返回 if (head == null) return null; if (head == tail) { // 先分离节点,然后返回 head.next = null; return head; } // 快慢指针找到链表中点 ListNode slow = head, fast = head; while (fast != tail) { slow = slow.next; fast = fast.next; if (fast != tail) { fast = fast.next; } } // 分 ListNode head1 = sort(head, slow); ListNode head2 = sort(slow, tail); // 治 ListNode sorted = merge(head1, head2); return sorted; } public ListNode merge(ListNode head1, ListNode head2) { ListNode dummyHead = new ListNode(0); ListNode temp = dummyHead, temp1 = head1, temp2 = head2; while (temp1 != null && temp2 != null) { if (temp1.val <= temp2.val) { temp.next = temp1; temp1 = temp1.next; } else { temp.next = temp2; temp2 = temp2.next; } temp = temp.next; } if (temp1 != null) { temp.next = temp1; } else if (temp2 != null) { temp.next = temp2; } return dummyHead.next; }
LeetCode算法题
LeetCode算法题
82.【删除排序链表中的重复元素 II】
解题思路:
链表兼具了递归和迭代结构,因此解题思路一定是递归或者迭代
由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。
最需要注意的一点是,因为可能头结点和头结点.next节点也是重复的,需要删除,因此需要新建一个哑巴节点连接头结点,预防这种情况。
148.【排序链表】
解题思路:
首先,先考虑排序算法中所有时间复杂度为O(nlogn)的,只有:归并排序、堆排序和快速排序。因为链表具有递归结构,首先考虑归并排序。
归并排序有两种,自顶向下和自底向上的。
首先,自顶向下的归并排序:利用递归写法,时间复杂度O(nlogn),空间复杂度O(logn)。排序过程如下
1,找到链表的中点,以中点为分界,将链表拆分成两个子链表。链表找中点,使用快慢指针即可。
2,对两个子链表分别排序
3,合并排好序的两个链表