豆包AI刷题实践记录与工具使用 & Go 语言基础语法 | 豆包MarsCode AI刷题

62 阅读5分钟

数字分组求偶数和

问题描述

小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。

  • numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。

例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369

解题思路

该问题可以看作是一个多组数字的选择问题,要求从每个数字组中选择一个数字,组成的数字的各位和为偶数。由于对时间复杂度要求不高,我们可以采用暴搜,具体的思路如下:

  1. 初始化数字组:每个数字组由多个数字组成。可以通过遍历每个数字组,选择其中一个数字,累加到当前的数字和中。
  2. 目标条件:累加的数字和必须为偶数。最终,我们需要计算出符合这一条件的所有组合方式。
  3. 使用深度优先搜索(DFS):遍历每个数字组的所有数字,通过递归的方式进行选择。每次选择一个数字后,检查其对当前和的影响,并继续递归。
  4. 递归的终止条件:当遍历完所有的数字组时,检查当前的数字和是否为偶数,若是,则计数加1。

代码实现

package main

import "fmt"

func solution(numbers []int) int {
    // 将数字转为字符串
    sub := make([]string, len(numbers))
    for i, num := range numbers {
        sub[i] = fmt.Sprintf("%d", num)
    }

    return dfs(sub, 0, 0)
}

// 暴搜,参数分别为:当前字符串数组、当前处理的数组号和当前数字和
func dfs(numbers []string, index int, currentSum int) int {
    // 如果已经搜完,判断当前数字和是否为偶数
    if index == len(numbers) {
        if currentSum%2 == 0 {
            return 1
        }
        return 0
    }

    cnt := 0
    // 遍历当前组每个数字
    for i := 0; i < len(numbers[index]); i++ {
        num := int(numbers[index][i] - '0') // 将字符转换为数字
        // 递归调用,选择下一个组的数字,并累加当前数字和
        cnt += dfs(numbers, index+1, currentSum+num)
    }

    return cnt
}

func main() {
    fmt.Println(solution([]int{123, 456, 789}) == 14)
    fmt.Println(solution([]int{123456789}) == 4)
    fmt.Println(solution([]int{14329, 7568}) == 10)
}

代码解析

  1. 函数solution:接收一个数字组列表 numbers,将其转化为字符串列表 sub。然后调用 dfs 函数开始暴搜,寻找符合条件的组合,并返回符合条件的情况总数。
  2. 深度优先搜索(DFS)dfs 函数递归遍历每个数字组的所有数字,尝试将每个数字加入到当前的和 currentSum 中。每次递归到一个数字组时,选择一个数字后递归进入下一个数字组。
  3. 递归终止条件:当 index == len(numbers) 时,表示已经遍历完所有的数字组,检查当前的和 currentSum 是否为偶数,如果是偶数,则符合条件,计数 cnt 加1。

知识点总结

  • 深度优先搜索(DFS):DFS 是一种用于遍历树状结构或图形结构的算法,尤其适用于递归问题。在此问题中,DFS 用来遍历每个数字组的数字组合,通过递归深度地选取数字,直到构建出完整的数字序列,并检查其和是否满足条件。

  • 回溯思想:该问题的求解过程中,采用了回溯的方式进行遍历。每次递归选择一个数字后,继续向下探索,最终得到所有可能的组合方式,并通过判断每个组合的和是否为偶数来进行筛选。

  • 字符到数字的转换:在处理每个数字组时,我们使用 numbers[index][i] - '0' 将字符型数字转换为整型数字。这个技巧在处理字符串中的数字时很常用。

  • 递归的终止条件:递归在遍历完整个数字组后终止,终止时需要检查当前和是否为偶数。如果是偶数,则返回 1,表示这是一个符合条件的组合;如果不是偶数,则返回 0。最后作用到上一层的cnt中,由最外层dfs返回最终结果。

  • 空间优化与递归效率:递归过程中,通过传递当前的数字和 currentSum 和索引 index,避免了不必要的计算,并能够在每层递归时逐步更新和,直到所有可能的组合都被检查过,在问题规模相对较小的情况下,能有效求解。

实践记录和工具运用

在 MarsCode AI 刷题过程中,结合题目解析、图解辅助,能提升编程技能。除此之外,在使用过程中我还感受到以下优点:

1. 即时反馈和代码优化:MarsCode AI 可以即时评估提交的代码,并提供优化建议。除了AC,还能通过 AI 的提示来改进代码的时间复杂度、空间复杂度,或代码风格。对提升编程能力、代码质量有很大帮助。

2. 多样化的题型:题库中涵盖了大量的题型,包括动态规划、队列、位运算、栈、数学、贪心、双指针、图论、模拟等。通过多维度的练习,能够提升不同领域的综合能力,而不仅仅局限于某一个特定领域的知识。

3. 题库难度分级:题库分为简单、中等、困难,能逐渐提高代码水平过程中,保持挑战感。这种“由浅入深”的学习方式有助于在实践中不断突破自己。

总结

通过在 MarsCode AI 上解决数字分组求偶数和问题,我学到了如何通过深度优先搜索(DFS)来解决多组数字选择的问题,并深入掌握了字符串解析、数字转换以及回溯思想的应用。结合 AI 辅助和自我总结的过程,提高了我的编程能力,也进一步深化了对算法和数据结构的理解。