本周的周赛题目看上去似乎比较简单,差不多 1 小时做完被挤出了 top 200,所以相对来说可能大家也做得比较顺手。

(有个值得一提的点是这周的比赛似乎考察了 4 个树的题目?)

图 1:第 179 场周赛排名(临时)

Q1:生成每种字符都是奇数个的字符串

这道题的题目比较唬烂,看上去很难,其实就是两种情况,如果给定的数是奇数,那么返回 N 个 A 就好了,如果给定的是偶数,那么就返回 N-1 个 A 和 1 个 B 就好了:

[[email protected]]# cat Q1.go
import "strings"

func generateTheString(n int) (rst string) {
    for i := 0; n != 0 && i < 26; i++ {
        if n%2 == 1 {
            rst += strings.Repeat(string('a'+i), n)
            n = 0
        } else {
            rst += strings.Repeat(string('a'+i), n-1)
            n = 1
        }
    }
    return
}

Q2:灯泡开关 III

这道题其实也不难,但是说实话,我还是卡了一下的,最后还是想明白了,其实你只要保证当前亮着的最大序号的灯和当前的时刻一致就好了,这就表示所有亮着的灯都是蓝色了。

其实回头想一想,这道题目还是在题目的描述很绕,仔细想一想就比较简单了:

[[email protected]]# cat Q2.go
func numTimesAllBlue(light []int) (rst int) {
    var (
        i       int
        maxOpen = 0
        length  = len(light)
    )
    for i = 0; i < length; i++ {
        if light[i] > maxOpen {
            maxOpen = light[i]
        }
        if maxOpen == i+1 {
            rst++
        }
    }
    return rst
}

Q3:通知所有员工所需的时间

这道题其实就是一个 BFS,然后针对每个叶子节点判断到当前叶子节点需要的时间,然后进行一个最大值的计算就可以了。

这里我的处理是一开始将 manager 构造出一棵树,因为 manager 不是一棵树,所以我构造了 employee:

[[email protected]]# cat Q3.go
type obj struct {
    No   int
    Time int
}

func numOfMinutes(n int, headID int, manager []int, informTime []int) int {
    var (
        i, count int
        curr     obj
        length   = len(manager)
        l        = list.New()
        employee = make([][]int, length)
    )

    for i = 0; i < length; i++ {
        if i == headID {
            continue
        }
        employee[manager[i]] = append(employee[manager[i]], i)
    }

    l.PushBack(obj{
        No:   headID,
        Time: informTime[headID],
    })
    for l.Len() > 0 {
        curr = l.Remove(l.Front()).(obj)
        for i = 0; i < len(employee[curr.No]); i++ {
            l.PushBack(obj{
                No:   employee[curr.No][i],
                Time: curr.Time + informTime[employee[curr.No][i]],
            })
        }
        if len(employee[curr.No]) == 0 {
            if curr.Time > count {
                count = curr.Time
            }
        }
    }

    return count
}

Q4:T 秒后青蛙的位置

这其实也是一道 BFS 的题目,但是,有几个点需要注意:

理解完这些之后其实就简单了:

[[email protected]]# cat Q4.go
type obj struct {
    target  int
    length  int
    posible float64
}

func frogPosition(length int, edges [][]int, t int, target int) float64 {
    var (
        i       int
        curr    obj
        graph   = make([][]int, length+1)
        visited = map[int]bool{}
        l       = list.New()
    )
    for i = 0; i < len(edges); i++ {
        graph[edges[i][0]] = append(graph[edges[i][0]], edges[i][1])
        graph[edges[i][1]] = append(graph[edges[i][1]], edges[i][0])
    }

    l.PushBack(obj{
        target:  1,
        length:  0,
        posible: 1.0,
    })
    for l.Len() != 0 {
        curr = l.Remove(l.Front()).(obj)
        if visited[curr.target] {
            continue
        }
        visited[curr.target] = true
        if curr.target == target {
            if curr.length > t {
                return 0
            }
            if curr.length == t {
                return curr.posible
            }
            for i = 0; i < len(graph[curr.target]); i++ {
                if !visited[graph[curr.target][i]] {
                    return 0
                }
            }
            return curr.posible
        }
        for i = 0; i < len(graph[curr.target]); i++ {
            childNum := len(graph[curr.target])
            if curr.target != 1 {
                childNum--
            }
            l.PushBack(obj{
                target:  graph[curr.target][i],
                length:  curr.length + 1,
                posible: curr.posible / float64(childNum),
            })
        }
    }
    return 0
}