练习内容:
1. 汉诺塔问题
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。
请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。
你需要原地修改栈。
示例 1:
输入:A = [2, 1, 0], B = [], C = []
输出:C = [2, 1, 0]
示例 2:
输入:A = [1, 0], B = [], C = []
输出:C = [1, 0]
题目来自leetcode
递归法:
思路:
将n-1个盘子从A柱放在C柱上,问题一步步拆解,符合递归的大问题分解成小问题规律。
然后进行递归公式分析
,终止条件推敲
。
1.当n=1时
,设置基准条件,将A柱上唯一的盘子直接放在C柱上。
2.当n>1时
,需要通过A柱上的n-1个盘子进行如下操作
- 将A柱的盘子通过C放到B上
- 当A柱上的最大盘子放在C柱上后,A柱为空
- 此时将B柱上的盘子通过A柱放在C上
python代码如下:
class Solution:
def hanota(self, A: List[int], B: List[int], C: List[int]) -> None:
"""
Do not return anything, modify C in-place instead.
"""
n = len(A)
self.recursive(n,A,B,C)
return C
def recursive(self,n,A,B,C):
#终止条件
if n == 1:
C.append(A.pop())
else:
self.recursive(n-1,A,C,B) # A通过C放到B上
C.append(A.pop()) # C上有最大盘子,此时A为空
self.recursive(n-1,B,A,C) # B通过A放到C上
代码执行后:
时间复杂度: O(2n-1)
空间复杂度: O(n)
2.排序链表
给你链表的头结点 head
,请将其按升序
排列并返回排序后的链表
。
进阶:
- 你可以在
O(n log n)
时间复杂度和常数级空间复杂度下,对链表进行排序吗?
示例1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例3:
输入:head = []
输出:[]
题目来自leetcode
归并排序+双指针取中法:
思路:
从题目中得知要保证O(n log n)
的时间复杂度,所以采用归并排序的方法,可以实现。但为了得到链表的中间值,需要采用快慢双指针的方法进行取值。
1.双指针将链表分成两部分:
- 设置边界,防止链表为空
fast
走两步,slow
走一步。将slow
的位置放在pre
里,当fast
走到末尾,slow
正好在中间。此时通过pre
打断链表。- 返回两组
head
和slow
链表
2.进行归并排序:
- 定义一个新链表
dummy
,表头为tail
- 当
h1
和h2
不为空时,如果h1
<h2
,将h1
加到tail
中,tail
移到h1
的位置。h1
向后移动。当h2
<h1
时,以此类推。 - 排序到最后,甩尾的数值直接加到
tail
的末尾。
题目来自leetcode
python代码如下:
class Solution:
def merge(self,h1,h2):
dummy = tail = ListNode()
while h1 and h2:
if h1.val < h2.val:
tail.next = h1
tail = h1
h1 = h1.next
else:
tail.next = h2
tail = h2
h2 = h2.next
tail.next = h1 or h2
return dummy.next
def sortList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
pre = None
fast = slow = head
while fast and fast.next:
pre = slow
fast = fast.next.next
slow = slow.next
pre.next = None # 找到中间值后,打断链表
return self.merge(self.sortList(head),self.sortList(slow))
代码执行后:
时间复杂度:O(n log n)
空间复杂度:O(1)
总结
本周的两道题分别对递归和归并排序的知识点展开的
我是小白,自学的编程,希望各位大佬如果看到文章中,有什么表述问题,还望不吝赐教。生怕误导别人~谢谢
- 本周两题任务完成