contest-253

231 阅读1分钟

这场AK了,题目比较水...

1.检查字符串是否为数组前缀 (简单模拟略)

2.移除石子使总数最小 (贪心+优先队列)

贪心的移除当前能减少最多的石子,有优先队列模拟该过程。

type IntHeap []int  // 定义一个类型

func (h IntHeap) Len() int { return len(h) }  // 绑定len方法,返回长度
func (h IntHeap) Less(i, j int) bool {  // 绑定less方法
   return h[i] > h[j]  // 如果h[i]<h[j]生成的就是小根堆,如果h[i]>h[j]生成的就是大根堆
}
func (h IntHeap) Swap(i, j int) {  // 绑定swap方法,交换两个元素位置
   h[i], h[j] = h[j], h[i]
}

func (h *IntHeap) Pop() interface{} {  // 绑定pop方法,从最后拿出一个元素并返回
   old := *h
   n := len(old)
   x := old[n-1]
   *h = old[0 : n-1]
   return x
}

func (h *IntHeap) Push(x interface{}) {  // 绑定push方法,插入新元素
   *h = append(*h, x.(int))
}

func minStoneSum(piles []int, k int) int {
   h := &IntHeap{}
   for i := 0 ; i < len(piles) ; i++ {
      heap.Push(h, piles[i])
   }
   for k > 0 {
      val, _ := heap.Pop(h).(int)
      t := val / 2
      heap.Push(h, val - t)
      k--
   }
   res := 0
   for h.Len() > 0 {
      v, _ := heap.Pop(h).(int)
      res += v
   }
   return res
}

3.使字符串平衡的最小交换次数 (前缀和)

首先需要知道一个合法的只包含一种括号类型的字符串,在该串的任何一个位置,左括号的数量一定大于等于右括号的数量,所以预先处理出每个位置的左括号和右括号的前缀和,如果当前位置的右括号数量大于左括号的数量,则需要进行一次交换。

func minSwaps(s string) int {
   left := make([]int, len(s))
   right := make([]int, len(s))
   if s[0] == '[' {
      left[0] = 1
   } else {
      right[0] = 1
   }
   for i := 1 ; i < len(s) ; i++ {
      left[i] += left[i - 1]
      right[i] += right[i - 1]
      if s[i] == '[' {
         left[i]++
      } else {
         right[i]++
      }
   }
   delta := 0
   for i := 0 ; i < len(s) ; i++ {
      if left[i] + delta < right[i] - delta {
         delta++
      }
   }
   return delta
}

4.找出到每个位置为止最长的有效障碍赛跑路线(dp+二分)

该题为最长上升子序列的模型,但是需要注意数据量,要用nlogn的解法才能过。

func longestObstacleCourseAtEachPosition(obstacles []int) []int {
   arr := make([]int, 0)
   res := make([]int, len(obstacles))
   for i := 0 ; i < len(obstacles) ; i++ {
      if len(arr) == 0 {
         arr = append(arr, obstacles[i])
         res[i] = 1
      } else if obstacles[i] >= arr[len(arr) - 1] {
         arr = append(arr, obstacles[i])
         res[i] = len(arr)
      } else {
         l := 0
         r := len(arr) - 1
         for l <= r {
            mid := (l + r) / 2
            if obstacles[i] >= arr[mid] {
               l = mid + 1
            } else {
               r = mid - 1
            }
         }
         arr[l] = obstacles[i]
         res[i] = l + 1
      }
   }
   return res
}