Срезы
left := nums[:mid]
right := nums[mid:]
Срезы не копируют данные; это полезно, пока части только читаются.
Раздели задачу на независимые части, реши их и объедини результаты.
Минимальный синтаксис, который понадобится в решении.
left := nums[:mid]
right := nums[mid:]
Срезы не копируют данные; это полезно, пока части только читаются.
if small(input) { return base(input) }
return combine(solve(left), solve(right))
Обязательно формулируй уменьшающийся размер задачи.
Три идиоматичных решения на Go с оценкой времени и памяти.
Делим fast/slow и сливаем отсортированные половины.
O(n log n) time · O(log n) stackfunc sortList(head *ListNode) *ListNode {
if head == nil || head.Next == nil { return head }
slow, fast := head, head.Next
for fast != nil && fast.Next != nil { slow, fast = slow.Next, fast.Next.Next }
right := slow.Next; slow.Next = nil
return mergeLists(sortList(head), sortList(right))
}
Середина сортированного массива становится корнем.
O(n) time · O(log n) stackfunc sortedArrayToBST(nums []int) *TreeNode {
if len(nums) == 0 { return nil }
mid := len(nums)/2
return &TreeNode{
Val: nums[mid],
Left: sortedArrayToBST(nums[:mid]),
Right: sortedArrayToBST(nums[mid+1:]),
}
}
Результат для половины степени используется дважды.
O(log n) time · O(log n) spacefunc power(x float64, n int) float64 {
if n == 0 { return 1 }
half := power(x, n/2)
if n%2 == 0 { return half*half }
return half*half*x
}