主要记录一些LeetCode上没有的题以及解法。

圆环回原点问题

题目描述:
圆环上有9个点,编号为0~8。从0点出发,每次可以逆时针和顺时针走一步,问走n步回到0点共有多少种走法?

解法:

  1. package main
  2. import "fmt"
  3. type Node struct {
  4. Next *Node
  5. Prev *Node
  6. Val int
  7. }
  8. func main() {
  9. root := makeListCircle(9)
  10. n := 8
  11. fmt.Println(returnBack1(root, n))
  12. fmt.Println(returnBack2(root, n))
  13. }
  14. // 构造特定长度的圆环双链表
  15. func makeListCircle(length int) *Node {
  16. root := &Node{nil, nil, 0}
  17. t := root
  18. for i := 1; i < length; i++ {
  19. t.Next = &Node{nil, t, i}
  20. t = t.Next
  21. }
  22. t.Next, root.Prev = root, t
  23. return root
  24. }
  25. // 解法一:哈希
  26. func returnBack1(root *Node, n int) (ans int) {
  27. m := map[int][]*Node{0: {root}} // m[n]: 走 n 步可以到达的节点集合
  28. // 每轮通过走 i-1 步可以到达的点的集合,统计出走 i 步可到达的点的结合
  29. for i := 1; i <= n; i++ {
  30. nodeList := m[i-1] // 走 i-1 步可以到达的点的集合
  31. for _, v := range nodeList {
  32. m[i] = append(m[i], v.Next, v.Prev) // i-1 加一步为 i 步到达的集合
  33. }
  34. }
  35. for _, v := range m[n] {
  36. if v == root {
  37. ans++
  38. }
  39. }
  40. return
  41. }
  42. // 解法二:动态规划
  43. func returnBack2(root *Node, n int) int {
  44. length := 9
  45. dp := make([][]int, n+1) // dp[i][j]: 走i步到达序号为j的点的次数
  46. for i := range dp {
  47. dp[i] = make([]int, length)
  48. }
  49. dp[0][0] = 1
  50. for i := 1; i <= n; i++ {
  51. for j := 0; j < 9; j++ {
  52. dp[i][j] = dp[i-1][(j-1+length)%length] + dp[i-1][(j+1)%length]
  53. }
  54. }
  55. return dp[n][0]
  56. }

阿拉伯数字转中文数字

题目描述:输入一个 int 类型数字,输出 string 类型的中文数字。
如图:
image.png
解法:

  1. func num2cn(n int) (ans string) {
  2. str := strconv.Itoa(int(math.Abs(float64(n))))
  3. dict := []string{
  4. "零", "一", "二", "三", "四",
  5. "五", "六", "七", "八", "九",
  6. "十", "百", "千", "万", "亿"
  7. }
  8. if n == 0 {
  9. return dict[0]
  10. }
  11. t := 0 // 第几个四位
  12. for i := len(str) - 1; i >= 0; {
  13. // 每次处理四位数
  14. curStr := ""
  15. cnt := 0
  16. for cnt < 4 && i >= 0 {
  17. num := int(str[i] - '0')
  18. // 处理当前数为 0 的情况
  19. if num == 0 {
  20. for cnt < 4 && i > 0 && num == 0 { // 去除当前四位的重复 0
  21. i--
  22. num = int(str[i] - '0')
  23. cnt++
  24. }
  25. if curStr != "" {
  26. curStr = dict[0] + curStr
  27. }
  28. } else {
  29. if cnt > 0 {
  30. curStr = dict[9+cnt] + curStr
  31. }
  32. // 避免“11”被翻译为“一十一”
  33. if !(num == 1 && i == 0 && cnt == 1) {
  34. curStr = dict[num] + curStr
  35. }
  36. cnt++
  37. i--
  38. }
  39. }
  40. if t > 0 && curStr != "" { // 如果不是第一个四位或者四位都为0,加上一个单位
  41. curStr += dict[12+t]
  42. }
  43. ans = curStr + ans
  44. t++
  45. }
  46. if n < 0 {
  47. ans = "负" + ans
  48. }
  49. return
  50. }