1.作为子字符串出现在单词中的字符串数目(模拟略)
2.构造元素不等于两相邻元素平均值的数组 (贪心)
根据题目的需求,为了保证(nums[i-1] + nums[i+1]) / 2 不等于 nums[i] 均成立,我的想法是贪心的将数组变成多个山脉形,也就是说让nums[i] > nums[i - 1],nums[i] > nums[i + 1],这样一定能满足题目的需求。
func rearrangeArray(nums []int) []int {
sort.Ints(nums)
for i := 2 ; i < len(nums) ; i += 2 {
t := nums[i]
nums[i] = nums[i - 1]
nums[i - 1] = t
}
return nums
}
3.数组元素的最小非零乘积 (贪心+快速幂)
这是一道数学题,多找几次规律可以发现,答案为(2p−1)(2p−2)^(2^(p−1)−1) 例如如果是p = 16,那交换之后最小的乘积一定是1*14(没有啥规律,就是多试几次) 最后求幂,那就再加上快速幂咯。
func minNonZeroProduct(p int) int {
return (1<<p - 1) % mod * pow(1<<p-2, 1<<(p-1)-1) % mod
}
func pow(x int, n int) int {
if n == 0 {
return 1
}
if n == 1 {
return x
}
tem := pow(x, n >> 1)
res := tem * tem % mod
if n % 2 == 0 {
return res
} else {
return res * x % mod
}
}
4.你能穿过矩阵的最后一天 (dfs/bfs+二分)
也算是一个经典的套路吧,首先能否从第一行走到最后一行,这是一个简单的搜索问题,用深/广搜都可以。之后考虑天数,没有啥规律只能枚举,而线性枚举太慢了,所以则采用二分的方式来进行搜索。
type div struct {
x int
y int
}
func latestDayToCross(row int, col int, cells [][]int) int {
dis := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
l := 0
r := row * col
res := 0
for l <= r {
m := (l + r) / 2
grid := make([][]int, row)
for i := 0 ; i < len(grid) ; i++ {
grid[i] = make([]int, col)
}
for i := 0 ; i < len(grid) ; i++ {
for j := 0 ; j < len(grid[i]) ; j++ {
grid[i][j] = 1
}
}
for i := 0 ; i < m ; i++ {
grid[cells[i][0] - 1][cells[i][1] - 1] = 0
}
q := make([]div, 0)
for i := 0 ; i < col ; i++ {
if grid[0][i] != 0 {
q = append(q, div{
x: 0,
y: i,
})
}
}
found := false
for len(q) > 0 {
cur := q[0]
q = q[1:]
for i := 0 ; i < 4 ; i++ {
x := cur.x + dis[i][0]
y := cur.y + dis[i][1]
for x >= 0 && y >= 0 && x < row && y < col && grid[x][y] == 1 {
if x == row - 1 {
found = true
break
}
q = append(q, div{
x: x,
y: y,
})
grid[x][y] = 0
}
}
}
if found {
res = m
l = m + 1
} else {
r = m - 1
}
}
return res
}