汉诺塔问题
题目
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。
请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。
code
func hanota(A []int, B []int, C []int) []int {
move(&A, &B, &C, len(A))
return C
}
func move(A,B,C *[]int, n int) {
if n == 1 {
*C = append(*C, (*A)[len(*A) - 1])
*A = (*A)[:len(*A)-1]
} else {
move(A,C,B,n-1)
move(A,B,C,1)
move(B,A,C,n-1)
}
}
排序链表
题目
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:
你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
code
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
// 归并排序链表 时间复杂度nlogn 因为在分治的时候需要复制链表长度的节点,所以空间复杂度为O(n)
// PS:常数级空间复杂度目前想法是用快排,在交换链表节点时需要记录各自前一个节点
func sortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
slow := head
fast := head
preSlow := &ListNode{}
for fast != nil {
if fast != nil {
fast = fast.Next
}
preSlow = slow
slow = slow.Next
if fast != nil {
fast = fast.Next
}
}
preSlow.Next = nil
l := sortList(head)
r := sortList(slow)
return mergeNode(l,r)
}
func mergeNode(left, right *ListNode) *ListNode{
preNode := &ListNode{}
tmp := preNode
for left != nil && right != nil {
if left.Val < right.Val {
preNode.Next = left
left = left.Next
} else {
preNode.Next = right
right = right.Next
}
preNode = preNode.Next
}
if left != nil {
preNode.Next = left
}
if right != nil {
preNode.Next = right
}
return tmp.Next
}