问题一
汉诺塔问题: https://leetcode-cn.com/problems/hanota-lcci/
思路:汉诺塔问题,使用递归解决,主要三个步骤:
(1)、将A上n - 1个盘子移动到B上,借助C
(2)、将A第n个盘子移动到C上
(3)、将B上的n - 1个盘子移动到C上,借助A
public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
move(A.size(), A, B, C);
}
public void move(int n, List<Integer> A, List<Integer> B, List<Integer> C) {
// 如果只有一个盘子,则直接移动到C
if (n == 1) {
C.add(A.remove(A.size() - 1));
return;
} else {
// 将A上 1 至 n - 1的盘子移动到B,以C为辅助
move(n - 1, A, C, B);
//将A上的n号盘子移动到C
C.add(A.remove(A.size() - 1));
// 将B上的盘子移到C,以A为辅助
move(n - 1, B, A, C);
}
}
问题二
排序链表:https://leetcode-cn.com/problems/sort-list/
思路:难点在于节点的指针变动,首先想到了将所有节点都放入list中,然后利用Collections进行排序后,再依次生成新的排序后的链表,但是时间复杂度较高。第二种思路是使用归并排序,归并排序是链表排序的一种有效方法,简单的讲,就是将要排序的链表一分为二之后再递归的一分为二,最后将排好序的链表再进行二合一,最终合成一个排序好的链表。
思路一:使用常规方法
public ListNode sortList(ListNode head) {
List<ListNode> list = new ArrayList<>();
while (head != null) {
list.add(head);
head = head.next;
}
Collections.sort(list, Comparator.comparingInt(o -> o.val));
ListNode resultNode = null, lastNode = null;
for (ListNode node : list) {
node.next = null;
if (lastNode == null) {
resultNode = node;
} else {
lastNode.next = node;
}
lastNode = node;
}
return resultNode;
}
思路二:使用归并排序
public ListNode sortList(ListNode head) {
return mergeSort(head);
}
// 归并排序
public ListNode mergeSort(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode slow = head, fast = head.next.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode right = mergeSort(slow.next);
// 断开连接
slow.next = null;
ListNode left = mergeSort(head);
return mergeList(left, right);
}
// 合并list
public ListNode mergeList(ListNode left, ListNode right) {
ListNode tmpHead = new ListNode(), currentHead = tmpHead;
while (left != null && right != null) {
if (left.val <= right.val) {
currentHead.next = left;
currentHead = left;
left = left.next;
} else {
currentHead.next = right;
currentHead = right;
right = right.next;
}
}
if (left != null) {
currentHead.next = left;
}
if (right != null) {
currentHead.next = right;
}
return tmpHead.next;
}