contestDouble-57

409 阅读2分钟

1.检查是否所有字符出现次数相同 (hash计数略)

2.最小未被占据椅子的编号 (优先队列+模拟)

用两个优先队列来,一个用座位号+离开时间进行排序,另一个用座位号来排序,按时间顺序模拟就好

type friend struct {
   arrive int
   leave  int
   num    int
}

type seat struct {
   freeTime int
   seatNum  int
}

// 优先级队列需要实现heap的interface
type PriorityQueue []*seat

// 绑定Len方法
func (pq PriorityQueue) Len() int {
   return len(pq)
}

// 绑定Less方法,这里用的是小于号,生成的是小根堆
func (pq PriorityQueue) Less(i, j int) bool {
   return pq[i].freeTime < pq[j].freeTime
}

// 绑定swap方法
func (pq PriorityQueue) Swap(i, j int) {
   pq[i], pq[j] = pq[j], pq[i]
}

// 绑定put方法,将index置为-1是为了标识该数据已经出了优先级队列了
func (pq *PriorityQueue) Pop() interface{} {
   old := *pq
   n := len(old)
   item := old[n-1]
   *pq = old[0 : n-1]
   return item
}

// 绑定push方法
func (pq *PriorityQueue) Push(x interface{}) {
   item := x.(*seat)
   *pq = append(*pq, item)
}

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 smallestChair(times [][]int, targetFriend int) int {
   friends := make([]friend, len(times))
   for i := 0 ; i < len(times) ; i++ {
      friends[i] = friend{arrive:times[i][0], leave:times[i][1], num:i}
   }
   sort.Slice(friends, func(i, j int) bool {
      if friends[i].arrive < friends[j].arrive {
         return true
      }
      return false
   })
   cur := 0
   needFree := make(PriorityQueue, 0)
   freeSeat := &IntHeap{}
   for i := 0 ; i < len(friends) ; i++ {
      if needFree.Len() != 0 && needFree[0].freeTime <= friends[i].arrive {
         for needFree.Len() > 0 && needFree[0].freeTime <= friends[i].arrive {
            val, _ := heap.Pop(&needFree).(*seat)
            heap.Push(freeSeat, val.seatNum)
         }
         if friends[i].num == targetFriend {
            return (*freeSeat)[0]
         }
         heap.Push(&needFree, &seat{freeTime:friends[i].leave, seatNum:(*freeSeat)[0]})
         heap.Pop(freeSeat)
      } else if freeSeat.Len() > 0 {
         if friends[i].num == targetFriend {
            return (*freeSeat)[0]
         }
         heap.Push(&needFree, &seat{freeTime:friends[i].leave, seatNum:(*freeSeat)[0]})
         heap.Pop(freeSeat)
      } else {
         if friends[i].num == targetFriend {
            return cur
         }
         heap.Push(&needFree, &seat{friends[i].leave, cur})
         cur++
      }
   }
   return 0
}

3.描述绘画结果 (差分)

题目已经给出了颜色不会相同的条件,同时只需要输出颜色的和,所以就用差分数组,把所有颜色和统计下来,由于没有相同的颜色,所以在一个颜色加入或者离开时,一定是一个可以输出的线段,需要用一个数组来记录端点,详情见代码。

func splitPainting(segments [][]int) [][]int64 {
   diff := make([]int, 100001)
   visited := make([]bool, 100001)
   res := make([][]int64, 0)
   for i := 0 ; i < len(segments) ; i++ {
      diff[segments[i][0]] += segments[i][2]
      diff[segments[i][1]] -= segments[i][2]
      visited[segments[i][0]] = true
      visited[segments[i][1]] = true
   }
   val := 0
   start := 0
   for i := 0 ; i < len(diff) ; i++ {
      if visited[i] {
         if val != 0 {
            t := make([]int64, 3)
            t[0] = int64(start)
            t[1] = int64(i)
            t[2] = int64(val)
            res = append(res, t)
         }
         start = i
         val += diff[i]
      }
   }
   return res
}

4.队列中可以看到的人数 (单调栈)

转化一下就是要求num[i]右边第一个比他大的数的位置,以及中间的数的数量,注意一点,中间的数是可以被遮挡的。考虑从后向前遍历,维护一个递减栈,如果当前元素比栈顶大,则直接出栈,并统计数量,这个值就是当前元素能看到的人数,同时已经出栈的这些元素对后续的元素也没有影响,因为比当前元素小,会被挡住。

func canSeePersonsCount(heights []int) []int {
   res := make([]int, len(heights))
   s := make([]int, 0)
   for i := len(heights) - 1; i >= 0 ; i-- {
      for len(s) > 0 && heights[i] > heights[s[len(s) - 1]] {
         res[i]++
         s = s[:len(s) - 1]
      }
      if len(s) > 0 {
         res[i]++
      }
      s = append(s, i)
   }
   return res
}