1. Squares of a Sorted Array
解题思路:排序搞一下即可。
AC 代码:
package main
import (
"fmt"
"sort"
)
func sortedSquares(A []int) []int {
var b []int
for i := range A {
b = append(b, A[i]*A[i])
}
sort.Ints(b)
return b
}
func main() {
fmt.Println(sortedSquares([]int{-4, -1, 0, 3, 10}))
}
2. Longest Turbulent Subarray
解题思路:预处理下数组,A[i] 与 A[i+1] 的大小关系无非有三种,相等(0),小于(-1),大于(1)。我们的目的就是要找下 -1, 1 交错出现的最大长度 + 1,扫描一遍数组即可。
AC 代码:
func maxInt(a, b int) int {
if a > b {
return a
}
return b
}
func maxTurbulenceSize(A []int) int {
if len(A) == 1 {
return 1
}
var (
ans int
b []int
sum int
)
for i := 0; i < len(A)-1; i++ {
if A[i] < A[i+1] {
b = append(b, -1)
} else if A[i] == A[i+1] {
b = append(b, 0)
} else {
b = append(b, 1)
}
}
for i := range b {
if b[i] == 0 {
ans = maxInt(ans, sum)
sum = 0
continue
}
if (i > 0 && b[i] != b[i-1]) || i == 0 {
sum++
ans = maxInt(ans, sum)
continue
}
sum = 1
}
ans = maxInt(ans, sum)
return ans + 1
}
func main() {
fmt.Println(maxTurbulenceSize([]int{1, 1, 1}))
fmt.Println(maxTurbulenceSize([]int{9, 4, 2, 10, 7, 8, 8, 1, 9}))
fmt.Println(maxTurbulenceSize([]int{4,8,12,16}))
}
3.Distribute Coins in Binary Tree
解题思路:这题一开始没想明白,先去搞的 D 题。 D 题搞完以后,这题才有了思路。 从叶子节点向上处理,在遇到自身节点不存在金币的时候,则其肯定是要向其父节点要的,如果父节点没有,则向其祖先节点要。我们在递归处理的时候需要记录下当前节点需要向父节点(借或送)多少个金币。如果不为0,则需要将当前借或送的金币数加到最终总消耗的步数上,最终递归到 root 节点时便是最终需要消耗的移动步数。
AC 代码:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func absInt(a int) int {
if a < 0 {
return -a
}
return a
}
func distributeCoins(root *TreeNode) int {
var (
cnt int
do func(root *TreeNode) int
)
do = func(root *TreeNode) int {
if root == nil {
return 0
}
num := root.Val
lnum := do(root.Left)
rnum := do(root.Right)
if lnum != 0 {
cnt += absInt(lnum)
}
if rnum != 0 {
cnt += absInt(rnum)
}
num += lnum
num += rnum
num--
return num
}
do(root)
return cnt
}
4. Unique Paths III
解题思路: 看到这题后,知道是要求解哈密顿路径。首先,容易想到 dfs 可以枚举出所有答案,但是可能超时。一不小心看到题目给的数据范围 1 <= grid.length * grid[0].length <= 20
也就是说最多会有 20 个点,所以直接状压 DP 搞一发。假设 dp[i][j] 表示经过 所有可达顶点且最后一个顶点是 j 的路径数,状态转移方程为 dp[i][j] = SUM(dp[i^(1<<j)][k]),k 属于顶点集合i且g[k][j]=1
,易知 dp[1<<s][s] = 1
。
AC 代码:
const (
maxn = 20
)
var dx = [4]int{-1, 1, 0, 0}
var dy = [4]int{0, 0, -1, 1}
func uniquePathsIII(grid [][]int) int {
if len(grid) == 0 {
return 0
}
n := len(grid)
if len(grid[0]) == 0 {
return 0
}
m := len(grid[0])
var (
s int
e int
f int
g [maxn][maxn]int
dp [(1 << maxn) + 10][20]int
)
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
for k := 0; k < 4; k++ {
x := i + dx[k]
y := j + dy[k]
if x >= 0 && x < n && y >= 0 && y < m && grid[x][y] != -1 {
g[i*m+j][x*m+y] = 1
}
}
if grid[i][j] == 1 {
s = i*m + j
}
if grid[i][j] == 2 {
e = i*m + j
}
if grid[i][j] != -1 {
f |= 1 << uint(i*m+j)
}
}
}
dp[1<<uint(s)][s] = 1
for i := 1; i <= f; i++ {
for j := 0; j < n*m; j++ {
if i&(1<<uint(j)) > 0 {
for k := 0; k < n*m; k++ {
if i&(1<<uint(k)) > 0 && k != j && g[k][j] == 1 {
dp[i][j] += dp[i^(1<<uint(j))][k]
}
}
}
}
}
return dp[f][e]
}
func main() {
fmt.Println(uniquePathsIII([][]int{
{1, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 2, -1},
}))
fmt.Println(uniquePathsIII([][]int{
{1, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 2},
}))
fmt.Println(uniquePathsIII([][]int{
{0, 1},
{2, 0},
}))
}