package q3510 import "container/heap" type Node struct { val int prev, next *Node arrPos, heapPos int } type MinAdjSum []*Node func (m *MinAdjSum) Len() int { return len(*m) } func (m *MinAdjSum) Less(i int, j int) bool { if (*m)[i].next == nil { return false } if (*m)[j].next == nil { return true } s1, p1 := (*m)[i].val+(*m)[i].next.val, (*m)[i].arrPos s2, p2 := (*m)[j].val+(*m)[j].next.val, (*m)[j].arrPos if s1 == s2 { return p1 < p2 } return s1 < s2 } func (m *MinAdjSum) Push(x any) { elem := x.(*Node) elem.heapPos = len(*m) *m = append(*m, elem) } func (m *MinAdjSum) Pop() any { ret := (*m)[len(*m)-1] (*m) = (*m)[:len(*m)-1] return ret } func (m *MinAdjSum) Swap(i int, j int) { (*m)[i].heapPos = j (*m)[j].heapPos = i (*m)[i], (*m)[j] = (*m)[j], (*m)[i] } func minimumPairRemoval(nums []int) int { outOfOrder := 0 for i := range len(nums) - 1 { if nums[i] > nums[i+1] { outOfOrder++ } } if outOfOrder == 0 { return 0 } nodes := make([]Node, len(nums)) hp := make(MinAdjSum, len(nums)) for i := range nums { nodes[i] = Node{val: nums[i], heapPos: i, arrPos: i} hp[i] = &nodes[i] if i > 0 { nodes[i].prev = &nodes[i-1] } if i+1 < len(nums) { nodes[i].next = &nodes[i+1] } } heap.Init(&hp) ops := 0 for ; outOfOrder > 0; ops++ { node := hp[0] next, prev := node.next, node.prev heap.Remove(&hp, node.heapPos) heap.Remove(&hp, next.heapPos) if prev != nil { heap.Remove(&hp, prev.heapPos) } // Update outOfOrder if next.val < node.val { outOfOrder-- } if next.next != nil && next.next.val < next.val { outOfOrder-- } if prev != nil && node.val < prev.val { outOfOrder-- } node.val += next.val if prev != nil && node.val < prev.val { outOfOrder++ } if next.next != nil && next.next.val < node.val { outOfOrder++ } // Update links & fix heap node.next = next.next if next.next != nil { next.next.prev = node } heap.Push(&hp, node) if prev != nil { heap.Push(&hp, prev) } } return ops } var _ = minimumPairRemoval