圆环回原点问题
题目描述:
圆环上有9个点,编号为0~8。从0点出发,每次可以逆时针和顺时针走一步,问走n步回到0点共有多少种走法?
解法:
package mainimport "fmt"type Node struct {Next *NodePrev *NodeVal int}func main() {root := makeListCircle(9)n := 8fmt.Println(returnBack1(root, n))fmt.Println(returnBack2(root, n))}// 构造特定长度的圆环双链表func makeListCircle(length int) *Node {root := &Node{nil, nil, 0}t := rootfor i := 1; i < length; i++ {t.Next = &Node{nil, t, i}t = t.Next}t.Next, root.Prev = root, treturn root}// 解法一:哈希func returnBack1(root *Node, n int) (ans int) {m := map[int][]*Node{0: {root}} // m[n]: 走 n 步可以到达的节点集合// 每轮通过走 i-1 步可以到达的点的集合,统计出走 i 步可到达的点的结合for i := 1; i <= n; i++ {nodeList := m[i-1] // 走 i-1 步可以到达的点的集合for _, v := range nodeList {m[i] = append(m[i], v.Next, v.Prev) // i-1 加一步为 i 步到达的集合}}for _, v := range m[n] {if v == root {ans++}}return}// 解法二:动态规划func returnBack2(root *Node, n int) int {length := 9dp := make([][]int, n+1) // dp[i][j]: 走i步到达序号为j的点的次数for i := range dp {dp[i] = make([]int, length)}dp[0][0] = 1for i := 1; i <= n; i++ {for j := 0; j < 9; j++ {dp[i][j] = dp[i-1][(j-1+length)%length] + dp[i-1][(j+1)%length]}}return dp[n][0]}
阿拉伯数字转中文数字
题目描述:输入一个 int 类型数字,输出 string 类型的中文数字。
如图:
解法:
func num2cn(n int) (ans string) {str := strconv.Itoa(int(math.Abs(float64(n))))dict := []string{"零", "一", "二", "三", "四","五", "六", "七", "八", "九","十", "百", "千", "万", "亿"}if n == 0 {return dict[0]}t := 0 // 第几个四位for i := len(str) - 1; i >= 0; {// 每次处理四位数curStr := ""cnt := 0for cnt < 4 && i >= 0 {num := int(str[i] - '0')// 处理当前数为 0 的情况if num == 0 {for cnt < 4 && i > 0 && num == 0 { // 去除当前四位的重复 0i--num = int(str[i] - '0')cnt++}if curStr != "" {curStr = dict[0] + curStr}} else {if cnt > 0 {curStr = dict[9+cnt] + curStr}// 避免“11”被翻译为“一十一”if !(num == 1 && i == 0 && cnt == 1) {curStr = dict[num] + curStr}cnt++i--}}if t > 0 && curStr != "" { // 如果不是第一个四位或者四位都为0,加上一个单位curStr += dict[12+t]}ans = curStr + anst++}if n < 0 {ans = "负" + ans}return}
